20
20
typedef float src_t ;
21
21
typedef uint32_t src_rep_t ;
22
22
#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 ;
24
27
#define src_rep_t_clz clzsi
25
28
26
29
#elif defined SRC_DOUBLE
27
30
typedef double src_t ;
28
31
typedef uint64_t src_rep_t ;
29
32
#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 ) {
32
39
#if defined __LP64__
33
40
return __builtin_clzl (a );
34
41
#else
@@ -38,6 +45,18 @@ static __inline int src_rep_t_clz(src_rep_t a) {
38
45
return 32 + clzsi (a & REP_C (0xffffffff ));
39
46
#endif
40
47
}
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 ;
41
60
42
61
#elif defined SRC_HALF
43
62
#ifdef COMPILER_RT_HAS_FLOAT16
@@ -47,7 +66,11 @@ typedef uint16_t src_t;
47
66
#endif
48
67
typedef uint16_t src_rep_t ;
49
68
#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
+
51
74
#define src_rep_t_clz __builtin_clz
52
75
53
76
#else
@@ -58,36 +81,83 @@ static const int srcSigBits = 10;
58
81
typedef float dst_t ;
59
82
typedef uint32_t dst_rep_t ;
60
83
#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 ;
62
88
63
89
#elif defined DST_DOUBLE
64
90
typedef double dst_t ;
65
91
typedef uint64_t dst_rep_t ;
66
92
#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 ;
68
97
69
98
#elif defined DST_QUAD
99
+ // TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
100
+ #if __LDBL_MANT_DIG__ == 113
70
101
typedef long double dst_t ;
102
+ #elif defined(__x86_64__ ) && \
103
+ (defined(__FLOAT128__ ) || defined(__SIZEOF_FLOAT128__ ))
104
+ typedef __float128 dst_t ;
105
+ #endif
71
106
typedef __uint128_t dst_rep_t ;
72
107
#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 ;
74
112
75
113
#else
76
114
#error Destination should be single, double, or quad precision!
77
115
#endif // end destination precision
78
116
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.
81
151
82
- static __inline src_rep_t srcToRep (src_t x ) {
152
+ static inline src_rep_t srcToRep (src_t x ) {
83
153
const union {
84
154
src_t f ;
85
155
src_rep_t i ;
86
156
} rep = {.f = x };
87
157
return rep .i ;
88
158
}
89
159
90
- static __inline dst_t dstFromRep (dst_rep_t x ) {
160
+ static inline dst_t dstFromRep (dst_rep_t x ) {
91
161
const union {
92
162
dst_t f ;
93
163
dst_rep_t i ;
0 commit comments