Skip to content

Commit dfa7b16

Browse files
author
Jorge Aparicio
committed
use AAPCS calling convention on all aeabi intrinsics
also, on ARM, inline(always) the actual implementation of the intrinsics so we end with code like this: ``` 00000000 <__aeabi_dadd>: (implementation here) ``` instead of "trampolines" like this: ``` 00000000 <__aeabi_dadd>: (shuffle registers) (call __adddf3) 00000000 <__adddf3>: (implementation here) ``` closes #116
1 parent 3e8aa49 commit dfa7b16

File tree

7 files changed

+36
-24
lines changed

7 files changed

+36
-24
lines changed

src/arm.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,44 +62,44 @@ pub unsafe fn __aeabi_ldivmod() {
6262

6363
// TODO: These aeabi_* functions should be defined as aliases
6464
#[cfg_attr(not(test), no_mangle)]
65-
pub extern "C" fn __aeabi_dadd(a: f64, b: f64) -> f64 {
65+
pub extern "aapcs" fn __aeabi_dadd(a: f64, b: f64) -> f64 {
6666
::float::add::__adddf3(a, b)
6767
}
6868

6969
#[cfg_attr(not(test), no_mangle)]
70-
pub extern "C" fn __aeabi_fadd(a: f32, b: f32) -> f32 {
70+
pub extern "aapcs" fn __aeabi_fadd(a: f32, b: f32) -> f32 {
7171
::float::add::__addsf3(a, b)
7272
}
7373

7474
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
7575
#[cfg_attr(not(test), no_mangle)]
76-
pub extern "C" fn __aeabi_idiv(a: i32, b: i32) -> i32 {
76+
pub extern "aapcs" fn __aeabi_idiv(a: i32, b: i32) -> i32 {
7777
::int::sdiv::__divsi3(a, b)
7878
}
7979

8080
#[cfg_attr(not(test), no_mangle)]
81-
pub extern "C" fn __aeabi_lasr(a: i64, b: u32) -> i64 {
81+
pub extern "aapcs" fn __aeabi_lasr(a: i64, b: u32) -> i64 {
8282
::int::shift::__ashrdi3(a, b)
8383
}
8484

8585
#[cfg_attr(not(test), no_mangle)]
86-
pub extern "C" fn __aeabi_llsl(a: u64, b: u32) -> u64 {
86+
pub extern "aapcs" fn __aeabi_llsl(a: u64, b: u32) -> u64 {
8787
::int::shift::__ashldi3(a, b)
8888
}
8989

9090
#[cfg_attr(not(test), no_mangle)]
91-
pub extern "C" fn __aeabi_llsr(a: u64, b: u32) -> u64 {
91+
pub extern "aapcs" fn __aeabi_llsr(a: u64, b: u32) -> u64 {
9292
::int::shift::__lshrdi3(a, b)
9393
}
9494

9595
#[cfg_attr(not(test), no_mangle)]
96-
pub extern "C" fn __aeabi_lmul(a: u64, b: u64) -> u64 {
96+
pub extern "aapcs" fn __aeabi_lmul(a: u64, b: u64) -> u64 {
9797
::int::mul::__muldi3(a, b)
9898
}
9999

100100
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
101101
#[cfg_attr(not(test), no_mangle)]
102-
pub extern "C" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
102+
pub extern "aapcs" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
103103
::int::udiv::__udivsi3(a, b)
104104
}
105105

@@ -113,55 +113,55 @@ extern "C" {
113113
// FIXME: The `*4` and `*8` variants should be defined as aliases.
114114

115115
#[cfg_attr(not(test), no_mangle)]
116-
pub unsafe extern "C" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) {
116+
pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) {
117117
memcpy(dest, src, n);
118118
}
119119
#[cfg_attr(not(test), no_mangle)]
120-
pub unsafe extern "C" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) {
120+
pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) {
121121
memcpy(dest, src, n);
122122
}
123123
#[cfg_attr(not(test), no_mangle)]
124-
pub unsafe extern "C" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) {
124+
pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) {
125125
memcpy(dest, src, n);
126126
}
127127

128128
#[cfg_attr(not(test), no_mangle)]
129-
pub unsafe extern "C" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) {
129+
pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) {
130130
memmove(dest, src, n);
131131
}
132132
#[cfg_attr(not(test), no_mangle)]
133-
pub unsafe extern "C" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) {
133+
pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) {
134134
memmove(dest, src, n);
135135
}
136136
#[cfg_attr(not(test), no_mangle)]
137-
pub unsafe extern "C" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) {
137+
pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) {
138138
memmove(dest, src, n);
139139
}
140140

141141
// Note the different argument order
142142
#[cfg_attr(not(test), no_mangle)]
143-
pub unsafe extern "C" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) {
143+
pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) {
144144
memset(dest, c, n);
145145
}
146146
#[cfg_attr(not(test), no_mangle)]
147-
pub unsafe extern "C" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) {
147+
pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) {
148148
memset(dest, c, n);
149149
}
150150
#[cfg_attr(not(test), no_mangle)]
151-
pub unsafe extern "C" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) {
151+
pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) {
152152
memset(dest, c, n);
153153
}
154154

155155
#[cfg_attr(not(test), no_mangle)]
156-
pub unsafe extern "C" fn __aeabi_memclr(dest: *mut u8, n: usize) {
156+
pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) {
157157
memset(dest, 0, n);
158158
}
159159
#[cfg_attr(not(test), no_mangle)]
160-
pub unsafe extern "C" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
160+
pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
161161
memset(dest, 0, n);
162162
}
163163
#[cfg_attr(not(test), no_mangle)]
164-
pub unsafe extern "C" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
164+
pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
165165
memset(dest, 0, n);
166166
}
167167

src/float/add.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ macro_rules! add {
77
($intrinsic:ident: $ty:ty) => {
88
/// Returns `a + b`
99
#[allow(unused_parens)]
10-
#[cfg_attr(not(test), no_mangle)]
10+
#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
11+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
1112
pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty {
1213
let one = Wrapping(1 as <$ty as Float>::Int);
1314
let zero = Wrapping(0 as <$ty as Float>::Int);

src/int/mul.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use int::Int;
44
macro_rules! mul {
55
($intrinsic:ident: $ty:ty) => {
66
/// Returns `a * b`
7-
#[cfg_attr(not(test), no_mangle)]
7+
#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
8+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
89
pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
910
let half_bits = <$ty>::bits() / 4;
1011
let lower_mask = !0 >> half_bits;

src/int/sdiv.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ macro_rules! mod_ {
4242
macro_rules! divmod {
4343
($intrinsic:ident, $div:ident: $ty:ty) => {
4444
/// Returns `a / b` and sets `*rem = n % d`
45-
#[cfg_attr(not(test), no_mangle)]
45+
#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
46+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
4647
pub extern "C" fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty {
4748
#[cfg(all(feature = "c", any(target_arch = "x86")))]
4849
extern {

src/int/shift.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ macro_rules! ashl {
44
($intrinsic:ident: $ty:ty) => {
55
/// Returns `a << b`, requires `b < $ty::bits()`
66
#[cfg_attr(not(test), no_mangle)]
7+
#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
8+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
79
pub extern "C" fn $intrinsic(a: $ty, b: u32) -> $ty {
810
let half_bits = <$ty>::bits() / 2;
911
if b & half_bits != 0 {
@@ -21,6 +23,8 @@ macro_rules! ashr {
2123
($intrinsic:ident: $ty:ty) => {
2224
/// Returns arithmetic `a >> b`, requires `b < $ty::bits()`
2325
#[cfg_attr(not(test), no_mangle)]
26+
#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
27+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
2428
pub extern "C" fn $intrinsic(a: $ty, b: u32) -> $ty {
2529
let half_bits = <$ty>::bits() / 2;
2630
if b & half_bits != 0 {

src/int/udiv.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use int::{Int, LargeInt};
33

44
/// Returns `n / d`
55
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
6-
#[cfg_attr(not(test), no_mangle)]
6+
#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
7+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
78
pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
89
// Special cases
910
if d == 0 {

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
// NOTE cfg(all(feature = "c", ..)) indicate that compiler-rt provides an arch optimized
2929
// implementation of that intrinsic and we'll prefer to use that
3030

31+
// NOTE(aapcs, aeabi, arm) ARM targets use intrinsics named __aeabi_* instead of the intrinsics
32+
// that follow "x86 naming convention" (e.g. addsf3). Those aeabi intrinsics must adhere to the
33+
// AAPCS calling convention (`extern "aapcs"`) because that's how LLVM will call them.
34+
3135
// TODO(rust-lang/rust#37029) use e.g. checked_div(_).unwrap_or_else(|| abort())
3236
macro_rules! udiv {
3337
($a:expr, $b:expr) => {

0 commit comments

Comments
 (0)