Mercurial > projects > ldc
diff gen/asmstmt.cpp @ 305:2b72433d5c8c trunk
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
Fixed problems with label collisions when using labels inside inline asm. LabelStatement is now easily reached given its
Identifier, which should be useful elsewhere too.
Enabled inline asm for building the lib/compiler/llvmdc runtime code, fixing branches out of asm makes this possible.
author | lindquist |
---|---|
date | Fri, 27 Jun 2008 22:04:35 +0200 |
parents | 3ebc136702dd |
children | d59c363fccad |
line wrap: on
line diff
--- a/gen/asmstmt.cpp Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/asmstmt.cpp Fri Jun 27 22:04:35 2008 +0200 @@ -461,16 +461,24 @@ // a post-asm switch // maps each special value to a goto destination - std::map<int, LabelDsymbol*> valToGoto; + std::map<int, Identifier*> valToGoto; // location of the value containing the index into the valToGoto map // will be set if post-asm dispatcher block is needed llvm::AllocaInst* jump_target; { + FuncDeclaration* fd = gIR->func()->decl; + char* fdmangle = fd->mangle(); + + // we use a simple static counter to make sure the new end labels are unique + static size_t uniqueLabelsId = 0; + std::ostringstream asmGotoEndLabel; + asmGotoEndLabel << "." << fdmangle << "__llvm_asm_end" << uniqueLabelsId++; + // initialize the setter statement we're going to build IRAsmStmt* outSetterStmt = new IRAsmStmt; - std::string asmGotoEnd = "jmp __llvm_asm_end ; "; + std::string asmGotoEnd = "jmp "+asmGotoEndLabel.str()+" ; "; std::ostringstream code; code << asmGotoEnd; @@ -490,7 +498,7 @@ end = asmblock->internalLabels.end(); bool skip = false; for(it = asmblock->internalLabels.begin(); it != end; ++it) - if((*it)->equals(a->isBranchToLabel->ident)) + if((*it)->equals(a->isBranchToLabel)) skip = true; if(skip) continue; @@ -499,11 +507,11 @@ valToGoto[n_goto] = a->isBranchToLabel; // provide an in-asm target for the branch and set value - Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->ident->string); - code << a->isBranchToLabel->ident->string << ": ; "; + Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string); + code << fdmangle << '_' << a->isBranchToLabel->string << ": ; "; code << "movl $<<in" << n_goto << ">>, $<<out0>> ; "; //FIXME: Store the value -> label mapping somewhere, so it can be referenced later - outSetterStmt->in.push_back(llvm::ConstantInt::get(llvm::IntegerType::get(32), n_goto)); + outSetterStmt->in.push_back(DtoConstUint(n_goto)); outSetterStmt->in_c += "i,"; code << asmGotoEnd; @@ -513,11 +521,11 @@ { // finalize code outSetterStmt->code = code.str(); - outSetterStmt->code += "__llvm_asm_end: ; "; + outSetterStmt->code += asmGotoEndLabel.str()+": ; "; // create storage for and initialize the temporary jump_target = new llvm::AllocaInst(llvm::IntegerType::get(32), "__llvm_jump_target", p->topallocapoint()); - gIR->ir->CreateStore(llvm::ConstantInt::get(llvm::IntegerType::get(32), 0), jump_target); + gIR->ir->CreateStore(DtoConstUint(0), jump_target); // setup variable for output from asm outSetterStmt->out_c = "=*m,"; outSetterStmt->out.push_back(jump_target); @@ -623,7 +631,7 @@ llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, valToGoto.size()); // add all cases - std::map<int, LabelDsymbol*>::iterator it, end = valToGoto.end(); + std::map<int, Identifier*>::iterator it, end = valToGoto.end(); for(it = valToGoto.begin(); it != end; ++it) { llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb);