[svn r320] Begun work on branches out of asm blocks. Unfinished.

This commit is contained in:
Christian Kamm
2008-06-24 21:38:23 +02:00
parent f621a5a77b
commit 84dd282b8c
5 changed files with 68 additions and 4 deletions

View File

@@ -791,6 +791,10 @@ struct AsmStatement : Statement
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

View File

@@ -78,6 +78,8 @@ AsmStatement::AsmStatement(Loc loc, Token *tokens) :
refparam = 0;
naked = 0;
regs = 0;
isBranchToLabel = NULL;
}
Statement *AsmStatement::syntaxCopy()
@@ -433,6 +435,7 @@ assert(0);
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 @@ void AsmBlockStatement::toIR(IRState* p)
}
}
// 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 @@ void AsmBlockStatement::toIR(IRState* p)
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 @@ void AsmBlockStatement::toIR(IRState* p)
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 @@ Statement *AsmBlockStatement::syntaxCopy()
}
AsmBlockStatement *cs = new AsmBlockStatement(loc, a);
return cs;
}
}

View File

@@ -1427,7 +1427,7 @@ struct AsmProcessor
}
void addLabel(char* id) {
insnTemplate->writestring(".LDASM_");
//insnTemplate->writestring(".LDASM_");
insnTemplate->writestring(id);
}
@@ -1911,9 +1911,12 @@ struct AsmProcessor
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

View File

@@ -72,12 +72,18 @@ struct IRAsmStmt
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

View File

@@ -1066,10 +1066,11 @@ void LabelStatement::toIR(IRState* p)
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
{