@@ -79,6 +79,25 @@ mod int_to_float {
79
79
F :: from_bits ( conv ( i. unsigned_abs ( ) ) | sign_bit)
80
80
}
81
81
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 `EXPONENT_BITS` bits.
89
+ let adj = ( i_m >> f16:: EXPONENT_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:: EXPONENT_MAX as u16 - 1 {
95
+ f16:: INFINITY . to_bits ( )
96
+ } else {
97
+ repr :: < f16 > ( e, m)
98
+ }
99
+ }
100
+
82
101
pub fn u32_to_f32_bits ( i : u32 ) -> u32 {
83
102
if i == 0 {
84
103
return 0 ;
@@ -122,6 +141,32 @@ mod int_to_float {
122
141
( h as u128 ) << 64
123
142
}
124
143
144
+ pub fn u64_to_f16_bits ( i : u64 ) -> u16 {
145
+ let n = i. leading_zeros ( ) ;
146
+ let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
147
+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u64 , f16 > ( ) ) as u16 ;
148
+
149
+ // Within the upper `F::BITS`, everything except for the signifcand
150
+ // gets truncated
151
+ let d1: u16 = ( i_m >> ( u64:: BITS - f16:: BITS - f16:: SIGNIFICAND_BITS - 1 ) ) . cast ( ) ;
152
+
153
+ // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
154
+ // check if it is nonzero.
155
+ let d2: u16 = ( i_m << f16:: BITS >> f16:: BITS != 0 ) . into ( ) ;
156
+ let adj = d1 | d2;
157
+
158
+ // Mantissa with implicit bit set
159
+ let m = m_adj :: < f16 > ( m_base, adj) ;
160
+ let e = if i == 0 { 0 } else { exp :: < u64 , f16 > ( n) - 1 } ;
161
+
162
+ // Clamp to infinity if the exponent is out of range
163
+ if e >= f16:: EXPONENT_MAX as u16 - 1 {
164
+ f16:: INFINITY . to_bits ( )
165
+ } else {
166
+ repr :: < f16 > ( e, m)
167
+ }
168
+ }
169
+
125
170
pub fn u64_to_f32_bits ( i : u64 ) -> u32 {
126
171
let n = i. leading_zeros ( ) ;
127
172
let i_m = i. wrapping_shl ( n) ;
@@ -160,6 +205,32 @@ mod int_to_float {
160
205
repr :: < f128 > ( e, m)
161
206
}
162
207
208
+ pub fn u128_to_f16_bits ( i : u128 ) -> u16 {
209
+ let n = i. leading_zeros ( ) ;
210
+ let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
211
+ let m_base: u16 = ( i_m >> shift_f_lt_i :: < u128 , f16 > ( ) ) as u16 ;
212
+
213
+ // Within the upper `F::BITS`, everything except for the signifcand
214
+ // gets truncated
215
+ let d1: u16 = ( i_m >> ( u128:: BITS - f16:: BITS - f16:: SIGNIFICAND_BITS - 1 ) ) . cast ( ) ;
216
+
217
+ // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
218
+ // check if it is nonzero.
219
+ let d2: u16 = ( i_m << f16:: BITS >> f16:: BITS != 0 ) . into ( ) ;
220
+ let adj = d1 | d2;
221
+
222
+ // Mantissa with implicit bit set
223
+ let m = m_adj :: < f16 > ( m_base, adj) ;
224
+ let e = if i == 0 { 0 } else { exp :: < u128 , f16 > ( n) - 1 } ;
225
+
226
+ // Clamp to infinity if the exponent is out of range
227
+ if e >= f16:: EXPONENT_MAX as u16 - 1 {
228
+ f16:: INFINITY . to_bits ( )
229
+ } else {
230
+ repr :: < f16 > ( e, m)
231
+ }
232
+ }
233
+
163
234
pub fn u128_to_f32_bits ( i : u128 ) -> u32 {
164
235
let n = i. leading_zeros ( ) ;
165
236
let i_m = i. wrapping_shl ( n) ; // Mantissa, shifted so the first bit is nonzero
@@ -210,6 +281,11 @@ mod int_to_float {
210
281
211
282
// Conversions from unsigned integers to floats.
212
283
intrinsics ! {
284
+ #[ cfg( f16_enabled) ]
285
+ pub extern "C" fn __floatunsihf( i: u32 ) -> f16 {
286
+ f16:: from_bits( int_to_float:: u32_to_f16_bits( i) )
287
+ }
288
+
213
289
#[ arm_aeabi_alias = __aeabi_ui2f]
214
290
pub extern "C" fn __floatunsisf( i: u32 ) -> f32 {
215
291
f32 :: from_bits( int_to_float:: u32_to_f32_bits( i) )
@@ -220,6 +296,17 @@ intrinsics! {
220
296
f64 :: from_bits( int_to_float:: u32_to_f64_bits( i) )
221
297
}
222
298
299
+ #[ ppc_alias = __floatunsikf]
300
+ #[ cfg( f128_enabled) ]
301
+ pub extern "C" fn __floatunsitf( i: u32 ) -> f128 {
302
+ f128:: from_bits( int_to_float:: u32_to_f128_bits( i) )
303
+ }
304
+
305
+ #[ cfg( f16_enabled) ]
306
+ pub extern "C" fn __floatundihf( i: u64 ) -> f16 {
307
+ f16:: from_bits( int_to_float:: u64_to_f16_bits( i) )
308
+ }
309
+
223
310
#[ arm_aeabi_alias = __aeabi_ul2f]
224
311
pub extern "C" fn __floatundisf( i: u64 ) -> f32 {
225
312
f32 :: from_bits( int_to_float:: u64_to_f32_bits( i) )
@@ -230,6 +317,17 @@ intrinsics! {
230
317
f64 :: from_bits( int_to_float:: u64_to_f64_bits( i) )
231
318
}
232
319
320
+ #[ ppc_alias = __floatundikf]
321
+ #[ cfg( f128_enabled) ]
322
+ pub extern "C" fn __floatunditf( i: u64 ) -> f128 {
323
+ f128:: from_bits( int_to_float:: u64_to_f128_bits( i) )
324
+ }
325
+
326
+ #[ cfg( f16_enabled) ]
327
+ pub extern "C" fn __floatuntihf( i: u128 ) -> f16 {
328
+ f16:: from_bits( int_to_float:: u128_to_f16_bits( i) )
329
+ }
330
+
233
331
#[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
234
332
pub extern "C" fn __floatuntisf( i: u128 ) -> f32 {
235
333
f32 :: from_bits( int_to_float:: u128_to_f32_bits( i) )
@@ -240,18 +338,6 @@ intrinsics! {
240
338
f64 :: from_bits( int_to_float:: u128_to_f64_bits( i) )
241
339
}
242
340
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
341
#[ ppc_alias = __floatuntikf]
256
342
#[ cfg( f128_enabled) ]
257
343
pub extern "C" fn __floatuntitf( i: u128 ) -> f128 {
@@ -261,6 +347,11 @@ intrinsics! {
261
347
262
348
// Conversions from signed integers to floats.
263
349
intrinsics ! {
350
+ #[ cfg( f16_enabled) ]
351
+ pub extern "C" fn __floatsihf( i: i32 ) -> f16 {
352
+ int_to_float:: signed( i, int_to_float:: u32_to_f16_bits)
353
+ }
354
+
264
355
#[ arm_aeabi_alias = __aeabi_i2f]
265
356
pub extern "C" fn __floatsisf( i: i32 ) -> f32 {
266
357
int_to_float:: signed( i, int_to_float:: u32_to_f32_bits)
@@ -271,6 +362,17 @@ intrinsics! {
271
362
int_to_float:: signed( i, int_to_float:: u32_to_f64_bits)
272
363
}
273
364
365
+ #[ ppc_alias = __floatsikf]
366
+ #[ cfg( f128_enabled) ]
367
+ pub extern "C" fn __floatsitf( i: i32 ) -> f128 {
368
+ int_to_float:: signed( i, int_to_float:: u32_to_f128_bits)
369
+ }
370
+
371
+ #[ cfg( f16_enabled) ]
372
+ pub extern "C" fn __floatdihf( i: i64 ) -> f16 {
373
+ int_to_float:: signed( i, int_to_float:: u64_to_f16_bits)
374
+ }
375
+
274
376
#[ arm_aeabi_alias = __aeabi_l2f]
275
377
pub extern "C" fn __floatdisf( i: i64 ) -> f32 {
276
378
int_to_float:: signed( i, int_to_float:: u64_to_f32_bits)
@@ -281,6 +383,17 @@ intrinsics! {
281
383
int_to_float:: signed( i, int_to_float:: u64_to_f64_bits)
282
384
}
283
385
386
+ #[ ppc_alias = __floatdikf]
387
+ #[ cfg( f128_enabled) ]
388
+ pub extern "C" fn __floatditf( i: i64 ) -> f128 {
389
+ int_to_float:: signed( i, int_to_float:: u64_to_f128_bits)
390
+ }
391
+
392
+ #[ cfg( f16_enabled) ]
393
+ pub extern "C" fn __floattihf( i: i128 ) -> f16 {
394
+ int_to_float:: signed( i, int_to_float:: u128_to_f16_bits)
395
+ }
396
+
284
397
#[ cfg_attr( target_os = "uefi" , unadjusted_on_win64) ]
285
398
pub extern "C" fn __floattisf( i: i128 ) -> f32 {
286
399
int_to_float:: signed( i, int_to_float:: u128_to_f32_bits)
@@ -291,18 +404,6 @@ intrinsics! {
291
404
int_to_float:: signed( i, int_to_float:: u128_to_f64_bits)
292
405
}
293
406
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
407
#[ ppc_alias = __floattikf]
307
408
#[ cfg( f128_enabled) ]
308
409
pub extern "C" fn __floattitf( i: i128 ) -> f128 {
0 commit comments