Mercurial > projects > ldc
comparison gen/asmstmt.cpp @ 229:cac3d27ae481 trunk
[svn r245] initial support for labels in inline asm, broken :/
author | lindquist |
---|---|
date | Sat, 07 Jun 2008 21:31:38 +0200 |
parents | 3092a38dddab |
children | 61aa721a6b7f |
comparison
equal
deleted
inserted
replaced
228:52d1e9d27dc6 | 229:cac3d27ae481 |
---|---|
66 clobbersMemory = 0; | 66 clobbersMemory = 0; |
67 } | 67 } |
68 }; | 68 }; |
69 | 69 |
70 llvm::InlineAsm* | 70 llvm::InlineAsm* |
71 d_build_asm_stmt(std::string code, std::deque<DValue*> const& output_values, std::deque<DValue*> const& input_values, std::string constraints) | 71 d_build_asm_stmt(std::string const& code, |
72 std::deque<LLValue*> const& output_values, | |
73 std::deque<LLValue*> const& input_values, | |
74 std::string const& constraints) | |
72 { | 75 { |
73 std::vector<const LLType*> params; | 76 std::vector<const LLType*> params; |
74 | 77 |
75 // outputs | 78 // outputs |
76 const LLType* ret = LLType::VoidTy; | 79 const LLType* ret = LLType::VoidTy; |
77 if (!output_values.empty()) | 80 if (!output_values.empty()) |
78 { | 81 { |
79 assert(output_values.size() == 1); | 82 assert(output_values.size() == 1); |
80 const LLType* llty = DtoType(output_values[0]->getType()); | 83 const LLType* llty = output_values[0]->getType(); |
81 std::cout << "out: " << *llty << '\n'; | 84 std::cout << "out: " << *llty << '\n'; |
82 params.push_back(llty); | 85 params.push_back(llty); |
83 } | 86 } |
84 | 87 |
85 // inputs | 88 // inputs |
86 if (!input_values.empty()) | 89 if (!input_values.empty()) |
87 { | 90 { |
88 assert(input_values.size() == 1); | 91 assert(input_values.size() == 1); |
89 const LLType* llty = DtoType(input_values[0]->getType()); | 92 const LLType* llty = input_values[0]->getType(); |
90 std::cout << "in: " << *llty << '\n'; | 93 std::cout << "in: " << *llty << '\n'; |
91 params.push_back(llty); | 94 params.push_back(llty); |
92 } | 95 } |
93 | 96 |
94 llvm::FunctionType* asmfnty = llvm::FunctionType::get(ret, params, false); | 97 llvm::FunctionType* asmfnty = llvm::FunctionType::get(ret, params, false); |
254 if (! asmcode) | 257 if (! asmcode) |
255 return; | 258 return; |
256 | 259 |
257 static std::string i_cns = "i"; | 260 static std::string i_cns = "i"; |
258 static std::string p_cns = "m"; | 261 static std::string p_cns = "m"; |
262 static std::string l_cns = "X"; | |
259 static std::string m_cns = "*m"; | 263 static std::string m_cns = "*m"; |
260 static std::string mw_cns = "=*m"; | 264 static std::string mw_cns = "=*m"; |
261 static std::string mrw_cns = "+*m"; | 265 static std::string mrw_cns = "+*m"; |
262 static std::string memory_name = "memory"; | 266 static std::string memory_name = "memory"; |
263 | 267 |
264 AsmCode * code = (AsmCode *) asmcode; | 268 AsmCode * code = (AsmCode *) asmcode; |
265 std::deque<DValue*> input_values; | 269 std::deque<LLValue*> input_values; |
266 std::deque<std::string> input_constraints; | 270 std::deque<std::string> input_constraints; |
267 std::deque<DValue*> output_values; | 271 std::deque<LLValue*> output_values; |
268 std::deque<std::string> output_constraints; | 272 std::deque<std::string> output_constraints; |
269 std::deque<std::string> clobbers; | 273 std::deque<std::string> clobbers; |
270 | 274 |
271 // FIXME | 275 // FIXME |
272 #define HOST_WIDE_INT long | 276 #define HOST_WIDE_INT long |
280 | 284 |
281 for (unsigned i = 0; i < code->args.dim; i++) { | 285 for (unsigned i = 0; i < code->args.dim; i++) { |
282 AsmArg * arg = (AsmArg *) code->args.data[i]; | 286 AsmArg * arg = (AsmArg *) code->args.data[i]; |
283 | 287 |
284 bool is_input = true; | 288 bool is_input = true; |
285 DValue* arg_val = 0; | 289 LLValue* arg_val = 0; |
286 std::string cns; | 290 std::string cns; |
287 | 291 |
288 std::cout << std::endl; | 292 std::cout << std::endl; |
289 | 293 |
290 switch (arg->type) { | 294 switch (arg->type) { |
291 case Arg_Integer: | 295 case Arg_Integer: |
292 arg_val = arg->expr->toElem(irs); | 296 arg_val = arg->expr->toElem(irs)->getRVal(); |
293 do_integer: | 297 do_integer: |
294 cns = i_cns; | 298 cns = i_cns; |
295 break; | 299 break; |
296 case Arg_Pointer: | 300 case Arg_Pointer: |
297 // FIXME | 301 // FIXME |
298 std::cout << "asm fixme Arg_Pointer" << std::endl; | 302 std::cout << "asm fixme Arg_Pointer" << std::endl; |
299 arg_val = arg->expr->toElem(irs); | 303 if (arg->expr->op == TOKdsymbol) |
300 arg_val = new DVarValue(arg_val->getType()->pointerTo(), arg_val->getRVal(), true); | 304 { |
305 DsymbolExp* dse = (DsymbolExp*)arg->expr; | |
306 LabelDsymbol* lbl = dse->s->isLabel(); | |
307 assert(lbl); | |
308 arg_val = lbl->statement->llvmBB; | |
309 if (!arg_val) | |
310 { | |
311 arg_val = lbl->statement->llvmBB = llvm::BasicBlock::Create("label", irs->topfunc()); | |
312 } | |
313 cns = l_cns; | |
314 } | |
315 else | |
316 { | |
317 arg_val = arg->expr->toElem(irs)->getRVal(); | |
318 cns = p_cns; | |
319 } | |
301 /*if (arg->expr->op == TOKvar) | 320 /*if (arg->expr->op == TOKvar) |
302 arg_val = arg->expr->toElem(irs); | 321 arg_val = arg->expr->toElem(irs); |
303 else if (arg->expr->op == TOKdsymbol) | 322 else if (arg->expr->op == TOKdsymbol) |
304 arg_val = arg->expr->toElem(irs); | 323 arg_val = arg->expr->toElem(irs); |
305 else | 324 else |
306 assert(0);*/ | 325 assert(0);*/ |
307 | 326 |
308 cns = p_cns; | |
309 break; | 327 break; |
310 case Arg_Memory: | 328 case Arg_Memory: |
311 // FIXME | 329 // FIXME |
312 std::cout << "asm fixme Arg_Memory" << std::endl; | 330 std::cout << "asm fixme Arg_Memory" << std::endl; |
313 if (arg->expr->op == TOKvar) | 331 arg_val = arg->expr->toElem(irs)->getRVal(); |
314 arg_val = arg->expr->toElem(irs); | 332 // if (arg->expr->op == TOKvar) |
315 else | 333 // arg_val = arg->expr->toElem(irs); |
316 arg_val = arg->expr->toElem(irs); | 334 // else |
335 // arg_val = arg->expr->toElem(irs); | |
317 | 336 |
318 switch (arg->mode) { | 337 switch (arg->mode) { |
319 case Mode_Input: cns = m_cns; break; | 338 case Mode_Input: cns = m_cns; break; |
320 case Mode_Output: cns = mw_cns; is_input = false; break; | 339 case Mode_Output: cns = mw_cns; is_input = false; break; |
321 case Mode_Update: cns = mrw_cns; is_input = false; break; | 340 case Mode_Update: cns = mrw_cns; is_input = false; break; |
323 } | 342 } |
324 break; | 343 break; |
325 case Arg_FrameRelative: | 344 case Arg_FrameRelative: |
326 // FIXME | 345 // FIXME |
327 std::cout << "asm fixme Arg_FrameRelative" << std::endl; | 346 std::cout << "asm fixme Arg_FrameRelative" << std::endl; |
347 assert(0); | |
328 /* if (arg->expr->op == TOKvar) | 348 /* if (arg->expr->op == TOKvar) |
329 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; | 349 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; |
330 else | 350 else |
331 assert(0);*/ | 351 assert(0);*/ |
332 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { | 352 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { |
340 clobbers_mem = true; | 360 clobbers_mem = true; |
341 break; | 361 break; |
342 case Arg_LocalSize: | 362 case Arg_LocalSize: |
343 // FIXME | 363 // FIXME |
344 std::cout << "asm fixme Arg_LocalSize" << std::endl; | 364 std::cout << "asm fixme Arg_LocalSize" << std::endl; |
365 assert(0); | |
345 /* var_frame_offset = cfun->x_frame_offset; | 366 /* var_frame_offset = cfun->x_frame_offset; |
346 if (var_frame_offset < 0) | 367 if (var_frame_offset < 0) |
347 var_frame_offset = - var_frame_offset; | 368 var_frame_offset = - var_frame_offset; |
348 arg_val = irs->integerConstant( var_frame_offset );*/ | 369 arg_val = irs->integerConstant( var_frame_offset );*/ |
349 goto do_integer; | 370 goto do_integer; |
458 LLSmallVector<LLValue*, 2> callargs; | 479 LLSmallVector<LLValue*, 2> callargs; |
459 | 480 |
460 size_t cn = output_values.size(); | 481 size_t cn = output_values.size(); |
461 for (size_t i=0; i<cn; ++i) | 482 for (size_t i=0; i<cn; ++i) |
462 { | 483 { |
463 LLValue* val = output_values[i]->getRVal(); | 484 callargs.push_back(output_values[i]); |
464 callargs.push_back(val); | |
465 } | 485 } |
466 | 486 |
467 cn = input_values.size(); | 487 cn = input_values.size(); |
468 for (size_t i=0; i<cn; ++i) | 488 for (size_t i=0; i<cn; ++i) |
469 { | 489 { |
470 // FIXME: these should not be allowed to intermix with asm calls. they should somehow | 490 callargs.push_back(input_values[i]); |
471 // be outputted before any asm from a block, or the asm's should be moved after ... | |
472 LLValue* val = input_values[i]->getRVal(); | |
473 callargs.push_back(val); | |
474 } | 491 } |
475 | 492 |
476 llvm::CallInst* call = irs->ir->CreateCall(t, callargs.begin(), callargs.end(), ""); | 493 llvm::CallInst* call = irs->ir->CreateCall(t, callargs.begin(), callargs.end(), ""); |
477 | 494 } |
478 /* | |
479 // FIXME | |
480 //ASM_VOLATILE_P( t ) = 1; | |
481 //irs->addExp( t ); | |
482 if (code->dollarLabel) | |
483 d_expand_priv_asm_label(irs, code->dollarLabel); | |
484 */ | |
485 } |