Mercurial > projects > ldc
changeset 299:df8a7b8d5929 trunk
[svn r320] Begun work on branches out of asm blocks. Unfinished.
author | ChristianK |
---|---|
date | Tue, 24 Jun 2008 21:38:23 +0200 |
parents | 3b8ada4c9f8b |
children | 7b1040c76dd2 |
files | dmd/statement.h gen/asmstmt.cpp gen/d-asm-i386.h gen/irstate.h gen/statements.cpp |
diffstat | 5 files changed, 68 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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; i<n; ++i) + { + IRAsmStmt* a = asmblock->s[i]; + + // skip non-branch statements + if(!a->isBranchToLabel) + continue; + + // if internal, no special handling is necessary, skip + std::vector<Identifier*>::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<LLValue*> outargs; std::vector<LLValue*> 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; i<n; ++i) { IRAsmStmt* a = asmblock->s[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 +}
--- 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
--- 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<LLValue*> out; std::vector<LLValue*> in; + + // if this is nonzero, it contains the target ident + Identifier* isBranchToLabel; }; struct IRAsmBlock { std::vector<IRAsmStmt*> s; std::set<std::string> clobs; + + // stores the labels within the asm block + std::vector<Identifier*> internalLabels; }; // represents the module
--- 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 {