changeset 1446:fe151804995a

Improve ABI conformance on x86 by passing the `sret` parameter in EAX if there's no `this`.
author Frits van Bommel <fvbommel wxs.nl>
date Sun, 31 May 2009 12:43:59 +0200
parents 1dc1232aa91a
children a400b1dd657f
files gen/abi.cpp gen/tocall.cpp
diffstat 2 files changed, 11 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/gen/abi.cpp	Sun May 31 17:11:51 2009 +0200
+++ b/gen/abi.cpp	Sun May 31 12:43:59 2009 +0200
@@ -196,8 +196,16 @@
                 Logger::println("Putting context ptr in register");
                 fty.arg_nest->attrs = llvm::Attribute::InReg;
             }
+            else if (IrFuncTyArg* sret = fty.arg_sret)
+            {
+                Logger::println("Putting sret ptr in register");
+                // sret and inreg are incompatible, but the ABI requires the
+                // sret parameter to be in EAX in this situation...
+                sret->attrs = (sret->attrs | llvm::Attribute::InReg)
+                                & ~llvm::Attribute::StructRet;
+            }
             // otherwise try to mark the last param inreg
-            else if (!fty.arg_sret && !fty.args.empty())
+            else if (!fty.args.empty())
             {
                 // The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met:
                 //   * It fits in EAX.
--- a/gen/tocall.cpp	Sun May 31 17:11:51 2009 +0200
+++ b/gen/tocall.cpp	Sun May 31 12:43:59 2009 +0200
@@ -322,7 +322,8 @@
         // add attrs for hidden ptr
         Attr.Index = 1;
         Attr.Attrs = tf->fty.arg_sret->attrs;
-        assert((Attr.Attrs & llvm::Attribute::StructRet) && "Sret arg not sret?");
+        assert((Attr.Attrs & (llvm::Attribute::StructRet | llvm::Attribute::InReg))
+            && "Sret arg not sret or inreg?");
         attrs.push_back(Attr);
     }