Skip to content

Commit

Permalink
Merge pull request #606 from tgross35/f16-f128-intrinsics-min
Browse files Browse the repository at this point in the history
Add addition, subtraction, multiplication, and compare operations for `f128`
  • Loading branch information
Amanieu authored May 16, 2024
2 parents 7f33201 + 6a847ab commit 449643f
Show file tree
Hide file tree
Showing 25 changed files with 923 additions and 226 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ These builtins are needed to support 128-bit integers.

These builtins are needed to support `f16` and `f128`, which are in the process of being added to Rust.

- [ ] addtf3.c
- [ ] comparetf2.c
- [x] addtf3.c
- [x] comparetf2.c
- [ ] divtf3.c
- [x] extenddftf2.c
- [x] extendhfsf2.c
Expand All @@ -249,13 +249,13 @@ These builtins are needed to support `f16` and `f128`, which are in the process
- [ ] floatsitf.c
- [ ] floatunditf.c
- [ ] floatunsitf.c
- [ ] multf3.c
- [x] multf3.c
- [ ] powitf2.c
- [ ] ppc/fixtfdi.c
- [ ] ppc/fixunstfdi.c
- [ ] ppc/floatditf.c
- [ ] ppc/floatunditf.c
- [ ] subtf3.c
- [x] subtf3.c
- [x] truncdfhf2.c
- [x] truncsfhf2.c
- [x] trunctfdf2.c
Expand Down
11 changes: 0 additions & 11 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,6 @@ mod c {
("__floatsitf", "floatsitf.c"),
("__floatunditf", "floatunditf.c"),
("__floatunsitf", "floatunsitf.c"),
("__addtf3", "addtf3.c"),
("__multf3", "multf3.c"),
("__subtf3", "subtf3.c"),
("__divtf3", "divtf3.c"),
("__powitf2", "powitf2.c"),
("__fe_getround", "fp_mode.c"),
Expand All @@ -564,30 +561,22 @@ mod c {
if target_arch == "mips64" {
sources.extend(&[
("__netf2", "comparetf2.c"),
("__addtf3", "addtf3.c"),
("__multf3", "multf3.c"),
("__subtf3", "subtf3.c"),
("__fixtfsi", "fixtfsi.c"),
("__floatsitf", "floatsitf.c"),
("__fixunstfsi", "fixunstfsi.c"),
("__floatunsitf", "floatunsitf.c"),
("__fe_getround", "fp_mode.c"),
("__divtf3", "divtf3.c"),
]);
}

if target_arch == "loongarch64" {
sources.extend(&[
("__netf2", "comparetf2.c"),
("__addtf3", "addtf3.c"),
("__multf3", "multf3.c"),
("__subtf3", "subtf3.c"),
("__fixtfsi", "fixtfsi.c"),
("__floatsitf", "floatsitf.c"),
("__fixunstfsi", "fixunstfsi.c"),
("__floatunsitf", "floatunsitf.c"),
("__fe_getround", "fp_mode.c"),
("__divtf3", "divtf3.c"),
]);
}

Expand Down
2 changes: 1 addition & 1 deletion ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fi
if [ "${NO_STD:-}" = "1" ]; then
echo "nothing to do for no_std"
else
run="cargo test --manifest-path testcrate/Cargo.toml --target $target"
run="cargo test --manifest-path testcrate/Cargo.toml --no-fail-fast --target $target"
$run
$run --release
$run --features c
Expand Down
32 changes: 21 additions & 11 deletions src/float/add.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::float::Float;
use crate::int::{CastInto, Int};
use crate::int::{CastInto, Int, MinInt};

/// Returns `a + b`
fn add<F: Float>(a: F, b: F) -> F
Expand Down Expand Up @@ -57,17 +57,17 @@ where
}

// zero + anything = anything
if a_abs == Int::ZERO {
if a_abs == MinInt::ZERO {
// but we need to get the sign right for zero + zero
if b_abs == Int::ZERO {
if b_abs == MinInt::ZERO {
return F::from_repr(a.repr() & b.repr());
} else {
return b;
}
}

// anything + zero = anything
if b_abs == Int::ZERO {
if b_abs == MinInt::ZERO {
return a;
}
}
Expand Down Expand Up @@ -113,10 +113,10 @@ where
// Shift the significand of b by the difference in exponents, with a sticky
// bottom bit to get rounding correct.
let align = a_exponent.wrapping_sub(b_exponent).cast();
if align != Int::ZERO {
if align != MinInt::ZERO {
if align < bits {
let sticky =
F::Int::from_bool(b_significand << bits.wrapping_sub(align).cast() != Int::ZERO);
F::Int::from_bool(b_significand << bits.wrapping_sub(align).cast() != MinInt::ZERO);
b_significand = (b_significand >> align.cast()) | sticky;
} else {
b_significand = one; // sticky; b is known to be non-zero.
Expand All @@ -125,8 +125,8 @@ where
if subtraction {
a_significand = a_significand.wrapping_sub(b_significand);
// If a == -b, return +zero.
if a_significand == Int::ZERO {
return F::from_repr(Int::ZERO);
if a_significand == MinInt::ZERO {
return F::from_repr(MinInt::ZERO);
}

// If partial cancellation occured, we need to left-shift the result
Expand All @@ -143,8 +143,8 @@ where

// If the addition carried up, we need to right-shift the result and
// adjust the exponent:
if a_significand & implicit_bit << 4 != Int::ZERO {
let sticky = F::Int::from_bool(a_significand & one != Int::ZERO);
if a_significand & implicit_bit << 4 != MinInt::ZERO {
let sticky = F::Int::from_bool(a_significand & one != MinInt::ZERO);
a_significand = a_significand >> 1 | sticky;
a_exponent += 1;
}
Expand All @@ -160,7 +160,7 @@ where
// need to shift the significand.
let shift = (1 - a_exponent).cast();
let sticky =
F::Int::from_bool((a_significand << bits.wrapping_sub(shift).cast()) != Int::ZERO);
F::Int::from_bool((a_significand << bits.wrapping_sub(shift).cast()) != MinInt::ZERO);
a_significand = a_significand >> shift.cast() | sticky;
a_exponent = 0;
}
Expand Down Expand Up @@ -203,6 +203,16 @@ intrinsics! {
add(a, b)
}

#[cfg(not(any(feature = "no-f16-f128", target_arch = "powerpc", target_arch = "powerpc64")))]
pub extern "C" fn __addtf3(a: f128, b: f128) -> f128 {
add(a, b)
}

#[cfg(all(not(feature = "no-f16-f128"), any(target_arch = "powerpc", target_arch = "powerpc64")))]
pub extern "C" fn __addkf3(a: f128, b: f128) -> f128 {
add(a, b)
}

#[cfg(target_arch = "arm")]
pub extern "C" fn __addsf3vfp(a: f32, b: f32) -> f32 {
a + b
Expand Down
85 changes: 84 additions & 1 deletion src/float/cmp.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(unreachable_code)]

use crate::float::Float;
use crate::int::Int;
use crate::int::MinInt;

#[derive(Clone, Copy)]
enum Result {
Expand Down Expand Up @@ -172,6 +172,89 @@ intrinsics! {
}
}

#[cfg(not(any(
feature = "no-f16-f128",
target_arch = "powerpc",
target_arch = "powerpc64"
)))]
intrinsics! {
#[avr_skip]
pub extern "C" fn __letf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __getf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_ge_abi()
}

#[avr_skip]
pub extern "C" fn __unordtf2(a: f128, b: f128) -> i32 {
unord(a, b) as i32
}

#[avr_skip]
pub extern "C" fn __eqtf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __lttf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __netf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __gttf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_ge_abi()
}
}

#[cfg(all(
not(feature = "no-f16-f128"),
any(target_arch = "powerpc", target_arch = "powerpc64")
))]
intrinsics! {
#[avr_skip]
pub extern "C" fn __lekf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __gekf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_ge_abi()
}

#[avr_skip]
pub extern "C" fn __unordkf2(a: f128, b: f128) -> i32 {
unord(a, b) as i32
}

#[avr_skip]
pub extern "C" fn __eqkf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __ltkf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __nekf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_le_abi()
}

#[avr_skip]
pub extern "C" fn __gtkf2(a: f128, b: f128) -> i32 {
cmp(a, b).to_ge_abi()
}
}

#[cfg(target_arch = "arm")]
intrinsics! {
pub extern "aapcs" fn __aeabi_fcmple(a: f32, b: f32) -> i32 {
Expand Down
Loading

0 comments on commit 449643f

Please sign in to comment.