comparison gen/asmstmt.cpp @ 312:553f844ae5b9 trunk

[svn r333] Fix inline asm bug with multiple branches to the same label.
author ChristianK
date Sun, 29 Jun 2008 22:07:15 +0200
parents d59c363fccad
children aaade6ded589
comparison
equal deleted inserted replaced
311:9967a3270837 312:553f844ae5b9
458 // build forwarder for in-asm branches to external labels 458 // build forwarder for in-asm branches to external labels
459 // this additional asm code sets the __llvm_jump_target variable 459 // this additional asm code sets the __llvm_jump_target variable
460 // to a unique value that will identify the jump target in 460 // to a unique value that will identify the jump target in
461 // a post-asm switch 461 // a post-asm switch
462 462
463 // maps each special value to a goto destination 463 // maps each goto destination to its special value
464 std::map<int, Identifier*> valToGoto; 464 std::map<Identifier*, int> gotoToVal;
465 465
466 // location of the value containing the index into the valToGoto map 466 // location of the special value determining the goto label
467 // will be set if post-asm dispatcher block is needed 467 // will be set if post-asm dispatcher block is needed
468 llvm::AllocaInst* jump_target; 468 llvm::AllocaInst* jump_target;
469 469
470 { 470 {
471 FuncDeclaration* fd = gIR->func()->decl; 471 FuncDeclaration* fd = gIR->func()->decl;
501 if((*it)->equals(a->isBranchToLabel)) 501 if((*it)->equals(a->isBranchToLabel))
502 skip = true; 502 skip = true;
503 if(skip) 503 if(skip)
504 continue; 504 continue;
505 505
506 // if we already set things up for this branch target, skip
507 if(gotoToVal.find(a->isBranchToLabel) != gotoToVal.end())
508 continue;
509
506 // record that the jump needs to be handled in the post-asm dispatcher 510 // record that the jump needs to be handled in the post-asm dispatcher
507 valToGoto[n_goto] = a->isBranchToLabel; 511 gotoToVal[a->isBranchToLabel] = n_goto;
508 512
509 // provide an in-asm target for the branch and set value 513 // provide an in-asm target for the branch and set value
510 Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string); 514 Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string);
511 code << fdmangle << '_' << a->isBranchToLabel->string << ": ; "; 515 code << fdmangle << '_' << a->isBranchToLabel->string << ": ; ";
512 code << "movl $<<in" << n_goto << ">>, $<<out0>> ; "; 516 code << "movl $<<in" << n_goto << ">>, $<<out0>> ; ";
617 621
618 p->asmBlock = NULL; 622 p->asmBlock = NULL;
619 Logger::println("END ASM"); 623 Logger::println("END ASM");
620 624
621 // if asm contained external branches, emit goto forwarder code 625 // if asm contained external branches, emit goto forwarder code
622 if(!valToGoto.empty()) 626 if(!gotoToVal.empty())
623 { 627 {
624 assert(jump_target); 628 assert(jump_target);
625 629
626 // make new blocks 630 // make new blocks
627 llvm::BasicBlock* oldend = gIR->scopeend(); 631 llvm::BasicBlock* oldend = gIR->scopeend();
628 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterasmgotoforwarder", p->topfunc(), oldend); 632 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterasmgotoforwarder", p->topfunc(), oldend);
629 633
630 llvm::LoadInst* val = p->ir->CreateLoad(jump_target, "__llvm_jump_target_value"); 634 llvm::LoadInst* val = p->ir->CreateLoad(jump_target, "__llvm_jump_target_value");
631 llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, valToGoto.size()); 635 llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size());
632 636
633 // add all cases 637 // add all cases
634 std::map<int, Identifier*>::iterator it, end = valToGoto.end(); 638 std::map<Identifier*, int>::iterator it, end = gotoToVal.end();
635 for(it = valToGoto.begin(); it != end; ++it) 639 for(it = gotoToVal.begin(); it != end; ++it)
636 { 640 {
637 llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb); 641 llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb);
638 sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->first), casebb); 642 sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->second), casebb);
639 643
640 p->scope() = IRScope(casebb,bb); 644 p->scope() = IRScope(casebb,bb);
641 DtoGoto(&loc, it->second, enclosinghandler); 645 DtoGoto(&loc, it->first, enclosinghandler);
642 } 646 }
643 647
644 p->scope() = IRScope(bb,oldend); 648 p->scope() = IRScope(bb,oldend);
645 } 649 }
646 } 650 }