diff 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
line wrap: on
line diff
--- a/gen/statements.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/statements.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -25,6 +25,7 @@
 #include "gen/arrays.h"
 #include "gen/todebug.h"
 #include "gen/dvalue.h"
+#include "gen/abi.h"
 
 #include "ir/irfunction.h"
 #include "ir/irmodule.h"
@@ -54,38 +55,47 @@
     Logger::println("ReturnStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    // is there a return value expression?
     if (exp)
     {
-        if (p->topfunc()->getReturnType() == LLType::VoidTy) {
+        // if the functions return type is void this means that
+        // we are returning through a pointer argument
+        if (p->topfunc()->getReturnType() == LLType::VoidTy)
+        {
+            // sanity check
             IrFunction* f = p->func();
             assert(f->type->retInPtr);
             assert(f->decl->ir.irFunc->retArg);
 
+            // emit dbg line
             if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
 
+            // get return pointer
             DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg);
-
             DValue* e = exp->toElem(p);
-
+            // store return value
             DtoAssign(loc, rvar, e);
 
+            // emit scopes
             DtoEnclosingHandlers(enclosinghandler, NULL);
 
+            // emit dbg end function
             if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
+
+            // emit ret
             llvm::ReturnInst::Create(p->scopebb());
 
         }
-        else {
+        // the return type is not void, so this is a normal "register" return
+        else
+        {
             if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
             DValue* e = exp->toElem(p);
             LLValue* v = e->getRVal();
             delete e;
 
-            // swap real/imag parts on a x87
-            if (global.params.cpu == ARCHx86 && exp->type->toBasetype()->iscomplex())
-            {
-                v = DtoAggrPairSwap(v);
-            }
+            // do abi specific transformations on the return value
+            v = gABI->putRet(p->func()->type, v);
 
             if (Logger::enabled())
                 Logger::cout() << "return value is '" <<*v << "'\n";
@@ -113,6 +123,7 @@
             llvm::ReturnInst::Create(v, p->scopebb());
         }
     }
+    // no return value expression means it's a void function
     else
     {
         assert(p->topfunc()->getReturnType() == LLType::VoidTy);