]> git.lizzy.rs Git - rust.git/commitdiff
Fix C aggregate-passing ABI on powerpc
authorSamuel Holland <samuel@sholland.org>
Thu, 5 Sep 2019 01:40:18 +0000 (20:40 -0500)
committerSamuel Holland <samuel@sholland.org>
Wed, 6 Nov 2019 02:23:58 +0000 (20:23 -0600)
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.

See #64259 for more discussion, which addresses the ABI for the special
case of ZSTs (empty structs).

src/librustc_target/abi/call/mod.rs
src/librustc_target/abi/call/powerpc.rs

index 396b962003803d2b623e0ee25431a7ded1f7a2fa..33335f462a7aeda8447b91eed74c59ad0ab15020 100644 (file)
@@ -554,7 +554,7 @@ pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(),
             "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),
index b2c8d26ff1f86e44b2e755527808714125f42c3f..740bd7222f237034bbcc7a6d6dbbd430a71b6980 100644 (file)
@@ -1,49 +1,28 @@
-use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::call::{ArgAbi, FnAbi};
 
-fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, 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>(ret: &mut ArgAbi<'_, 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<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, 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>(arg: &mut ArgAbi<'_, 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, fn_abi: &mut FnAbi<'_, Ty>)
-    where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
-{
-    let mut offset = Size::ZERO;
+pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
-        classify_ret(cx, &mut fn_abi.ret, &mut offset);
+        classify_ret(&mut fn_abi.ret);
     }
 
     for arg in &mut fn_abi.args {
         if arg.is_ignore() { continue; }
-        classify_arg(cx, arg, &mut offset);
+        classify_arg(arg);
     }
 }