Mercurial > projects > ldc
changeset 1002:c749648ed2b8
Fix cfloat return on x86_64: only perform ABI transformation for non-extern(D)
functions.
There's no need to waste cycles with extern(D), which we get to define
ourselves. Fixes tests/mini/asm8.d. (Since the asm abiret code already assumed
{xmm0, xmm1} returns)
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 26 Feb 2009 23:35:39 +0100 |
parents | 7a0238db1962 |
children | de97188378bc |
files | gen/abi.cpp gen/naked.cpp tests/mini/asm8.d |
diffstat | 3 files changed, 66 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/abi.cpp Thu Feb 26 22:47:06 2009 +0100 +++ b/gen/abi.cpp Thu Feb 26 23:35:39 2009 +0100 @@ -180,7 +180,8 @@ // test if rewrite applies to function bool test(TypeFunction* tf) { - return (tf->next->toBasetype() == Type::tcomplex32); + return (tf->linkage != LINKd) + && (tf->next->toBasetype() == Type::tcomplex32); } };
--- a/gen/naked.cpp Thu Feb 26 22:47:06 2009 +0100 +++ b/gen/naked.cpp Thu Feb 26 23:35:39 2009 +0100 @@ -279,7 +279,7 @@ // For compatibility, use the GCC/LLVM-GCC way for extern(C/Windows) // extern(C) cfloat -> %xmm0 (extract two floats) as->out_c = "={xmm0},"; - asmblock->retty = LLStructType::get(LLType::DoubleTy, NULL);; + asmblock->retty = LLType::DoubleTy; asmblock->retfixup = &x86_64_cfloatRetFixup; } else if (rt->iscomplex()) { // cdouble and extern(D) cfloat -> re=%xmm0, im=%xmm1
--- a/tests/mini/asm8.d Thu Feb 26 22:47:06 2009 +0100 +++ b/tests/mini/asm8.d Thu Feb 26 23:35:39 2009 +0100 @@ -118,29 +118,31 @@ } else version (X86_64) { - version(all) { - asm - { - movss XMM0, [one_f]; - movss XMM1, [two_f]; - } - } else { - // Code for when LDC becomes ABI-compatible with GCC - // regarding cfloat returns. - asm { - movd EAX, [one_f]; - movd ECX, [two_f]; - - // invalid operand size :( - //shl RCX, 32; - //or RAX, RCX; - - pushq RAX; - mov [RSP + 4], EAX; - popq RAX; - - movd XMM0, RAX; - } + asm + { + movss XMM0, [one_f]; + movss XMM1, [two_f]; + } + } + else static assert(0, "todo"); +} + +extern(C) cfloat cf_C() +{ + version(X86) + { + asm { fld1; fld two_f; } + } + else version (X86_64) + { + asm { + mov EAX, [one_f]; + mov ECX, [two_f]; + + shl RCX, 32; + or RAX, RCX; + + movd XMM0, RAX; } } else static assert(0, "todo"); @@ -160,33 +162,41 @@ } else version (X86_64) { - version(all) { - asm - { - naked; - movss XMM0, [one_f]; - movss XMM1, [two_f]; - ret; - } - } else { - // Code for when LDC becomes ABI-compatible with GCC - // regarding cfloat returns. - asm { - naked; - mov EAX, [one_f]; - mov ECX, [two_f]; - - // invalid operand size :( - //shl RCX, 32; - //or RAX, RCX; - - pushq RAX; - mov [RSP + 4], EAX; - popq RAX; - - movd RAX, XMM0; - ret; - } + asm + { + naked; + movss XMM0, [one_f]; + movss XMM1, [two_f]; + ret; + } + } + else static assert(0, "todo"); +} + +extern(C) cfloat cf2_C() +{ + version(X86) + { + asm + { + naked; + fld1; + fld two_f; + ret; + } + } + else version (X86_64) + { + asm { + naked; + mov EAX, [one_f]; + mov ECX, [two_f]; + + shl RCX, 32; + or RAX, RCX; + + movd XMM0, RAX; + ret; } } else static assert(0, "todo"); @@ -369,6 +379,9 @@ assert(cf() == 1+2i); assert(cf2() == 1+2i); + assert(cf_C() == 1+2i); + assert(cf2_C() == 1+2i); + assert(cd() == 1+2i); assert(cd2() == 1+2i);