Mercurial > projects > ldc
comparison gen/statements.cpp @ 988:2667e3a145be
- Fixed LLVM style CL args for D2.
- Moved main() into its own file gen/main.cpp
- Fixed basic cross compilation
- removed the option for setting OS
- added support for llc's mattr, mcpu and mtriple switches
- added basic ABI abstraction for return value rewrites, it's not perfect and will probably be completely rewritten once I get to handling parameter rewrites as well.
- x86-64 extern(C) abi for cfloat returns now match (llvm-)gcc.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Thu, 26 Feb 2009 14:11:49 +0100 |
parents | ae710cba0884 |
children | 18ad5601dff7 |
comparison
equal
deleted
inserted
replaced
987:73ff89728d85 | 988:2667e3a145be |
---|---|
23 #include "gen/llvmhelpers.h" | 23 #include "gen/llvmhelpers.h" |
24 #include "gen/runtime.h" | 24 #include "gen/runtime.h" |
25 #include "gen/arrays.h" | 25 #include "gen/arrays.h" |
26 #include "gen/todebug.h" | 26 #include "gen/todebug.h" |
27 #include "gen/dvalue.h" | 27 #include "gen/dvalue.h" |
28 #include "gen/abi.h" | |
28 | 29 |
29 #include "ir/irfunction.h" | 30 #include "ir/irfunction.h" |
30 #include "ir/irmodule.h" | 31 #include "ir/irmodule.h" |
31 #include "ir/irlandingpad.h" | 32 #include "ir/irlandingpad.h" |
32 | 33 |
52 void ReturnStatement::toIR(IRState* p) | 53 void ReturnStatement::toIR(IRState* p) |
53 { | 54 { |
54 Logger::println("ReturnStatement::toIR(): %s", loc.toChars()); | 55 Logger::println("ReturnStatement::toIR(): %s", loc.toChars()); |
55 LOG_SCOPE; | 56 LOG_SCOPE; |
56 | 57 |
58 // is there a return value expression? | |
57 if (exp) | 59 if (exp) |
58 { | 60 { |
59 if (p->topfunc()->getReturnType() == LLType::VoidTy) { | 61 // if the functions return type is void this means that |
62 // we are returning through a pointer argument | |
63 if (p->topfunc()->getReturnType() == LLType::VoidTy) | |
64 { | |
65 // sanity check | |
60 IrFunction* f = p->func(); | 66 IrFunction* f = p->func(); |
61 assert(f->type->retInPtr); | 67 assert(f->type->retInPtr); |
62 assert(f->decl->ir.irFunc->retArg); | 68 assert(f->decl->ir.irFunc->retArg); |
63 | 69 |
70 // emit dbg line | |
64 if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); | 71 if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); |
65 | 72 |
73 // get return pointer | |
66 DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg); | 74 DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg); |
67 | |
68 DValue* e = exp->toElem(p); | 75 DValue* e = exp->toElem(p); |
69 | 76 // store return value |
70 DtoAssign(loc, rvar, e); | 77 DtoAssign(loc, rvar, e); |
71 | 78 |
79 // emit scopes | |
72 DtoEnclosingHandlers(enclosinghandler, NULL); | 80 DtoEnclosingHandlers(enclosinghandler, NULL); |
73 | 81 |
82 // emit dbg end function | |
74 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); | 83 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); |
84 | |
85 // emit ret | |
75 llvm::ReturnInst::Create(p->scopebb()); | 86 llvm::ReturnInst::Create(p->scopebb()); |
76 | 87 |
77 } | 88 } |
78 else { | 89 // the return type is not void, so this is a normal "register" return |
90 else | |
91 { | |
79 if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); | 92 if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); |
80 DValue* e = exp->toElem(p); | 93 DValue* e = exp->toElem(p); |
81 LLValue* v = e->getRVal(); | 94 LLValue* v = e->getRVal(); |
82 delete e; | 95 delete e; |
83 | 96 |
84 // swap real/imag parts on a x87 | 97 // do abi specific transformations on the return value |
85 if (global.params.cpu == ARCHx86 && exp->type->toBasetype()->iscomplex()) | 98 v = gABI->putRet(p->func()->type, v); |
86 { | |
87 v = DtoAggrPairSwap(v); | |
88 } | |
89 | 99 |
90 if (Logger::enabled()) | 100 if (Logger::enabled()) |
91 Logger::cout() << "return value is '" <<*v << "'\n"; | 101 Logger::cout() << "return value is '" <<*v << "'\n"; |
92 | 102 |
93 // can happen for classes and void main | 103 // can happen for classes and void main |
111 | 121 |
112 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); | 122 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); |
113 llvm::ReturnInst::Create(v, p->scopebb()); | 123 llvm::ReturnInst::Create(v, p->scopebb()); |
114 } | 124 } |
115 } | 125 } |
126 // no return value expression means it's a void function | |
116 else | 127 else |
117 { | 128 { |
118 assert(p->topfunc()->getReturnType() == LLType::VoidTy); | 129 assert(p->topfunc()->getReturnType() == LLType::VoidTy); |
119 DtoEnclosingHandlers(enclosinghandler, NULL); | 130 DtoEnclosingHandlers(enclosinghandler, NULL); |
120 | 131 |