diff --git a/src/librustc_trans/cabi_x86_64.rs b/src/librustc_trans/cabi_x86_64.rs index 62bac8469ce..b8144a3ca7a 100644 --- a/src/librustc_trans/cabi_x86_64.rs +++ b/src/librustc_trans/cabi_x86_64.rs @@ -134,12 +134,13 @@ fn reg_component(cls: &[Option], i: &mut usize, size: Size) -> Option None, Some(Class::Int) => { *i += 1; - Some(match size.bytes() { - 1 => Reg::i8(), - 2 => Reg::i16(), - 3 | - 4 => Reg::i32(), - _ => Reg::i64() + Some(if size.bytes() < 8 { + Reg { + kind: RegKind::Integer, + size + } + } else { + Reg::i64() }) } Some(Class::Sse) => { diff --git a/src/test/codegen/abi-x86_64_sysv.rs b/src/test/codegen/abi-x86_64_sysv.rs new file mode 100644 index 00000000000..88666e9c1fd --- /dev/null +++ b/src/test/codegen/abi-x86_64_sysv.rs @@ -0,0 +1,39 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// only-x86_64 + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +pub struct S24 { + a: i8, + b: i8, + c: i8, +} + +pub struct S48 { + a: i16, + b: i16, + c: i8, +} + +// CHECK: i24 @struct_24_bits(i24 +#[no_mangle] +pub extern "sysv64" fn struct_24_bits(a: S24) -> S24 { + a +} + +// CHECK: i48 @struct_48_bits(i48 +#[no_mangle] +pub extern "sysv64" fn struct_48_bits(a: S48) -> S48 { + a +} diff --git a/src/test/codegen/repr-transparent-sysv64.rs b/src/test/codegen/repr-transparent-sysv64.rs new file mode 100644 index 00000000000..7a30983fdd3 --- /dev/null +++ b/src/test/codegen/repr-transparent-sysv64.rs @@ -0,0 +1,39 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// only-x86_64 + +// compile-flags: -C no-prepopulate-passes + +#![crate_type="lib"] +#![feature(repr_transparent)] + +#[repr(C)] +pub struct Rgb8 { r: u8, g: u8, b: u8 } + +#[repr(transparent)] +pub struct Rgb8Wrap(Rgb8); + +// CHECK: i24 @test_Rgb8Wrap(i24) +#[no_mangle] +pub extern "sysv64" fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { loop {} } + +#[repr(C)] +pub union FloatBits { + float: f32, + bits: u32, +} + +#[repr(transparent)] +pub struct SmallUnion(FloatBits); + +// CHECK: i32 @test_SmallUnion(i32) +#[no_mangle] +pub extern "sysv64" fn test_SmallUnion(_: SmallUnion) -> SmallUnion { loop {} } diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs index 31020d8b94f..087fa9b16b4 100644 --- a/src/test/codegen/repr-transparent.rs +++ b/src/test/codegen/repr-transparent.rs @@ -123,55 +123,13 @@ pub struct StructWithProjection(::It); pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } -// The rest of this file tests newtypes around small aggregates on an ABI where small aggregates are -// packed into one register. This is ABI-dependent, so instead we focus on one ABI and supply a -// dummy definition for other ABIs to keep FileCheck happy. +// All that remains to be tested are aggregates. They are tested in separate files called repr- +// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR +// function signatures vary so much that it's not reasonably possible to cover all of them with a +// single CHECK line. // -// Bigger aggregates are tested in separate files called repr-transparent-aggregate-*.rs because -// there, the expected LLVM IR function signatures vary so much that it's not reasonably possible to -// cover all of them with a single CHECK line. Instead we group ABIs by the general "shape" of the -// signature and have a separate test file for each bin. -// -// PS: You may be wondering why we don't just compare the return types and argument types for -// equality with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on -// newtypes containing aggregates. This is OK on all ABIs we support, but because LLVM has not -// gotten rid of pointee types yet, the IR function signature will be syntactically different (%Foo* -// vs %FooWrapper*). - -#[repr(C)] -pub struct Rgb8 { r: u8, g: u8, b: u8 } - -#[repr(transparent)] -pub struct Rgb8Wrap(Rgb8); - -// NB: closing parenthesis is missing because sometimes the argument has a name and sometimes not -// CHECK: define i32 @test_Rgb8Wrap(i32 -#[no_mangle] -#[cfg(all(target_arch="x86_64", target_os="linux"))] -pub extern fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { loop {} } - -#[cfg(not(all(target_arch="x86_64", target_os="linux")))] -#[no_mangle] -pub extern fn test_Rgb8Wrap(_: u32) -> u32 { loop {} } - -// Same as with the small struct above: ABI-dependent, we only test the interesting case -// (ABIs that pack the aggregate into a scalar) and stub it out on other ABIs - -#[repr(C)] -pub union FloatBits { - float: f32, - bits: u32, -} - -#[repr(transparent)] -pub struct SmallUnion(FloatBits); - -// NB: closing parenthesis is missing because sometimes the argument has a name and sometimes not -// CHECK: define i32 @test_SmallUnion(i32 -#[no_mangle] -#[cfg(all(target_arch="x86_64", target_os="linux"))] -pub extern fn test_SmallUnion(_: SmallUnion) -> SmallUnion { loop {} } - -#[cfg(not(all(target_arch="x86_64", target_os="linux")))] -#[no_mangle] -pub extern fn test_SmallUnion(_: u32) -> u32 { loop {} } +// You may be wondering why we don't just compare the return types and argument types for equality +// with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes +// containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of +// pointee types yet, the IR function signature will be syntactically different (%Foo* vs +// %FooWrapper*).