changeset 939:cac9895be400

Automated merge with http://hg.dsource.org/projects/ldc
author Christian Kamm <kamm incasoftware de>
date Wed, 04 Feb 2009 18:39:39 +0100
parents 6c09179ebba0 (current diff) a904cc9bc064 (diff)
children 39519a1ff603
files gen/functions.cpp gen/tocall.cpp
diffstat 4 files changed, 17 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mtype.c	Wed Feb 04 16:02:05 2009 +0100
+++ b/dmd/mtype.c	Wed Feb 04 18:39:39 2009 +0100
@@ -2691,7 +2691,7 @@
     this->retInPtr = false;
     this->usesThis = false;
     this->usesNest = false;
-    this->structInregArg = false;
+    this->structInregArg = NULL;
     this->retAttrs = 0;
     this->thisAttrs = 0;
     this->reverseParams = false;
--- a/dmd/mtype.h	Wed Feb 04 16:02:05 2009 +0100
+++ b/dmd/mtype.h	Wed Feb 04 18:39:39 2009 +0100
@@ -23,6 +23,7 @@
 
 // llvm
 #include "../ir/irtype.h"
+namespace llvm { class Type; }
 
 struct Scope;
 struct Identifier;
@@ -438,7 +439,8 @@
     bool retInPtr;
     bool usesThis;
     bool usesNest;
-    bool structInregArg;
+    // when the last arg is a struct and passed in EAX, this holds its real type
+    const llvm::Type* structInregArg;
     unsigned retAttrs;
     unsigned thisAttrs; // also used for nest
     // parameter index in the llvm function that contains the first not-implicit arg
--- a/gen/functions.cpp	Wed Feb 04 16:02:05 2009 +0100
+++ b/gen/functions.cpp	Wed Feb 04 18:39:39 2009 +0100
@@ -220,15 +220,15 @@
                     arg->llvmAttrs |= llvm::Attribute::InReg;
                     assert((f->thisAttrs & llvm::Attribute::InReg) == 0 && "can't have two inreg args!");
 
-                    // structs need to go from {...}* byval to {...} inreg
+                    // structs need to go from {...}* byval to i8/i16/i32 inreg
                     if ((arg->storageClass & STCin) && t->ty == Tstruct)
                     {
                         int n_param = f->reverseParams ? f->firstRealArg + n - 1 - n_inreg : f->firstRealArg + n_inreg;
                         assert(isaPointer(paramvec[n_param]) && (arg->llvmAttrs & llvm::Attribute::ByVal)
                             && "struct parameter expected to be {...}* byval before inreg is applied");
-                        paramvec[n_param] = paramvec[n_param]->getContainedType(0);
+                        f->structInregArg = paramvec[n_param]->getContainedType(0);
+                        paramvec[n_param] = LLIntegerType::get(8*t->size());
                         arg->llvmAttrs &= ~llvm::Attribute::ByVal;
-                        f->structInregArg = true;
                     }
                 }
             }
@@ -763,11 +763,14 @@
             if (f->structInregArg && i == (f->reverseParams ? n - 1 : 0))
             {
                 int n_param = f->reverseParams ? f->firstRealArg + n - 1 - i : f->firstRealArg + i;
-                assert(!f->usesNest && !f->usesThis && isaStruct(functype->getParamType(n_param))
+                const LLType* paramty = functype->getParamType(n_param);
+                assert(!f->usesNest && !f->usesThis && 
+                    llvm::isa<LLIntegerType>(paramty) && isaStruct(f->structInregArg)
                     && "Preconditions for inreg struct arg not met!");
 
-                LLValue* mem = DtoAlloca(functype->getParamType(n_param), "inregstructarg");
-                DtoStore(irloc->value, mem);
+                LLValue* mem = DtoAlloca(f->structInregArg, "inregstructarg");
+                
+                DtoStore(irloc->value, DtoBitCast(mem, getPtrToType(paramty)));
                 irloc->value = mem;
             }
 
--- a/gen/tocall.cpp	Wed Feb 04 16:02:05 2009 +0100
+++ b/gen/tocall.cpp	Wed Feb 04 18:39:39 2009 +0100
@@ -373,15 +373,16 @@
             DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
             LLValue* arg = argval->getRVal();
 
+            int j = tf->reverseParams ? beg + n - i - 1 : beg + i;
+
             // if it's a struct inreg arg, load first to pass as first-class value
             if (tf->structInregArg && i == (tf->reverseParams ? n - 1 : 0))
             {
-                assert(fnarg->llvmAttrs & llvm::Attribute::InReg);
+                assert((fnarg->llvmAttrs & llvm::Attribute::InReg) && isaStruct(tf->structInregArg));
+                arg = DtoBitCast(arg, getPtrToType(callableTy->getParamType(j)));
                 arg = DtoLoad(arg);
             }
 
-            int j = tf->reverseParams ? beg + n - i - 1 : beg + i;
-
             // parameter type mismatch, this is hard to get rid of
             if (arg->getType() != callableTy->getParamType(j))
             {