@@ -79,6 +79,26 @@ mod int_to_float {
79
79
F :: from_bits ( conv ( i. unsigned_abs ( ) ) | sign_bit)
80
80
}
81
81
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
+
82
102
pub fn u32_to_f32_bits ( i : u32 ) -> u32 {
83
103
if i == 0 {
84
104
return 0 ;
@@ -122,6 +142,33 @@ mod int_to_float {
122
142
( h as u128 ) << 64
123
143
}
124
144
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
+
125
172
pub fn u64_to_f32_bits ( i : u64 ) -> u32 {
126
173
let n = i. leading_zeros ( ) ;
127
174
let i_m = i. wrapping_shl ( n) ;
@@ -160,6 +207,33 @@ mod int_to_float {
160
207
repr :: < f128 > ( e, m)
161
208
}
162
209
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
+
163
237
pub fn u128_to_f32_bits ( i : u128 ) -> u32 {
164
238
let n = i. leading_zeros ( ) ;
165
239
let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
@@ -210,6 +284,11 @@ mod int_to_float {
210
284
211
285
// Conversions from unsigned integers to floats.
212
286
intrinsics ! {
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
+
213
292
#[ arm_aeabi_alias = __aeabi_ui2f]
214
293
pub extern "C" fn __floatunsisf( i: u32 ) -> f32 {
215
294
f32 :: from_bits( int_to_float:: u32_to_f32_bits( i) )
@@ -220,6 +299,17 @@ intrinsics! {
220
299
f64 :: from_bits( int_to_float:: u32_to_f64_bits( i) )
221
300
}
222
301
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
+
223
313
#[ arm_aeabi_alias = __aeabi_ul2f]
224
314
pub extern "C" fn __floatundisf( i: u64 ) -> f32 {
225
315
f32 :: from_bits( int_to_float:: u64_to_f32_bits( i) )
@@ -230,6 +320,17 @@ intrinsics! {
230
320
f64 :: from_bits( int_to_float:: u64_to_f64_bits( i) )
231
321
}
232
322
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
+
233
334
#[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
234
335
pub extern "C" fn __floatuntisf( i: u128 ) -> f32 {
235
336
f32 :: from_bits( int_to_float:: u128_to_f32_bits( i) )
@@ -240,18 +341,6 @@ intrinsics! {
240
341
f64 :: from_bits( int_to_float:: u128_to_f64_bits( i) )
241
342
}
242
343
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
-
255
344
#[ ppc_alias = __floatuntikf]
256
345
#[ cfg( f128_enabled) ]
257
346
pub extern "C" fn __floatuntitf( i: u128 ) -> f128 {
@@ -261,6 +350,11 @@ intrinsics! {
261
350
262
351
// Conversions from signed integers to floats.
263
352
intrinsics ! {
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
+
264
358
#[ arm_aeabi_alias = __aeabi_i2f]
265
359
pub extern "C" fn __floatsisf( i: i32 ) -> f32 {
266
360
int_to_float:: signed( i, int_to_float:: u32_to_f32_bits)
@@ -271,6 +365,17 @@ intrinsics! {
271
365
int_to_float:: signed( i, int_to_float:: u32_to_f64_bits)
272
366
}
273
367
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
+
274
379
#[ arm_aeabi_alias = __aeabi_l2f]
275
380
pub extern "C" fn __floatdisf( i: i64 ) -> f32 {
276
381
int_to_float:: signed( i, int_to_float:: u64_to_f32_bits)
@@ -281,6 +386,17 @@ intrinsics! {
281
386
int_to_float:: signed( i, int_to_float:: u64_to_f64_bits)
282
387
}
283
388
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
+
284
400
#[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
285
401
pub extern "C" fn __floattisf( i: i128 ) -> f32 {
286
402
int_to_float:: signed( i, int_to_float:: u128_to_f32_bits)
@@ -291,18 +407,6 @@ intrinsics! {
291
407
int_to_float:: signed( i, int_to_float:: u128_to_f64_bits)
292
408
}
293
409
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
-
306
410
#[ ppc_alias = __floattikf]
307
411
#[ cfg( f128_enabled) ]
308
412
pub extern "C" fn __floattitf( i: i128 ) -> f128 {
0 commit comments