From 2fe8f2cd7441a7c8be4ef112453a5b7ed8388e02 Mon Sep 17 00:00:00 2001 From: Frits van Bommel Date: Sun, 31 May 2009 12:43:59 +0200 Subject: [PATCH] Improve ABI conformance on x86 by passing the `sret` parameter in EAX if there's no `this`. --- gen/abi.cpp | 10 +++++++++- gen/tocall.cpp | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gen/abi.cpp b/gen/abi.cpp index 4551c1ce..130e49f1 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -196,8 +196,16 @@ struct X86TargetABI : TargetABI 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. diff --git a/gen/tocall.cpp b/gen/tocall.cpp index fea5e91a..62b373d8 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -322,7 +322,8 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* // 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); }