Mercurial > projects > ldc
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); +}