Improve ABI conformance on x86 by passing the sret parameter in EAX if there's

no `this`.
This commit is contained in:
Frits van Bommel
2009-05-31 12:43:59 +02:00
parent 1e9ad13b12
commit 2fe8f2cd74
2 changed files with 11 additions and 2 deletions

View File

@@ -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.

View File

@@ -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);
}