Skip to content

Commit 9aa3a25

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 + 47b45d1 commit 9aa3a25

File tree

9 files changed

+120
-71
lines changed

9 files changed

+120
-71
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

+15-6
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
@@ -194,14 +203,14 @@ mod tests {
194203
use qc::{F32, F64};
195204

196205
check! {
197-
fn __addsf3(f: extern fn(f32, f32) -> f32,
206+
fn __addsf3(f: extern "C" fn(f32, f32) -> f32,
198207
a: F32,
199208
b: F32)
200209
-> Option<F32> {
201210
Some(F32(f(a.0, b.0)))
202211
}
203212

204-
fn __adddf3(f: extern fn(f64, f64) -> f64,
213+
fn __adddf3(f: extern "C" fn(f64, f64) -> f64,
205214
a: F64,
206215
b: F64) -> Option<F64> {
207216
Some(F64(f(a.0, b.0)))

src/float/pow.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ mod tests {
3434
use qc::{I32, F32, F64};
3535

3636
check! {
37-
fn __powisf2(f: extern fn(f32, i32) -> f32,
37+
fn __powisf2(f: extern "C" fn(f32, i32) -> f32,
3838
a: F32,
3939
b: I32) -> Option<F32> {
4040
Some(F32(f(a.0, b.0)))
4141
}
4242

43-
fn __powidf2(f: extern fn(f64, i32) -> f64,
43+
fn __powidf2(f: extern "C" fn(f64, i32) -> f64,
4444
a: F64,
4545
b: I32) -> Option<F64> {
4646
Some(F64(f(a.0, b.0)))

src/int/mul.rs

+19-10
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);
@@ -90,12 +99,12 @@ mod tests {
9099
use qc::{I32, I64, U64};
91100

92101
check! {
93-
fn __muldi3(f: extern fn(u64, u64) -> u64, a: U64, b: U64)
102+
fn __muldi3(f: extern "C" fn(u64, u64) -> u64, a: U64, b: U64)
94103
-> Option<u64> {
95104
Some(f(a.0, b.0))
96105
}
97106

98-
fn __mulosi4(f: extern fn(i32, i32, &mut i32) -> i32,
107+
fn __mulosi4(f: extern "C" fn(i32, i32, &mut i32) -> i32,
99108
a: I32,
100109
b: I32) -> Option<(i32, i32)> {
101110
let (a, b) = (a.0, b.0);
@@ -107,7 +116,7 @@ mod tests {
107116
Some((r, overflow))
108117
}
109118

110-
fn __mulodi4(f: extern fn(i64, i64, &mut i32) -> i64,
119+
fn __mulodi4(f: extern "C" fn(i64, i64, &mut i32) -> i64,
111120
a: I64,
112121
b: I64) -> Option<(i64, i32)> {
113122
let (a, b) = (a.0, b.0);
@@ -130,11 +139,11 @@ mod tests_i128 {
130139
use qc::I128;
131140

132141
check! {
133-
fn __multi3(f: extern fn(i128, i128) -> i128, a: I128, b: I128)
142+
fn __multi3(f: extern "C" fn(i128, i128) -> i128, a: I128, b: I128)
134143
-> Option<i128> {
135144
Some(f(a.0, b.0))
136145
}
137-
fn __muloti4(f: extern fn(i128, i128, &mut i32) -> i128,
146+
fn __muloti4(f: extern "C" fn(i128, i128, &mut i32) -> i128,
138147
a: I128,
139148
b: I128) -> Option<(i128, i32)> {
140149
let (a, b) = (a.0, b.0);

src/int/sdiv.rs

+31-12
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,16 +86,20 @@ 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 {
9599
use qc::{U32, U64};
96100

97101
check! {
98-
fn __divdi3(f: extern fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
102+
fn __divdi3(f: extern "C" fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
99103
let (n, d) = (n.0 as i64, d.0 as i64);
100104
if d == 0 {
101105
None
@@ -104,7 +108,7 @@ mod tests {
104108
}
105109
}
106110

107-
fn __moddi3(f: extern fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
111+
fn __moddi3(f: extern "C" fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
108112
let (n, d) = (n.0 as i64, d.0 as i64);
109113
if d == 0 {
110114
None
@@ -113,7 +117,22 @@ mod tests {
113117
}
114118
}
115119

116-
fn __divmoddi4(f: extern fn(i64, i64, &mut i64) -> i64,
120+
#[cfg(target_arch = "arm")]
121+
fn __divmoddi4(f: extern "aapcs" fn(i64, i64, &mut i64) -> i64,
122+
n: U64,
123+
d: U64) -> Option<(i64, i64)> {
124+
let (n, d) = (n.0 as i64, d.0 as i64);
125+
if d == 0 {
126+
None
127+
} else {
128+
let mut r = 0;
129+
let q = f(n, d, &mut r);
130+
Some((q, r))
131+
}
132+
}
133+
134+
#[cfg(not(target_arch = "arm"))]
135+
fn __divmoddi4(f: extern "C" fn(i64, i64, &mut i64) -> i64,
117136
n: U64,
118137
d: U64) -> Option<(i64, i64)> {
119138
let (n, d) = (n.0 as i64, d.0 as i64);
@@ -126,7 +145,7 @@ mod tests {
126145
}
127146
}
128147

129-
fn __divsi3(f: extern fn(i32, i32) -> i32,
148+
fn __divsi3(f: extern "C" fn(i32, i32) -> i32,
130149
n: U32,
131150
d: U32) -> Option<i32> {
132151
let (n, d) = (n.0 as i32, d.0 as i32);
@@ -137,7 +156,7 @@ mod tests {
137156
}
138157
}
139158

140-
fn __modsi3(f: extern fn(i32, i32) -> i32,
159+
fn __modsi3(f: extern "C" fn(i32, i32) -> i32,
141160
n: U32,
142161
d: U32) -> Option<i32> {
143162
let (n, d) = (n.0 as i32, d.0 as i32);
@@ -148,7 +167,7 @@ mod tests {
148167
}
149168
}
150169

151-
fn __divmodsi4(f: extern fn(i32, i32, &mut i32) -> i32,
170+
fn __divmodsi4(f: extern "C" fn(i32, i32, &mut i32) -> i32,
152171
n: U32,
153172
d: U32) -> Option<(i32, i32)> {
154173
let (n, d) = (n.0 as i32, d.0 as i32);
@@ -172,7 +191,7 @@ mod tests_i128 {
172191
use qc::U128;
173192
check! {
174193

175-
fn __divti3(f: extern fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
194+
fn __divti3(f: extern "C" fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
176195
let (n, d) = (n.0 as i128, d.0 as i128);
177196
if d == 0 {
178197
None
@@ -181,7 +200,7 @@ mod tests_i128 {
181200
}
182201
}
183202

184-
fn __modti3(f: extern fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
203+
fn __modti3(f: extern "C" fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
185204
let (n, d) = (n.0 as i128, d.0 as i128);
186205
if d == 0 {
187206
None

0 commit comments

Comments
 (0)