From 03d26e11781518a2f7e38589907fce3dcbf433e0 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Fri, 27 Jun 2008 22:04:35 +0200 Subject: [PATCH] [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. --- dmd/constfold.c | 12 ++++---- dmd/declaration.c | 2 +- dmd/declaration.h | 7 +++++ dmd/dump.c | 2 +- dmd/expression.c | 29 ++++++++++---------- dmd/func.c | 2 +- dmd/init.c | 2 +- dmd/lexer.c | 4 +-- dmd/mangle.c | 4 +-- dmd/mars.h | 19 +++++++++++-- dmd/mtype.c | 16 +++++------ dmd/optimize.c | 8 ++++-- dmd/root.c | 3 +- dmd/statement.c | 6 +++- dmd/statement.h | 7 ++--- dmd/template.c | 4 +-- gen/asmstmt.cpp | 26 ++++++++++++------ gen/d-asm-i386.h | 4 ++- gen/irstate.h | 2 +- gen/llvmhelpers.cpp | 37 ++++++++++++++++++++----- gen/llvmhelpers.h | 4 ++- gen/statements.cpp | 11 ++++---- tango/lib/compiler/llvmdc/lifetime.d | 11 +++----- tango/lib/compiler/llvmdc/llvmdc.mak | 4 +-- tango/lib/gc/basic/gc.d | 3 +- tangotests/asm7.d | 41 ++++++++++++++++++++++++++++ test/{arrays.d => arrays15.d} | 0 27 files changed, 186 insertions(+), 84 deletions(-) create mode 100644 tangotests/asm7.d rename test/{arrays.d => arrays15.d} (100%) diff --git a/dmd/constfold.c b/dmd/constfold.c index f913337e..25c05d0a 100644 --- a/dmd/constfold.c +++ b/dmd/constfold.c @@ -1160,7 +1160,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) uinteger_t i = e2->toInteger(); if (i >= es1->len) - e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len); + e1->error("string index %llu is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len); else { unsigned value = es1->charAt(i); e = new IntegerExp(loc, value, type); @@ -1172,7 +1172,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) uinteger_t i = e2->toInteger(); if (i >= length) - { e2->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length); + { + e2->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length); } else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; @@ -1187,7 +1188,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; if (i >= ale->elements->dim) - { e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); + { + e2->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); } else { e = (Expression *)ale->elements->data[i]; @@ -1237,7 +1239,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) uinteger_t iupr = upr->toInteger(); if (iupr > es1->len || ilwr > iupr) - e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); + e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr); else { integer_t value; void *s; @@ -1264,7 +1266,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) uinteger_t iupr = upr->toInteger(); if (iupr > es1->elements->dim || ilwr > iupr) - e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); + e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr); else { Expressions *elements = new Expressions(); diff --git a/dmd/declaration.c b/dmd/declaration.c index ed49b291..482f45b7 100644 --- a/dmd/declaration.c +++ b/dmd/declaration.c @@ -675,7 +675,7 @@ void VarDeclaration::semantic(Scope *sc) { Argument *arg = Argument::getNth(tt->arguments, i); OutBuffer buf; - buf.printf("_%s_field_%zu", ident->toChars(), i); + buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i); buf.writeByte(0); char *name = (char *)buf.extractData(); Identifier *id = new Identifier(name, TOKidentifier); diff --git a/dmd/declaration.h b/dmd/declaration.h index 8b36061a..914e38d9 100644 --- a/dmd/declaration.h +++ b/dmd/declaration.h @@ -16,6 +16,7 @@ #endif /* __DMC__ */ #include +#include #include "dsymbol.h" #include "lexer.h" @@ -24,6 +25,7 @@ struct Expression; struct Statement; struct LabelDsymbol; +struct LabelStatement; struct Initializer; struct Module; struct InlineScanState; @@ -611,6 +613,11 @@ struct FuncDeclaration : Declaration // llvmdc stuff bool runTimeHack; std::set nestedVars; + + // we keep our own table of label statements as LabelDsymbolS + // don't always carry their corresponding statement along ... + typedef std::map LabelMap; + LabelMap labmap; }; struct FuncAliasDeclaration : FuncDeclaration diff --git a/dmd/dump.c b/dmd/dump.c index 1f6fecd1..8d521884 100644 --- a/dmd/dump.c +++ b/dmd/dump.c @@ -52,7 +52,7 @@ void Expression::dump(int i) void IntegerExp::dump(int i) { indent(i); - printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type)); + printf("%p %lld type=%s\n", this, (intmax_t)value, type_print(type)); } void IdentifierExp::dump(int i) diff --git a/dmd/expression.c b/dmd/expression.c index 7a73dca6..2a6f2b95 100644 --- a/dmd/expression.c +++ b/dmd/expression.c @@ -405,7 +405,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume size_t nparams = Argument::dim(tf->parameters); if (nargs > nparams && tf->varargs == 0) - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) @@ -429,7 +429,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume { if (tf->varargs == 2 && i + 1 == nparams) goto L2; - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); break; } arg = p->defaultArg->copy(); @@ -443,7 +443,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume if (arg->implicitConvTo(p->type)) { if (nargs != nparams) - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); goto L1; } L2: @@ -1050,8 +1050,7 @@ char *IntegerExp::toChars() return Expression::toChars(); #else static char buffer[sizeof(value) * 3 + 1]; - - sprintf(buffer, "%jd", value); + sprintf(buffer, "%lld", value); return buffer; #endif } @@ -1228,11 +1227,11 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) break; case Tint64: - buf->printf("%jdL", v); + buf->printf("%lldL", v); break; case Tuns64: - buf->printf("%juLU", v); + buf->printf("%lluLU", v); break; case Tbit: @@ -1254,17 +1253,17 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) } } else if (v & 0x8000000000000000LL) - buf->printf("0x%jx", v); + buf->printf("0x%llx", v); else - buf->printf("%jd", v); + buf->printf("%lld", v); } void IntegerExp::toMangleBuffer(OutBuffer *buf) { if ((sinteger_t)value < 0) - buf->printf("N%jd", -value); + buf->printf("N%lld", -value); else - buf->printf("%jd", value); + buf->printf("%lld", value); } /******************************** RealExp **************************/ @@ -6469,7 +6468,7 @@ Expression *SliceExp::semantic(Scope *sc) } else { - error("string slice [%ju .. %ju] is out of bounds", i1, i2); + error("string slice [%llu .. %llu] is out of bounds", i1, i2); e = e1; } return e; @@ -6828,9 +6827,9 @@ Expression *IndexExp::semantic(Scope *sc) } else { - error("array index [%ju] is outside array bounds [0 .. %zu]", - index, length); - e = e1; + error("array index [%llu] is outside array bounds [0 .. %"PRIuSIZE"]", + index, length); + e = e1; } break; } diff --git a/dmd/func.c b/dmd/func.c index 2d67ea6f..c098c439 100644 --- a/dmd/func.c +++ b/dmd/func.c @@ -767,7 +767,7 @@ void FuncDeclaration::semantic3(Scope *sc) * because we need it later on. */ OutBuffer buf; - buf.printf("_param_%zu", i); + buf.printf("_param_%"PRIuSIZE, i); char *name = (char *)buf.extractData(); id = new Identifier(name, TOKidentifier); arg->ident = id; diff --git a/dmd/init.c b/dmd/init.c index 47e99b7d..ccc85776 100644 --- a/dmd/init.c +++ b/dmd/init.c @@ -382,7 +382,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t) } unsigned long amax = 0x80000000; if ((unsigned long) dim * t->next->size() >= amax) - error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->next->size()); + error(loc, "array dimension %u exceeds max of %llu", dim, amax / t->next->size()); return this; } diff --git a/dmd/lexer.c b/dmd/lexer.c index b78d53a4..87e2ffde 100644 --- a/dmd/lexer.c +++ b/dmd/lexer.c @@ -137,11 +137,11 @@ char *Token::toChars() break; case TOKint64v: - sprintf(buffer,"%jdL",int64value); + sprintf(buffer,"%lldL",int64value); break; case TOKuns64v: - sprintf(buffer,"%juUL",uns64value); + sprintf(buffer,"%lluUL",uns64value); break; #if IN_GCC diff --git a/dmd/mangle.c b/dmd/mangle.c index 1e88fcee..5eead78e 100644 --- a/dmd/mangle.c +++ b/dmd/mangle.c @@ -213,7 +213,7 @@ char *TemplateInstance::mangle() p += 2; buf.writestring(p); } - buf.printf("%zu%s", strlen(id), id); + buf.printf("%"PRIuSIZE"%s", strlen(id), id); id = buf.toChars(); buf.data = NULL; //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id); @@ -241,7 +241,7 @@ char *Dsymbol::mangle() p += 2; buf.writestring(p); } - buf.printf("%zu%s", strlen(id), id); + buf.printf("%"PRIuSIZE"%s", strlen(id), id); id = buf.toChars(); buf.data = NULL; //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); diff --git a/dmd/mars.h b/dmd/mars.h index 4167a539..49875659 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -16,8 +16,10 @@ #endif /* __DMC__ */ #include -#include -#include +#include +#define __STDC_FORMAT_MACROS 1 +#include +#include #ifdef __DMC__ #ifdef DEBUG @@ -225,6 +227,19 @@ typedef long double real_t; #include "d-gcc-complex_t.h" #endif +// taken from GDC +// for handling printf incompatibilities +#if __MSVCRT__ +#define PRIuSIZE "Iu" +#define PRIxSIZE "Ix" +#elif __MINGW32__ +#define PRIuSIZE "u" +#define PRIxSIZE "x" +#else +#define PRIuSIZE "zu" +#define PRIxSIZE "zx" +#endif + struct Module; //typedef unsigned Loc; // file location diff --git a/dmd/mtype.c b/dmd/mtype.c index 743acca5..ffdb7598 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -1653,7 +1653,7 @@ d_uns64 TypeSArray::size(Loc loc) return sz; Loverflow: - error(loc, "index %jd overflow for static array", sz); + error(loc, "index %lld overflow for static array", sz); return 1; } @@ -1721,7 +1721,7 @@ void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol sc = sc->pop(); if (d >= td->objects->dim) - { error(loc, "tuple index %ju exceeds %u", d, td->objects->dim); + { error(loc, "tuple index %llu exceeds %u", d, td->objects->dim); goto Ldefault; } Object *o = (Object *)td->objects->data[(size_t)d]; @@ -1775,7 +1775,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) uinteger_t d = dim->toUInteger(); if (d >= sd->objects->dim) - { error(loc, "tuple index %ju exceeds %u", d, sd->objects->dim); + { error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim); return Type::terror; } Object *o = (Object *)sd->objects->data[(size_t)d]; @@ -1832,7 +1832,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) if (n && n2 / n != d2) { Loverflow: - error(loc, "index %jd overflow for static array", d1); + error(loc, "index %lld overflow for static array", d1); dim = new IntegerExp(0, 1, tsize_t); } } @@ -1846,7 +1846,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) uinteger_t d = dim->toUInteger(); if (d >= tt->arguments->dim) - { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); + { error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim); return Type::terror; } Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; @@ -1867,7 +1867,7 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf) { buf->writeByte(mangleChar[ty]); if (dim) - buf->printf("%ju", dim->toInteger()); + buf->printf("%llu", dim->toInteger()); if (next) next->toDecoBuffer(buf); } @@ -4965,7 +4965,7 @@ Type *TypeSlice::semantic(Loc loc, Scope *sc) uinteger_t i2 = upr->toUInteger(); if (!(i1 <= i2 && i2 <= tt->arguments->dim)) - { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim); + { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim); return Type::terror; } @@ -5010,7 +5010,7 @@ void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol sc = sc->pop(); if (!(i1 <= i2 && i2 <= td->objects->dim)) - { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim); + { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim); goto Ldefault; } diff --git a/dmd/optimize.c b/dmd/optimize.c index 8356e13c..57c6fff2 100644 --- a/dmd/optimize.c +++ b/dmd/optimize.c @@ -234,7 +234,7 @@ Expression *AddrExp::optimize(int result) TypeSArray *ts = (TypeSArray *)ve->type; integer_t dim = ts->dim->toInteger(); if (index < 0 || index >= dim) - error("array index %jd is out of bounds [0..%jd]", index, dim); + error("array index %lld is out of bounds [0..%lld]", index, dim); e = new SymOffExp(loc, ve->var, index * ts->next->size()); e->type = type; return e; @@ -380,7 +380,8 @@ Expression *BinExp::optimize(int result) integer_t i2 = e2->toInteger(); d_uns64 sz = e1->type->size() * 8; if (i2 < 0 || i2 > sz) - { error("shift assign by %jd is outside the range 0..%zu", i2, sz); + { + error("shift assign by %lld is outside the range 0..%"PRIuSIZE, i2, sz); e2 = new IntegerExp(0); } } @@ -475,7 +476,8 @@ Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, E integer_t i2 = e->e2->toInteger(); d_uns64 sz = e->e1->type->size() * 8; if (i2 < 0 || i2 > sz) - { error("shift by %jd is outside the range 0..%zu", i2, sz); + { + error("shift by %lld is outside the range 0..%"PRIuSIZE, i2, sz); e->e2 = new IntegerExp(0); } if (e->e1->isConst() == 1) diff --git a/dmd/root.c b/dmd/root.c index f7336e6e..d0b1b8c7 100644 --- a/dmd/root.c +++ b/dmd/root.c @@ -36,6 +36,7 @@ #include "root.h" #include "dchar.h" #include "mem.h" +#include "mars.h" #if 0 //__SC__ //def DEBUG extern "C" void __cdecl _assert(void *e, void *f, unsigned line) @@ -1325,7 +1326,7 @@ void File::stat() void File::checkoffset(size_t offset, size_t nbytes) { if (offset > len || offset + nbytes > len) - error("Corrupt file '%s': offset x%zx off end of file",toChars(),offset); + error("Corrupt file '%s': offset x%"PRIxSIZE" off end of file",toChars(),offset); } char *File::toChars() diff --git a/dmd/statement.c b/dmd/statement.c index b7c08e1f..d28f96eb 100644 --- a/dmd/statement.c +++ b/dmd/statement.c @@ -3519,6 +3519,7 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement) this->lblock = NULL; this->isReturnLabel = 0; this->llvmBB = NULL; + this->asmLabel = false; } Statement *LabelStatement::syntaxCopy() @@ -3546,6 +3547,10 @@ Statement *LabelStatement::semantic(Scope *sc) if (statement) statement = statement->semantic(sc); sc->pop(); + + // LLVMDC put in labmap + fd->labmap[ident->toChars()] = this; + return this; } @@ -3605,7 +3610,6 @@ LabelDsymbol::LabelDsymbol(Identifier *ident) : Dsymbol(ident) { statement = NULL; - asmLabel = false; } LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()? diff --git a/dmd/statement.h b/dmd/statement.h index 4e231f4b..a330adf2 100644 --- a/dmd/statement.h +++ b/dmd/statement.h @@ -761,13 +761,12 @@ struct LabelStatement : Statement // LLVMDC llvm::BasicBlock* llvmBB; + bool asmLabel; // for labels inside inline assembler }; struct LabelDsymbol : Dsymbol { LabelStatement *statement; -// LLVMDC - bool asmLabel; // for labels inside inline assembler LabelDsymbol(Identifier *ident); LabelDsymbol *isLabel(); @@ -793,8 +792,8 @@ struct AsmStatement : Statement void toIR(IRState *irs); // LLVMDC - // non-zero if this is a branch, contains the target - LabelDsymbol* isBranchToLabel; + // non-zero if this is a branch, contains the target labels identifier + Identifier* isBranchToLabel; }; struct AsmBlockStatement : CompoundStatement diff --git a/dmd/template.c b/dmd/template.c index 4138f94b..18800ec2 100644 --- a/dmd/template.c +++ b/dmd/template.c @@ -3444,7 +3444,7 @@ Identifier *TemplateInstance::genIdent() //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); id = tempdecl->ident->toChars(); - buf.printf("__T%zu%s", strlen(id), id); + buf.printf("__T%"PRIuSIZE"%s", strlen(id), id); args = tiargs; for (int i = 0; i < args->dim; i++) { Object *o = (Object *)args->data[i]; @@ -3511,7 +3511,7 @@ Identifier *TemplateInstance::genIdent() else { char *p = sa->mangle(); - buf.printf("%zu%s", strlen(p), p); + buf.printf("%"PRIuSIZE"%s", strlen(p), p); } } else if (va) diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index e6afd525..1f0c122f 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -461,16 +461,24 @@ void AsmBlockStatement::toIR(IRState* p) // a post-asm switch // maps each special value to a goto destination - std::map valToGoto; + std::map 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 @@ void AsmBlockStatement::toIR(IRState* p) 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 @@ void AsmBlockStatement::toIR(IRState* p) 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 $<>, $<> ; "; //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 @@ void AsmBlockStatement::toIR(IRState* p) { // 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 @@ void AsmBlockStatement::toIR(IRState* p) llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, valToGoto.size()); // add all cases - std::map::iterator it, end = valToGoto.end(); + std::map::iterator it, end = valToGoto.end(); for(it = valToGoto.begin(); it != end; ++it) { llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb); diff --git a/gen/d-asm-i386.h b/gen/d-asm-i386.h index f17f9f3a..4214021f 100644 --- a/gen/d-asm-i386.h +++ b/gen/d-asm-i386.h @@ -1420,6 +1420,8 @@ struct AsmProcessor } void addLabel(char* id) { + insnTemplate->writestring(sc->func->mangle()); + insnTemplate->writestring("_"); insnTemplate->writestring(id); } @@ -1902,7 +1904,7 @@ struct AsmProcessor asmcode->dollarLabel = 1; } else if (e->op == TOKdsymbol) { LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s; - stmt->isBranchToLabel = lbl; + stmt->isBranchToLabel = lbl->ident; use_star = false; addLabel(lbl->ident->toChars()); diff --git a/gen/irstate.h b/gen/irstate.h index 4a4dd29c..f4aa9024 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -74,7 +74,7 @@ struct IRAsmStmt std::vector in; // if this is nonzero, it contains the target label - LabelDsymbol* isBranchToLabel; + Identifier* isBranchToLabel; }; struct IRAsmBlock diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 9cd167f8..6c97e953 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -150,35 +150,58 @@ void DtoAssert(Loc* loc, DValue* msg) gIR->ir->CreateUnreachable(); } +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// LABEL HELPER +////////////////////////////////////////////////////////////////////////////////////////*/ +LabelStatement* DtoLabelStatement(Identifier* ident) +{ + FuncDeclaration* fd = gIR->func()->decl; + FuncDeclaration::LabelMap::iterator iter = fd->labmap.find(ident->toChars()); + if (iter == fd->labmap.end()) + { + if (fd->returnLabel->ident->equals(ident)) + { + assert(fd->returnLabel->statement); + return fd->returnLabel->statement; + } + return NULL; + } + return iter->second; +} + /****************************************************************************************/ /*//////////////////////////////////////////////////////////////////////////////////////// // GOTO HELPER ////////////////////////////////////////////////////////////////////////////////////////*/ -void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfinally) +void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally) { assert(!gIR->scopereturned()); + LabelStatement* lblstmt = DtoLabelStatement(target); + assert(lblstmt != NULL); + // if the target label is inside inline asm, error - if(target->asmLabel) + if(lblstmt->asmLabel) error("cannot goto into inline asm block", loc->toChars()); - if (target->statement->llvmBB == NULL) - target->statement->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); + if (lblstmt->llvmBB == NULL) + lblstmt->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); // find finallys between goto and label TryFinallyStatement* endfinally = enclosingtryfinally; - while(endfinally != NULL && endfinally != target->statement->enclosingtryfinally) { + while(endfinally != NULL && endfinally != lblstmt->enclosingtryfinally) { endfinally = endfinally->enclosingtryfinally; } // error if didn't find tf statement of label - if(endfinally != target->statement->enclosingtryfinally) + if(endfinally != lblstmt->enclosingtryfinally) error("cannot goto into try block", loc->toChars()); // emit code for finallys between goto and label DtoFinallyBlocks(enclosingtryfinally, endfinally); - llvm::BranchInst::Create(target->statement->llvmBB, gIR->scopebb()); + llvm::BranchInst::Create(lblstmt->llvmBB, gIR->scopebb()); } /****************************************************************************************/ diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 66fe3173..c86065d0 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -13,8 +13,10 @@ void DtoDeleteArray(DValue* arr); // assertion generator void DtoAssert(Loc* loc, DValue* msg); +// return the LabelStatement from the current function with the given identifier or NULL if not found +LabelStatement* DtoLabelStatement(Identifier* ident); // emit goto -void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfinally); +void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally); // generates IR for finally blocks between the 'start' and 'end' statements // will begin with the finally block belonging to 'start' and does not include diff --git a/gen/statements.cpp b/gen/statements.cpp index e0385d3e..e74e61f5 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -1045,6 +1045,8 @@ void LabelStatement::toIR(IRState* p) if (p->asmBlock) { IRAsmStmt* a = new IRAsmStmt; + a->code += p->func()->decl->mangle(); + a->code += "_"; a->code += ident->toChars(); a->code += ":"; p->asmBlock->s.push_back(a); @@ -1052,18 +1054,17 @@ void LabelStatement::toIR(IRState* p) } else { - assert(tf == NULL); - + llvm::BasicBlock* oldend = gIR->scopeend(); if (llvmBB) llvmBB->moveBefore(oldend); else llvmBB = llvm::BasicBlock::Create("label", p->topfunc(), oldend); - + if (!p->scopereturned()) llvm::BranchInst::Create(llvmBB, p->scopebb()); - + p->scope() = IRScope(llvmBB,oldend); } @@ -1086,7 +1087,7 @@ void GotoStatement::toIR(IRState* p) llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); - DtoGoto(&loc, label, enclosingtryfinally); + DtoGoto(&loc, label->ident, enclosingtryfinally); p->scope() = IRScope(bb,oldend); } diff --git a/tango/lib/compiler/llvmdc/lifetime.d b/tango/lib/compiler/llvmdc/lifetime.d index 21f6e596..46a786ab 100644 --- a/tango/lib/compiler/llvmdc/lifetime.d +++ b/tango/lib/compiler/llvmdc/lifetime.d @@ -29,9 +29,6 @@ module lifetime; //debug=PRINTF; //debug=PRINTF2; -// we're not allowed to jump out of asm blocks -//version(D_InlineAsm_X86) version = Asm86; - private { import tango.stdc.stdlib; @@ -213,7 +210,7 @@ extern (C) void* _d_newarrayT(TypeInfo ti, size_t length) if (length == 0 || size == 0) return null; - version (Asm86) + version (D_InlineAsm_X86) { asm { @@ -252,7 +249,7 @@ extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length) auto initializer = ti.next.init(); auto isize = initializer.length; auto q = initializer.ptr; - version (Asm86) + version (D_InlineAsm_X86) { asm { @@ -515,7 +512,7 @@ body if (newlength) { - version (Asm86) + version (D_InlineAsm_X86) { size_t newsize = void; @@ -614,7 +611,7 @@ body if (newlength) { - version (Asm86) + version (D_InlineAsm_X86) { size_t newsize = void; diff --git a/tango/lib/compiler/llvmdc/llvmdc.mak b/tango/lib/compiler/llvmdc/llvmdc.mak index db6a8f21..9aea4749 100644 --- a/tango/lib/compiler/llvmdc/llvmdc.mak +++ b/tango/lib/compiler/llvmdc/llvmdc.mak @@ -24,10 +24,10 @@ MD=mkdir -p CFLAGS=-g $(ADD_CFLAGS) #DFLAGS=-release -O3 -inline -w $(ADD_DFLAGS) -DFLAGS=-g -w -noasm $(ADD_DFLAGS) +DFLAGS=-g -w $(ADD_DFLAGS) #TFLAGS=-O3 -inline -w $(ADD_DFLAGS) -TFLAGS=-g -w -noasm $(ADD_DFLAGS) +TFLAGS=-g -w $(ADD_DFLAGS) DOCFLAGS=-version=DDoc diff --git a/tango/lib/gc/basic/gc.d b/tango/lib/gc/basic/gc.d index a303908f..64040bb1 100644 --- a/tango/lib/gc/basic/gc.d +++ b/tango/lib/gc/basic/gc.d @@ -70,8 +70,7 @@ extern (C) void gc_term() // NOTE: Due to popular demand, this has been re-enabled. It still has // the problems mentioned above though, so I guess we'll see. - // FIXME: LLVMDC crashes ... - //_gc.fullCollectNoStack(); // not really a 'collect all' -- still scans + _gc.fullCollectNoStack(); // not really a 'collect all' -- still scans // static data area, roots, and ranges. _gc.Dtor(); } diff --git a/tangotests/asm7.d b/tangotests/asm7.d new file mode 100644 index 00000000..9ea56339 --- /dev/null +++ b/tangotests/asm7.d @@ -0,0 +1,41 @@ +module tangotests.asm7; + +// test massive label collisions (runtime uses Loverflow too) + +void main() +{ + int a = add(1,2); + int s = sub(1,2); + assert(a == 3); + assert(s == -1); +} + +int add(int a, int b) +{ + int res; + asm + { + mov EAX, a; + add EAX, b; + jo Loverflow; + mov res, EAX; + } + return res; +Loverflow: + assert(0, "add overflow"); +} + +int sub(int a, int b) +{ + int res; + asm + { + mov EAX, a; + sub EAX, b; + jo Loverflow; + mov res, EAX; + } + return res; +Loverflow: + assert(0, "sub overflow"); +} diff --git a/test/arrays.d b/test/arrays15.d similarity index 100% rename from test/arrays.d rename to test/arrays15.d