Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e648aa8

Browse files
committedNov 6, 2019
Fix C aggregate-passing ABI on powerpc
The existing code (which looks like it was copied from MIPS) passes aggregates by value in registers. This is wrong. According to the SVR4 powerpc psABI, all aggregates are passed indirectly. See rust-lang#64259 for more discussion, which addresses the ABI for the special case of ZSTs (empty structs).
1 parent 1423bec commit e648aa8

File tree

2 files changed

+11
-32
lines changed

2 files changed

+11
-32
lines changed
 

‎src/librustc_target/abi/call/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
554554
"arm" => arm::compute_abi_info(cx, self),
555555
"mips" => mips::compute_abi_info(cx, self),
556556
"mips64" => mips64::compute_abi_info(cx, self),
557-
"powerpc" => powerpc::compute_abi_info(cx, self),
557+
"powerpc" => powerpc::compute_abi_info(self),
558558
"powerpc64" => powerpc64::compute_abi_info(cx, self),
559559
"s390x" => s390x::compute_abi_info(cx, self),
560560
"msp430" => msp430::compute_abi_info(self),
Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,28 @@
1-
use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
2-
use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
1+
use crate::abi::call::{ArgAbi, FnAbi};
32

4-
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
5-
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
6-
{
7-
if !ret.layout.is_aggregate() {
8-
ret.extend_integer_width_to(32);
9-
} else {
3+
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
4+
if ret.layout.is_aggregate() {
105
ret.make_indirect();
11-
*offset += cx.data_layout().pointer_size;
6+
} else {
7+
ret.extend_integer_width_to(32);
128
}
139
}
1410

15-
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
16-
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
17-
{
18-
let dl = cx.data_layout();
19-
let size = arg.layout.size;
20-
let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
21-
11+
fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
2212
if arg.layout.is_aggregate() {
23-
arg.cast_to(Uniform {
24-
unit: Reg::i32(),
25-
total: size
26-
});
27-
if !offset.is_aligned(align) {
28-
arg.pad_with(Reg::i32());
29-
}
13+
arg.make_indirect();
3014
} else {
3115
arg.extend_integer_width_to(32);
3216
}
33-
34-
*offset = offset.align_to(align) + size.align_to(align);
3517
}
3618

37-
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
38-
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
39-
{
40-
let mut offset = Size::ZERO;
19+
pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
4120
if !fn_abi.ret.is_ignore() {
42-
classify_ret(cx, &mut fn_abi.ret, &mut offset);
21+
classify_ret(&mut fn_abi.ret);
4322
}
4423

4524
for arg in &mut fn_abi.args {
4625
if arg.is_ignore() { continue; }
47-
classify_arg(cx, arg, &mut offset);
26+
classify_arg(arg);
4827
}
4928
}

0 commit comments

Comments
 (0)
Please sign in to comment.