2020typedef float src_t ;
2121typedef uint32_t src_rep_t ;
2222#define SRC_REP_C UINT32_C
23- static const int srcSigBits = 23 ;
23+ static const int srcBits = sizeof (src_t ) * CHAR_BIT ;
24+ static const int srcSigFracBits = 23 ;
25+ // -1 accounts for the sign bit.
26+ static const int srcExpBits = srcBits - srcSigFracBits - 1 ;
2427#define src_rep_t_clz clzsi
2528
2629#elif defined SRC_DOUBLE
2730typedef double src_t ;
2831typedef uint64_t src_rep_t ;
2932#define SRC_REP_C UINT64_C
30- static const int srcSigBits = 52 ;
31- static __inline int src_rep_t_clz (src_rep_t a ) {
33+ static const int srcBits = sizeof (src_t ) * CHAR_BIT ;
34+ static const int srcSigFracBits = 52 ;
35+ // -1 accounts for the sign bit.
36+ static const int srcExpBits = srcBits - srcSigFracBits - 1 ;
37+
38+ static inline int src_rep_t_clz_impl (src_rep_t a ) {
3239#if defined __LP64__
3340 return __builtin_clzl (a );
3441#else
@@ -38,6 +45,18 @@ static __inline int src_rep_t_clz(src_rep_t a) {
3845 return 32 + clzsi (a & REP_C (0xffffffff ));
3946#endif
4047}
48+ #define src_rep_t_clz src_rep_t_clz_impl
49+
50+ #elif defined SRC_80
51+ typedef long double src_t ;
52+ typedef __uint128_t src_rep_t ;
53+ #define SRC_REP_C (__uint128_t)
54+ // sign bit, exponent and significand occupy the lower 80 bits.
55+ static const int srcBits = 80 ;
56+ static const int srcSigFracBits = 63 ;
57+ // -1 accounts for the sign bit.
58+ // -1 accounts for the explicitly stored integer bit.
59+ static const int srcExpBits = srcBits - srcSigFracBits - 1 - 1 ;
4160
4261#elif defined SRC_HALF
4362#ifdef COMPILER_RT_HAS_FLOAT16
@@ -47,7 +66,11 @@ typedef uint16_t src_t;
4766#endif
4867typedef uint16_t src_rep_t ;
4968#define SRC_REP_C UINT16_C
50- static const int srcSigBits = 10 ;
69+ static const int srcBits = sizeof (src_t ) * CHAR_BIT ;
70+ static const int srcSigFracBits = 10 ;
71+ // -1 accounts for the sign bit.
72+ static const int srcExpBits = srcBits - srcSigFracBits - 1 ;
73+
5174#define src_rep_t_clz __builtin_clz
5275
5376#else
@@ -58,36 +81,83 @@ static const int srcSigBits = 10;
5881typedef float dst_t ;
5982typedef uint32_t dst_rep_t ;
6083#define DST_REP_C UINT32_C
61- static const int dstSigBits = 23 ;
84+ static const int dstBits = sizeof (dst_t ) * CHAR_BIT ;
85+ static const int dstSigFracBits = 23 ;
86+ // -1 accounts for the sign bit.
87+ static const int dstExpBits = dstBits - dstSigFracBits - 1 ;
6288
6389#elif defined DST_DOUBLE
6490typedef double dst_t ;
6591typedef uint64_t dst_rep_t ;
6692#define DST_REP_C UINT64_C
67- static const int dstSigBits = 52 ;
93+ static const int dstBits = sizeof (dst_t ) * CHAR_BIT ;
94+ static const int dstSigFracBits = 52 ;
95+ // -1 accounts for the sign bit.
96+ static const int dstExpBits = dstBits - dstSigFracBits - 1 ;
6897
6998#elif defined DST_QUAD
99+ // TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
100+ #if __LDBL_MANT_DIG__ == 113
70101typedef long double dst_t ;
102+ #elif defined(__x86_64__ ) && \
103+ (defined(__FLOAT128__ ) || defined(__SIZEOF_FLOAT128__ ))
104+ typedef __float128 dst_t ;
105+ #endif
71106typedef __uint128_t dst_rep_t ;
72107#define DST_REP_C (__uint128_t)
73- static const int dstSigBits = 112 ;
108+ static const int dstBits = sizeof (dst_t ) * CHAR_BIT ;
109+ static const int dstSigFracBits = 112 ;
110+ // -1 accounts for the sign bit.
111+ static const int dstExpBits = dstBits - dstSigFracBits - 1 ;
74112
75113#else
76114#error Destination should be single, double, or quad precision!
77115#endif // end destination precision
78116
79- // End of specialization parameters. Two helper routines for conversion to and
80- // from the representation of floating-point data as integer values follow.
117+ // End of specialization parameters.
118+
119+ // TODO: These helper routines should be placed into fp_lib.h
120+ // Currently they depend on macros/constants defined above.
121+
122+ static inline src_rep_t extract_sign_from_src (src_rep_t x ) {
123+ const src_rep_t srcSignMask = SRC_REP_C (1 ) << (srcBits - 1 );
124+ return (x & srcSignMask ) >> (srcBits - 1 );
125+ }
126+
127+ static inline src_rep_t extract_exp_from_src (src_rep_t x ) {
128+ const int srcSigBits = srcBits - 1 - srcExpBits ;
129+ const src_rep_t srcExpMask = ((SRC_REP_C (1 ) << srcExpBits ) - 1 ) << srcSigBits ;
130+ return (x & srcExpMask ) >> srcSigBits ;
131+ }
132+
133+ static inline src_rep_t extract_sig_frac_from_src (src_rep_t x ) {
134+ const src_rep_t srcSigFracMask = (SRC_REP_C (1 ) << srcSigFracBits ) - 1 ;
135+ return x & srcSigFracMask ;
136+ }
137+
138+ #ifdef src_rep_t_clz
139+ static inline int clz_in_sig_frac (src_rep_t sigFrac ) {
140+ const int skip = (sizeof (dst_t ) * CHAR_BIT - srcBits ) + 1 + srcExpBits ;
141+ return src_rep_t_clz (sigFrac ) - skip ;
142+ }
143+ #endif
144+
145+ static inline dst_rep_t construct_dst_rep (dst_rep_t sign , dst_rep_t exp , dst_rep_t sigFrac ) {
146+ return (sign << (dstBits - 1 )) | (exp << (dstBits - 1 - dstExpBits )) | sigFrac ;
147+ }
148+
149+ // Two helper routines for conversion to and from the representation of
150+ // floating-point data as integer values follow.
81151
82- static __inline src_rep_t srcToRep (src_t x ) {
152+ static inline src_rep_t srcToRep (src_t x ) {
83153 const union {
84154 src_t f ;
85155 src_rep_t i ;
86156 } rep = {.f = x };
87157 return rep .i ;
88158}
89159
90- static __inline dst_t dstFromRep (dst_rep_t x ) {
160+ static inline dst_t dstFromRep (dst_rep_t x ) {
91161 const union {
92162 dst_t f ;
93163 dst_rep_t i ;
0 commit comments