xref: /aosp_15_r20/external/compiler-rt/lib/builtins/fp_extend.h (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot //===-lib/fp_extend.h - low precision -> high precision conversion -*- C -*-===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot //                     The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is dual licensed under the MIT and the University of Illinois Open
6*7c3d14c8STreehugger Robot // Source Licenses. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // Set source and destination setting
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
13*7c3d14c8STreehugger Robot 
14*7c3d14c8STreehugger Robot #ifndef FP_EXTEND_HEADER
15*7c3d14c8STreehugger Robot #define FP_EXTEND_HEADER
16*7c3d14c8STreehugger Robot 
17*7c3d14c8STreehugger Robot #include "int_lib.h"
18*7c3d14c8STreehugger Robot 
19*7c3d14c8STreehugger Robot #if defined SRC_SINGLE
20*7c3d14c8STreehugger Robot typedef float src_t;
21*7c3d14c8STreehugger Robot typedef uint32_t src_rep_t;
22*7c3d14c8STreehugger Robot #define SRC_REP_C UINT32_C
23*7c3d14c8STreehugger Robot static const int srcSigBits = 23;
24*7c3d14c8STreehugger Robot #define src_rep_t_clz __builtin_clz
25*7c3d14c8STreehugger Robot 
26*7c3d14c8STreehugger Robot #elif defined SRC_DOUBLE
27*7c3d14c8STreehugger Robot typedef double src_t;
28*7c3d14c8STreehugger Robot typedef uint64_t src_rep_t;
29*7c3d14c8STreehugger Robot #define SRC_REP_C UINT64_C
30*7c3d14c8STreehugger Robot static const int srcSigBits = 52;
src_rep_t_clz(src_rep_t a)31*7c3d14c8STreehugger Robot static __inline int src_rep_t_clz(src_rep_t a) {
32*7c3d14c8STreehugger Robot #if defined __LP64__
33*7c3d14c8STreehugger Robot     return __builtin_clzl(a);
34*7c3d14c8STreehugger Robot #else
35*7c3d14c8STreehugger Robot     if (a & REP_C(0xffffffff00000000))
36*7c3d14c8STreehugger Robot         return __builtin_clz(a >> 32);
37*7c3d14c8STreehugger Robot     else
38*7c3d14c8STreehugger Robot         return 32 + __builtin_clz(a & REP_C(0xffffffff));
39*7c3d14c8STreehugger Robot #endif
40*7c3d14c8STreehugger Robot }
41*7c3d14c8STreehugger Robot 
42*7c3d14c8STreehugger Robot #elif defined SRC_HALF
43*7c3d14c8STreehugger Robot typedef uint16_t src_t;
44*7c3d14c8STreehugger Robot typedef uint16_t src_rep_t;
45*7c3d14c8STreehugger Robot #define SRC_REP_C UINT16_C
46*7c3d14c8STreehugger Robot static const int srcSigBits = 10;
47*7c3d14c8STreehugger Robot #define src_rep_t_clz __builtin_clz
48*7c3d14c8STreehugger Robot 
49*7c3d14c8STreehugger Robot #else
50*7c3d14c8STreehugger Robot #error Source should be half, single, or double precision!
51*7c3d14c8STreehugger Robot #endif //end source precision
52*7c3d14c8STreehugger Robot 
53*7c3d14c8STreehugger Robot #if defined DST_SINGLE
54*7c3d14c8STreehugger Robot typedef float dst_t;
55*7c3d14c8STreehugger Robot typedef uint32_t dst_rep_t;
56*7c3d14c8STreehugger Robot #define DST_REP_C UINT32_C
57*7c3d14c8STreehugger Robot static const int dstSigBits = 23;
58*7c3d14c8STreehugger Robot 
59*7c3d14c8STreehugger Robot #elif defined DST_DOUBLE
60*7c3d14c8STreehugger Robot typedef double dst_t;
61*7c3d14c8STreehugger Robot typedef uint64_t dst_rep_t;
62*7c3d14c8STreehugger Robot #define DST_REP_C UINT64_C
63*7c3d14c8STreehugger Robot static const int dstSigBits = 52;
64*7c3d14c8STreehugger Robot 
65*7c3d14c8STreehugger Robot #elif defined DST_QUAD
66*7c3d14c8STreehugger Robot typedef long double dst_t;
67*7c3d14c8STreehugger Robot typedef __uint128_t dst_rep_t;
68*7c3d14c8STreehugger Robot #define DST_REP_C (__uint128_t)
69*7c3d14c8STreehugger Robot static const int dstSigBits = 112;
70*7c3d14c8STreehugger Robot 
71*7c3d14c8STreehugger Robot #else
72*7c3d14c8STreehugger Robot #error Destination should be single, double, or quad precision!
73*7c3d14c8STreehugger Robot #endif //end destination precision
74*7c3d14c8STreehugger Robot 
75*7c3d14c8STreehugger Robot // End of specialization parameters.  Two helper routines for conversion to and
76*7c3d14c8STreehugger Robot // from the representation of floating-point data as integer values follow.
77*7c3d14c8STreehugger Robot 
srcToRep(src_t x)78*7c3d14c8STreehugger Robot static __inline src_rep_t srcToRep(src_t x) {
79*7c3d14c8STreehugger Robot     const union { src_t f; src_rep_t i; } rep = {.f = x};
80*7c3d14c8STreehugger Robot     return rep.i;
81*7c3d14c8STreehugger Robot }
82*7c3d14c8STreehugger Robot 
dstFromRep(dst_rep_t x)83*7c3d14c8STreehugger Robot static __inline dst_t dstFromRep(dst_rep_t x) {
84*7c3d14c8STreehugger Robot     const union { dst_t f; dst_rep_t i; } rep = {.i = x};
85*7c3d14c8STreehugger Robot     return rep.f;
86*7c3d14c8STreehugger Robot }
87*7c3d14c8STreehugger Robot // End helper routines.  Conversion implementation follows.
88*7c3d14c8STreehugger Robot 
89*7c3d14c8STreehugger Robot #endif //FP_EXTEND_HEADER
90