Skip to content

Commit 9550d45

Browse files
committed
Add support for f128 integer exponentiation
Adds `__powitf2`
1 parent 449643f commit 9550d45

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ These builtins are needed to support `f16` and `f128`, which are in the process
250250
- [ ] floatunditf.c
251251
- [ ] floatunsitf.c
252252
- [x] multf3.c
253-
- [ ] powitf2.c
253+
- [x] powitf2.c
254254
- [ ] ppc/fixtfdi.c
255255
- [ ] ppc/fixunstfdi.c
256256
- [ ] ppc/floatditf.c

build.rs

-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,6 @@ mod c {
544544
("__floatunditf", "floatunditf.c"),
545545
("__floatunsitf", "floatunsitf.c"),
546546
("__divtf3", "divtf3.c"),
547-
("__powitf2", "powitf2.c"),
548547
("__fe_getround", "fp_mode.c"),
549548
("__fe_raise_inexact", "fp_mode.c"),
550549
]);

src/float/pow.rs

+12
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,16 @@ intrinsics! {
3535
pub extern "C" fn __powidf2(a: f64, b: i32) -> f64 {
3636
pow(a, b)
3737
}
38+
39+
#[avr_skip]
40+
#[cfg(not(any(feature = "no-f16-f128", target_arch = "powerpc", target_arch = "powerpc64")))]
41+
pub extern "C" fn __powitf2(a: f128, b: i32) -> f128 {
42+
pow(a, b)
43+
}
44+
45+
#[avr_skip]
46+
#[cfg(all(not(feature = "no-f16-f128"), any(target_arch = "powerpc", target_arch = "powerpc64")))]
47+
pub extern "C" fn __powikf2(a: f128, b: i32) -> f128 {
48+
pow(a, b)
49+
}
3850
}

testcrate/tests/misc.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// makes configuration easier
22
#![allow(unused_macros)]
3+
#![feature(f128)]
34

45
use testcrate::*;
56

@@ -96,7 +97,7 @@ fn leading_zeros() {
9697
// https://github.com/rust-lang/rust/issues/73920.
9798
// TODO how do we resolve this indeterminacy?
9899
macro_rules! pow {
99-
($($f:ty, $tolerance:expr, $fn:ident);*;) => {
100+
($($f:ty, $tolerance:expr, $fn:ident);* ;) => {
100101
$(
101102
fuzz_float_2(N, |x: $f, y: $f| {
102103
if !(Float::is_subnormal(x) || Float::is_subnormal(y) || x.is_nan()) {
@@ -118,12 +119,12 @@ macro_rules! pow {
118119
b < $tolerance
119120
} else {
120121
let quo = b / a;
121-
(quo < (1. + $tolerance)) && (quo > (1. - $tolerance))
122+
(quo < (1. + black_box($tolerance))) && (quo > (1. - black_box($tolerance)))
122123
}
123124
};
124125
if !good {
125126
panic!(
126-
"{}({}, {}): std: {}, builtins: {}",
127+
"{}({:?}, {:?}): std: {:?}, builtins: {:?}",
127128
stringify!($fn), x, n, tmp0, tmp1
128129
);
129130
}
@@ -139,8 +140,27 @@ fn float_pow() {
139140
use compiler_builtins::float::pow::{__powidf2, __powisf2};
140141
use compiler_builtins::float::Float;
141142

143+
fn black_box<T>(val: T) -> T {
144+
val
145+
}
146+
142147
pow!(
143148
f32, 1e-4, __powisf2;
144149
f64, 1e-12, __powidf2;
145150
);
151+
152+
// There is no apfloat fallback for `powi` so we just skip these tests on these platforms
153+
#[cfg(not(any(feature = "no-f16-f128", feature = "no-sys-f128")))]
154+
{
155+
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
156+
use compiler_builtins::float::pow::__powikf2 as __powitf2;
157+
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
158+
use compiler_builtins::float::pow::__powitf2;
159+
160+
// FIXME(f16_f128): we do this to block const eval which currently ICEs. Change this
161+
// once it works correctly.
162+
use core::hint::black_box;
163+
164+
pow!(f128, 1e-24, __powitf2;);
165+
}
146166
}

0 commit comments

Comments
 (0)