ソースを参照

Handle aeabi aliasing

Objects in compiler-rt may have two symbols, so this makes sure that we don't
bring in those objects by accident by defining the aliases ourselves.
Alex Crichton 7 年 前
コミット
7de57cd4f9
10 ファイル変更95 行追加86 行削除
  1. 16 14
      ci/run.sh
  2. 0 58
      src/arm.rs
  3. 2 0
      src/float/add.rs
  4. 14 0
      src/float/conv.rs
  5. 2 0
      src/float/sub.rs
  6. 1 0
      src/int/mul.rs
  7. 1 0
      src/int/sdiv.rs
  8. 3 0
      src/int/shift.rs
  9. 1 0
      src/int/udiv.rs
  10. 55 14
      src/macros.rs

+ 16 - 14
ci/run.sh

@@ -50,19 +50,6 @@ case $1 in
         ;;
 esac
 
-# Verify that there are no undefined symbols to `panic` within our implementations
-# TODO(#79) fix the undefined references problem for debug-assertions+lto
-case $1 in
-    thumb*)
-        RUSTFLAGS="-C debug-assertions=no" xargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto -C link-arg=-nostartfiles
-        xargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto
-        ;;
-    *)
-        RUSTFLAGS="-C debug-assertions=no" cargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto
-        cargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto
-        ;;
-esac
-
 PREFIX=$(echo $1 | sed -e 's/unknown-//')-
 case $1 in
     armv7-*)
@@ -109,9 +96,24 @@ for rlib in $(echo $path); do
     set -ex
 done
 
+rm -f $path
+
+# Verify that there are no undefined symbols to `panic` within our implementations
+# TODO(#79) fix the undefined references problem for debug-assertions+lto
+case $1 in
+    thumb*)
+        RUSTFLAGS="-C debug-assertions=no" xargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto -C link-arg=-nostartfiles
+        xargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto
+        ;;
+    *)
+        RUSTFLAGS="-C debug-assertions=no" cargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto
+        cargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto
+        ;;
+esac
+
 # Ensure no references to a panicking function
 for rlib in $(echo $path); do
-    set +x
+    set +ex
     $PREFIX$NM -u $rlib 2>&1 | grep panicking
 
     if test $? = 0; then

+ 0 - 58
src/arm.rs

@@ -60,64 +60,6 @@ pub unsafe fn __aeabi_ldivmod() {
     intrinsics::unreachable();
 }
 
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_dadd(a: f64, b: f64) -> f64 {
-    ::float::add::__adddf3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_fadd(a: f32, b: f32) -> f32 {
-    ::float::add::__addsf3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_dsub(a: f64, b: f64) -> f64 {
-    ::float::sub::__subdf3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_fsub(a: f32, b: f32) -> f32 {
-    ::float::sub::__subsf3(a, b)
-}
-
-#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_idiv(a: i32, b: i32) -> i32 {
-    ::int::sdiv::__divsi3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_lasr(a: i64, b: u32) -> i64 {
-    ::int::shift::__ashrdi3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_llsl(a: u64, b: u32) -> u64 {
-    ::int::shift::__ashldi3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_llsr(a: u64, b: u32) -> u64 {
-    ::int::shift::__lshrdi3(a, b)
-}
-
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_lmul(a: u64, b: u64) -> u64 {
-    ::int::mul::__muldi3(a, b)
-}
-
-#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
-#[cfg_attr(not(test), no_mangle)]
-pub extern "aapcs" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
-    ::int::udiv::__udivsi3(a, b)
-}
-
-#[cfg(not(feature = "c"))]
-#[cfg_attr(not(test), no_mangle)]
-pub extern "C" fn __aeabi_ui2d(a: u32) -> f64 {
-    ::float::conv::__floatunsidf(a)
-}
-
 // TODO: These aeabi_* functions should be defined as aliases
 #[cfg(not(feature = "mem"))]
 extern "C" {

+ 2 - 0
src/float/add.rs

@@ -181,11 +181,13 @@ macro_rules! add {
 
 intrinsics! {
     #[aapcs_on_arm]
+    #[arm_aeabi_alias = __aeabi_fadd]
     pub extern "C" fn __addsf3(a: f32, b: f32) -> f32 {
         add!(a, b, f32)
     }
 
     #[aapcs_on_arm]
+    #[arm_aeabi_alias = __aeabi_dadd]
     pub extern "C" fn __adddf3(a: f64, b: f64) -> f64 {
         add!(a, b, f64)
     }

+ 14 - 0
src/float/conv.rs

@@ -70,15 +70,18 @@ macro_rules! int_to_float {
 }
 
 intrinsics! {
+    #[arm_aeabi_alias = __aeabi_i2f]
     pub extern "C" fn __floatsisf(i: i32) -> f32 {
         int_to_float!(i, i32, f32)
     }
 
+    #[arm_aeabi_alias = __aeabi_i2d]
     pub extern "C" fn __floatsidf(i: i32) -> f64 {
         int_to_float!(i, i32, f64)
     }
 
     #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
+    #[arm_aeabi_alias = __aeabi_l2d]
     pub extern "C" fn __floatdidf(i: i64) -> f64 {
         // On x86_64 LLVM will use native instructions for this conversion, we
         // can just do it directly
@@ -99,16 +102,19 @@ intrinsics! {
         int_to_float!(i, i128, f64)
     }
 
+    #[arm_aeabi_alias = __aeabi_ui2f]
     pub extern "C" fn __floatunsisf(i: u32) -> f32 {
         int_to_float!(i, u32, f32)
     }
 
+    #[arm_aeabi_alias = __aeabi_ui2d]
     pub extern "C" fn __floatunsidf(i: u32) -> f64 {
         int_to_float!(i, u32, f64)
     }
 
     #[use_c_shim_if(all(any(target_arch = "x86", target_arch = "x86_64"),
                         not(target_env = "msvc")))]
+    #[arm_aeabi_alias = __aeabi_ul2d]
     pub extern "C" fn __floatundidf(i: u64) -> f64 {
         int_to_float!(i, u64, f64)
     }
@@ -182,10 +188,12 @@ macro_rules! float_to_int {
 }
 
 intrinsics! {
+    #[arm_aeabi_alias = __aeabi_f2iz]
     pub extern "C" fn __fixsfsi(f: f32) -> i32 {
         float_to_int!(f, f32, i32)
     }
 
+    #[arm_aeabi_alias = __aeabi_f2lz]
     pub extern "C" fn __fixsfdi(f: f32) -> i64 {
         float_to_int!(f, f32, i64)
     }
@@ -195,10 +203,12 @@ intrinsics! {
         float_to_int!(f, f32, i128)
     }
 
+    #[arm_aeabi_alias = __aeabi_d2iz]
     pub extern "C" fn __fixdfsi(f: f64) -> i32 {
         float_to_int!(f, f64, i32)
     }
 
+    #[arm_aeabi_alias = __aeabi_d2lz]
     pub extern "C" fn __fixdfdi(f: f64) -> i64 {
         float_to_int!(f, f64, i64)
     }
@@ -208,10 +218,12 @@ intrinsics! {
         float_to_int!(f, f64, i128)
     }
 
+    #[arm_aeabi_alias = __aeabi_f2uiz]
     pub extern "C" fn __fixunssfsi(f: f32) -> u32 {
         float_to_int!(f, f32, u32)
     }
 
+    #[arm_aeabi_alias = __aeabi_f2ulz]
     pub extern "C" fn __fixunssfdi(f: f32) -> u64 {
         float_to_int!(f, f32, u64)
     }
@@ -221,10 +233,12 @@ intrinsics! {
         float_to_int!(f, f32, u128)
     }
 
+    #[arm_aeabi_alias = __aeabi_d2uiz]
     pub extern "C" fn __fixunsdfsi(f: f64) -> u32 {
         float_to_int!(f, f64, u32)
     }
 
+    #[arm_aeabi_alias = __aeabi_d2ulz]
     pub extern "C" fn __fixunsdfdi(f: f64) -> u64 {
         float_to_int!(f, f64, u64)
     }

+ 2 - 0
src/float/sub.rs

@@ -1,10 +1,12 @@
 use float::Float;
 
 intrinsics! {
+    #[arm_aeabi_alias = __aeabi_fsub]
     pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 {
         a + f32::from_repr(b.repr() ^ f32::sign_mask())
     }
 
+    #[arm_aeabi_alias = __aeabi_dsub]
     pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 {
         a + f64::from_repr(b.repr() ^ f64::sign_mask())
     }

+ 1 - 0
src/int/mul.rs

@@ -72,6 +72,7 @@ impl Mulo for i128 {}
 
 intrinsics! {
     #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
+    #[arm_aeabi_alias = __aeabi_lmul]
     pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 {
         a.mul(b)
     }

+ 1 - 0
src/int/sdiv.rs

@@ -60,6 +60,7 @@ impl Divmod for i64 {}
 
 intrinsics! {
     #[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))]
+    #[arm_aeabi_alias = __aeabi_idiv]
     pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 {
         a.div(b)
     }

+ 3 - 0
src/int/shift.rs

@@ -66,6 +66,7 @@ impl Lshr for u128 {}
 
 intrinsics! {
     #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
+    #[arm_aeabi_alias = __aeabi_llsl]
     pub extern "C" fn __ashldi3(a: u64, b: u32) -> u64 {
         a.ashl(b)
     }
@@ -75,6 +76,7 @@ intrinsics! {
     }
 
     #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
+    #[arm_aeabi_alias = __aeabi_lasr]
     pub extern "C" fn __ashrdi3(a: i64, b: u32) -> i64 {
         a.ashr(b)
     }
@@ -84,6 +86,7 @@ intrinsics! {
     }
 
     #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
+    #[arm_aeabi_alias = __aeabi_llsr]
     pub extern "C" fn __lshrdi3(a: u64, b: u32) -> u64 {
         a.lshr(b)
     }

+ 1 - 0
src/int/udiv.rs

@@ -155,6 +155,7 @@ intrinsics! {
     #[use_c_shim_if(all(target_arch = "arm",
                         not(target_os = "ios"),
                         not(thumbv6m)))]
+    #[arm_aeabi_alias = __aeabi_uidiv]
     /// Returns `n / d`
     pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
         // Special cases

+ 55 - 14
src/macros.rs

@@ -7,7 +7,7 @@ macro_rules! intrinsics {
     // intrinsic.
     (
         #[use_c_shim_if($($cfg_clause:tt)*)]
-        $(#[$attr:meta])*
+        $(#[$($attr:tt)*])*
         pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
             $($body:tt)*
         }
@@ -16,7 +16,6 @@ macro_rules! intrinsics {
     ) => (
 
         #[cfg(all(feature = "c", $($cfg_clause)*))]
-        $(#[$attr])*
         pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
             extern $abi {
                 fn $name($($argname: $ty),*) -> $ret;
@@ -28,7 +27,7 @@ macro_rules! intrinsics {
 
         #[cfg(not(all(feature = "c", $($cfg_clause)*)))]
         intrinsics! {
-            $(#[$attr])*
+            $(#[$($attr)*])*
             pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
                 $($body)*
             }
@@ -42,7 +41,7 @@ macro_rules! intrinsics {
     // ARM and `"C"` elsewhere.
     (
         #[aapcs_on_arm]
-        $(#[$attr:meta])*
+        $(#[$($attr:tt)*])*
         pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
             $($body:tt)*
         }
@@ -51,7 +50,7 @@ macro_rules! intrinsics {
     ) => (
         #[cfg(target_arch = "arm")]
         intrinsics! {
-            $(#[$attr])*
+            $(#[$($attr)*])*
             pub extern "aapcs" fn $name( $($argname: $ty),* ) -> $ret {
                 $($body)*
             }
@@ -59,7 +58,7 @@ macro_rules! intrinsics {
 
         #[cfg(not(target_arch = "arm"))]
         intrinsics! {
-            $(#[$attr])*
+            $(#[$($attr)*])*
             pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
                 $($body)*
             }
@@ -72,7 +71,7 @@ macro_rules! intrinsics {
     // win64 for some methods.
     (
         #[unadjusted_on_win64]
-        $(#[$attr:meta])*
+        $(#[$($attr:tt)*])*
         pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
             $($body:tt)*
         }
@@ -81,7 +80,7 @@ macro_rules! intrinsics {
     ) => (
         #[cfg(all(windows, target_pointer_width = "64"))]
         intrinsics! {
-            $(#[$attr])*
+            $(#[$($attr)*])*
             pub extern "unadjusted" fn $name( $($argname: $ty),* ) -> $ret {
                 $($body)*
             }
@@ -89,7 +88,7 @@ macro_rules! intrinsics {
 
         #[cfg(not(all(windows, target_pointer_width = "64")))]
         intrinsics! {
-            $(#[$attr])*
+            $(#[$($attr)*])*
             pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
                 $($body)*
             }
@@ -102,7 +101,7 @@ macro_rules! intrinsics {
     // bit calling convention correct.
     (
         #[win64_128bit_abi_hack]
-        $(#[$attr:meta])*
+        $(#[$($attr:tt)*])*
         pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
             $($body:tt)*
         }
@@ -110,7 +109,7 @@ macro_rules! intrinsics {
         $($rest:tt)*
     ) => (
         #[cfg(all(windows, target_pointer_width = "64"))]
-        $(#[$attr])*
+        $(#[$($attr)*])*
         pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
             $($body)*
         }
@@ -130,7 +129,7 @@ macro_rules! intrinsics {
 
         #[cfg(not(all(windows, target_pointer_width = "64")))]
         intrinsics! {
-            $(#[$attr])*
+            $(#[$($attr)*])*
             pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
                 $($body)*
             }
@@ -139,15 +138,57 @@ macro_rules! intrinsics {
         intrinsics!($($rest)*);
     );
 
+    // A bunch of intrinsics on ARM are aliased in the standard compiler-rt
+    // build under `__aeabi_*` aliases, and LLVM will call these instead of the
+    // original function. Handle that here
     (
-        $(#[$attr:meta])*
+        #[arm_aeabi_alias = $alias:ident]
+        $(#[$($attr:tt)*])*
         pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
             $($body:tt)*
         }
 
         $($rest:tt)*
     ) => (
-        $(#[$attr])*
+        #[cfg(target_arch = "arm")]
+        $(#[$($attr)*])*
+        pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
+            $($body)*
+        }
+
+        #[cfg(target_arch = "arm")]
+        pub mod $name {
+            intrinsics! {
+                pub extern "aapcs" fn $alias( $($argname: $ty),* ) -> $ret {
+                    super::$name($($argname),*)
+                }
+
+                pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
+                    super::$name($($argname),*)
+                }
+            }
+        }
+
+        #[cfg(not(target_arch = "arm"))]
+        intrinsics! {
+            $(#[$($attr)*])*
+            pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
+                $($body)*
+            }
+        }
+
+        intrinsics!($($rest)*);
+    );
+
+    (
+        $(#[$($attr:tt)*])*
+        pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
+            $($body:tt)*
+        }
+
+        $($rest:tt)*
+    ) => (
+        $(#[$($attr)*])*
         #[cfg_attr(not(test), no_mangle)]
         pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
             $($body)*