Skip to content

Commit

Permalink
Cleaned up the code and added tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
YaLTeR committed Dec 22, 2016
1 parent c461cdf commit 5e2cea9
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 30 deletions.
55 changes: 25 additions & 30 deletions src/librustc_trans/cabi_x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,46 +61,41 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType, flavor: Flavor) {
if flavor == Flavor::Fastcall {
// Mark arguments as InReg like clang does it,
// so our fastcall is compatible with C/C++ fastcall.
// Clang reference: ib/CodeGen/TargetInfo.cpp
let is_mcu_abi = ccx.sess().target.target.target_os.eq("elfiamcu");
let is_soft_float_abi = ccx.sess().target.target.options.features.contains("+soft-float");

// Clang reference: lib/CodeGen/TargetInfo.cpp
// See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()

// IsSoftFloatABI is only set to true on ARM platforms,
// which in turn can't be x86?

let mut free_regs = 2;

for arg in &mut fty.args {
if !arg.is_ignore() && !arg.is_indirect() {
if !is_soft_float_abi {
if arg.ty.kind() == Float {
continue;
}
}
if arg.is_ignore() || arg.is_indirect() { continue; }

let size = llbitsize_of_real(ccx, arg.ty);
let size_in_regs = (size + 31) / 32;
if arg.ty.kind() == Float {
continue;
}

if size_in_regs == 0 {
continue;
}
let size = llbitsize_of_real(ccx, arg.ty);
let size_in_regs = (size + 31) / 32;

if !is_mcu_abi {
if size_in_regs > free_regs {
break;
}
} else {
if size_in_regs > free_regs || size_in_regs > 2 {
continue;
}
}
if size_in_regs == 0 {
continue;
}

free_regs -= size_in_regs;
if size_in_regs > free_regs {
break;
}

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

if free_regs == 0 {
break;
}
if size <= 32 && (arg.ty.kind() == Pointer || arg.ty.kind() == Integer) {
arg.attrs.set(ArgAttribute::InReg);
}

if free_regs == 0 {
break;
}
}
}
Expand Down
85 changes: 85 additions & 0 deletions src/test/codegen/fastcall-inreg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Checks if the "fastcall" calling convention marks function arguments
// as "inreg" like the C/C++ compilers for the platforms.
// x86 only.

// ignore-aarch64
// ignore-aarch64_be
// ignore-arm
// ignore-armeb
// ignore-avr
// ignore-bpfel
// ignore-bpfeb
// ignore-hexagon
// ignore-mips
// ignore-mipsel
// ignore-mips64
// ignore-mips64el
// ignore-msp430
// ignore-powerpc64
// ignore-powerpc64le
// ignore-powerpc
// ignore-r600
// ignore-amdgcn
// ignore-sparc
// ignore-sparcv9
// ignore-sparcel
// ignore-s390x
// ignore-tce
// ignore-thumb
// ignore-thumbeb
// ignore-x86_64 no-ignore-x86
// ignore-xcore
// ignore-nvptx
// ignore-nvptx64
// ignore-le32
// ignore-le64
// ignore-amdil
// ignore-amdil64
// ignore-hsail
// ignore-hsail64
// ignore-spir
// ignore-spir64
// ignore-kalimba
// ignore-shave
// ignore-wasm32
// ignore-wasm64

// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

mod tests {
// CHECK: @f1(i32 inreg, i32 inreg, i32)
#[no_mangle]
extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}

// CHECK: @f2(i32* inreg, i32* inreg, i32*)
#[no_mangle]
extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}

// CHECK: @f3(float, i32 inreg, i32 inreg, i32)
#[no_mangle]
extern "fastcall" fn f3(_: f32, _: i32, _: i32, _: i32) {}

// CHECK: @f4(i32 inreg, float, i32 inreg, i32)
#[no_mangle]
extern "fastcall" fn f4(_: i32, _: f32, _: i32, _: i32) {}

// CHECK: @f5(i64, i32)
#[no_mangle]
extern "fastcall" fn f5(_: i64, _: i32) {}

// CHECK: @f6(i1 inreg zeroext, i32 inreg, i32)
#[no_mangle]
extern "fastcall" fn f6(_: bool, _: i32, _: i32) {}
}

0 comments on commit 5e2cea9

Please sign in to comment.