ARM: keep some non-aeabi symbols around
- multi3: there's no aeabi equivalent - divmod{s,d}i4: these are directly called by __aeabi_{l,i}divmod - add{s,d}f3: required by the C sub{s,d}f3 implementation but make sure they also use the AAPCS calling convention
This commit is contained in:
parent
dfa7b161aa
commit
57085be2ea
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user