diff --git a/dmd/statement.c b/dmd/statement.c index 0117aeab..b7c08e1f 100644 --- a/dmd/statement.c +++ b/dmd/statement.c @@ -3605,7 +3605,7 @@ LabelDsymbol::LabelDsymbol(Identifier *ident) : Dsymbol(ident) { statement = NULL; - asmLabelNum = 0; + asmLabel = false; } LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()? diff --git a/dmd/statement.h b/dmd/statement.h index 6819c83b..4e231f4b 100644 --- a/dmd/statement.h +++ b/dmd/statement.h @@ -767,7 +767,7 @@ struct LabelDsymbol : Dsymbol { LabelStatement *statement; // LLVMDC - unsigned asmLabelNum; // for inline assembler labels + bool asmLabel; // for labels inside inline assembler LabelDsymbol(Identifier *ident); LabelDsymbol *isLabel(); diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index 0d3c075b..e6afd525 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -1,6 +1,5 @@ -// Taken from GDC source tree, licence unclear? -// -// Taken from an earlier version of DMD -- why is it missing from 0.79? +// Taken from GDC source tree. Original by David Friedman. +// Released under the Artistic License found in dmd/artistic.txt #include "gen/llvm.h" #include "llvm/InlineAsm.h" @@ -131,69 +130,6 @@ int AsmStatement::comeFrom() return FALSE; } -/* GCC does not support jumps from asm statements. When optimization - is turned on, labels referenced only from asm statements will not - be output at the correct location. There are ways around this: - - 1) Reference the label with a reachable goto statement - 2) Have reachable computed goto in the function - 3) Hack cfgbuild.c to act as though there is a computed goto. - - These are all pretty bad, but if would be nice to be able to tell - GCC not to optimize in this case (even on per label/block basis). - - The current solution is output our own private labels (as asm - statements) along with the "real" label. If the label happens to - be referred to by a goto statement, the "real" label will also be - output in the correct location. - - Also had to add 'asmLabelNum' to LabelDsymbol to indicate it needs - special processing. - - (junk) d-lang.cc:916:case LABEL_DECL: // C doesn't do this. D needs this for referencing labels in inline assembler since there may be not goto referencing it. - -*/ - -static unsigned d_priv_asm_label_serial = 0; - -// may need to make this target-specific -static void d_format_priv_asm_label(char * buf, unsigned n) -{ - //ASM_GENERATE_INTERNAL_LABEL(buf, "LDASM", n);//inserts a '*' for use with assemble_name - assert(0); - sprintf(buf, ".LDASM%u", n); -} - -void -d_expand_priv_asm_label(IRState * irs, unsigned n) -{ -/* char buf[64]; - d_format_priv_asm_label(buf, n); - strcat(buf, ":"); - tree insnt = build_string(strlen(buf), buf); -#if D_GCC_VER < 40 - expand_asm(insnt, 1); -#else - tree t = d_build_asm_stmt(insnt, NULL_TREE, NULL_TREE, NULL_TREE); - ASM_VOLATILE_P( t ) = 1; - ASM_INPUT_P( t) = 1; // what is this doing? - irs->addExp(t); -#endif*/ -} - - -// StringExp::toIR usually adds a NULL. We don't want that... - -/*static tree -naturalString(Expression * e) -{ - // don't fail, just an error? - assert(e->op == TOKstring); - StringExp * s = (StringExp *) e; - assert(s->sz == 1); - return build_string(s->len, (char *) s->string); -}*/ - #include "d-asm-i386.h" diff --git a/gen/d-asm-i386.h b/gen/d-asm-i386.h index 8aee7530..f17f9f3a 100644 --- a/gen/d-asm-i386.h +++ b/gen/d-asm-i386.h @@ -1,4 +1,5 @@ -// Taken from GDC source, GPL! +// Taken from GDC source tree. Original by David Friedman. +// Released under the Artistic License found in dmd/artistic.txt #include "dmd/id.h" @@ -1418,16 +1419,7 @@ struct AsmProcessor asmcode->args.push( new AsmArg(type, e, mode) ); } - void addLabel(unsigned n) { - // No longer taking the address of the actual label -- doesn't seem like it would help. - char buf[64]; - - d_format_priv_asm_label(buf, n); - insnTemplate->writestring(buf); - } - void addLabel(char* id) { - //insnTemplate->writestring(".LDASM_"); insnTemplate->writestring(id); } @@ -1906,15 +1898,10 @@ struct AsmProcessor the %an format must be used with the "p" constraint. */ if (isDollar(e)) { - unsigned lbl_num = ++d_priv_asm_label_serial; - addLabel(lbl_num); - asmcode->dollarLabel = lbl_num; // could make the dollar label part of the same asm.. + error("dollar labels are not supported", stmt->loc.toChars()); + asmcode->dollarLabel = 1; } 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; use_star = false; diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index f07c698f..9cd167f8 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -158,6 +158,10 @@ void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfi { assert(!gIR->scopereturned()); + // if the target label is inside inline asm, error + if(target->asmLabel) + error("cannot goto into inline asm block", loc->toChars()); + if (target->statement->llvmBB == NULL) target->statement->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); diff --git a/gen/statements.cpp b/gen/statements.cpp index bfeb2eb6..e0385d3e 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -1045,7 +1045,6 @@ void LabelStatement::toIR(IRState* p) if (p->asmBlock) { IRAsmStmt* a = new IRAsmStmt; -// a->code = ".LDASM_"; a->code += ident->toChars(); a->code += ":"; p->asmBlock->s.push_back(a);