[pkg-d-commits] [ldc] 13/14: PPC/PPC64: Fix ABI errors.

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:35:55 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v0.17.2
in repository ldc.

commit fb06a994f1fb02ac68ceb020a11187168fa93c2e
Author: Kai Nacke <kai at redstar.de>
Date:   Sat Aug 13 12:11:09 2016 +0200

    PPC/PPC64: Fix ABI errors.
    
    Issue #1652 seems to be caused by ABI errors in the bootstrap compiler.
    This PR updates the PPC/PPC64 ABI to conform to clang/gcc output.
---
 gen/abi-ppc.cpp | 72 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/gen/abi-ppc.cpp b/gen/abi-ppc.cpp
index b3748cf..905d8ae 100644
--- a/gen/abi-ppc.cpp
+++ b/gen/abi-ppc.cpp
@@ -29,6 +29,8 @@
 
 struct PPCTargetABI : TargetABI {
   ExplicitByvalRewrite byvalRewrite;
+  CompositeToArray32 compositeToArray32;
+  CompositeToArray64 compositeToArray64;
   IntegerRewrite integerRewrite;
   const bool Is64Bit;
 
@@ -39,20 +41,49 @@ struct PPCTargetABI : TargetABI {
       return false;
     }
 
-    // Return structs and static arrays on the stack. The latter is needed
-    // because otherwise LLVM tries to actually return the array in a number
-    // of physical registers, which leads, depending on the target, to
-    // either horrendous codegen or backend crashes.
+    // FIXME
     Type *rt = tf->next->toBasetype();
-    return (rt->ty == Tstruct || rt->ty == Tsarray);
+    if (tf->linkage == LINKd)
+      return rt->ty == Tsarray || rt->ty == Tstruct;
+
+    // The ABI specifies that aggregates of size 8 bytes or less are
+    // returned in r3/r4 (ppc) or in r3 (ppc64). Looking at the IR
+    // generated by clang this seems not to be implemented. Regardless
+    // of size, the aggregate is always returned as sret.
+    return rt->ty == Tsarray || rt->ty == Tstruct;
   }
 
   bool passByVal(Type *t) override {
-    TY ty = t->toBasetype()->ty;
-    return ty == Tstruct || ty == Tsarray;
+    // On ppc, aggregates are always passed as an indirect value.
+    // On ppc64, they are always passed by value. However, clang
+    // used byval for type > 64 bytes.
+    t = t->toBasetype();
+    return (t->ty == Tsarray || t->ty == Tstruct) && (!Is64Bit || t->size() > 64);
   }
 
   void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
+    // RETURN VALUE
+    Type *retTy = fty.ret->type->toBasetype();
+    if (!fty.ret->byref) {
+      if (retTy->ty == Tstruct || retTy->ty == Tsarray) {
+        if (canRewriteAsInt(retTy, Is64Bit)) {
+          fty.ret->rewrite = &integerRewrite;
+          fty.ret->ltype = integerRewrite.type(fty.ret->type, fty.ret->ltype);
+        } else {
+          if (Is64Bit) {
+            fty.ret->rewrite = &compositeToArray64;
+            fty.ret->ltype =
+                compositeToArray64.type(fty.ret->type, fty.ret->ltype);
+          } else {
+            fty.ret->rewrite = &compositeToArray32;
+            fty.ret->ltype =
+                compositeToArray32.type(fty.ret->type, fty.ret->ltype);
+          }
+        }
+      } else if (retTy->isintegral())
+        fty.ret->attrs.add(retTy->isunsigned() ? LLAttribute::ZExt
+                                               : LLAttribute::SExt);
+    }
     // EXPLICIT PARAMETERS
     for (auto arg : fty.args) {
       if (!arg->byref) {
@@ -66,24 +97,19 @@ struct PPCTargetABI : TargetABI {
 
     if (ty->ty == Tstruct || ty->ty == Tsarray) {
       if (canRewriteAsInt(ty, Is64Bit)) {
-        if (!IntegerRewrite::isObsoleteFor(arg.ltype)) {
-          arg.rewrite = &integerRewrite;
-          arg.ltype = integerRewrite.type(arg.type, arg.ltype);
-        }
+        arg.rewrite = &integerRewrite;
+        arg.ltype = integerRewrite.type(arg.type, arg.ltype);
       } else {
-        // these types are passed byval:
-        // the caller allocates a copy and then passes a pointer to the copy
-        arg.rewrite = &byvalRewrite;
-        arg.ltype = byvalRewrite.type(arg.type, arg.ltype);
-
-        // the copy is treated as a local variable of the callee
-        // hence add the NoAlias and NoCapture attributes
-        arg.attrs.clear()
-            .add(LLAttribute::NoAlias)
-            .add(LLAttribute::NoCapture)
-            .addAlignment(byvalRewrite.alignment(arg.type));
+        if (Is64Bit) {
+          arg.rewrite = &compositeToArray64;
+          arg.ltype = compositeToArray64.type(arg.type, arg.ltype);
+        } else {
+          arg.rewrite = &compositeToArray32;
+          arg.ltype = compositeToArray32.type(arg.type, arg.ltype);
+        }
       }
-    }
+    } else if (ty->isintegral())
+      arg.attrs.add(ty->isunsigned() ? LLAttribute::ZExt : LLAttribute::SExt);
   }
 };
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list