@@ -78,6 +78,26 @@ mod int_to_float {
7878 F :: from_bits ( conv ( i. unsigned_abs ( ) ) | sign_bit)
7979 }
8080
81+ #[ cfg( f16_enabled) ]
82+ pub fn u32_to_f16_bits ( i : u32 ) -> u16 {
83+ let n = i. leading_zeros ( ) ;
84+ let i_m = i. wrapping_shl ( n) ;
85+ // Mantissa with implicit bit set
86+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u32 , f16 > ( ) ) as u16 ;
87+ // The entire lower half of `i` will be truncated (masked portion), plus the
88+ // next `EXP_BITS` bits.
89+ let adj = ( i_m >> f16:: EXP_BITS | i_m & 0xFF ) as u16 ;
90+ let m = m_adj :: < f16 > ( m_base, adj) ;
91+ let e = if i == 0 { 0 } else { exp :: < u32 , f16 > ( n) - 1 } ;
92+ // Any int can have an exponent out of range for `f16`, unlike other float types.
93+ // Clamp this.
94+ if e >= f16:: EXP_SAT as u16 - 1 {
95+ f16:: INFINITY . to_bits ( )
96+ } else {
97+ repr :: < f16 > ( e, m)
98+ }
99+ }
100+
81101 pub fn u32_to_f32_bits ( i : u32 ) -> u32 {
82102 if i == 0 {
83103 return 0 ;
@@ -121,6 +141,33 @@ mod int_to_float {
121141 ( h as u128 ) << 64
122142 }
123143
144+ #[ cfg( f16_enabled) ]
145+ pub fn u64_to_f16_bits ( i : u64 ) -> u16 {
146+ let n = i. leading_zeros ( ) ;
147+ let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
148+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u64 , f16 > ( ) ) as u16 ;
149+
150+ // Within the upper `F::BITS`, everything except for the signifcand
151+ // gets truncated
152+ let d1: u16 = ( i_m >> ( u64:: BITS - f16:: BITS - f16:: SIG_BITS - 1 ) ) . cast ( ) ;
153+
154+ // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
155+ // check if it is nonzero.
156+ let d2: u16 = ( i_m << f16:: BITS >> f16:: BITS != 0 ) . into ( ) ;
157+ let adj = d1 | d2;
158+
159+ // Mantissa with implicit bit set
160+ let m = m_adj :: < f16 > ( m_base, adj) ;
161+ let e = if i == 0 { 0 } else { exp :: < u64 , f16 > ( n) - 1 } ;
162+
163+ // Clamp to infinity if the exponent is out of range
164+ if e >= f16:: EXP_SAT as u16 - 1 {
165+ f16:: INFINITY . to_bits ( )
166+ } else {
167+ repr :: < f16 > ( e, m)
168+ }
169+ }
170+
124171 pub fn u64_to_f32_bits ( i : u64 ) -> u32 {
125172 let n = i. leading_zeros ( ) ;
126173 let i_m = i. wrapping_shl ( n) ;
@@ -159,6 +206,33 @@ mod int_to_float {
159206 repr :: < f128 > ( e, m)
160207 }
161208
209+ #[ cfg( f16_enabled) ]
210+ pub fn u128_to_f16_bits ( i : u128 ) -> u16 {
211+ let n = i. leading_zeros ( ) ;
212+ let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
213+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u128 , f16 > ( ) ) as u16 ;
214+
215+ // Within the upper `F::BITS`, everything except for the signifcand
216+ // gets truncated
217+ let d1: u16 = ( i_m >> ( u128:: BITS - f16:: BITS - f16:: SIG_BITS - 1 ) ) . cast ( ) ;
218+
219+ // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
220+ // check if it is nonzero.
221+ let d2: u16 = ( i_m << f16:: BITS >> f16:: BITS != 0 ) . into ( ) ;
222+ let adj = d1 | d2;
223+
224+ // Mantissa with implicit bit set
225+ let m = m_adj :: < f16 > ( m_base, adj) ;
226+ let e = if i == 0 { 0 } else { exp :: < u128 , f16 > ( n) - 1 } ;
227+
228+ // Clamp to infinity if the exponent is out of range
229+ if e >= f16:: EXP_SAT as u16 - 1 {
230+ f16:: INFINITY . to_bits ( )
231+ } else {
232+ repr :: < f16 > ( e, m)
233+ }
234+ }
235+
162236 pub fn u128_to_f32_bits ( i : u128 ) -> u32 {
163237 let n = i. leading_zeros ( ) ;
164238 let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
@@ -209,6 +283,11 @@ mod int_to_float {
209283
210284// Conversions from unsigned integers to floats.
211285intrinsics ! {
286+ #[ cfg( f16_enabled) ]
287+ pub extern "C" fn __floatunsihf( i: u32 ) -> f16 {
288+ f16:: from_bits( int_to_float:: u32_to_f16_bits( i) )
289+ }
290+
212291 #[ arm_aeabi_alias = __aeabi_ui2f]
213292 pub extern "C" fn __floatunsisf( i: u32 ) -> f32 {
214293 f32 :: from_bits( int_to_float:: u32_to_f32_bits( i) )
@@ -219,6 +298,17 @@ intrinsics! {
219298 f64 :: from_bits( int_to_float:: u32_to_f64_bits( i) )
220299 }
221300
301+ #[ ppc_alias = __floatunsikf]
302+ #[ cfg( f128_enabled) ]
303+ pub extern "C" fn __floatunsitf( i: u32 ) -> f128 {
304+ f128:: from_bits( int_to_float:: u32_to_f128_bits( i) )
305+ }
306+
307+ #[ cfg( f16_enabled) ]
308+ pub extern "C" fn __floatundihf( i: u64 ) -> f16 {
309+ f16:: from_bits( int_to_float:: u64_to_f16_bits( i) )
310+ }
311+
222312 #[ arm_aeabi_alias = __aeabi_ul2f]
223313 pub extern "C" fn __floatundisf( i: u64 ) -> f32 {
224314 f32 :: from_bits( int_to_float:: u64_to_f32_bits( i) )
@@ -229,6 +319,17 @@ intrinsics! {
229319 f64 :: from_bits( int_to_float:: u64_to_f64_bits( i) )
230320 }
231321
322+ #[ ppc_alias = __floatundikf]
323+ #[ cfg( f128_enabled) ]
324+ pub extern "C" fn __floatunditf( i: u64 ) -> f128 {
325+ f128:: from_bits( int_to_float:: u64_to_f128_bits( i) )
326+ }
327+
328+ #[ cfg( f16_enabled) ]
329+ pub extern "C" fn __floatuntihf( i: u128 ) -> f16 {
330+ f16:: from_bits( int_to_float:: u128_to_f16_bits( i) )
331+ }
332+
232333 #[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
233334 pub extern "C" fn __floatuntisf( i: u128 ) -> f32 {
234335 f32 :: from_bits( int_to_float:: u128_to_f32_bits( i) )
@@ -239,18 +340,6 @@ intrinsics! {
239340 f64 :: from_bits( int_to_float:: u128_to_f64_bits( i) )
240341 }
241342
242- #[ ppc_alias = __floatunsikf]
243- #[ cfg( f128_enabled) ]
244- pub extern "C" fn __floatunsitf( i: u32 ) -> f128 {
245- f128:: from_bits( int_to_float:: u32_to_f128_bits( i) )
246- }
247-
248- #[ ppc_alias = __floatundikf]
249- #[ cfg( f128_enabled) ]
250- pub extern "C" fn __floatunditf( i: u64 ) -> f128 {
251- f128:: from_bits( int_to_float:: u64_to_f128_bits( i) )
252- }
253-
254343 #[ ppc_alias = __floatuntikf]
255344 #[ cfg( f128_enabled) ]
256345 pub extern "C" fn __floatuntitf( i: u128 ) -> f128 {
@@ -260,6 +349,11 @@ intrinsics! {
260349
261350// Conversions from signed integers to floats.
262351intrinsics ! {
352+ #[ cfg( f16_enabled) ]
353+ pub extern "C" fn __floatsihf( i: i32 ) -> f16 {
354+ int_to_float:: signed( i, int_to_float:: u32_to_f16_bits)
355+ }
356+
263357 #[ arm_aeabi_alias = __aeabi_i2f]
264358 pub extern "C" fn __floatsisf( i: i32 ) -> f32 {
265359 int_to_float:: signed( i, int_to_float:: u32_to_f32_bits)
@@ -270,6 +364,17 @@ intrinsics! {
270364 int_to_float:: signed( i, int_to_float:: u32_to_f64_bits)
271365 }
272366
367+ #[ ppc_alias = __floatsikf]
368+ #[ cfg( f128_enabled) ]
369+ pub extern "C" fn __floatsitf( i: i32 ) -> f128 {
370+ int_to_float:: signed( i, int_to_float:: u32_to_f128_bits)
371+ }
372+
373+ #[ cfg( f16_enabled) ]
374+ pub extern "C" fn __floatdihf( i: i64 ) -> f16 {
375+ int_to_float:: signed( i, int_to_float:: u64_to_f16_bits)
376+ }
377+
273378 #[ arm_aeabi_alias = __aeabi_l2f]
274379 pub extern "C" fn __floatdisf( i: i64 ) -> f32 {
275380 int_to_float:: signed( i, int_to_float:: u64_to_f32_bits)
@@ -280,6 +385,17 @@ intrinsics! {
280385 int_to_float:: signed( i, int_to_float:: u64_to_f64_bits)
281386 }
282387
388+ #[ ppc_alias = __floatdikf]
389+ #[ cfg( f128_enabled) ]
390+ pub extern "C" fn __floatditf( i: i64 ) -> f128 {
391+ int_to_float:: signed( i, int_to_float:: u64_to_f128_bits)
392+ }
393+
394+ #[ cfg( f16_enabled) ]
395+ pub extern "C" fn __floattihf( i: i128 ) -> f16 {
396+ int_to_float:: signed( i, int_to_float:: u128_to_f16_bits)
397+ }
398+
283399 #[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
284400 pub extern "C" fn __floattisf( i: i128 ) -> f32 {
285401 int_to_float:: signed( i, int_to_float:: u128_to_f32_bits)
@@ -290,18 +406,6 @@ intrinsics! {
290406 int_to_float:: signed( i, int_to_float:: u128_to_f64_bits)
291407 }
292408
293- #[ ppc_alias = __floatsikf]
294- #[ cfg( f128_enabled) ]
295- pub extern "C" fn __floatsitf( i: i32 ) -> f128 {
296- int_to_float:: signed( i, int_to_float:: u32_to_f128_bits)
297- }
298-
299- #[ ppc_alias = __floatdikf]
300- #[ cfg( f128_enabled) ]
301- pub extern "C" fn __floatditf( i: i64 ) -> f128 {
302- int_to_float:: signed( i, int_to_float:: u64_to_f128_bits)
303- }
304-
305409 #[ ppc_alias = __floattikf]
306410 #[ cfg( f128_enabled) ]
307411 pub extern "C" fn __floattitf( i: i128 ) -> f128 {
0 commit comments