diff --git a/README.md b/README.md index ffef4e52..07b78ca4 100644 --- a/README.md +++ b/README.md @@ -213,16 +213,22 @@ These builtins are needed to support 128-bit integers, which are in the process - [x] udivti3.c - [x] umodti3.c +These builtins are needed to support 128-bit floating point numbers, which are +in the process of being added to Rust. + +- [x] addtf3.c +- [x] comparetf2.c +- [x] divtf3.c +- [x] multf3.c +- [x] subtf3.c + ## Unimplemented functions -These builtins involve floating-point types ("`f128`", "`f80`" and complex numbers) that are not supported by Rust. +These builtins involve floating-point types ("`f80`" and complex numbers) that are not supported by Rust. -- ~~addtf3.c~~ -- ~~comparetf2.c~~ - ~~divdc3.c~~ - ~~divsc3.c~~ - ~~divtc3.c~~ -- ~~divtf3.c~~ - ~~divxc3.c~~ - ~~extenddftf2.c~~ - ~~extendsftf2.c~~ @@ -250,7 +256,6 @@ These builtins involve floating-point types ("`f128`", "`f80`" and complex numbe - ~~muldc3.c~~ - ~~mulsc3.c~~ - ~~multc3.c~~ -- ~~multf3.c~~ - ~~mulxc3.c~~ - ~~powitf2.c~~ - ~~powixf2.c~~ @@ -264,7 +269,6 @@ These builtins involve floating-point types ("`f128`", "`f80`" and complex numbe - ~~ppc/gcc_qmul.c~~ - ~~ppc/gcc_qsub.c~~ - ~~ppc/multc3.c~~ -- ~~subtf3.c~~ - ~~trunctfdf2.c~~ - ~~trunctfsf2.c~~ - ~~x86_64/floatdixf.c~~ diff --git a/src/float/add.rs b/src/float/add.rs index 804f4b51..d4f7fd3a 100644 --- a/src/float/add.rs +++ b/src/float/add.rs @@ -201,6 +201,10 @@ intrinsics! { add(a, b) } + pub extern "C" fn __addtf3(a: f128, b: f128) -> f128 { + add(a, b) + } + #[cfg(target_arch = "arm")] pub extern "C" fn __addsf3vfp(a: f32, b: f32) -> f32 { a + b diff --git a/src/float/cmp.rs b/src/float/cmp.rs index 1c8917af..46e903dc 100644 --- a/src/float/cmp.rs +++ b/src/float/cmp.rs @@ -170,6 +170,41 @@ intrinsics! { pub extern "C" fn __gtdf2(a: f64, b: f64) -> i32 { cmp(a, b).to_ge_abi() } + + #[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(target_arch = "arm")] diff --git a/src/float/div.rs b/src/float/div.rs index d587fe4f..9038f6b9 100644 --- a/src/float/div.rs +++ b/src/float/div.rs @@ -914,6 +914,15 @@ intrinsics! { div64(a, b) } + // TODO: how should `HInt` be handled? + pub extern "C" fn __divtf3(a: f128, b: f128) -> f128 { + if cfg!(target_pointer_width = "64") { + div32(a, b) + } else { + div64(a, b) + } + } + #[cfg(target_arch = "arm")] pub extern "C" fn __divsf3vfp(a: f32, b: f32) -> f32 { a / b diff --git a/src/float/mod.rs b/src/float/mod.rs index fdbe9dde..3917a24c 100644 --- a/src/float/mod.rs +++ b/src/float/mod.rs @@ -59,7 +59,7 @@ pub(crate) trait Float: /// A mask for the significand const SIGNIFICAND_MASK: Self::Int; - // The implicit bit of the float format + /// The implicit bit of the float format const IMPLICIT_BIT: Self::Int; /// A mask for the exponent @@ -171,5 +171,8 @@ macro_rules! float_impl { }; } +// FIXME: there aren't any intrinsics for f16 that I know of, do we need this? +float_impl!(f16, u16, i16, i16, 16, 10); float_impl!(f32, u32, i32, i16, 32, 23); float_impl!(f64, u64, i64, i16, 64, 52); +float_impl!(f128, u128, i128, i16, 128, 112); diff --git a/src/float/mul.rs b/src/float/mul.rs index 378fa970..eed29527 100644 --- a/src/float/mul.rs +++ b/src/float/mul.rs @@ -199,6 +199,10 @@ intrinsics! { mul(a, b) } + pub extern "C" fn __multf3(a: f128, b: f128) -> f128 { + mul(a, b) + } + #[cfg(target_arch = "arm")] pub extern "C" fn __mulsf3vfp(a: f32, b: f32) -> f32 { a * b diff --git a/src/float/sub.rs b/src/float/sub.rs index 64653ee2..6bb3271a 100644 --- a/src/float/sub.rs +++ b/src/float/sub.rs @@ -1,5 +1,6 @@ use crate::float::add::__adddf3; use crate::float::add::__addsf3; +use crate::float::add::__addtf3; use crate::float::Float; intrinsics! { @@ -15,6 +16,10 @@ intrinsics! { __adddf3(a, f64::from_repr(b.repr() ^ f64::SIGN_MASK)) } + pub extern "C" fn __subtf3(a: f128, b: f128) -> f128 { + __addtf3(a, f128::from_repr(b.repr() ^ f128::SIGN_MASK)) + } + #[cfg(target_arch = "arm")] pub extern "C" fn __subsf3vfp(a: f32, b: f32) -> f32 { a - b diff --git a/src/lib.rs b/src/lib.rs index a414efde..62bd69ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,17 +2,19 @@ #![cfg_attr(not(feature = "no-asm"), feature(asm))] #![feature(abi_unadjusted)] #![feature(asm_experimental_arch)] +#![feature(c_unwind)] #![cfg_attr(not(feature = "no-asm"), feature(global_asm))] #![feature(cfg_target_has_atomic)] #![feature(compiler_builtins)] #![feature(core_ffi_c)] #![feature(core_intrinsics)] +#![feature(f128)] +#![feature(f16)] #![feature(inline_const)] #![feature(lang_items)] #![feature(linkage)] #![feature(naked_functions)] #![feature(repr_simd)] -#![feature(c_unwind)] #![no_builtins] #![no_std] #![allow(unused_features)]