Skip to content

Commit

Permalink
Fix powerpc64 ELFv2 big-endian struct-passing ABI
Browse files Browse the repository at this point in the history
The requirements here are not "ELFv1" requirements, but big-endian
requirements, as the extension or non-extension of the argument is
necessary to put the argument in the correct half of the register.
Parameter passing in the ELFv2 ABI needs these same transformations.
Since this code makes no difference on little-endian machines, simplify
it to use the same code path everywhere.
  • Loading branch information
smaeul committed Nov 15, 2018
1 parent 81303d7 commit 346e976
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 18 deletions.
29 changes: 12 additions & 17 deletions src/librustc_target/abi/call/powerpc64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>, abi: ABI)
let size = ret.layout.size;
let bits = size.bits();
if bits <= 128 {
let unit = if bits <= 8 {
let unit = if cx.data_layout().endian == Endian::Big {
Reg { kind: RegKind::Integer, size }
} else if bits <= 8 {
Reg::i8()
} else if bits <= 16 {
Reg::i16()
Expand Down Expand Up @@ -110,22 +112,15 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI)
}

let size = arg.layout.size;
let (unit, total) = match abi {
ELFv1 => {
// In ELFv1, aggregates smaller than a doubleword should appear in
// the least-significant bits of the parameter doubleword. The rest
// should be padded at their tail to fill out multiple doublewords.
if size.bits() <= 64 {
(Reg { kind: RegKind::Integer, size }, size)
} else {
let align = Align::from_bits(64, 64).unwrap();
(Reg::i64(), size.abi_align(align))
}
},
ELFv2 => {
// In ELFv2, we can just cast directly.
(Reg::i64(), size)
},
let (unit, total) = if size.bits() <= 64 {
// Aggregates smaller than a doubleword should appear in
// the least-significant bits of the parameter doubleword.
(Reg { kind: RegKind::Integer, size }, size)
} else {
// Aggregates larger than a doubleword should be padded
// at the tail to fill out a whole number of doublewords.
let align = Align::from_bits(64, 64).unwrap();
(Reg::i64(), size.abi_align(align))
};

arg.cast_to(Uniform {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_target/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl HasDataLayout for TargetDataLayout {
}

/// Endianness of the target, which must match cfg(target-endian).
#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq)]
pub enum Endian {
Little,
Big
Expand Down

0 comments on commit 346e976

Please sign in to comment.