From 20e6c6520011ffd50ca851b537e84ab7fd995f4d Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sat, 26 Feb 2011 13:04:09 +0300 Subject: [PATCH] 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? --- gen/abi-generic.h | 19 +++++++++++++++++++ gen/abi-x86-64.cpp | 10 +++++++++- gen/abi.cpp | 19 ------------------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/gen/abi-generic.h b/gen/abi-generic.h index a3ffa4a8..83a883c4 100644 --- a/gen/abi-generic.h +++ b/gen/abi-generic.h @@ -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 diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index e1ed8614..0839679b 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -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) { diff --git a/gen/abi.cpp b/gen/abi.cpp index ab0af4c9..50c3dd01 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -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}