# HG changeset patch # User Frits van Bommel # Date 1235687739 -3600 # Node ID c749648ed2b898f025475bb6e7ed82e8ce8486c4 # Parent 7a0238db1962f8a1cb70ea8da4d5e41e46778784 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) diff -r 7a0238db1962 -r c749648ed2b8 gen/abi.cpp --- 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); } }; diff -r 7a0238db1962 -r c749648ed2b8 gen/naked.cpp --- 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 diff -r 7a0238db1962 -r c749648ed2b8 tests/mini/asm8.d --- 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);