]>
git.proxmox.com Git - rustc.git/blob - vendor/compiler_builtins/src/float/conv.rs
1 /// Conversions from integers to floats.
3 /// These are hand-optimized bit twiddling code,
4 /// which unfortunately isn't the easiest kind of code to read.
6 /// The algorithm is explained here: https://blog.m-ou.se/floats/
8 pub fn u32_to_f32_bits(i
: u32) -> u32 {
12 let n
= i
.leading_zeros();
13 let a
= (i
<< n
) >> 8; // Significant bits, with bit 24 still in tact.
14 let b
= (i
<< n
) << 24; // Insignificant bits, only relevant for rounding.
15 let m
= a
+ ((b
- (b
>> 31 & !a
)) >> 31); // Add one when we need to round up. Break ties to even.
16 let e
= 157 - n
; // Exponent plus 127, minus one.
17 (e
<< 23) + m
// + not |, so the mantissa can overflow into the exponent.
20 pub fn u32_to_f64_bits(i
: u32) -> u64 {
24 let n
= i
.leading_zeros();
25 let m
= (i
as u64) << (21 + n
); // Significant bits, with bit 53 still in tact.
26 let e
= 1053 - n
as u64; // Exponent plus 1023, minus one.
27 (e
<< 52) + m
// Bit 53 of m will overflow into e.
30 pub fn u64_to_f32_bits(i
: u64) -> u32 {
31 let n
= i
.leading_zeros();
32 let y
= i
.wrapping_shl(n
);
33 let a
= (y
>> 40) as u32; // Significant bits, with bit 24 still in tact.
34 let b
= (y
>> 8 | y
& 0xFFFF) as u32; // Insignificant bits, only relevant for rounding.
35 let m
= a
+ ((b
- (b
>> 31 & !a
)) >> 31); // Add one when we need to round up. Break ties to even.
36 let e
= if i
== 0 { 0 }
else { 189 - n }
; // Exponent plus 127, minus one, except for zero.
37 (e
<< 23) + m
// + not |, so the mantissa can overflow into the exponent.
40 pub fn u64_to_f64_bits(i
: u64) -> u64 {
44 let n
= i
.leading_zeros();
45 let a
= (i
<< n
) >> 11; // Significant bits, with bit 53 still in tact.
46 let b
= (i
<< n
) << 53; // Insignificant bits, only relevant for rounding.
47 let m
= a
+ ((b
- (b
>> 63 & !a
)) >> 63); // Add one when we need to round up. Break ties to even.
48 let e
= 1085 - n
as u64; // Exponent plus 1023, minus one.
49 (e
<< 52) + m
// + not |, so the mantissa can overflow into the exponent.
52 pub fn u128_to_f32_bits(i
: u128
) -> u32 {
53 let n
= i
.leading_zeros();
54 let y
= i
.wrapping_shl(n
);
55 let a
= (y
>> 104) as u32; // Significant bits, with bit 24 still in tact.
56 let b
= (y
>> 72) as u32 | ((y
<< 32) >> 32 != 0) as u32; // Insignificant bits, only relevant for rounding.
57 let m
= a
+ ((b
- (b
>> 31 & !a
)) >> 31); // Add one when we need to round up. Break ties to even.
58 let e
= if i
== 0 { 0 }
else { 253 - n }
; // Exponent plus 127, minus one, except for zero.
59 (e
<< 23) + m
// + not |, so the mantissa can overflow into the exponent.
62 pub fn u128_to_f64_bits(i
: u128
) -> u64 {
63 let n
= i
.leading_zeros();
64 let y
= i
.wrapping_shl(n
);
65 let a
= (y
>> 75) as u64; // Significant bits, with bit 53 still in tact.
66 let b
= (y
>> 11 | y
& 0xFFFF_FFFF) as u64; // Insignificant bits, only relevant for rounding.
67 let m
= a
+ ((b
- (b
>> 63 & !a
)) >> 63); // Add one when we need to round up. Break ties to even.
68 let e
= if i
== 0 { 0 }
else { 1149 - n as u64 }
; // Exponent plus 1023, minus one, except for zero.
69 (e
<< 52) + m
// + not |, so the mantissa can overflow into the exponent.
73 // Conversions from unsigned integers to floats.
75 #[arm_aeabi_alias = __aeabi_ui2f]
76 pub extern "C" fn __floatunsisf(i
: u32) -> f32 {
77 f32::from_bits(int_to_float
::u32_to_f32_bits(i
))
80 #[arm_aeabi_alias = __aeabi_ui2d]
81 pub extern "C" fn __floatunsidf(i
: u32) -> f64 {
82 f64::from_bits(int_to_float
::u32_to_f64_bits(i
))
85 #[arm_aeabi_alias = __aeabi_ul2f]
86 pub extern "C" fn __floatundisf(i
: u64) -> f32 {
87 f32::from_bits(int_to_float
::u64_to_f32_bits(i
))
90 #[arm_aeabi_alias = __aeabi_ul2d]
91 pub extern "C" fn __floatundidf(i
: u64) -> f64 {
92 f64::from_bits(int_to_float
::u64_to_f64_bits(i
))
95 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
96 pub extern "C" fn __floatuntisf(i
: u128
) -> f32 {
97 f32::from_bits(int_to_float
::u128_to_f32_bits(i
))
100 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
101 pub extern "C" fn __floatuntidf(i
: u128
) -> f64 {
102 f64::from_bits(int_to_float
::u128_to_f64_bits(i
))
106 // Conversions from signed integers to floats.
108 #[arm_aeabi_alias = __aeabi_i2f]
109 pub extern "C" fn __floatsisf(i
: i32) -> f32 {
110 let sign_bit
= ((i
>> 31) as u32) << 31;
111 f32::from_bits(int_to_float
::u32_to_f32_bits(i
.unsigned_abs()) | sign_bit
)
114 #[arm_aeabi_alias = __aeabi_i2d]
115 pub extern "C" fn __floatsidf(i
: i32) -> f64 {
116 let sign_bit
= ((i
>> 31) as u64) << 63;
117 f64::from_bits(int_to_float
::u32_to_f64_bits(i
.unsigned_abs()) | sign_bit
)
120 #[arm_aeabi_alias = __aeabi_l2f]
121 pub extern "C" fn __floatdisf(i
: i64) -> f32 {
122 let sign_bit
= ((i
>> 63) as u32) << 31;
123 f32::from_bits(int_to_float
::u64_to_f32_bits(i
.unsigned_abs()) | sign_bit
)
126 #[arm_aeabi_alias = __aeabi_l2d]
127 pub extern "C" fn __floatdidf(i
: i64) -> f64 {
128 let sign_bit
= ((i
>> 63) as u64) << 63;
129 f64::from_bits(int_to_float
::u64_to_f64_bits(i
.unsigned_abs()) | sign_bit
)
132 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
133 pub extern "C" fn __floattisf(i
: i128
) -> f32 {
134 let sign_bit
= ((i
>> 127) as u32) << 31;
135 f32::from_bits(int_to_float
::u128_to_f32_bits(i
.unsigned_abs()) | sign_bit
)
138 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
139 pub extern "C" fn __floattidf(i
: i128
) -> f64 {
140 let sign_bit
= ((i
>> 127) as u64) << 63;
141 f64::from_bits(int_to_float
::u128_to_f64_bits(i
.unsigned_abs()) | sign_bit
)
145 // Conversions from floats to unsigned integers.
147 #[arm_aeabi_alias = __aeabi_f2uiz]
148 pub extern "C" fn __fixunssfsi(f
: f32) -> u32 {
149 let fbits
= f
.to_bits();
150 if fbits
< 127 << 23 { // >= 0, < 1
152 } else if fbits
< 159 << 23 { // >= 1, < max
153 let m
= 1 << 31 | fbits
<< 8; // Mantissa and the implicit 1-bit.
154 let s
= 158 - (fbits
>> 23); // Shift based on the exponent and bias.
156 } else if fbits
<= 255 << 23 { // >= max (incl. inf)
158 } else { // Negative or NaN
163 #[arm_aeabi_alias = __aeabi_f2ulz]
164 pub extern "C" fn __fixunssfdi(f
: f32) -> u64 {
165 let fbits
= f
.to_bits();
166 if fbits
< 127 << 23 { // >= 0, < 1
168 } else if fbits
< 191 << 23 { // >= 1, < max
169 let m
= 1 << 63 | (fbits
as u64) << 40; // Mantissa and the implicit 1-bit.
170 let s
= 190 - (fbits
>> 23); // Shift based on the exponent and bias.
172 } else if fbits
<= 255 << 23 { // >= max (incl. inf)
174 } else { // Negative or NaN
179 #[cfg_attr(target_feature = "llvm14-builtins-abi", win64_128bit_abi_hack)]
180 #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
181 pub extern "C" fn __fixunssfti(f
: f32) -> u128
{
182 let fbits
= f
.to_bits();
183 if fbits
< 127 << 23 { // >= 0, < 1
185 } else if fbits
< 255 << 23 { // >= 1, < inf
186 let m
= 1 << 127 | (fbits
as u128
) << 104; // Mantissa and the implicit 1-bit.
187 let s
= 254 - (fbits
>> 23); // Shift based on the exponent and bias.
189 } else if fbits
== 255 << 23 { // == inf
191 } else { // Negative or NaN
196 #[arm_aeabi_alias = __aeabi_d2uiz]
197 pub extern "C" fn __fixunsdfsi(f
: f64) -> u32 {
198 let fbits
= f
.to_bits();
199 if fbits
< 1023 << 52 { // >= 0, < 1
201 } else if fbits
< 1055 << 52 { // >= 1, < max
202 let m
= 1 << 31 | (fbits
>> 21) as u32; // Mantissa and the implicit 1-bit.
203 let s
= 1054 - (fbits
>> 52); // Shift based on the exponent and bias.
205 } else if fbits
<= 2047 << 52 { // >= max (incl. inf)
207 } else { // Negative or NaN
212 #[arm_aeabi_alias = __aeabi_d2ulz]
213 pub extern "C" fn __fixunsdfdi(f
: f64) -> u64 {
214 let fbits
= f
.to_bits();
215 if fbits
< 1023 << 52 { // >= 0, < 1
217 } else if fbits
< 1087 << 52 { // >= 1, < max
218 let m
= 1 << 63 | fbits
<< 11; // Mantissa and the implicit 1-bit.
219 let s
= 1086 - (fbits
>> 52); // Shift based on the exponent and bias.
221 } else if fbits
<= 2047 << 52 { // >= max (incl. inf)
223 } else { // Negative or NaN
228 #[cfg_attr(target_feature = "llvm14-builtins-abi", win64_128bit_abi_hack)]
229 #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
230 pub extern "C" fn __fixunsdfti(f
: f64) -> u128
{
231 let fbits
= f
.to_bits();
232 if fbits
< 1023 << 52 { // >= 0, < 1
234 } else if fbits
< 1151 << 52 { // >= 1, < max
235 let m
= 1 << 127 | (fbits
as u128
) << 75; // Mantissa and the implicit 1-bit.
236 let s
= 1150 - (fbits
>> 52); // Shift based on the exponent and bias.
238 } else if fbits
<= 2047 << 52 { // >= max (incl. inf)
240 } else { // Negative or NaN
246 // Conversions from floats to signed integers.
248 #[arm_aeabi_alias = __aeabi_f2iz]
249 pub extern "C" fn __fixsfsi(f
: f32) -> i32 {
250 let fbits
= f
.to_bits() & !0 >> 1; // Remove sign bit.
251 if fbits
< 127 << 23 { // >= 0, < 1
253 } else if fbits
< 158 << 23 { // >= 1, < max
254 let m
= 1 << 31 | fbits
<< 8; // Mantissa and the implicit 1-bit.
255 let s
= 158 - (fbits
>> 23); // Shift based on the exponent and bias.
256 let u
= (m
>> s
) as i32; // Unsigned result.
257 if f
.is_sign_negative() { -u }
else { u }
258 } else if fbits
<= 255 << 23 { // >= max (incl. inf)
259 if f
.is_sign_negative() { i32::MIN }
else { i32::MAX }
265 #[arm_aeabi_alias = __aeabi_f2lz]
266 pub extern "C" fn __fixsfdi(f
: f32) -> i64 {
267 let fbits
= f
.to_bits() & !0 >> 1; // Remove sign bit.
268 if fbits
< 127 << 23 { // >= 0, < 1
270 } else if fbits
< 190 << 23 { // >= 1, < max
271 let m
= 1 << 63 | (fbits
as u64) << 40; // Mantissa and the implicit 1-bit.
272 let s
= 190 - (fbits
>> 23); // Shift based on the exponent and bias.
273 let u
= (m
>> s
) as i64; // Unsigned result.
274 if f
.is_sign_negative() { -u }
else { u }
275 } else if fbits
<= 255 << 23 { // >= max (incl. inf)
276 if f
.is_sign_negative() { i64::MIN }
else { i64::MAX }
282 #[cfg_attr(target_feature = "llvm14-builtins-abi", win64_128bit_abi_hack)]
283 #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
284 pub extern "C" fn __fixsfti(f
: f32) -> i128
{
285 let fbits
= f
.to_bits() & !0 >> 1; // Remove sign bit.
286 if fbits
< 127 << 23 { // >= 0, < 1
288 } else if fbits
< 254 << 23 { // >= 1, < max
289 let m
= 1 << 127 | (fbits
as u128
) << 104; // Mantissa and the implicit 1-bit.
290 let s
= 254 - (fbits
>> 23); // Shift based on the exponent and bias.
291 let u
= (m
>> s
) as i128
; // Unsigned result.
292 if f
.is_sign_negative() { -u }
else { u }
293 } else if fbits
<= 255 << 23 { // >= max (incl. inf)
294 if f
.is_sign_negative() { i128::MIN }
else { i128::MAX }
300 #[arm_aeabi_alias = __aeabi_d2iz]
301 pub extern "C" fn __fixdfsi(f
: f64) -> i32 {
302 let fbits
= f
.to_bits() & !0 >> 1; // Remove sign bit.
303 if fbits
< 1023 << 52 { // >= 0, < 1
305 } else if fbits
< 1054 << 52 { // >= 1, < max
306 let m
= 1 << 31 | (fbits
>> 21) as u32; // Mantissa and the implicit 1-bit.
307 let s
= 1054 - (fbits
>> 52); // Shift based on the exponent and bias.
308 let u
= (m
>> s
) as i32; // Unsigned result.
309 if f
.is_sign_negative() { -u }
else { u }
310 } else if fbits
<= 2047 << 52 { // >= max (incl. inf)
311 if f
.is_sign_negative() { i32::MIN }
else { i32::MAX }
317 #[arm_aeabi_alias = __aeabi_d2lz]
318 pub extern "C" fn __fixdfdi(f
: f64) -> i64 {
319 let fbits
= f
.to_bits() & !0 >> 1; // Remove sign bit.
320 if fbits
< 1023 << 52 { // >= 0, < 1
322 } else if fbits
< 1086 << 52 { // >= 1, < max
323 let m
= 1 << 63 | fbits
<< 11; // Mantissa and the implicit 1-bit.
324 let s
= 1086 - (fbits
>> 52); // Shift based on the exponent and bias.
325 let u
= (m
>> s
) as i64; // Unsigned result.
326 if f
.is_sign_negative() { -u }
else { u }
327 } else if fbits
<= 2047 << 52 { // >= max (incl. inf)
328 if f
.is_sign_negative() { i64::MIN }
else { i64::MAX }
334 #[cfg_attr(target_feature = "llvm14-builtins-abi", win64_128bit_abi_hack)]
335 #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
336 pub extern "C" fn __fixdfti(f
: f64) -> i128
{
337 let fbits
= f
.to_bits() & !0 >> 1; // Remove sign bit.
338 if fbits
< 1023 << 52 { // >= 0, < 1
340 } else if fbits
< 1150 << 52 { // >= 1, < max
341 let m
= 1 << 127 | (fbits
as u128
) << 75; // Mantissa and the implicit 1-bit.
342 let s
= 1150 - (fbits
>> 52); // Shift based on the exponent and bias.
343 let u
= (m
>> s
) as i128
; // Unsigned result.
344 if f
.is_sign_negative() { -u }
else { u }
345 } else if fbits
<= 2047 << 52 { // >= max (incl. inf)
346 if f
.is_sign_negative() { i128::MIN }
else { i128::MAX }