1+ use core:: ops:: Neg ;
2+
13use crate :: int:: { CastFrom , CastInto , Int , MinInt } ;
24
35use super :: Float ;
@@ -150,12 +152,11 @@ fn float_to_unsigned_int<F, U>(f: F) -> U
150152where
151153 F : Float ,
152154 U : Int ,
153- u32 : CastInto < F :: Int > ,
154155 u32 : CastFrom < F :: Int > ,
155156 F :: Int : CastInto < U > ,
156157 F :: Int : CastFrom < u32 > ,
157158{
158- let uint_max_exp: u32 = F :: EXPONENT_BIAS + U :: BITS ;
159+ let uint_max_exp: u32 = F :: EXPONENT_BIAS + U :: MAX . ilog2 ( ) + 1 ;
159160 let fbits = f. repr ( ) ;
160161
161162 if fbits < F :: ONE . repr ( ) {
@@ -166,6 +167,7 @@ where
166167 let mantissa = if U :: BITS >= F :: Int :: BITS {
167168 U :: cast_from ( fbits) << ( U :: BITS - F :: SIGNIFICAND_BITS - 1 )
168169 } else {
170+ // FIXME magic number for when we go smaller
169171 U :: cast_from ( fbits >> 21 )
170172 } ;
171173
@@ -183,6 +185,51 @@ where
183185 }
184186}
185187
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+
186233// Conversions from floats to unsigned integers.
187234intrinsics ! {
188235 #[ arm_aeabi_alias = __aeabi_f2uiz]
@@ -220,103 +267,31 @@ intrinsics! {
220267intrinsics ! {
221268 #[ arm_aeabi_alias = __aeabi_f2iz]
222269 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)
236271 }
237272
238273 #[ arm_aeabi_alias = __aeabi_f2lz]
239274 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)
253276 }
254277
255278 #[ win64_128bit_abi_hack]
256279 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)
270281 }
271282
272283 #[ arm_aeabi_alias = __aeabi_d2iz]
273284 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)
287286 }
288287
289288 #[ arm_aeabi_alias = __aeabi_d2lz]
290289 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)
304291 }
305292
306293 #[ win64_128bit_abi_hack]
307294 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)
321296 }
322297}
0 commit comments