93 lines
3.4 KiB
Diff
93 lines
3.4 KiB
Diff
From b99ae159cca4c92146e07a4184064634ed4bd52d Mon Sep 17 00:00:00 2001
|
|
From: Samuel Holland <samuel@sholland.org>
|
|
Date: Sat, 21 Dec 2019 16:50:55 +0100
|
|
Subject: [PATCH 06/18] 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.
|
|
---
|
|
src/librustc_target/abi/call/mod.rs | 2 +-
|
|
src/librustc_target/abi/call/powerpc.rs | 41 ++++++-------------------
|
|
2 files changed, 11 insertions(+), 32 deletions(-)
|
|
|
|
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
|
|
index 17bad189..81175fc0 100644
|
|
--- a/src/librustc_target/abi/call/mod.rs
|
|
+++ b/src/librustc_target/abi/call/mod.rs
|
|
@@ -554,7 +554,7 @@ impl<'a, Ty> FnType<'a, Ty> {
|
|
"arm" => arm::compute_abi_info(cx, self),
|
|
"mips" => mips::compute_abi_info(cx, self),
|
|
"mips64" => mips64::compute_abi_info(cx, self),
|
|
- "powerpc" => powerpc::compute_abi_info(cx, self),
|
|
+ "powerpc" => powerpc::compute_abi_info(self),
|
|
"powerpc64" => powerpc64::compute_abi_info(cx, self),
|
|
"s390x" => s390x::compute_abi_info(cx, self),
|
|
"msp430" => msp430::compute_abi_info(self),
|
|
diff --git a/src/librustc_target/abi/call/powerpc.rs b/src/librustc_target/abi/call/powerpc.rs
|
|
index d496abf8..f20defd6 100644
|
|
--- a/src/librustc_target/abi/call/powerpc.rs
|
|
+++ b/src/librustc_target/abi/call/powerpc.rs
|
|
@@ -1,49 +1,28 @@
|
|
-use crate::abi::call::{ArgType, FnType, Reg, Uniform};
|
|
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
|
|
+use crate::abi::call::{ArgType, FnType};
|
|
|
|
-fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size)
|
|
- where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
|
|
-{
|
|
- if !ret.layout.is_aggregate() {
|
|
- ret.extend_integer_width_to(32);
|
|
- } else {
|
|
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
|
|
+ if ret.layout.is_aggregate() {
|
|
ret.make_indirect();
|
|
- *offset += cx.data_layout().pointer_size;
|
|
+ } else {
|
|
+ ret.extend_integer_width_to(32);
|
|
}
|
|
}
|
|
|
|
-fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size)
|
|
- where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
|
|
-{
|
|
- let dl = cx.data_layout();
|
|
- let size = arg.layout.size;
|
|
- let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
|
|
-
|
|
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
|
|
if arg.layout.is_aggregate() {
|
|
- arg.cast_to(Uniform {
|
|
- unit: Reg::i32(),
|
|
- total: size
|
|
- });
|
|
- if !offset.is_aligned(align) {
|
|
- arg.pad_with(Reg::i32());
|
|
- }
|
|
+ arg.make_indirect();
|
|
} else {
|
|
arg.extend_integer_width_to(32);
|
|
}
|
|
-
|
|
- *offset = offset.align_to(align) + size.align_to(align);
|
|
}
|
|
|
|
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>)
|
|
- where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
|
|
-{
|
|
- let mut offset = Size::ZERO;
|
|
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
|
|
if !fty.ret.is_ignore() {
|
|
- classify_ret_ty(cx, &mut fty.ret, &mut offset);
|
|
+ classify_ret_ty(&mut fty.ret);
|
|
}
|
|
|
|
for arg in &mut fty.args {
|
|
if arg.is_ignore() { continue; }
|
|
- classify_arg_ty(cx, arg, &mut offset);
|
|
+ classify_arg_ty(arg);
|
|
}
|
|
}
|
|
--
|
|
2.24.0
|
|
|