Mercurial > projects > ldc
comparison 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 |
comparison
equal
deleted
inserted
replaced
1151:3cf0066e6faf | 1152:521dd1626d76 |
---|---|
1 #include "gen/llvm.h" | 1 #include "gen/llvm.h" |
2 #include "llvm/InlineAsm.h" | |
2 | 3 |
3 #include "expression.h" | 4 #include "expression.h" |
4 #include "statement.h" | 5 #include "statement.h" |
5 #include "declaration.h" | 6 #include "declaration.h" |
7 #include "template.h" | |
6 | 8 |
7 #include <cassert> | 9 #include <cassert> |
8 | 10 |
9 #include "gen/logger.h" | 11 #include "gen/logger.h" |
10 #include "gen/irstate.h" | 12 #include "gen/irstate.h" |
11 #include "gen/llvmhelpers.h" | 13 #include "gen/llvmhelpers.h" |
12 #include "gen/tollvm.h" | 14 #include "gen/tollvm.h" |
15 #include "gen/dvalue.h" | |
13 | 16 |
14 ////////////////////////////////////////////////////////////////////////////////////////// | 17 ////////////////////////////////////////////////////////////////////////////////////////// |
15 | 18 |
16 void Statement::toNakedIR(IRState *p) | 19 void Statement::toNakedIR(IRState *p) |
17 { | 20 { |
318 } | 321 } |
319 | 322 |
320 // return values always go in the front | 323 // return values always go in the front |
321 asmblock->s.push_front(as); | 324 asmblock->s.push_front(as); |
322 } | 325 } |
326 | |
327 ////////////////////////////////////////////////////////////////////////////////////////// | |
328 | |
329 // sort of kinda related to naked ... | |
330 | |
331 DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments) | |
332 { | |
333 Logger::println("DtoInlineAsmExpr @ %s", loc.toChars()); | |
334 LOG_SCOPE; | |
335 | |
336 TemplateInstance* ti = fd->toParent()->isTemplateInstance(); | |
337 assert(ti && "invalid inline __asm expr"); | |
338 | |
339 assert(arguments->dim >= 2 && "invalid __asm call"); | |
340 | |
341 // get code param | |
342 Expression* e = (Expression*)arguments->data[0]; | |
343 Logger::println("code exp: %s", e->toChars()); | |
344 StringExp* se = (StringExp*)e; | |
345 if (e->op != TOKstring || se->sz != 1) | |
346 { | |
347 e->error("__asm code argument is not a char[] string literal"); | |
348 fatal(); | |
349 } | |
350 std::string code((char*)se->string, se->len); | |
351 | |
352 // get constraints param | |
353 e = (Expression*)arguments->data[1]; | |
354 Logger::println("constraint exp: %s", e->toChars()); | |
355 se = (StringExp*)e; | |
356 if (e->op != TOKstring || se->sz != 1) | |
357 { | |
358 e->error("__asm constraints argument is not a char[] string literal"); | |
359 fatal(); | |
360 } | |
361 std::string constraints((char*)se->string, se->len); | |
362 | |
363 // build runtime arguments | |
364 size_t n = arguments->dim; | |
365 | |
366 LLSmallVector<llvm::Value*, 8> args; | |
367 args.reserve(n-2); | |
368 std::vector<const llvm::Type*> argtypes; | |
369 argtypes.reserve(n-2); | |
370 | |
371 for (size_t i = 2; i < n; i++) | |
372 { | |
373 e = (Expression*)arguments->data[i]; | |
374 args.push_back(e->toElem(gIR)->getRVal()); | |
375 argtypes.push_back(args.back()->getType()); | |
376 } | |
377 | |
378 // build asm function type | |
379 llvm::FunctionType* FT = llvm::FunctionType::get(llvm::Type::VoidTy, argtypes, false); | |
380 | |
381 // build asm call | |
382 bool sideeffect = true; | |
383 llvm::InlineAsm* ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect); | |
384 | |
385 llvm::Value* v = gIR->ir->CreateCall(ia, args.begin(), args.end(), ""); | |
386 | |
387 // return NULL for now | |
388 return NULL; | |
389 } | |
390 | |
391 | |
392 | |
393 | |
394 | |
395 | |
396 | |
397 | |
398 | |
399 | |
400 |