Mercurial > projects > ldc
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},"; }