diff gen/functions.cpp @ 720:e177ae483f8e

Added inreg attribute where appropriate on x86 to follow ABI docs. Removed now unnecessary temporary variable in StringExp.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Thu, 23 Oct 2008 00:34:46 +0200
parents 7261ff0f95ff
children 55f6c2e454d7
line wrap: on
line diff
--- a/gen/functions.cpp	Wed Oct 22 21:50:08 2008 +0200
+++ b/gen/functions.cpp	Thu Oct 23 00:34:46 2008 +0200
@@ -171,6 +171,39 @@
     bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
     llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
 
+    // tell first param to be passed in a register if we can
+    // ONLY extern(D) functions !
+    if ((n > 0 || usesthis || usesnest) && f->linkage == LINKd)
+    {
+        // FIXME: Only x86 right now ...
+        if (global.params.cpu == ARCHx86)
+        {
+            // pass first param in EAX if it fits, is not floating point and is not a 3 byte struct.
+            // FIXME: struct are not passed in EAX yet
+
+            // if there is a implicit context parameter, pass it in EAX
+            if (usesthis || usesnest)
+            {
+                f->thisAttrs |= llvm::Attribute::InReg;
+            }
+            // otherwise check the first formal parameter
+            else
+            {
+                Argument* arg = Argument::getNth(f->parameters, 0);
+                Type* t = arg->type->toBasetype();
+
+                // 32bit ints, pointers, classes and static arrays are candidate for being passed in EAX
+                if ((arg->storageClass & STCin) &&
+                    ((t->isscalar() && !t->isfloating()) || t->ty == Tclass || t->ty == Tsarray) &&
+                    (t->size() <= PTRSIZE))
+                {
+                    arg->llvmAttrs |= llvm::Attribute::InReg;
+                }
+            }
+        }
+    }
+
+    // done
     f->retInPtr = retinptr;
     f->usesThis = usesthis;
     f->usesNest = usesnest;
@@ -350,6 +383,14 @@
         attrs.push_back(PAWI);
     }
 
+    // set this/nest param attrs
+    if (f->thisAttrs)
+    {
+        PAWI.Index = f->retInPtr ? 2 : 1;
+        PAWI.Attrs = f->thisAttrs;
+        attrs.push_back(PAWI);
+    }
+
     // set attrs on the rest of the arguments
     for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k)
     {