Skip to content

Commit 5e2cea9

Browse files
committed
Cleaned up the code and added tests.
1 parent c461cdf commit 5e2cea9

File tree

2 files changed

+110
-30
lines changed

2 files changed

+110
-30
lines changed

src/librustc_trans/cabi_x86.rs

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,46 +61,41 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType, flavor: Flavor) {
6161
if flavor == Flavor::Fastcall {
6262
// Mark arguments as InReg like clang does it,
6363
// so our fastcall is compatible with C/C++ fastcall.
64-
// Clang reference: ib/CodeGen/TargetInfo.cpp
65-
let is_mcu_abi = ccx.sess().target.target.target_os.eq("elfiamcu");
66-
let is_soft_float_abi = ccx.sess().target.target.options.features.contains("+soft-float");
64+
65+
// Clang reference: lib/CodeGen/TargetInfo.cpp
66+
// See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()
67+
68+
// IsSoftFloatABI is only set to true on ARM platforms,
69+
// which in turn can't be x86?
6770

6871
let mut free_regs = 2;
6972

7073
for arg in &mut fty.args {
71-
if !arg.is_ignore() && !arg.is_indirect() {
72-
if !is_soft_float_abi {
73-
if arg.ty.kind() == Float {
74-
continue;
75-
}
76-
}
74+
if arg.is_ignore() || arg.is_indirect() { continue; }
7775

78-
let size = llbitsize_of_real(ccx, arg.ty);
79-
let size_in_regs = (size + 31) / 32;
76+
if arg.ty.kind() == Float {
77+
continue;
78+
}
8079

81-
if size_in_regs == 0 {
82-
continue;
83-
}
80+
let size = llbitsize_of_real(ccx, arg.ty);
81+
let size_in_regs = (size + 31) / 32;
8482

85-
if !is_mcu_abi {
86-
if size_in_regs > free_regs {
87-
break;
88-
}
89-
} else {
90-
if size_in_regs > free_regs || size_in_regs > 2 {
91-
continue;
92-
}
93-
}
83+
if size_in_regs == 0 {
84+
continue;
85+
}
9486

95-
free_regs -= size_in_regs;
87+
if size_in_regs > free_regs {
88+
break;
89+
}
9690

97-
if !is_mcu_abi && size <= 32 && (arg.ty.kind() == Pointer || arg.ty.kind() == Integer) {
98-
arg.attrs.set(ArgAttribute::InReg);
99-
}
91+
free_regs -= size_in_regs;
10092

101-
if free_regs == 0 {
102-
break;
103-
}
93+
if size <= 32 && (arg.ty.kind() == Pointer || arg.ty.kind() == Integer) {
94+
arg.attrs.set(ArgAttribute::InReg);
95+
}
96+
97+
if free_regs == 0 {
98+
break;
10499
}
105100
}
106101
}

src/test/codegen/fastcall-inreg.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Checks if the "fastcall" calling convention marks function arguments
12+
// as "inreg" like the C/C++ compilers for the platforms.
13+
// x86 only.
14+
15+
// ignore-aarch64
16+
// ignore-aarch64_be
17+
// ignore-arm
18+
// ignore-armeb
19+
// ignore-avr
20+
// ignore-bpfel
21+
// ignore-bpfeb
22+
// ignore-hexagon
23+
// ignore-mips
24+
// ignore-mipsel
25+
// ignore-mips64
26+
// ignore-mips64el
27+
// ignore-msp430
28+
// ignore-powerpc64
29+
// ignore-powerpc64le
30+
// ignore-powerpc
31+
// ignore-r600
32+
// ignore-amdgcn
33+
// ignore-sparc
34+
// ignore-sparcv9
35+
// ignore-sparcel
36+
// ignore-s390x
37+
// ignore-tce
38+
// ignore-thumb
39+
// ignore-thumbeb
40+
// ignore-x86_64 no-ignore-x86
41+
// ignore-xcore
42+
// ignore-nvptx
43+
// ignore-nvptx64
44+
// ignore-le32
45+
// ignore-le64
46+
// ignore-amdil
47+
// ignore-amdil64
48+
// ignore-hsail
49+
// ignore-hsail64
50+
// ignore-spir
51+
// ignore-spir64
52+
// ignore-kalimba
53+
// ignore-shave
54+
// ignore-wasm32
55+
// ignore-wasm64
56+
57+
// compile-flags: -C no-prepopulate-passes
58+
59+
#![crate_type = "lib"]
60+
61+
mod tests {
62+
// CHECK: @f1(i32 inreg, i32 inreg, i32)
63+
#[no_mangle]
64+
extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
65+
66+
// CHECK: @f2(i32* inreg, i32* inreg, i32*)
67+
#[no_mangle]
68+
extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}
69+
70+
// CHECK: @f3(float, i32 inreg, i32 inreg, i32)
71+
#[no_mangle]
72+
extern "fastcall" fn f3(_: f32, _: i32, _: i32, _: i32) {}
73+
74+
// CHECK: @f4(i32 inreg, float, i32 inreg, i32)
75+
#[no_mangle]
76+
extern "fastcall" fn f4(_: i32, _: f32, _: i32, _: i32) {}
77+
78+
// CHECK: @f5(i64, i32)
79+
#[no_mangle]
80+
extern "fastcall" fn f5(_: i64, _: i32) {}
81+
82+
// CHECK: @f6(i1 inreg zeroext, i32 inreg, i32)
83+
#[no_mangle]
84+
extern "fastcall" fn f6(_: bool, _: i32, _: i32) {}
85+
}

0 commit comments

Comments
 (0)