diff gen/naked.cpp @ 1018:e8c6dbcd33d1

- Fixed x86-32 C ABI for complex number return values. - Removed unused code from the ABI class.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 01 Mar 2009 19:01:05 +0100
parents c749648ed2b8
children 80490f65d4e1
line wrap: on
line diff
--- a/gen/naked.cpp	Sun Mar 01 11:04:05 2009 +0100
+++ b/gen/naked.cpp	Sun Mar 01 19:01:05 2009 +0100
@@ -175,6 +175,13 @@
     return b->CreateInsertValue(undef, orig, 0, "asm.ret");
 }
 
+static LLValue* x86_cfloatRetFixup(IRBuilderHelper b, LLValue* orig) {
+    assert(orig->getType() == LLType::DoubleTy);
+    LLType* retty = LLStructType::get(LLType::DoubleTy, NULL);
+    LLValue* undef = llvm::UndefValue::get(retty);
+    return b->CreateInsertValue(undef, orig, 0, "asm.ret");
+}
+
 void emitABIReturnAsmStmt(IRAsmBlock* asmblock, Loc loc, FuncDeclaration* fdecl)
 {
     Logger::println("emitABIReturnAsmStmt(%s)", fdecl->mangle());
@@ -204,8 +211,19 @@
         else if (rt->isfloating())
         {
             if (rt->iscomplex()) {
-                as->out_c = "={st},={st(1)},";
-                asmblock->retn = 2;
+                if (fdecl->linkage == LINKd) {
+                    // extern(D) always returns on the FPU stack
+                    as->out_c = "={st},={st(1)},";
+                    asmblock->retn = 2;
+                } else if (rt->ty == Tcomplex32) {
+                    // extern(C) cfloat is return as i64
+                    as->out_c = "=A,";
+                    asmblock->retty = LLType::Int64Ty;
+                } else {
+                    // cdouble and creal extern(C) are returned in pointer
+                    // don't add anything!
+                    return;
+                }
             } else {
                 as->out_c = "={st},";
             }