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.
This commit is contained in:
parent
a839d53a02
commit
7de57cd4f9
30
ci/run.sh
30
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
|
||||
|
|
58
src/arm.rs
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" {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,49 @@ macro_rules! intrinsics {
|
|||
|
||||
#[cfg(not(all(windows, target_pointer_width = "64")))]
|
||||
intrinsics! {
|
||||
$(#[$attr])*
|
||||
$(#[$($attr)*])*
|
||||
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
|
||||
$($body)*
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
(
|
||||
#[arm_aeabi_alias = $alias:ident]
|
||||
$(#[$($attr:tt)*])*
|
||||
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
|
||||
$($body:tt)*
|
||||
}
|
||||
|
||||
$($rest:tt)*
|
||||
) => (
|
||||
#[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)*
|
||||
}
|
||||
|
@ -140,14 +181,14 @@ macro_rules! intrinsics {
|
|||
);
|
||||
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
$(#[$($attr:tt)*])*
|
||||
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
|
||||
$($body:tt)*
|
||||
}
|
||||
|
||||
$($rest:tt)*
|
||||
) => (
|
||||
$(#[$attr])*
|
||||
$(#[$($attr)*])*
|
||||
#[cfg_attr(not(test), no_mangle)]
|
||||
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
|
||||
$($body)*
|
||||
|
|
Loading…
Reference in New Issue