changeset 526:642f6fa854e5

First step towards D abi compliance. Framepointer elimination is now disabled for functions using inline asm (with a hack from aKor).
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 19 Aug 2008 20:18:01 +0200
parents b18b6135e54b
children cecfee2d01a8
files gen/functions.cpp gen/tocall.cpp tests/mini/callingconv1.d
diffstat 3 files changed, 47 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/gen/functions.cpp	Sun Aug 17 13:16:35 2008 +0200
+++ b/gen/functions.cpp	Tue Aug 19 20:18:01 2008 +0200
@@ -592,6 +592,16 @@
         fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
         fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type), "function_vresult");
     }
+    
+    // this hack makes sure the frame pointer elimination optimization is disabled.
+    // this this eliminates a bunch of inline asm related issues.
+    // naked must always eliminate the framepointer however...
+    if (fd->inlineAsm && !fd->naked)
+    {
+        // emit a call to llvm_eh_unwind_init
+        LLFunction* hack = GET_INTRINSIC_DECL(eh_unwind_init);
+        gIR->ir->CreateCall(hack, "");
+    }
 
     // give the 'this' argument storage and debug info
     if (f->usesThis)
--- a/gen/tocall.cpp	Sun Aug 17 13:16:35 2008 +0200
+++ b/gen/tocall.cpp	Tue Aug 19 20:18:01 2008 +0200
@@ -37,7 +37,12 @@
     if (l == LINKc || l == LINKcpp)
         return llvm::CallingConv::C;
     else if (l == LINKd || l == LINKdefault)
-        return llvm::CallingConv::Fast;
+    {
+        if (global.params.cpu == ARCHx86)
+            return llvm::CallingConv::X86_StdCall;
+        else
+            return llvm::CallingConv::Fast;
+    }
     else if (l == LINKwindows)
         return llvm::CallingConv::X86_StdCall;
     else
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/callingconv1.d	Tue Aug 19 20:18:01 2008 +0200
@@ -0,0 +1,31 @@
+module mini.callingconv1;
+
+extern(C) int printf(char*, ...);
+
+float foo(float a, float b)
+{
+    return a + b;
+}
+
+void main()
+{
+    float a = 1.5;
+    float b = 2.5;
+    float c;
+
+    asm
+    {
+        mov EAX, [a];
+        push EAX;
+        mov EAX, [b];
+        push EAX;
+        call foo;
+        fstp c;
+    }
+
+    printf("%f\n", c);
+    
+    assert(c == 4.0);
+    
+    printf("passed\n", c);
+}