@@ -79,6 +79,26 @@ mod int_to_float {
7979 F :: from_bits ( conv ( i. unsigned_abs ( ) ) | sign_bit)
8080 }
8181
82+ #[ cfg( f16_enabled) ]
83+ pub fn u32_to_f16_bits ( i : u32 ) -> u16 {
84+ let n = i. leading_zeros ( ) ;
85+ let i_m = i. wrapping_shl ( n) ;
86+ // Mantissa with implicit bit set
87+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u32 , f16 > ( ) ) as u16 ;
88+ // The entire lower half of `i` will be truncated (masked portion), plus the
89+ // next `EXPONENT_BITS` bits.
90+ let adj = ( i_m >> f16:: EXPONENT_BITS | i_m & 0xFF ) as u16 ;
91+ let m = m_adj :: < f16 > ( m_base, adj) ;
92+ let e = if i == 0 { 0 } else { exp :: < u32 , f16 > ( n) - 1 } ;
93+ // Any int can have an exponent out of range for `f16`, unlike other float types.
94+ // Clamp this.
95+ if e >= f16:: EXPONENT_MAX as u16 - 1 {
96+ f16:: INFINITY . to_bits ( )
97+ } else {
98+ repr :: < f16 > ( e, m)
99+ }
100+ }
101+
82102 pub fn u32_to_f32_bits ( i : u32 ) -> u32 {
83103 if i == 0 {
84104 return 0 ;
@@ -122,6 +142,33 @@ mod int_to_float {
122142 ( h as u128 ) << 64
123143 }
124144
145+ #[ cfg( f16_enabled) ]
146+ pub fn u64_to_f16_bits ( i : u64 ) -> u16 {
147+ let n = i. leading_zeros ( ) ;
148+ let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
149+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u64 , f16 > ( ) ) as u16 ;
150+
151+ // Within the upper `F::BITS`, everything except for the signifcand
152+ // gets truncated
153+ let d1: u16 = ( i_m >> ( u64:: BITS - f16:: BITS - f16:: SIGNIFICAND_BITS - 1 ) ) . cast ( ) ;
154+
155+ // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
156+ // check if it is nonzero.
157+ let d2: u16 = ( i_m << f16:: BITS >> f16:: BITS != 0 ) . into ( ) ;
158+ let adj = d1 | d2;
159+
160+ // Mantissa with implicit bit set
161+ let m = m_adj :: < f16 > ( m_base, adj) ;
162+ let e = if i == 0 { 0 } else { exp :: < u64 , f16 > ( n) - 1 } ;
163+
164+ // Clamp to infinity if the exponent is out of range
165+ if e >= f16:: EXPONENT_MAX as u16 - 1 {
166+ f16:: INFINITY . to_bits ( )
167+ } else {
168+ repr :: < f16 > ( e, m)
169+ }
170+ }
171+
125172 pub fn u64_to_f32_bits ( i : u64 ) -> u32 {
126173 let n = i. leading_zeros ( ) ;
127174 let i_m = i. wrapping_shl ( n) ;
@@ -160,6 +207,33 @@ mod int_to_float {
160207 repr :: < f128 > ( e, m)
161208 }
162209
210+ #[ cfg( f16_enabled) ]
211+ pub fn u128_to_f16_bits ( i : u128 ) -> u16 {
212+ let n = i. leading_zeros ( ) ;
213+ let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
214+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u128 , f16 > ( ) ) as u16 ;
215+
216+ // Within the upper `F::BITS`, everything except for the signifcand
217+ // gets truncated
218+ let d1: u16 = ( i_m >> ( u128:: BITS - f16:: BITS - f16:: SIGNIFICAND_BITS - 1 ) ) . cast ( ) ;
219+
220+ // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
221+ // check if it is nonzero.
222+ let d2: u16 = ( i_m << f16:: BITS >> f16:: BITS != 0 ) . into ( ) ;
223+ let adj = d1 | d2;
224+
225+ // Mantissa with implicit bit set
226+ let m = m_adj :: < f16 > ( m_base, adj) ;
227+ let e = if i == 0 { 0 } else { exp :: < u128 , f16 > ( n) - 1 } ;
228+
229+ // Clamp to infinity if the exponent is out of range
230+ if e >= f16:: EXPONENT_MAX as u16 - 1 {
231+ f16:: INFINITY . to_bits ( )
232+ } else {
233+ repr :: < f16 > ( e, m)
234+ }
235+ }
236+
163237 pub fn u128_to_f32_bits ( i : u128 ) -> u32 {
164238 let n = i. leading_zeros ( ) ;
165239 let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
@@ -210,6 +284,11 @@ mod int_to_float {
210284
211285// Conversions from unsigned integers to floats.
212286intrinsics ! {
287+ #[ cfg( f16_enabled) ]
288+ pub extern "C" fn __floatunsihf( i: u32 ) -> f16 {
289+ f16:: from_bits( int_to_float:: u32_to_f16_bits( i) )
290+ }
291+
213292 #[ arm_aeabi_alias = __aeabi_ui2f]
214293 pub extern "C" fn __floatunsisf( i: u32 ) -> f32 {
215294 f32 :: from_bits( int_to_float:: u32_to_f32_bits( i) )
@@ -220,6 +299,17 @@ intrinsics! {
220299 f64 :: from_bits( int_to_float:: u32_to_f64_bits( i) )
221300 }
222301
302+ #[ ppc_alias = __floatunsikf]
303+ #[ cfg( f128_enabled) ]
304+ pub extern "C" fn __floatunsitf( i: u32 ) -> f128 {
305+ f128:: from_bits( int_to_float:: u32_to_f128_bits( i) )
306+ }
307+
308+ #[ cfg( f16_enabled) ]
309+ pub extern "C" fn __floatundihf( i: u64 ) -> f16 {
310+ f16:: from_bits( int_to_float:: u64_to_f16_bits( i) )
311+ }
312+
223313 #[ arm_aeabi_alias = __aeabi_ul2f]
224314 pub extern "C" fn __floatundisf( i: u64 ) -> f32 {
225315 f32 :: from_bits( int_to_float:: u64_to_f32_bits( i) )
@@ -230,6 +320,17 @@ intrinsics! {
230320 f64 :: from_bits( int_to_float:: u64_to_f64_bits( i) )
231321 }
232322
323+ #[ ppc_alias = __floatundikf]
324+ #[ cfg( f128_enabled) ]
325+ pub extern "C" fn __floatunditf( i: u64 ) -> f128 {
326+ f128:: from_bits( int_to_float:: u64_to_f128_bits( i) )
327+ }
328+
329+ #[ cfg( f16_enabled) ]
330+ pub extern "C" fn __floatuntihf( i: u128 ) -> f16 {
331+ f16:: from_bits( int_to_float:: u128_to_f16_bits( i) )
332+ }
333+
233334 #[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
234335 pub extern "C" fn __floatuntisf( i: u128 ) -> f32 {
235336 f32 :: from_bits( int_to_float:: u128_to_f32_bits( i) )
@@ -240,18 +341,6 @@ intrinsics! {
240341 f64 :: from_bits( int_to_float:: u128_to_f64_bits( i) )
241342 }
242343
243- #[ ppc_alias = __floatunsikf]
244- #[ cfg( f128_enabled) ]
245- pub extern "C" fn __floatunsitf( i: u32 ) -> f128 {
246- f128:: from_bits( int_to_float:: u32_to_f128_bits( i) )
247- }
248-
249- #[ ppc_alias = __floatundikf]
250- #[ cfg( f128_enabled) ]
251- pub extern "C" fn __floatunditf( i: u64 ) -> f128 {
252- f128:: from_bits( int_to_float:: u64_to_f128_bits( i) )
253- }
254-
255344 #[ ppc_alias = __floatuntikf]
256345 #[ cfg( f128_enabled) ]
257346 pub extern "C" fn __floatuntitf( i: u128 ) -> f128 {
@@ -261,6 +350,11 @@ intrinsics! {
261350
262351// Conversions from signed integers to floats.
263352intrinsics ! {
353+ #[ cfg( f16_enabled) ]
354+ pub extern "C" fn __floatsihf( i: i32 ) -> f16 {
355+ int_to_float:: signed( i, int_to_float:: u32_to_f16_bits)
356+ }
357+
264358 #[ arm_aeabi_alias = __aeabi_i2f]
265359 pub extern "C" fn __floatsisf( i: i32 ) -> f32 {
266360 int_to_float:: signed( i, int_to_float:: u32_to_f32_bits)
@@ -271,6 +365,17 @@ intrinsics! {
271365 int_to_float:: signed( i, int_to_float:: u32_to_f64_bits)
272366 }
273367
368+ #[ ppc_alias = __floatsikf]
369+ #[ cfg( f128_enabled) ]
370+ pub extern "C" fn __floatsitf( i: i32 ) -> f128 {
371+ int_to_float:: signed( i, int_to_float:: u32_to_f128_bits)
372+ }
373+
374+ #[ cfg( f16_enabled) ]
375+ pub extern "C" fn __floatdihf( i: i64 ) -> f16 {
376+ int_to_float:: signed( i, int_to_float:: u64_to_f16_bits)
377+ }
378+
274379 #[ arm_aeabi_alias = __aeabi_l2f]
275380 pub extern "C" fn __floatdisf( i: i64 ) -> f32 {
276381 int_to_float:: signed( i, int_to_float:: u64_to_f32_bits)
@@ -281,6 +386,17 @@ intrinsics! {
281386 int_to_float:: signed( i, int_to_float:: u64_to_f64_bits)
282387 }
283388
389+ #[ ppc_alias = __floatdikf]
390+ #[ cfg( f128_enabled) ]
391+ pub extern "C" fn __floatditf( i: i64 ) -> f128 {
392+ int_to_float:: signed( i, int_to_float:: u64_to_f128_bits)
393+ }
394+
395+ #[ cfg( f16_enabled) ]
396+ pub extern "C" fn __floattihf( i: i128 ) -> f16 {
397+ int_to_float:: signed( i, int_to_float:: u128_to_f16_bits)
398+ }
399+
284400 #[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
285401 pub extern "C" fn __floattisf( i: i128 ) -> f32 {
286402 int_to_float:: signed( i, int_to_float:: u128_to_f32_bits)
@@ -291,18 +407,6 @@ intrinsics! {
291407 int_to_float:: signed( i, int_to_float:: u128_to_f64_bits)
292408 }
293409
294- #[ ppc_alias = __floatsikf]
295- #[ cfg( f128_enabled) ]
296- pub extern "C" fn __floatsitf( i: i32 ) -> f128 {
297- int_to_float:: signed( i, int_to_float:: u32_to_f128_bits)
298- }
299-
300- #[ ppc_alias = __floatdikf]
301- #[ cfg( f128_enabled) ]
302- pub extern "C" fn __floatditf( i: i64 ) -> f128 {
303- int_to_float:: signed( i, int_to_float:: u64_to_f128_bits)
304- }
305-
306410 #[ ppc_alias = __floattikf]
307411 #[ cfg( f128_enabled) ]
308412 pub extern "C" fn __floattitf( i: i128 ) -> f128 {
0 commit comments