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 }