]> git.proxmox.com Git - rustc.git/blame - vendor/compiler_builtins/src/float/conv.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / vendor / compiler_builtins / src / float / conv.rs
CommitLineData
923072b8
FG
1/// Conversions from integers to floats.
2///
3/// These are hand-optimized bit twiddling code,
4/// which unfortunately isn't the easiest kind of code to read.
5///
6/// The algorithm is explained here: https://blog.m-ou.se/floats/
7mod int_to_float {
8 pub fn u32_to_f32_bits(i: u32) -> u32 {
9 if i == 0 {
10 return 0;
17df50a5 11 }
923072b8
FG
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.
2b03887a 16 let e = 157 - n; // Exponent plus 127, minus one.
923072b8 17 (e << 23) + m // + not |, so the mantissa can overflow into the exponent.
041b39d2
XL
18 }
19
923072b8
FG
20 pub fn u32_to_f64_bits(i: u32) -> u64 {
21 if i == 0 {
22 return 0;
23 }
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.
041b39d2
XL
28 }
29
923072b8
FG
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.
94b46f34
XL
38 }
39
923072b8
FG
40 pub fn u64_to_f64_bits(i: u64) -> u64 {
41 if i == 0 {
42 return 0;
041b39d2 43 }
923072b8 44 let n = i.leading_zeros();
2b03887a
FG
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.
923072b8
FG
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.
50 }
51
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.
60 }
61
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.
041b39d2 70 }
923072b8 71}
041b39d2 72
923072b8
FG
73// Conversions from unsigned integers to floats.
74intrinsics! {
041b39d2
XL
75 #[arm_aeabi_alias = __aeabi_ui2f]
76 pub extern "C" fn __floatunsisf(i: u32) -> f32 {
923072b8 77 f32::from_bits(int_to_float::u32_to_f32_bits(i))
041b39d2
XL
78 }
79
80 #[arm_aeabi_alias = __aeabi_ui2d]
81 pub extern "C" fn __floatunsidf(i: u32) -> f64 {
923072b8 82 f64::from_bits(int_to_float::u32_to_f64_bits(i))
041b39d2
XL
83 }
84
94b46f34
XL
85 #[arm_aeabi_alias = __aeabi_ul2f]
86 pub extern "C" fn __floatundisf(i: u64) -> f32 {
923072b8 87 f32::from_bits(int_to_float::u64_to_f32_bits(i))
94b46f34
XL
88 }
89
041b39d2
XL
90 #[arm_aeabi_alias = __aeabi_ul2d]
91 pub extern "C" fn __floatundidf(i: u64) -> f64 {
923072b8 92 f64::from_bits(int_to_float::u64_to_f64_bits(i))
041b39d2 93 }
041b39d2 94
f2b60f7d 95 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
923072b8
FG
96 pub extern "C" fn __floatuntisf(i: u128) -> f32 {
97 f32::from_bits(int_to_float::u128_to_f32_bits(i))
17df50a5 98 }
17df50a5 99
f2b60f7d 100 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
923072b8
FG
101 pub extern "C" fn __floatuntidf(i: u128) -> f64 {
102 f64::from_bits(int_to_float::u128_to_f64_bits(i))
17df50a5 103 }
041b39d2
XL
104}
105
923072b8 106// Conversions from signed integers to floats.
041b39d2 107intrinsics! {
923072b8
FG
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)
041b39d2
XL
112 }
113
923072b8
FG
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)
041b39d2
XL
118 }
119
923072b8
FG
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)
041b39d2
XL
124 }
125
923072b8
FG
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)
041b39d2 130 }
5099ac24 131
f2b60f7d 132 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
5099ac24 133 pub extern "C" fn __floattisf(i: i128) -> f32 {
923072b8
FG
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)
5099ac24
FG
136 }
137
f2b60f7d 138 #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
5099ac24 139 pub extern "C" fn __floattidf(i: i128) -> f64 {
923072b8
FG
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)
5099ac24 142 }
923072b8 143}
5099ac24 144
923072b8
FG
145// Conversions from floats to unsigned integers.
146intrinsics! {
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
151 0
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.
155 m >> s
156 } else if fbits <= 255 << 23 { // >= max (incl. inf)
157 u32::MAX
158 } else { // Negative or NaN
159 0
160 }
5099ac24
FG
161 }
162
923072b8
FG
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
167 0
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.
171 m >> s
172 } else if fbits <= 255 << 23 { // >= max (incl. inf)
173 u64::MAX
174 } else { // Negative or NaN
175 0
176 }
5099ac24
FG
177 }
178
923072b8
FG
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
184 0
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.
188 m >> s
189 } else if fbits == 255 << 23 { // == inf
190 u128::MAX
191 } else { // Negative or NaN
192 0
193 }
5099ac24
FG
194 }
195
923072b8
FG
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
200 0
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.
204 m >> s
205 } else if fbits <= 2047 << 52 { // >= max (incl. inf)
206 u32::MAX
207 } else { // Negative or NaN
208 0
209 }
5099ac24
FG
210 }
211
923072b8
FG
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
216 0
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.
220 m >> s
221 } else if fbits <= 2047 << 52 { // >= max (incl. inf)
222 u64::MAX
223 } else { // Negative or NaN
224 0
225 }
5099ac24
FG
226 }
227
923072b8
FG
228 #[cfg_attr(target_feature = "llvm14-builtins-abi", win64_128bit_abi_hack)]
229 #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
5099ac24 230 pub extern "C" fn __fixunsdfti(f: f64) -> u128 {
923072b8
FG
231 let fbits = f.to_bits();
232 if fbits < 1023 << 52 { // >= 0, < 1
233 0
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.
237 m >> s
238 } else if fbits <= 2047 << 52 { // >= max (incl. inf)
239 u128::MAX
240 } else { // Negative or NaN
241 0
242 }
5099ac24
FG
243 }
244}
245
923072b8 246// Conversions from floats to signed integers.
5099ac24 247intrinsics! {
923072b8
FG
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
252 0
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 }
260 } else { // NaN
261 0
262 }
5099ac24
FG
263 }
264
923072b8
FG
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
269 0
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 }
277 } else { // NaN
278 0
279 }
5099ac24
FG
280 }
281
923072b8
FG
282 #[cfg_attr(target_feature = "llvm14-builtins-abi", win64_128bit_abi_hack)]
283 #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
5099ac24 284 pub extern "C" fn __fixsfti(f: f32) -> i128 {
923072b8
FG
285 let fbits = f.to_bits() & !0 >> 1; // Remove sign bit.
286 if fbits < 127 << 23 { // >= 0, < 1
287 0
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 }
295 } else { // NaN
296 0
297 }
5099ac24
FG
298 }
299
923072b8
FG
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
304 0
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 }
312 } else { // NaN
313 0
314 }
5099ac24
FG
315 }
316
923072b8
FG
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
321 0
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 }
329 } else { // NaN
330 0
331 }
5099ac24 332 }
041b39d2 333
923072b8
FG
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
339 0
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 }
347 } else { // NaN
348 0
349 }
041b39d2
XL
350 }
351}