# HG changeset patch # User ChristianK # Date 1214336303 -7200 # Node ID df8a7b8d59295e877be0faa4ae6a36f97385ab65 # Parent 3b8ada4c9f8b51a551f3303531a640101dab0dc7 [svn r320] Begun work on branches out of asm blocks. Unfinished. diff -r 3b8ada4c9f8b -r df8a7b8d5929 dmd/statement.h --- a/dmd/statement.h Tue Jun 24 17:24:55 2008 +0200 +++ b/dmd/statement.h Tue Jun 24 21:38:23 2008 +0200 @@ -791,6 +791,10 @@ virtual AsmStatement *isAsmStatement() { return this; } void toIR(IRState *irs); + + // LLVMDC + // non-zero if this is a branch, contains the target + Identifier* isBranchToLabel; }; struct AsmBlockStatement : CompoundStatement diff -r 3b8ada4c9f8b -r df8a7b8d5929 gen/asmstmt.cpp --- a/gen/asmstmt.cpp Tue Jun 24 17:24:55 2008 +0200 +++ b/gen/asmstmt.cpp Tue Jun 24 21:38:23 2008 +0200 @@ -78,6 +78,8 @@ refparam = 0; naked = 0; regs = 0; + + isBranchToLabel = NULL; } Statement *AsmStatement::syntaxCopy() @@ -433,6 +435,7 @@ asmStmt->in_c = llvmInConstraints; asmStmt->out.insert(asmStmt->out.begin(), output_values.begin(), output_values.end()); asmStmt->in.insert(asmStmt->in.begin(), input_values.begin(), input_values.end()); + asmStmt->isBranchToLabel = isBranchToLabel; asmblock->s.push_back(asmStmt); } @@ -508,6 +511,51 @@ } } + // build forwarder for in-asm branches to external labels + // this additional asm code sets the __llvm_jump_target variable + // to a unique value that will identify the jump target in + // a post-asm switch + //FIXME: Need to init __llvm_jump_target + //FIXME: Store the value -> label mapping somewhere, so it can be referenced later + std::string asmGotoEnd = "jmp __llvm_asm_end ; "; + std::string outGotoSetter = asmGotoEnd; + + size_t n = asmblock->s.size(); + for(size_t i=0; is[i]; + + // skip non-branch statements + if(!a->isBranchToLabel) + continue; + + // if internal, no special handling is necessary, skip + std::vector::const_iterator it, end; + end = asmblock->internalLabels.end(); + bool skip = false; + for(it = asmblock->internalLabels.begin(); it != end; ++it) + if((*it)->equals(a->isBranchToLabel)) + skip = true; + if(skip) + continue; + + // 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->string); + outGotoSetter += a->isBranchToLabel->string; + outGotoSetter += ": ; "; + outGotoSetter += "nop ; "; //FIXME: Change this to set __llvm_jump_target to a unique value + outGotoSetter += asmGotoEnd; + } + if(outGotoSetter != asmGotoEnd) + { + outGotoSetter += "__llvm_asm_end: ; "; + IRAsmStmt* outSetterStmt = new IRAsmStmt; + outSetterStmt->code = outGotoSetter; + //FIXME: set other stuff + asmblock->s.push_back(outSetterStmt); + } + + // build asm block std::vector outargs; std::vector inargs; @@ -519,7 +567,7 @@ std::string code; size_t asmIdx = 0; - size_t n = asmblock->s.size(); + n = asmblock->s.size(); for (size_t i=0; is[i]; @@ -588,6 +636,8 @@ p->asmBlock = NULL; Logger::println("END ASM"); + + //FIXME: Emit goto forwarder code here } // the whole idea of this statement is to avoid the flattening @@ -609,4 +659,4 @@ } AsmBlockStatement *cs = new AsmBlockStatement(loc, a); return cs; -} \ No newline at end of file +} diff -r 3b8ada4c9f8b -r df8a7b8d5929 gen/d-asm-i386.h --- a/gen/d-asm-i386.h Tue Jun 24 17:24:55 2008 +0200 +++ b/gen/d-asm-i386.h Tue Jun 24 21:38:23 2008 +0200 @@ -1427,7 +1427,7 @@ } void addLabel(char* id) { - insnTemplate->writestring(".LDASM_"); + //insnTemplate->writestring(".LDASM_"); insnTemplate->writestring(id); } @@ -1911,9 +1911,12 @@ asmcode->dollarLabel = lbl_num; // could make the dollar label part of the same asm.. } else if (e->op == TOKdsymbol) { LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s; + // this can probably be removed if (! lbl->asmLabelNum) lbl->asmLabelNum = ++d_priv_asm_label_serial; + stmt->isBranchToLabel = lbl->ident; + use_star = false; addLabel(lbl->ident->toChars()); } else if ((decl && decl->isCodeseg())) { // if function or label diff -r 3b8ada4c9f8b -r df8a7b8d5929 gen/irstate.h --- a/gen/irstate.h Tue Jun 24 17:24:55 2008 +0200 +++ b/gen/irstate.h Tue Jun 24 21:38:23 2008 +0200 @@ -72,12 +72,18 @@ std::string in_c; std::vector out; std::vector in; + + // if this is nonzero, it contains the target ident + Identifier* isBranchToLabel; }; struct IRAsmBlock { std::vector s; std::set clobs; + + // stores the labels within the asm block + std::vector internalLabels; }; // represents the module diff -r 3b8ada4c9f8b -r df8a7b8d5929 gen/statements.cpp --- a/gen/statements.cpp Tue Jun 24 17:24:55 2008 +0200 +++ b/gen/statements.cpp Tue Jun 24 21:38:23 2008 +0200 @@ -1066,10 +1066,11 @@ if (p->asmBlock) { IRAsmStmt* a = new IRAsmStmt; - a->code = ".LDASM_"; +// a->code = ".LDASM_"; a->code += ident->toChars(); a->code += ":"; p->asmBlock->s.push_back(a); + p->asmBlock->internalLabels.push_back(ident); } else {