10
10
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOATPROPERTIES_H
11
11
12
12
#include " src/__support/UInt128.h"
13
- #include " src/__support/macros/attributes.h" // LIBC_INLINE
13
+ #include " src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
14
14
#include " src/__support/macros/properties/float.h" // LIBC_COMPILER_HAS_FLOAT128
15
15
16
16
#include < stdint.h>
@@ -27,22 +27,98 @@ enum class FPType {
27
27
X86_Binary80,
28
28
};
29
29
30
- template <FPType> struct FPProperties {};
31
- template <> struct FPProperties <FPType::IEEE754_Binary32> {
32
- typedef uint32_t BitsType;
30
+ // For now 'FPEncoding', 'FPBaseProperties' and 'FPCommonProperties' are
31
+ // implementation details.
32
+ namespace internal {
33
+
34
+ // The type of encoding for supported floating point types.
35
+ enum class FPEncoding {
36
+ IEEE754,
37
+ X86_ExtendedPrecision,
38
+ };
39
+
40
+ template <FPType> struct FPBaseProperties {};
41
+
42
+ template <> struct FPBaseProperties <FPType::IEEE754_Binary16> {
43
+ using UIntType = uint16_t ;
44
+ LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 16 ;
45
+ LIBC_INLINE_VAR static constexpr int SIG_BITS = 10 ;
46
+ LIBC_INLINE_VAR static constexpr int EXP_BITS = 5 ;
47
+ LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754;
48
+ };
49
+
50
+ template <> struct FPBaseProperties <FPType::IEEE754_Binary32> {
51
+ using UIntType = uint32_t ;
52
+ LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 32 ;
53
+ LIBC_INLINE_VAR static constexpr int SIG_BITS = 23 ;
54
+ LIBC_INLINE_VAR static constexpr int EXP_BITS = 8 ;
55
+ LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754;
56
+ };
57
+
58
+ template <> struct FPBaseProperties <FPType::IEEE754_Binary64> {
59
+ using UIntType = uint64_t ;
60
+ LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 64 ;
61
+ LIBC_INLINE_VAR static constexpr int SIG_BITS = 52 ;
62
+ LIBC_INLINE_VAR static constexpr int EXP_BITS = 11 ;
63
+ LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754;
64
+ };
65
+
66
+ template <> struct FPBaseProperties <FPType::IEEE754_Binary128> {
67
+ using UIntType = UInt128;
68
+ LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 128 ;
69
+ LIBC_INLINE_VAR static constexpr int SIG_BITS = 112 ;
70
+ LIBC_INLINE_VAR static constexpr int EXP_BITS = 15 ;
71
+ LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754;
72
+ };
73
+
74
+ template <> struct FPBaseProperties <FPType::X86_Binary80> {
75
+ using UIntType = UInt128;
76
+ LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 80 ;
77
+ LIBC_INLINE_VAR static constexpr int SIG_BITS = 64 ;
78
+ LIBC_INLINE_VAR static constexpr int EXP_BITS = 15 ;
79
+ LIBC_INLINE_VAR static constexpr auto ENCODING =
80
+ FPEncoding::X86_ExtendedPrecision;
81
+ };
82
+
83
+ // Derives more properties from 'FPBaseProperties' above.
84
+ // This class serves as a halfway point between 'FPBaseProperties' and
85
+ // 'FPProperties' below.
86
+ template <FPType fp_type>
87
+ struct FPCommonProperties : private FPBaseProperties <fp_type> {
88
+ using UP = FPBaseProperties<fp_type>;
89
+ using BitsType = typename UP::UIntType;
90
+
91
+ LIBC_INLINE_VAR static constexpr uint32_t BIT_WIDTH = UP::TOTAL_BITS;
92
+ LIBC_INLINE_VAR static constexpr uint32_t MANTISSA_WIDTH = UP::SIG_BITS;
93
+ LIBC_INLINE_VAR static constexpr uint32_t EXPONENT_WIDTH = UP::EXP_BITS;
94
+
95
+ // The exponent bias. Always positive.
96
+ LIBC_INLINE_VAR static constexpr uint32_t EXPONENT_BIAS =
97
+ (1U << (UP::EXP_BITS - 1U )) - 1U ;
98
+ static_assert (EXPONENT_BIAS > 0 );
99
+ };
100
+
101
+ } // namespace internal
33
102
34
- static constexpr uint32_t BIT_WIDTH = sizeof (BitsType) * 8 ;
103
+ template <FPType> struct FPProperties {} ;
35
104
36
- static constexpr uint32_t MANTISSA_WIDTH = 23 ;
105
+ // ----------------
106
+ // Work In Progress
107
+ // ----------------
108
+ // The 'FPProperties' template specializations below are being slowly replaced
109
+ // with properties from 'FPCommonProperties' above. Once specializations are
110
+ // empty, 'FPProperties' declaration can be fully replace with
111
+ // 'FPCommonProperties' implementation.
112
+
113
+ template <>
114
+ struct FPProperties <FPType::IEEE754_Binary32>
115
+ : public internal::FPCommonProperties<FPType::IEEE754_Binary32> {
37
116
// The mantissa precision includes the implicit bit.
38
117
static constexpr uint32_t MANTISSA_PRECISION = MANTISSA_WIDTH + 1 ;
39
- static constexpr uint32_t EXPONENT_WIDTH = 8 ;
40
118
static constexpr BitsType MANTISSA_MASK = (BitsType(1 ) << MANTISSA_WIDTH) - 1 ;
41
119
static constexpr BitsType SIGN_MASK = BitsType(1 )
42
120
<< (EXPONENT_WIDTH + MANTISSA_WIDTH);
43
121
static constexpr BitsType EXPONENT_MASK = ~(SIGN_MASK | MANTISSA_MASK);
44
- static constexpr uint32_t EXPONENT_BIAS = 127 ;
45
-
46
122
static constexpr BitsType EXP_MANT_MASK = MANTISSA_MASK + EXPONENT_MASK;
47
123
static_assert (EXP_MANT_MASK == ~SIGN_MASK,
48
124
" Exponent and mantissa masks are not as expected." );
@@ -53,20 +129,14 @@ template <> struct FPProperties<FPType::IEEE754_Binary32> {
53
129
static constexpr BitsType QUIET_NAN_MASK = 0x00400000U ;
54
130
};
55
131
56
- template <> struct FPProperties <FPType::IEEE754_Binary64> {
57
- typedef uint64_t BitsType;
58
-
59
- static constexpr uint32_t BIT_WIDTH = sizeof (BitsType) * 8 ;
60
-
61
- static constexpr uint32_t MANTISSA_WIDTH = 52 ;
132
+ template <>
133
+ struct FPProperties <FPType::IEEE754_Binary64>
134
+ : public internal::FPCommonProperties<FPType::IEEE754_Binary64> {
62
135
static constexpr uint32_t MANTISSA_PRECISION = MANTISSA_WIDTH + 1 ;
63
- static constexpr uint32_t EXPONENT_WIDTH = 11 ;
64
136
static constexpr BitsType MANTISSA_MASK = (BitsType(1 ) << MANTISSA_WIDTH) - 1 ;
65
137
static constexpr BitsType SIGN_MASK = BitsType(1 )
66
138
<< (EXPONENT_WIDTH + MANTISSA_WIDTH);
67
139
static constexpr BitsType EXPONENT_MASK = ~(SIGN_MASK | MANTISSA_MASK);
68
- static constexpr uint32_t EXPONENT_BIAS = 1023 ;
69
-
70
140
static constexpr BitsType EXP_MANT_MASK = MANTISSA_MASK + EXPONENT_MASK;
71
141
static_assert (EXP_MANT_MASK == ~SIGN_MASK,
72
142
" Exponent and mantissa masks are not as expected." );
@@ -79,27 +149,20 @@ template <> struct FPProperties<FPType::IEEE754_Binary64> {
79
149
80
150
// Properties for numbers represented in 80 bits long double on non-Windows x86
81
151
// platforms.
82
- template <> struct FPProperties <FPType::X86_Binary80> {
83
- typedef UInt128 BitsType;
84
-
85
- static constexpr uint32_t BIT_WIDTH = (sizeof (BitsType) * 8 ) - 48 ;
152
+ template <>
153
+ struct FPProperties <FPType::X86_Binary80>
154
+ : public internal::FPCommonProperties<FPType::X86_Binary80> {
86
155
static constexpr BitsType FULL_WIDTH_MASK = ((BitsType(1 ) << BIT_WIDTH) - 1 );
87
-
88
156
static constexpr uint32_t MANTISSA_WIDTH = 63 ;
89
157
static constexpr uint32_t MANTISSA_PRECISION = MANTISSA_WIDTH + 1 ;
90
- static constexpr uint32_t EXPONENT_WIDTH = 15 ;
91
158
static constexpr BitsType MANTISSA_MASK = (BitsType(1 ) << MANTISSA_WIDTH) - 1 ;
92
-
93
159
// The x86 80 bit float represents the leading digit of the mantissa
94
160
// explicitly. This is the mask for that bit.
95
161
static constexpr BitsType EXPLICIT_BIT_MASK = (BitsType(1 ) << MANTISSA_WIDTH);
96
-
97
162
static constexpr BitsType SIGN_MASK =
98
163
BitsType (1 ) << (EXPONENT_WIDTH + MANTISSA_WIDTH + 1 );
99
164
static constexpr BitsType EXPONENT_MASK =
100
165
((BitsType(1 ) << EXPONENT_WIDTH) - 1 ) << (MANTISSA_WIDTH + 1 );
101
- static constexpr uint32_t EXPONENT_BIAS = 16383 ;
102
-
103
166
static constexpr BitsType EXP_MANT_MASK =
104
167
MANTISSA_MASK | EXPLICIT_BIT_MASK | EXPONENT_MASK;
105
168
static_assert (EXP_MANT_MASK == (~SIGN_MASK & FULL_WIDTH_MASK),
@@ -114,20 +177,14 @@ template <> struct FPProperties<FPType::X86_Binary80> {
114
177
115
178
// Properties for numbers represented in 128 bits long double on non x86
116
179
// platform.
117
- template <> struct FPProperties <FPType::IEEE754_Binary128> {
118
- typedef UInt128 BitsType;
119
-
120
- static constexpr uint32_t BIT_WIDTH = sizeof (BitsType) << 3 ;
121
-
122
- static constexpr uint32_t MANTISSA_WIDTH = 112 ;
180
+ template <>
181
+ struct FPProperties <FPType::IEEE754_Binary128>
182
+ : public internal::FPCommonProperties<FPType::IEEE754_Binary128> {
123
183
static constexpr uint32_t MANTISSA_PRECISION = MANTISSA_WIDTH + 1 ;
124
- static constexpr uint32_t EXPONENT_WIDTH = 15 ;
125
184
static constexpr BitsType MANTISSA_MASK = (BitsType(1 ) << MANTISSA_WIDTH) - 1 ;
126
185
static constexpr BitsType SIGN_MASK = BitsType(1 )
127
186
<< (EXPONENT_WIDTH + MANTISSA_WIDTH);
128
187
static constexpr BitsType EXPONENT_MASK = ~(SIGN_MASK | MANTISSA_MASK);
129
- static constexpr uint32_t EXPONENT_BIAS = 16383 ;
130
-
131
188
static constexpr BitsType EXP_MANT_MASK = MANTISSA_MASK | EXPONENT_MASK;
132
189
static_assert (EXP_MANT_MASK == ~SIGN_MASK,
133
190
" Exponent and mantissa masks are not as expected." );
0 commit comments