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