94 lines
3.4 KiB
Diff
94 lines
3.4 KiB
Diff
From c9a914f48652de22832a40ef9639ff8d57c57f31 Mon Sep 17 00:00:00 2001
|
|
From: Samuel Holland <samuel@sholland.org>
|
|
Date: Wed, 4 Sep 2019 20:40:18 -0500
|
|
Subject: [PATCH 07/16] 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 fbbd120f934..f4d98177072 100644
|
|
--- a/src/librustc_target/abi/call/mod.rs
|
|
+++ b/src/librustc_target/abi/call/mod.rs
|
|
@@ -562,7 +562,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),
|
|
"asmjs" => asmjs::compute_abi_info(cx, self),
|
|
diff --git a/src/librustc_target/abi/call/powerpc.rs b/src/librustc_target/abi/call/powerpc.rs
|
|
index d496abf8e8b..f20defd6f5b 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.21.0
|
|
|