diff --git a/src/float/add.rs b/src/float/add.rs index 8bb5b4b..65a7186 100644 --- a/src/float/add.rs +++ b/src/float/add.rs @@ -4,12 +4,11 @@ use core::num::Wrapping; use float::Float; macro_rules! add { - ($intrinsic:ident: $ty:ty) => { + ($abi:tt, $intrinsic:ident: $ty:ty) => { /// Returns `a + b` #[allow(unused_parens)] - #[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)] - #[cfg_attr(all(not(test), target_arch = "arm"), inline(always))] - pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty { + #[cfg_attr(not(test), no_mangle)] + pub extern $abi fn $intrinsic(a: $ty, b: $ty) -> $ty { let one = Wrapping(1 as <$ty as Float>::Int); let zero = Wrapping(0 as <$ty as Float>::Int); @@ -182,8 +181,17 @@ macro_rules! add { } } -add!(__addsf3: f32); -add!(__adddf3: f64); +#[cfg(target_arch = "arm")] +add!("aapcs", __addsf3: f32); + +#[cfg(not(target_arch = "arm"))] +add!("C", __addsf3: f32); + +#[cfg(target_arch = "arm")] +add!("aapcs", __adddf3: f64); + +#[cfg(not(target_arch = "arm"))] +add!("C", __adddf3: f64); // NOTE(cfg) for some reason, on arm*-unknown-linux-gnueabi*, our implementation doesn't // match the output of its gcc_s or compiler-rt counterpart. Until we investigate further, we'll diff --git a/src/int/mul.rs b/src/int/mul.rs index 046382a..64ceb72 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -2,11 +2,11 @@ use int::LargeInt; use int::Int; macro_rules! mul { - ($intrinsic:ident: $ty:ty) => { + ($(#[$attr:meta])+ | + $abi:tt, $intrinsic:ident: $ty:ty) => { /// Returns `a * b` - #[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)] - #[cfg_attr(all(not(test), target_arch = "arm"), inline(always))] - pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty { + $(#[$attr])+ + pub extern $abi fn $intrinsic(a: $ty, b: $ty) -> $ty { let half_bits = <$ty>::bits() / 4; let lower_mask = !0 >> half_bits; let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask); @@ -74,9 +74,17 @@ macro_rules! mulo { } #[cfg(not(all(feature = "c", target_arch = "x86")))] -mul!(__muldi3: u64); +mul!(#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)] + #[cfg_attr(all(not(test), target_arch = "arm"), inline(always))] + | "C", __muldi3: u64); -mul!(__multi3: i128); +#[cfg(not(target_arch = "arm"))] +mul!(#[cfg_attr(not(test), no_mangle)] + | "C", __multi3: i128); + +#[cfg(target_arch = "arm")] +mul!(#[cfg_attr(not(test), no_mangle)] + | "aapcs", __multi3: i128); mulo!(__mulosi4: i32); mulo!(__mulodi4: i64); diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 2676428..7a3e6e7 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -40,11 +40,10 @@ macro_rules! mod_ { } macro_rules! divmod { - ($intrinsic:ident, $div:ident: $ty:ty) => { + ($abi:tt, $intrinsic:ident, $div:ident: $ty:ty) => { /// Returns `a / b` and sets `*rem = n % d` - #[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)] - #[cfg_attr(all(not(test), target_arch = "arm"), inline(always))] - pub extern "C" fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty { + #[cfg_attr(not(test), no_mangle)] + pub extern $abi fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty { #[cfg(all(feature = "c", any(target_arch = "x86")))] extern { fn $div(a: $ty, b: $ty) -> $ty; @@ -87,9 +86,13 @@ mod_!(__modti3: i128, u128); mod_!(__modti3: i128, u128, ::U64x2, ::sconv); #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))] -divmod!(__divmodsi4, __divsi3: i32); +divmod!("C", __divmodsi4, __divsi3: i32); -divmod!(__divmoddi4, __divdi3: i64); +#[cfg(target_arch = "arm")] +divmod!("aapcs", __divmoddi4, __divdi3: i64); + +#[cfg(not(target_arch = "arm"))] +divmod!("C", __divmoddi4, __divdi3: i64); #[cfg(test)] mod tests { diff --git a/src/int/udiv.rs b/src/int/udiv.rs index 820c4cf..453ab00 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -80,15 +80,15 @@ pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 { #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))] #[cfg_attr(not(test), no_mangle)] pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 { - #[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios")))] + #[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))] extern "C" { fn __udivsi3(n: u32, d: u32) -> u32; } let q = match () { - #[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios")))] + #[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))] () => unsafe { __udivsi3(n, d) }, - #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))] + #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))] () => __udivsi3(n, d), }; if let Some(rem) = rem {