Skip to content

Commit ded247f

Browse files
committed
Add integer to f128 conversions
1 parent 53357e4 commit ded247f

File tree

6 files changed

+348
-68
lines changed

6 files changed

+348
-68
lines changed

README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,12 @@ of being added to Rust.
233233
- [x] fixunstfdi.c
234234
- [x] fixunstfsi.c
235235
- [x] fixunstfti.c
236-
- [ ] floatditf.c
237-
- [ ] floatsitf.c
238-
- [ ] floattitf.c
239-
- [ ] floatunditf.c
240-
- [ ] floatunsitf.c
241-
- [ ] floatuntitf.c
236+
- [x] floatditf.c
237+
- [x] floatsitf.c
238+
- [x] floattitf.c
239+
- [x] floatunditf.c
240+
- [x] floatunsitf.c
241+
- [x] floatuntitf.c
242242
- [x] multf3.c
243243
- [x] powitf2.c
244244
- [x] subtf3.c

build.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,6 @@ mod c {
522522
if (target.arch == "aarch64" || target.arch == "arm64ec") && consider_float_intrinsics {
523523
sources.extend(&[
524524
("__comparetf2", "comparetf2.c"),
525-
("__floatditf", "floatditf.c"),
526-
("__floatsitf", "floatsitf.c"),
527-
("__floatunditf", "floatunditf.c"),
528-
("__floatunsitf", "floatunsitf.c"),
529525
("__fe_getround", "fp_mode.c"),
530526
("__fe_raise_inexact", "fp_mode.c"),
531527
]);
@@ -540,21 +536,11 @@ mod c {
540536
}
541537

542538
if target.arch == "mips64" {
543-
sources.extend(&[
544-
("__netf2", "comparetf2.c"),
545-
("__floatsitf", "floatsitf.c"),
546-
("__floatunsitf", "floatunsitf.c"),
547-
("__fe_getround", "fp_mode.c"),
548-
]);
539+
sources.extend(&[("__netf2", "comparetf2.c"), ("__fe_getround", "fp_mode.c")]);
549540
}
550541

551542
if target.arch == "loongarch64" {
552-
sources.extend(&[
553-
("__netf2", "comparetf2.c"),
554-
("__floatsitf", "floatsitf.c"),
555-
("__floatunsitf", "floatunsitf.c"),
556-
("__fe_getround", "fp_mode.c"),
557-
]);
543+
sources.extend(&[("__netf2", "comparetf2.c"), ("__fe_getround", "fp_mode.c")]);
558544
}
559545

560546
// Remove the assembly implementations that won't compile for the target

examples/intrinsics.rs

+56-6
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,18 @@ mod intrinsics {
264264

265265
/* i32 operations */
266266

267+
// floatsisf
268+
pub fn aeabi_i2f(x: i32) -> f32 {
269+
x as f32
270+
}
271+
267272
// floatsidf
268273
pub fn aeabi_i2d(x: i32) -> f64 {
269274
x as f64
270275
}
271276

272-
// floatsisf
273-
pub fn aeabi_i2f(x: i32) -> f32 {
274-
x as f32
277+
pub fn floatsitf(x: i32) -> f128 {
278+
x as f128
275279
}
276280

277281
pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
@@ -294,6 +298,10 @@ mod intrinsics {
294298
x as f64
295299
}
296300

301+
pub fn floatditf(x: i64) -> f128 {
302+
x as f128
303+
}
304+
297305
pub fn mulodi4(a: i64, b: i64) -> i64 {
298306
a * b
299307
}
@@ -314,6 +322,18 @@ mod intrinsics {
314322

315323
/* i128 operations */
316324

325+
pub fn floattisf(x: i128) -> f32 {
326+
x as f32
327+
}
328+
329+
pub fn floattidf(x: i128) -> f64 {
330+
x as f64
331+
}
332+
333+
pub fn floattitf(x: i128) -> f128 {
334+
x as f128
335+
}
336+
317337
pub fn lshrti3(a: i128, b: usize) -> i128 {
318338
a >> b
319339
}
@@ -328,14 +348,18 @@ mod intrinsics {
328348

329349
/* u32 operations */
330350

351+
// floatunsisf
352+
pub fn aeabi_ui2f(x: u32) -> f32 {
353+
x as f32
354+
}
355+
331356
// floatunsidf
332357
pub fn aeabi_ui2d(x: u32) -> f64 {
333358
x as f64
334359
}
335360

336-
// floatunsisf
337-
pub fn aeabi_ui2f(x: u32) -> f32 {
338-
x as f32
361+
pub fn floatunsitf(x: u32) -> f128 {
362+
x as f128
339363
}
340364

341365
pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
@@ -358,6 +382,10 @@ mod intrinsics {
358382
x as f64
359383
}
360384

385+
pub fn floatunditf(x: u64) -> f128 {
386+
x as f128
387+
}
388+
361389
// udivdi3
362390
pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
363391
a * b
@@ -369,6 +397,18 @@ mod intrinsics {
369397

370398
/* u128 operations */
371399

400+
pub fn floatuntisf(x: u128) -> f32 {
401+
x as f32
402+
}
403+
404+
pub fn floatuntidf(x: u128) -> f64 {
405+
x as f64
406+
}
407+
408+
pub fn floatuntitf(x: u128) -> f128 {
409+
x as f128
410+
}
411+
372412
pub fn muloti4(a: u128, b: u128) -> Option<u128> {
373413
a.checked_mul(b)
374414
}
@@ -466,6 +506,16 @@ fn run() {
466506
bb(fixunstfsi(bb(2.)));
467507
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
468508
bb(fixunstfti(bb(2.)));
509+
bb(floatditf(bb(2)));
510+
bb(floatsitf(bb(2)));
511+
bb(floattidf(bb(2)));
512+
bb(floattisf(bb(2)));
513+
bb(floattitf(bb(2)));
514+
bb(floatunditf(bb(2)));
515+
bb(floatunsitf(bb(2)));
516+
bb(floatuntidf(bb(2)));
517+
bb(floatuntisf(bb(2)));
518+
bb(floatuntitf(bb(2)));
469519
bb(gttf(bb(2.), bb(2.)));
470520
bb(lshrti3(bb(2), bb(2)));
471521
bb(lttf(bb(2.), bb(2.)));

src/float/conv.rs

+80
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ mod int_to_float {
104104
repr::<f64>(e, m)
105105
}
106106

107+
#[cfg(f128_enabled)]
108+
pub fn u32_to_f128_bits(i: u32) -> u128 {
109+
if i == 0 {
110+
return 0;
111+
}
112+
let n = i.leading_zeros();
113+
114+
// Shift into mantissa position that is correct for the type, but shifted into the lower
115+
// 64 bits over so can can avoid 128-bit math.
116+
let m = (i as u64) << (shift_f_gt_i::<u32, f128>(n) - 64);
117+
let e = exp::<u32, f128>(n) as u64 - 1;
118+
// High 64 bits of f128 representation.
119+
let h = (e << (f128::SIGNIFICAND_BITS - 64)) + m;
120+
121+
// Shift back to the high bits, the rest of the mantissa will always be 0.
122+
(h as u128) << 64
123+
}
124+
107125
pub fn u64_to_f32_bits(i: u64) -> u32 {
108126
let n = i.leading_zeros();
109127
let i_m = i.wrapping_shl(n);
@@ -130,6 +148,18 @@ mod int_to_float {
130148
repr::<f64>(e, m)
131149
}
132150

151+
#[cfg(f128_enabled)]
152+
pub fn u64_to_f128_bits(i: u64) -> u128 {
153+
if i == 0 {
154+
return 0;
155+
}
156+
let n = i.leading_zeros();
157+
// Mantissa with implicit bit set
158+
let m = (i as u128) << shift_f_gt_i::<u64, f128>(n);
159+
let e = exp::<u64, f128>(n) - 1;
160+
repr::<f128>(e, m)
161+
}
162+
133163
pub fn u128_to_f32_bits(i: u128) -> u32 {
134164
let n = i.leading_zeros();
135165
let i_m = i.wrapping_shl(n); // Mantissa, shifted so the first bit is nonzero
@@ -162,6 +192,20 @@ mod int_to_float {
162192
let e = if i == 0 { 0 } else { exp::<u128, f64>(n) - 1 };
163193
repr::<f64>(e, m)
164194
}
195+
196+
#[cfg(f128_enabled)]
197+
pub fn u128_to_f128_bits(i: u128) -> u128 {
198+
if i == 0 {
199+
return 0;
200+
}
201+
let n = i.leading_zeros();
202+
// Mantissa with implicit bit set
203+
let m_base = (i << n) >> f128::EXPONENT_BITS;
204+
let adj = (i << n) << (f128::SIGNIFICAND_BITS + 1);
205+
let m = m_adj::<f128>(m_base, adj);
206+
let e = exp::<u128, f128>(n) - 1;
207+
repr::<f128>(e, m)
208+
}
165209
}
166210

167211
// Conversions from unsigned integers to floats.
@@ -195,6 +239,24 @@ intrinsics! {
195239
pub extern "C" fn __floatuntidf(i: u128) -> f64 {
196240
f64::from_bits(int_to_float::u128_to_f64_bits(i))
197241
}
242+
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+
#[ppc_alias = __floatuntikf]
256+
#[cfg(f128_enabled)]
257+
pub extern "C" fn __floatuntitf(i: u128) -> f128 {
258+
f128::from_bits(int_to_float::u128_to_f128_bits(i))
259+
}
198260
}
199261

200262
// Conversions from signed integers to floats.
@@ -228,6 +290,24 @@ intrinsics! {
228290
pub extern "C" fn __floattidf(i: i128) -> f64 {
229291
int_to_float::signed(i, int_to_float::u128_to_f64_bits)
230292
}
293+
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+
#[ppc_alias = __floattikf]
307+
#[cfg(f128_enabled)]
308+
pub extern "C" fn __floattitf(i: i128) -> f128 {
309+
int_to_float::signed(i, int_to_float::u128_to_f128_bits)
310+
}
231311
}
232312

233313
/// Generic float to unsigned int conversions.

0 commit comments

Comments
 (0)