diff gen/naked.cpp @ 1152:521dd1626d76

Added initial support for raw LLVM inline asm.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Sat, 28 Mar 2009 06:32:06 +0100
parents dbe4af57b240
children 4454126b4345
line wrap: on
line diff
--- a/gen/naked.cpp	Sat Mar 28 05:00:43 2009 +0100
+++ b/gen/naked.cpp	Sat Mar 28 06:32:06 2009 +0100
@@ -1,8 +1,10 @@
 #include "gen/llvm.h"
+#include "llvm/InlineAsm.h"
 
 #include "expression.h"
 #include "statement.h"
 #include "declaration.h"
+#include "template.h"
 
 #include <cassert>
 
@@ -10,6 +12,7 @@
 #include "gen/irstate.h"
 #include "gen/llvmhelpers.h"
 #include "gen/tollvm.h"
+#include "gen/dvalue.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
@@ -320,3 +323,78 @@
     // return values always go in the front
     asmblock->s.push_front(as);
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+// sort of kinda related to naked ...
+
+DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments)
+{
+    Logger::println("DtoInlineAsmExpr @ %s", loc.toChars());
+    LOG_SCOPE;
+
+    TemplateInstance* ti = fd->toParent()->isTemplateInstance();
+    assert(ti && "invalid inline __asm expr");
+
+    assert(arguments->dim >= 2 && "invalid __asm call");
+
+    // get code param
+    Expression* e = (Expression*)arguments->data[0];
+    Logger::println("code exp: %s", e->toChars());
+    StringExp* se = (StringExp*)e;
+    if (e->op != TOKstring || se->sz != 1)
+    {
+        e->error("__asm code argument is not a char[] string literal");
+        fatal();
+    }
+    std::string code((char*)se->string, se->len);
+
+    // get constraints param
+    e = (Expression*)arguments->data[1];
+    Logger::println("constraint exp: %s", e->toChars());
+    se = (StringExp*)e;
+    if (e->op != TOKstring || se->sz != 1)
+    {
+        e->error("__asm constraints argument is not a char[] string literal");
+        fatal();
+    }
+    std::string constraints((char*)se->string, se->len);
+
+    // build runtime arguments
+    size_t n = arguments->dim;
+
+    LLSmallVector<llvm::Value*, 8> args;
+    args.reserve(n-2);
+    std::vector<const llvm::Type*> argtypes;
+    argtypes.reserve(n-2);
+
+    for (size_t i = 2; i < n; i++)
+    {
+        e = (Expression*)arguments->data[i];
+        args.push_back(e->toElem(gIR)->getRVal());
+        argtypes.push_back(args.back()->getType());
+    }
+
+    // build asm function type
+    llvm::FunctionType* FT = llvm::FunctionType::get(llvm::Type::VoidTy, argtypes, false);
+
+    // build asm call
+    bool sideeffect = true;
+    llvm::InlineAsm* ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect);
+
+    llvm::Value* v = gIR->ir->CreateCall(ia, args.begin(), args.end(), "");
+
+    // return NULL for now
+    return NULL;
+}
+
+
+
+
+
+
+
+
+
+
+