To follow D ABI, swap real and imaginary parts of a complex return value on X86_64

TODO: should we disable this transformation for ldc1 in order to keep its ABI unchanged?
This commit is contained in:
Alexey Prokhin
2011-02-26 13:04:09 +03:00
parent d01f63431d
commit 20e6c65200
3 changed files with 28 additions and 20 deletions

View File

@@ -36,4 +36,23 @@ struct RemoveStructPadding : ABIRewrite {
}
};
//////////////////////////////////////////////////////////////////////////////
// simply swap of real/imag parts for proper x87 complex abi
struct X87_complex_swap : ABIRewrite
{
LLValue* get(Type*, DValue* v)
{
return DtoAggrPairSwap(v->getRVal());
}
LLValue* put(Type*, DValue* v)
{
return DtoAggrPairSwap(v->getRVal());
}
const LLType* type(Type*, const LLType* t)
{
return t;
}
};
#endif

View File

@@ -497,6 +497,7 @@ struct RegCount {
struct X86_64TargetABI : TargetABI {
X86_64_C_struct_rewrite struct_rewrite;
X87_complex_swap swapComplex;
RemoveStructPadding remove_padding;
void newFunctionType(TypeFunction* tf) {
@@ -676,15 +677,22 @@ void X86_64TargetABI::fixup(IrFuncTyArg& arg) {
void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
IrFuncTy& fty = tf->fty;
Type* rt = fty.ret->type->toBasetype();
if (tf->linkage == LINKd) {
if (!fty.arg_sret) {
Type* rt = fty.ret->type->toBasetype();
if (rt->ty == Tstruct && !fty.ret->byref) {
Logger::println("x86-64 D ABI: Transforming return type");
fixup_D(*fty.ret);
}
}
// complex {re,im} -> {im,re}
if (rt->iscomplex())
{
Logger::println("Rewriting complex return value");
fty.ret->rewrite = &swapComplex;
}
#if DMDV1
if (fty.arg_this) {

View File

@@ -29,25 +29,6 @@ void ABIRewrite::getL(Type* dty, DValue* v, llvm::Value* lval)
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// simply swap of real/imag parts for proper x87 complex abi
struct X87_complex_swap : ABIRewrite
{
LLValue* get(Type*, DValue* v)
{
return DtoAggrPairSwap(v->getRVal());
}
LLValue* put(Type*, DValue* v)
{
return DtoAggrPairSwap(v->getRVal());
}
const LLType* type(Type*, const LLType* t)
{
return t;
}
};
//////////////////////////////////////////////////////////////////////////////
struct X86_cfloat_rewrite : ABIRewrite
{
// i64 -> {float,float}