summaryrefslogtreecommitdiff
path: root/user/rust/0007-Fix-C-aggregate-passing-ABI-on-powerpc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/rust/0007-Fix-C-aggregate-passing-ABI-on-powerpc.patch')
-rw-r--r--user/rust/0007-Fix-C-aggregate-passing-ABI-on-powerpc.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/user/rust/0007-Fix-C-aggregate-passing-ABI-on-powerpc.patch b/user/rust/0007-Fix-C-aggregate-passing-ABI-on-powerpc.patch
new file mode 100644
index 000000000..05b91456f
--- /dev/null
+++ b/user/rust/0007-Fix-C-aggregate-passing-ABI-on-powerpc.patch
@@ -0,0 +1,93 @@
+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
+