Skip to content

Commit 346e976

Browse files
committed
Fix powerpc64 ELFv2 big-endian struct-passing ABI
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.
1 parent 81303d7 commit 346e976

File tree

2 files changed

+13
-18
lines changed

2 files changed

+13
-18
lines changed

src/librustc_target/abi/call/powerpc64.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>, abi: ABI)
7575
let size = ret.layout.size;
7676
let bits = size.bits();
7777
if bits <= 128 {
78-
let unit = if bits <= 8 {
78+
let unit = if cx.data_layout().endian == Endian::Big {
79+
Reg { kind: RegKind::Integer, size }
80+
} else if bits <= 8 {
7981
Reg::i8()
8082
} else if bits <= 16 {
8183
Reg::i16()
@@ -110,22 +112,15 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI)
110112
}
111113

112114
let size = arg.layout.size;
113-
let (unit, total) = match abi {
114-
ELFv1 => {
115-
// In ELFv1, aggregates smaller than a doubleword should appear in
116-
// the least-significant bits of the parameter doubleword. The rest
117-
// should be padded at their tail to fill out multiple doublewords.
118-
if size.bits() <= 64 {
119-
(Reg { kind: RegKind::Integer, size }, size)
120-
} else {
121-
let align = Align::from_bits(64, 64).unwrap();
122-
(Reg::i64(), size.abi_align(align))
123-
}
124-
},
125-
ELFv2 => {
126-
// In ELFv2, we can just cast directly.
127-
(Reg::i64(), size)
128-
},
115+
let (unit, total) = if size.bits() <= 64 {
116+
// Aggregates smaller than a doubleword should appear in
117+
// the least-significant bits of the parameter doubleword.
118+
(Reg { kind: RegKind::Integer, size }, size)
119+
} else {
120+
// Aggregates larger than a doubleword should be padded
121+
// at the tail to fill out a whole number of doublewords.
122+
let align = Align::from_bits(64, 64).unwrap();
123+
(Reg::i64(), size.abi_align(align))
129124
};
130125

131126
arg.cast_to(Uniform {

src/librustc_target/abi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ impl HasDataLayout for TargetDataLayout {
229229
}
230230

231231
/// Endianness of the target, which must match cfg(target-endian).
232-
#[derive(Copy, Clone)]
232+
#[derive(Copy, Clone, PartialEq)]
233233
pub enum Endian {
234234
Little,
235235
Big

0 commit comments

Comments
 (0)