Skip to content

Commit 8ad1f99

Browse files
committed
Auto merge of #141 - rust-lang-nursery:aapcs, r=alexcrichton
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 cc #66 r? @alexcrichton cc @mattico
2 parents 3e8aa49 + 57085be commit 8ad1f99

File tree

7 files changed

+68
-37
lines changed

7 files changed

+68
-37
lines changed

src/arm.rs

+20-20
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

+13-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ use core::num::Wrapping;
44
use float::Float;
55

66
macro_rules! add {
7-
($intrinsic:ident: $ty:ty) => {
7+
($abi:tt, $intrinsic:ident: $ty:ty) => {
88
/// Returns `a + b`
99
#[allow(unused_parens)]
1010
#[cfg_attr(not(test), no_mangle)]
11-
pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty {
11+
pub extern $abi fn $intrinsic(a: $ty, b: $ty) -> $ty {
1212
let one = Wrapping(1 as <$ty as Float>::Int);
1313
let zero = Wrapping(0 as <$ty as Float>::Int);
1414

@@ -181,8 +181,17 @@ macro_rules! add {
181181
}
182182
}
183183

184-
add!(__addsf3: f32);
185-
add!(__adddf3: f64);
184+
#[cfg(target_arch = "arm")]
185+
add!("aapcs", __addsf3: f32);
186+
187+
#[cfg(not(target_arch = "arm"))]
188+
add!("C", __addsf3: f32);
189+
190+
#[cfg(target_arch = "arm")]
191+
add!("aapcs", __adddf3: f64);
192+
193+
#[cfg(not(target_arch = "arm"))]
194+
add!("C", __adddf3: f64);
186195

187196
// NOTE(cfg) for some reason, on arm*-unknown-linux-gnueabi*, our implementation doesn't
188197
// match the output of its gcc_s or compiler-rt counterpart. Until we investigate further, we'll

src/int/mul.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ use int::LargeInt;
22
use int::Int;
33

44
macro_rules! mul {
5-
($intrinsic:ident: $ty:ty) => {
5+
($(#[$attr:meta])+ |
6+
$abi:tt, $intrinsic:ident: $ty:ty) => {
67
/// Returns `a * b`
7-
#[cfg_attr(not(test), no_mangle)]
8-
pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
8+
$(#[$attr])+
9+
pub extern $abi fn $intrinsic(a: $ty, b: $ty) -> $ty {
910
let half_bits = <$ty>::bits() / 4;
1011
let lower_mask = !0 >> half_bits;
1112
let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask);
@@ -73,9 +74,17 @@ macro_rules! mulo {
7374
}
7475

7576
#[cfg(not(all(feature = "c", target_arch = "x86")))]
76-
mul!(__muldi3: u64);
77+
mul!(#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
78+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
79+
| "C", __muldi3: u64);
80+
81+
#[cfg(not(target_arch = "arm"))]
82+
mul!(#[cfg_attr(not(test), no_mangle)]
83+
| "C", __multi3: i128);
7784

78-
mul!(__multi3: i128);
85+
#[cfg(target_arch = "arm")]
86+
mul!(#[cfg_attr(not(test), no_mangle)]
87+
| "aapcs", __multi3: i128);
7988

8089
mulo!(__mulosi4: i32);
8190
mulo!(__mulodi4: i64);

src/int/sdiv.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ macro_rules! mod_ {
4040
}
4141

4242
macro_rules! divmod {
43-
($intrinsic:ident, $div:ident: $ty:ty) => {
43+
($abi:tt, $intrinsic:ident, $div:ident: $ty:ty) => {
4444
/// Returns `a / b` and sets `*rem = n % d`
4545
#[cfg_attr(not(test), no_mangle)]
46-
pub extern "C" fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty {
46+
pub extern $abi fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty {
4747
#[cfg(all(feature = "c", any(target_arch = "x86")))]
4848
extern {
4949
fn $div(a: $ty, b: $ty) -> $ty;
@@ -86,9 +86,13 @@ mod_!(__modti3: i128, u128);
8686
mod_!(__modti3: i128, u128, ::U64x2, ::sconv);
8787

8888
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
89-
divmod!(__divmodsi4, __divsi3: i32);
89+
divmod!("C", __divmodsi4, __divsi3: i32);
9090

91-
divmod!(__divmoddi4, __divdi3: i64);
91+
#[cfg(target_arch = "arm")]
92+
divmod!("aapcs", __divmoddi4, __divdi3: i64);
93+
94+
#[cfg(not(target_arch = "arm"))]
95+
divmod!("C", __divmoddi4, __divdi3: i64);
9296

9397
#[cfg(test)]
9498
mod tests {

src/int/shift.rs

+4
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

+5-4
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 {
@@ -79,15 +80,15 @@ pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 {
7980
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
8081
#[cfg_attr(not(test), no_mangle)]
8182
pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
82-
#[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios")))]
83+
#[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))]
8384
extern "C" {
8485
fn __udivsi3(n: u32, d: u32) -> u32;
8586
}
8687

8788
let q = match () {
88-
#[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios")))]
89+
#[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))]
8990
() => unsafe { __udivsi3(n, d) },
90-
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
91+
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
9192
() => __udivsi3(n, d),
9293
};
9394
if let Some(rem) = rem {

src/lib.rs

+4
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)