@@ -47,6 +47,63 @@ def cFuncSuffix(bits):
47
47
if bits == 80 :
48
48
return 'l'
49
49
50
+ def llvmIntrinsicSuffix( bits) :
51
+ if bits == 32 :
52
+ return 'f32 '
53
+ if bits == 64 :
54
+ return 'f64 '
55
+ if bits == 80 :
56
+ return 'f80 '
57
+
58
+ def getInfBitPattern( bits) :
59
+ if bits == 32 :
60
+ return '0x7f800000 '
61
+ if bits == 64 :
62
+ return '0x7ff0000000000000 '
63
+ return 'error'
64
+
65
+ def getQuietNaNBitPattern( bits) :
66
+ if bits == 32 :
67
+ return '0x7fc00000 '
68
+ if bits == 64 :
69
+ return '0x7ff8000000000000 '
70
+ return 'error'
71
+
72
+ def getSignalingNanBitPattern( bits) :
73
+ if bits == 32 :
74
+ return '0x7fa00000 '
75
+ if bits == 64 :
76
+ return '0x7ff4000000000000 '
77
+ return 'error'
78
+
79
+ def getMinNormalBitPattern( bits) :
80
+ if bits == 32 :
81
+ return '0x00800000 '
82
+ if bits == 64 :
83
+ return '0x0010000000000000 '
84
+ return 'error'
85
+
86
+ def getExponentBitCount( bits) :
87
+ if bits == 32 :
88
+ return '8 '
89
+ if bits == 64 :
90
+ return '11 '
91
+ return 'error'
92
+
93
+ def getSignificantBitCount( bits) :
94
+ if bits == 32 :
95
+ return '23 '
96
+ if bits == 64 :
97
+ return '52 '
98
+ return 'error'
99
+
100
+ def getInfinityExponent( bits) :
101
+ if bits == 32 :
102
+ return '0xff '
103
+ if bits == 64 :
104
+ return '0x7ff '
105
+ return 'error'
106
+
50
107
} @
51
108
52
109
@ for bits in allFloatBits:
@@ -75,6 +132,150 @@ struct ${Self} : ReplPrintable {
75
132
}
76
133
}
77
134
135
+ @ if bits in allIntBits:
136
+ // Not transparent because the compiler crashes in that case.
137
+ //@@transparent
138
+ extension ${ Self} : IEEEFloatingPointNumber {
139
+ typealias _BitsType = UInt ${ bits}
140
+
141
+ static func _fromBitPattern( bits: _BitsType ) -> ${ Self} {
142
+ return ${ Self} ( Builtin . bitcast_Int ${ bits} _FPIEEE${ bits} ( bits. value) )
143
+ }
144
+
145
+ func _toBitPattern( ) - > _BitsType {
146
+ return _BitsType ( Builtin . bitcast_FPIEEE ${ bits} _Int${ bits} ( value) )
147
+ }
148
+
149
+ func __getSignBit( ) - > Int {
150
+ return Int ( _toBitPattern ( ) >> ${ bits - 1 } ) & 1
151
+ }
152
+
153
+ func __getBiasedExponent( ) - > _BitsType {
154
+ return ( _toBitPattern ( ) >> ${ getSignificantBitCount ( bits) } ) & ${ getInfinityExponent ( bits) }
155
+ }
156
+
157
+ func __getSignificand( ) - > _BitsType {
158
+ var mask : _BitsType = ( 1 << ${ getSignificantBitCount ( bits) } ) - 1
159
+ return _toBitPattern ( ) & mask
160
+ }
161
+
162
+ static func inf( ) - > ${ Self} {
163
+ return _fromBitPattern ( ${ getInfBitPattern ( bits) } )
164
+ }
165
+
166
+ static func NaN( ) - > ${ Self} {
167
+ return quietNaN ( )
168
+ }
169
+
170
+ static func quietNaN( ) - > ${ Self} {
171
+ return _fromBitPattern ( ${ getQuietNaNBitPattern ( bits) } )
172
+ }
173
+
174
+ static func signalingNaN( ) - > ${ Self} {
175
+ return _fromBitPattern ( ${ getSignalingNanBitPattern ( bits) } )
176
+ }
177
+
178
+ func isSignMinus( ) - > Bool {
179
+ return __getSignBit ( ) == 1
180
+ }
181
+
182
+ func isNormal( ) - > Bool {
183
+ var biasedExponent = __getBiasedExponent ( )
184
+ return biasedExponent != ${ getInfinityExponent ( bits) } &&
185
+ biasedExponent != 0
186
+ }
187
+
188
+ func isFinite( ) - > Bool {
189
+ return __getBiasedExponent ( ) != ${ getInfinityExponent ( bits) }
190
+ }
191
+
192
+ func isZero( ) - > Bool {
193
+ // Mask out the sign bit.
194
+ var mask : _BitsType = ( 1 << ( ${ bits} - 1 ) ) - 1
195
+ return ( _toBitPattern ( ) & mask) == 0
196
+ }
197
+
198
+ func isSubnormal( ) - > Bool {
199
+ if __getBiasedExponent ( ) == 0 {
200
+ return __getSignificand ( ) != 0
201
+ }
202
+ return false
203
+
204
+ // Alternative implementation:
205
+ // return !isNan() &&
206
+ // abs(self) < ${Self}._fromBitPattern(${getMinNormalBitPattern(bits)})
207
+ //
208
+ // But because we need to check for !isNan(), and do it safely in case of
209
+ // SNaN, we need to go down to the bit level, so open-coding the combined
210
+ // condition is going to be faster.
211
+ }
212
+
213
+ func isInfinite( ) - > Bool {
214
+ if __getBiasedExponent ( ) == ${ getInfinityExponent ( bits) } {
215
+ return __getSignificand ( ) == 0
216
+ }
217
+ return false
218
+
219
+ // Alternative implementation that is not safe in case of SNaN:
220
+ // return abs(self) == ${Self}.inf()
221
+ }
222
+
223
+ func isNaN( ) - > Bool {
224
+ if __getBiasedExponent ( ) == ${ getInfinityExponent ( bits) } {
225
+ return __getSignificand ( ) != 0
226
+ }
227
+ return false
228
+
229
+ // Alternative implementation that is not safe in case of SNaN:
230
+ // return self != self
231
+ }
232
+
233
+ func isSignaling( ) - > Bool {
234
+ if __getBiasedExponent ( ) == ${ getInfinityExponent ( bits) } {
235
+ // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded
236
+ // with the first bit of the trailing significand being 0. If the first
237
+ // bit of the trailing significand field is 0, some other bit of the
238
+ // trailing significand field must be non-zero to distinguish the NaN
239
+ // from infinity.
240
+ var significand = __getSignificand ( )
241
+ if significand != 0 {
242
+ return ( significand >> ( ${ getSignificantBitCount ( bits) } - 1 ) ) == 0
243
+ }
244
+ }
245
+ return false
246
+ }
247
+ }
248
+
249
+ // Not @transparent because the function is too complex.
250
+ extension ${ Self} /* : IEEEFloatingPointNumber */ {
251
+ var floatingPointClass : IEEEFloatingPointClass {
252
+ get:
253
+ var biasedExponent = __getBiasedExponent ( )
254
+ if biasedExponent == ${ getInfinityExponent ( bits) } {
255
+ var significand = __getSignificand ( )
256
+ // This is either +/-inf or NaN.
257
+ if significand == 0 {
258
+ return isSignMinus ( ) ? . NegativeInfinity : . PositiveInfinity
259
+ }
260
+ var isQNaN = ( significand >> ( ${ getSignificantBitCount ( bits) } - 1 ) ) == 1
261
+ return isQNaN ? . QuietNaN : . SignalingNaN
262
+ }
263
+
264
+ // OK, the number is finite.
265
+ var isMinus = isSignMinus ( )
266
+ if biasedExponent != 0 {
267
+ return isMinus ? . NegativeNormal : . PositiveNormal
268
+ }
269
+
270
+ // Exponent is zero.
271
+ if __getSignificand ( ) == 0 {
272
+ return isMinus ? . NegativeZero : . PositiveZero
273
+ }
274
+ return isMinus ? . NegativeSubnormal : . PositiveSubnormal
275
+ }
276
+ }
277
+ @ end
278
+
78
279
@@transparent
79
280
extension ${ Self} : BuiltinIntegerLiteralConvertible, IntegerLiteralConvertible {
80
281
static func _convertFromBuiltinIntegerLiteral( val: Builtin . Int ${ builtinIntLiteralBits} ) - > ${ Self} {
0 commit comments