1
+ use core:: ops:: Neg ;
2
+
1
3
use crate :: int:: { CastFrom , CastInto , Int , MinInt } ;
2
4
3
5
use super :: Float ;
@@ -150,12 +152,11 @@ fn float_to_unsigned_int<F, U>(f: F) -> U
150
152
where
151
153
F : Float ,
152
154
U : Int ,
153
- u32 : CastInto < F :: Int > ,
154
155
u32 : CastFrom < F :: Int > ,
155
156
F :: Int : CastInto < U > ,
156
157
F :: Int : CastFrom < u32 > ,
157
158
{
158
- let uint_max_exp: u32 = F :: EXPONENT_BIAS + U :: BITS ;
159
+ let uint_max_exp: u32 = F :: EXPONENT_BIAS + U :: MAX . ilog2 ( ) + 1 ;
159
160
let fbits = f. repr ( ) ;
160
161
161
162
if fbits < F :: ONE . repr ( ) {
@@ -166,6 +167,7 @@ where
166
167
let mantissa = if U :: BITS >= F :: Int :: BITS {
167
168
U :: cast_from ( fbits) << ( U :: BITS - F :: SIGNIFICAND_BITS - 1 )
168
169
} else {
170
+ // FIXME magic number for when we go smaller
169
171
U :: cast_from ( fbits >> 21 )
170
172
} ;
171
173
@@ -183,6 +185,51 @@ where
183
185
}
184
186
}
185
187
188
+ fn float_to_signed_int < F , I > ( f : F ) -> I
189
+ where
190
+ F : Float ,
191
+ I : Int + Neg < Output = I > ,
192
+ I :: UnsignedInt : Int ,
193
+ u32 : CastFrom < F :: Int > ,
194
+ F :: Int : CastInto < I :: UnsignedInt > ,
195
+ F :: Int : CastFrom < u32 > ,
196
+ {
197
+ let int_max_exp: u32 = F :: EXPONENT_BIAS + I :: MAX . ilog2 ( ) + 1 ;
198
+ let fbits = f. repr ( ) & !F :: SIGN_MASK ;
199
+
200
+ if fbits < F :: ONE . repr ( ) {
201
+ // >= 0.0, < 1.0 (< 0.0 are > 1.0 in int repr)
202
+ I :: ZERO
203
+ } else if fbits < F :: Int :: cast_from ( int_max_exp) << F :: SIGNIFICAND_BITS {
204
+ // >= 1, < U::max
205
+ let mantissa = if I :: BITS >= F :: Int :: BITS {
206
+ I :: UnsignedInt :: cast_from ( fbits) << ( I :: BITS - F :: SIGNIFICAND_BITS - 1 )
207
+ } else {
208
+ I :: UnsignedInt :: cast_from ( fbits >> 21 )
209
+ } ;
210
+
211
+ // Set the implicit 1-bit.
212
+ let m: I :: UnsignedInt = I :: UnsignedInt :: ONE << ( I :: BITS - 1 ) | mantissa;
213
+ // Shift based on the exponent and bias.
214
+ let s: u32 = int_max_exp - u32:: cast_from ( fbits >> F :: SIGNIFICAND_BITS ) ;
215
+ let u: I = I :: from_unsigned ( m >> s) ;
216
+ if f. is_sign_negative ( ) {
217
+ -u
218
+ } else {
219
+ u
220
+ }
221
+ } else if fbits <= F :: EXPONENT_MASK {
222
+ // >= max (incl. inf)
223
+ if f. is_sign_negative ( ) {
224
+ I :: MIN
225
+ } else {
226
+ I :: MAX
227
+ }
228
+ } else {
229
+ I :: ZERO
230
+ }
231
+ }
232
+
186
233
// Conversions from floats to unsigned integers.
187
234
intrinsics ! {
188
235
#[ arm_aeabi_alias = __aeabi_f2uiz]
@@ -220,103 +267,31 @@ intrinsics! {
220
267
intrinsics ! {
221
268
#[ arm_aeabi_alias = __aeabi_f2iz]
222
269
pub extern "C" fn __fixsfsi( f: f32 ) -> i32 {
223
- let fbits = f. to_bits( ) & !0 >> 1 ; // Remove sign bit.
224
- if fbits < 127 << 23 { // >= 0, < 1
225
- 0
226
- } else if fbits < 158 << 23 { // >= 1, < max
227
- let m = 1 << 31 | fbits << 8 ; // Mantissa and the implicit 1-bit.
228
- let s = 158 - ( fbits >> 23 ) ; // Shift based on the exponent and bias.
229
- let u = ( m >> s) as i32 ; // Unsigned result.
230
- if f. is_sign_negative( ) { -u } else { u }
231
- } else if fbits <= 255 << 23 { // >= max (incl. inf)
232
- if f. is_sign_negative( ) { i32 :: MIN } else { i32 :: MAX }
233
- } else { // NaN
234
- 0
235
- }
270
+ float_to_signed_int( f)
236
271
}
237
272
238
273
#[ arm_aeabi_alias = __aeabi_f2lz]
239
274
pub extern "C" fn __fixsfdi( f: f32 ) -> i64 {
240
- let fbits = f. to_bits( ) & !0 >> 1 ; // Remove sign bit.
241
- if fbits < 127 << 23 { // >= 0, < 1
242
- 0
243
- } else if fbits < 190 << 23 { // >= 1, < max
244
- let m = 1 << 63 | ( fbits as u64 ) << 40 ; // Mantissa and the implicit 1-bit.
245
- let s = 190 - ( fbits >> 23 ) ; // Shift based on the exponent and bias.
246
- let u = ( m >> s) as i64 ; // Unsigned result.
247
- if f. is_sign_negative( ) { -u } else { u }
248
- } else if fbits <= 255 << 23 { // >= max (incl. inf)
249
- if f. is_sign_negative( ) { i64 :: MIN } else { i64 :: MAX }
250
- } else { // NaN
251
- 0
252
- }
275
+ float_to_signed_int( f)
253
276
}
254
277
255
278
#[ win64_128bit_abi_hack]
256
279
pub extern "C" fn __fixsfti( f: f32 ) -> i128 {
257
- let fbits = f. to_bits( ) & !0 >> 1 ; // Remove sign bit.
258
- if fbits < 127 << 23 { // >= 0, < 1
259
- 0
260
- } else if fbits < 254 << 23 { // >= 1, < max
261
- let m = 1 << 127 | ( fbits as u128 ) << 104 ; // Mantissa and the implicit 1-bit.
262
- let s = 254 - ( fbits >> 23 ) ; // Shift based on the exponent and bias.
263
- let u = ( m >> s) as i128 ; // Unsigned result.
264
- if f. is_sign_negative( ) { -u } else { u }
265
- } else if fbits <= 255 << 23 { // >= max (incl. inf)
266
- if f. is_sign_negative( ) { i128 :: MIN } else { i128 :: MAX }
267
- } else { // NaN
268
- 0
269
- }
280
+ float_to_signed_int( f)
270
281
}
271
282
272
283
#[ arm_aeabi_alias = __aeabi_d2iz]
273
284
pub extern "C" fn __fixdfsi( f: f64 ) -> i32 {
274
- let fbits = f. to_bits( ) & !0 >> 1 ; // Remove sign bit.
275
- if fbits < 1023 << 52 { // >= 0, < 1
276
- 0
277
- } else if fbits < 1054 << 52 { // >= 1, < max
278
- let m = 1 << 31 | ( fbits >> 21 ) as u32 ; // Mantissa and the implicit 1-bit.
279
- let s = 1054 - ( fbits >> 52 ) ; // Shift based on the exponent and bias.
280
- let u = ( m >> s) as i32 ; // Unsigned result.
281
- if f. is_sign_negative( ) { -u } else { u }
282
- } else if fbits <= 2047 << 52 { // >= max (incl. inf)
283
- if f. is_sign_negative( ) { i32 :: MIN } else { i32 :: MAX }
284
- } else { // NaN
285
- 0
286
- }
285
+ float_to_signed_int( f)
287
286
}
288
287
289
288
#[ arm_aeabi_alias = __aeabi_d2lz]
290
289
pub extern "C" fn __fixdfdi( f: f64 ) -> i64 {
291
- let fbits = f. to_bits( ) & !0 >> 1 ; // Remove sign bit.
292
- if fbits < 1023 << 52 { // >= 0, < 1
293
- 0
294
- } else if fbits < 1086 << 52 { // >= 1, < max
295
- let m = 1 << 63 | fbits << 11 ; // Mantissa and the implicit 1-bit.
296
- let s = 1086 - ( fbits >> 52 ) ; // Shift based on the exponent and bias.
297
- let u = ( m >> s) as i64 ; // Unsigned result.
298
- if f. is_sign_negative( ) { -u } else { u }
299
- } else if fbits <= 2047 << 52 { // >= max (incl. inf)
300
- if f. is_sign_negative( ) { i64 :: MIN } else { i64 :: MAX }
301
- } else { // NaN
302
- 0
303
- }
290
+ float_to_signed_int( f)
304
291
}
305
292
306
293
#[ win64_128bit_abi_hack]
307
294
pub extern "C" fn __fixdfti( f: f64 ) -> i128 {
308
- let fbits = f. to_bits( ) & !0 >> 1 ; // Remove sign bit.
309
- if fbits < 1023 << 52 { // >= 0, < 1
310
- 0
311
- } else if fbits < 1150 << 52 { // >= 1, < max
312
- let m = 1 << 127 | ( fbits as u128 ) << 75 ; // Mantissa and the implicit 1-bit.
313
- let s = 1150 - ( fbits >> 52 ) ; // Shift based on the exponent and bias.
314
- let u = ( m >> s) as i128 ; // Unsigned result.
315
- if f. is_sign_negative( ) { -u } else { u }
316
- } else if fbits <= 2047 << 52 { // >= max (incl. inf)
317
- if f. is_sign_negative( ) { i128 :: MIN } else { i128 :: MAX }
318
- } else { // NaN
319
- 0
320
- }
295
+ float_to_signed_int( f)
321
296
}
322
297
}
0 commit comments