Ver Fonte

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
Jorge Aparicio há 8 anos atrás
pai
commit
57085be2ea
4 ficheiros alterados com 40 adições e 21 exclusões
  1. 14 6
      src/float/add.rs
  2. 14 6
      src/int/mul.rs
  3. 9 6
      src/int/sdiv.rs
  4. 3 3
      src/int/udiv.rs

+ 14 - 6
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

+ 14 - 6
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);
+
+#[cfg(not(target_arch = "arm"))]
+mul!(#[cfg_attr(not(test), no_mangle)]
+     | "C", __multi3: i128);
 
-mul!(__multi3: i128);
+#[cfg(target_arch = "arm")]
+mul!(#[cfg_attr(not(test), no_mangle)]
+     | "aapcs", __multi3: i128);
 
 mulo!(__mulosi4: i32);
 mulo!(__mulodi4: i64);

+ 9 - 6
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);
+
+#[cfg(target_arch = "arm")]
+divmod!("aapcs", __divmoddi4, __divdi3: i64);
 
-divmod!(__divmoddi4, __divdi3: i64);
+#[cfg(not(target_arch = "arm"))]
+divmod!("C", __divmoddi4, __divdi3: i64);
 
 #[cfg(test)]
 mod tests {

+ 3 - 3
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 {