Skip to content

Commit 6f7e12b

Browse files
committed
Add integer to f128 conversions
1 parent 3b73f31 commit 6f7e12b

File tree

6 files changed

+301
-28
lines changed

6 files changed

+301
-28
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
- [ ] 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
("__powitf2", "powitf2.c"),
530526
("__fe_getround", "fp_mode.c"),
531527
("__fe_raise_inexact", "fp_mode.c"),
@@ -541,21 +537,11 @@ mod c {
541537
}
542538

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

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

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

examples/intrinsics.rs

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

267267
/* i32 operations */
268268

269+
// floatsisf
270+
pub fn aeabi_i2f(x: i32) -> f32 {
271+
x as f32
272+
}
273+
269274
// floatsidf
270275
pub fn aeabi_i2d(x: i32) -> f64 {
271276
x as f64
272277
}
273278

274-
// floatsisf
275-
pub fn aeabi_i2f(x: i32) -> f32 {
276-
x as f32
279+
pub fn floatsitf(x: i32) -> f128 {
280+
x as f128
277281
}
278282

279283
pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
@@ -296,6 +300,10 @@ mod intrinsics {
296300
x as f64
297301
}
298302

303+
pub fn floatditf(x: i64) -> f128 {
304+
x as f128
305+
}
306+
299307
pub fn mulodi4(a: i64, b: i64) -> i64 {
300308
a * b
301309
}
@@ -316,6 +324,18 @@ mod intrinsics {
316324

317325
/* i128 operations */
318326

327+
pub fn floattisf(x: i128) -> f32 {
328+
x as f32
329+
}
330+
331+
pub fn floattidf(x: i128) -> f64 {
332+
x as f64
333+
}
334+
335+
pub fn floattitf(x: i128) -> f128 {
336+
x as f128
337+
}
338+
319339
pub fn lshrti3(a: i128, b: usize) -> i128 {
320340
a >> b
321341
}
@@ -330,14 +350,18 @@ mod intrinsics {
330350

331351
/* u32 operations */
332352

353+
// floatunsisf
354+
pub fn aeabi_ui2f(x: u32) -> f32 {
355+
x as f32
356+
}
357+
333358
// floatunsidf
334359
pub fn aeabi_ui2d(x: u32) -> f64 {
335360
x as f64
336361
}
337362

338-
// floatunsisf
339-
pub fn aeabi_ui2f(x: u32) -> f32 {
340-
x as f32
363+
pub fn floatunsitf(x: u32) -> f128 {
364+
x as f128
341365
}
342366

343367
pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
@@ -360,6 +384,10 @@ mod intrinsics {
360384
x as f64
361385
}
362386

387+
pub fn floatunditf(x: u64) -> f128 {
388+
x as f128
389+
}
390+
363391
// udivdi3
364392
pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
365393
a * b
@@ -371,6 +399,18 @@ mod intrinsics {
371399

372400
/* u128 operations */
373401

402+
pub fn floatuntisf(x: u128) -> f32 {
403+
x as f32
404+
}
405+
406+
pub fn floatuntidf(x: u128) -> f64 {
407+
x as f64
408+
}
409+
410+
pub fn floatuntitf(x: u128) -> f128 {
411+
x as f128
412+
}
413+
374414
pub fn muloti4(a: u128, b: u128) -> Option<u128> {
375415
a.checked_mul(b)
376416
}
@@ -468,6 +508,16 @@ fn run() {
468508
bb(fixunstfsi(bb(2.)));
469509
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
470510
bb(fixunstfti(bb(2.)));
511+
bb(floatditf(bb(2)));
512+
bb(floatsitf(bb(2)));
513+
bb(floattidf(bb(2)));
514+
bb(floattisf(bb(2)));
515+
bb(floattitf(bb(2)));
516+
bb(floatunditf(bb(2)));
517+
bb(floatunsitf(bb(2)));
518+
bb(floatuntidf(bb(2)));
519+
bb(floatuntisf(bb(2)));
520+
bb(floatuntitf(bb(2)));
471521
bb(gttf(bb(2.), bb(2.)));
472522
bb(lshrti3(bb(2), bb(2)));
473523
bb(lttf(bb(2.), bb(2.)));

src/float/conv.rs

+76
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,23 @@ mod int_to_float {
9191
repr::<f64>(e, m)
9292
}
9393

94+
#[cfg(not(feature = "no-f16-f128"))]
95+
pub fn u32_to_f128_bits(i: u32) -> u128 {
96+
if i == 0 {
97+
return 0;
98+
}
99+
let n = i.leading_zeros();
100+
101+
// High 64 significant bits, with bit 113 still in tact.
102+
let m = (i as u64) << (f128::SIGNIFICAND_BITS - u32::BITS + 1 - 64 + n);
103+
let e = (u32::BITS + f128::EXPONENT_BIAS - 2 - n) as u64;
104+
// High 64 bits of f128 representation.
105+
let h = (e << (f128::SIGNIFICAND_BITS - 64)) + m;
106+
107+
// Result was calculated as a u64 to avoid 128-bit operations (lower bits are always 0).
108+
(h as u128) << 64
109+
}
110+
94111
pub fn u64_to_f32_bits(i: u64) -> u32 {
95112
let n = i.leading_zeros();
96113
let i_m = i.wrapping_shl(n); // Mantissa, shifted so the first bit is nonzero
@@ -114,6 +131,17 @@ mod int_to_float {
114131
repr::<f64>(e, m)
115132
}
116133

134+
#[cfg(not(feature = "no-f16-f128"))]
135+
pub fn u64_to_f128_bits(i: u64) -> u128 {
136+
if i == 0 {
137+
return 0;
138+
}
139+
let n = i.leading_zeros();
140+
let m = m_f_gt_i::<_, f128>(i, n);
141+
let e = exp::<u64, f128>(n);
142+
repr::<f128>(e, m)
143+
}
144+
117145
pub fn u128_to_f32_bits(i: u128) -> u32 {
118146
let n = i.leading_zeros();
119147
let i_m = i.wrapping_shl(n); // Mantissa, shifted so the first bit is nonzero
@@ -144,6 +172,18 @@ mod int_to_float {
144172
let e = if i == 0 { 0 } else { exp::<u128, f64>(n) };
145173
repr::<f64>(e, m)
146174
}
175+
176+
#[cfg(not(feature = "no-f16-f128"))]
177+
pub fn u128_to_f128_bits(i: u128) -> u128 {
178+
if i == 0 {
179+
return 0;
180+
}
181+
let n = i.leading_zeros();
182+
let (m_base, adj) = m_f_eq_i::<u128, f128>(i, n);
183+
let m = m_adj::<f128>(m_base, adj);
184+
let e = exp::<u128, f128>(n);
185+
repr::<f128>(e, m)
186+
}
147187
}
148188

149189
// Conversions from unsigned integers to floats.
@@ -177,6 +217,24 @@ intrinsics! {
177217
pub extern "C" fn __floatuntidf(i: u128) -> f64 {
178218
f64::from_bits(int_to_float::u128_to_f64_bits(i))
179219
}
220+
221+
#[ppc_alias = __floatunsikf]
222+
#[cfg(not(feature = "no-f16-f128"))]
223+
pub extern "C" fn __floatunsitf(i: u32) -> f128 {
224+
f128::from_bits(int_to_float::u32_to_f128_bits(i))
225+
}
226+
227+
#[ppc_alias = __floatundikf]
228+
#[cfg(not(feature = "no-f16-f128"))]
229+
pub extern "C" fn __floatunditf(i: u64) -> f128 {
230+
f128::from_bits(int_to_float::u64_to_f128_bits(i))
231+
}
232+
233+
#[ppc_alias = __floatuntikf]
234+
#[cfg(not(feature = "no-f16-f128"))]
235+
pub extern "C" fn __floatuntitf(i: u128) -> f128 {
236+
f128::from_bits(int_to_float::u128_to_f128_bits(i))
237+
}
180238
}
181239

182240
// Conversions from signed integers to floats.
@@ -210,6 +268,24 @@ intrinsics! {
210268
pub extern "C" fn __floattidf(i: i128) -> f64 {
211269
int_to_float::signed(i, int_to_float::u128_to_f64_bits)
212270
}
271+
272+
#[ppc_alias = __floatsikf]
273+
#[cfg(not(feature = "no-f16-f128"))]
274+
pub extern "C" fn __floatsitf(i: i32) -> f128 {
275+
int_to_float::signed(i, int_to_float::u32_to_f128_bits)
276+
}
277+
278+
#[ppc_alias = __floatdikf]
279+
#[cfg(not(feature = "no-f16-f128"))]
280+
pub extern "C" fn __floatditf(i: i64) -> f128 {
281+
int_to_float::signed(i, int_to_float::u64_to_f128_bits)
282+
}
283+
284+
#[ppc_alias = __floattikf]
285+
#[cfg(not(feature = "no-f16-f128"))]
286+
pub extern "C" fn __floattitf(i: i128) -> f128 {
287+
int_to_float::signed(i, int_to_float::u128_to_f128_bits)
288+
}
213289
}
214290

215291
/// Generic float to unsigned int conversions.

0 commit comments

Comments
 (0)