From b542c403b8211e1e99278b206b82f5f601dd8cbd 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/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 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