changeset 1050:32ead42679d1

Fix a bug in the X86 ABI. The size of a struct is different from the size of a pointer to that struct...
author Frits van Bommel <fvbommel wxs.nl>
date Fri, 06 Mar 2009 21:15:13 +0100
parents afe271b0e271
children dc608dc33081
files gen/abi.cpp gen/tocall.cpp gen/tollvm.cpp ir/irfunction.cpp
diffstat 4 files changed, 46 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/gen/abi.cpp	Fri Mar 06 19:12:48 2009 +0100
+++ b/gen/abi.cpp	Fri Mar 06 21:15:13 2009 +0100
@@ -133,9 +133,9 @@
         const LLType* t = LLIntegerType::get(dty->size()*8);
         DtoLoad(DtoBitCast(mem, getPtrToType(t)));
     }
-    const LLType* type(Type*, const LLType* t)
+    const LLType* type(Type* t, const LLType*)
     {
-        size_t sz = getTypePaddedSize(t)*8;
+        size_t sz = t->size()*8;
         return LLIntegerType::get(sz);
     }
 };
@@ -178,6 +178,7 @@
             // complex {re,im} -> {im,re}
             if (rt->iscomplex())
             {
+                Logger::println("Rewriting complex return value");
                 fty->ret->rewrite = &swapComplex;
             }
 
@@ -186,10 +187,12 @@
             // mark this/nested params inreg
             if (fty->arg_this)
             {
+                Logger::println("Putting 'this' in register");
                 fty->arg_this->attrs = llvm::Attribute::InReg;
             }
             else if (fty->arg_nest)
             {
+                Logger::println("Putting context ptr in register");
                 fty->arg_nest->attrs = llvm::Attribute::InReg;
             }
             // otherwise try to mark the last param inreg
@@ -206,6 +209,7 @@
 
                 if (last->byref && !last->isByVal())
                 {
+                    Logger::println("Putting last (byref) parameter in register");
                     last->attrs |= llvm::Attribute::InReg;
                 }
                 else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) // right?
--- a/gen/tocall.cpp	Fri Mar 06 19:12:48 2009 +0100
+++ b/gen/tocall.cpp	Fri Mar 06 21:15:13 2009 +0100
@@ -373,6 +373,16 @@
     else
     {
         Logger::println("doing normal arguments");
+        if (Logger::enabled()) {
+            Logger::println("Arguments so far: (%d)", (int)args.size());
+            Logger::indent();
+            for (size_t i = 0; i < args.size(); i++) {
+                Logger::cout() << *args[i] << '\n';
+            }
+            Logger::undent();
+            Logger::cout() << "Function type: " << tf->toChars() << '\n';
+            Logger::cout() << "LLVM functype: " << *callable->getType() << '\n';
+        }
 
         size_t n = Argument::dim(tf->parameters);
 
@@ -386,9 +396,19 @@
             assert(fnarg);
             DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
 
+            if (Logger::enabled()) {
+                Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n';
+                Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n';
+            }
+
             // give the ABI a say
             LLValue* arg = tf->fty->putParam(argval->getType(), i, argval);
 
+            if (Logger::enabled()) {
+                Logger::cout() << "Argument after ABI: " << *arg << '\n';
+                Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n';
+            }
+
             int j = tf->fty->reverseParams ? beg + n - i - 1 : beg + i;
 
             // Hack around LDC assuming structs are in memory:
--- a/gen/tollvm.cpp	Fri Mar 06 19:12:48 2009 +0100
+++ b/gen/tollvm.cpp	Fri Mar 06 21:15:13 2009 +0100
@@ -578,7 +578,7 @@
 {
     if (v->getType() == t)
         return v;
-    assert(!(isaStruct(t) || isaStruct(v->getType())));
+    assert(!isaStruct(t));
     return gIR->ir->CreateBitCast(v, t, name ? name : "tmp");
 }
 
--- a/ir/irfunction.cpp	Fri Mar 06 19:12:48 2009 +0100
+++ b/ir/irfunction.cpp	Fri Mar 06 21:15:13 2009 +0100
@@ -3,6 +3,7 @@
 #include "gen/tollvm.h"
 #include "gen/abi.h"
 #include "gen/dvalue.h"
+#include "gen/logger.h"
 #include "ir/irfunction.h"
 
 #include <sstream>
@@ -27,32 +28,44 @@
 llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val)
 {
     assert(!arg_sret);
-    if (ret->rewrite)
+    if (ret->rewrite) {
+        Logger::println("Rewrite: putRet");
+        LOG_SCOPE
         return ret->rewrite->put(dty, val);
+    }
     return val->getRVal();
 }
 
 llvm::Value* IrFuncTy::getRet(Type* dty, DValue* val)
 {
     assert(!arg_sret);
-    if (ret->rewrite)
+    if (ret->rewrite) {
+        Logger::println("Rewrite: getRet");
+        LOG_SCOPE
         return ret->rewrite->get(dty, val);
+    }
     return val->getRVal();
 }
 
 llvm::Value* IrFuncTy::putParam(Type* dty, int idx, DValue* val)
 {
     assert(idx >= 0 && idx < args.size() && "invalid putParam");
-    if (args[idx]->rewrite)
+    if (args[idx]->rewrite) {
+        Logger::println("Rewrite: putParam");
+        LOG_SCOPE
         return args[idx]->rewrite->put(dty, val);
+    }
     return val->getRVal();
 }
 
 llvm::Value* IrFuncTy::getParam(Type* dty, int idx, DValue* val)
 {
     assert(idx >= 0 && idx < args.size() && "invalid getParam");
-    if (args[idx]->rewrite)
+    if (args[idx]->rewrite) {
+        Logger::println("Rewrite: getParam (get)");
+        LOG_SCOPE
         return args[idx]->rewrite->get(dty, val);
+    }
     return val->getRVal();
 }
 
@@ -62,6 +75,8 @@
 
     if (args[idx]->rewrite)
     {
+        Logger::println("Rewrite: getParam (getL)");
+        LOG_SCOPE
         args[idx]->rewrite->getL(dty, val, lval);
         return;
     }