diff options
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.patch | 93 |
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 + |