# HG changeset patch # User lindquist # Date 1214597075 -7200 # Node ID 2b72433d5c8ca0fdb5f8d4ead60b845ea2885497 # Parent 3ebc136702ddd7c5b4d610cf28efb7715cc50dca [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. diff -r 3ebc136702dd -r 2b72433d5c8c dmd/constfold.c --- a/dmd/constfold.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/constfold.c Fri Jun 27 22:04:35 2008 +0200 @@ -1160,7 +1160,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/declaration.c --- a/dmd/declaration.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/declaration.c Fri Jun 27 22:04:35 2008 +0200 @@ -675,7 +675,7 @@ { 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/declaration.h --- a/dmd/declaration.h Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/declaration.h Fri Jun 27 22:04:35 2008 +0200 @@ -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 @@ // 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/dump.c --- a/dmd/dump.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/dump.c Fri Jun 27 22:04:35 2008 +0200 @@ -52,7 +52,7 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/expression.c --- a/dmd/expression.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/expression.c Fri Jun 27 22:04:35 2008 +0200 @@ -405,7 +405,7 @@ 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ } } 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 @@ } 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 @@ } 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/func.c --- a/dmd/func.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/func.c Fri Jun 27 22:04:35 2008 +0200 @@ -767,7 +767,7 @@ * 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/init.c --- a/dmd/init.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/init.c Fri Jun 27 22:04:35 2008 +0200 @@ -382,7 +382,7 @@ } 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/lexer.c --- a/dmd/lexer.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/lexer.c Fri Jun 27 22:04:35 2008 +0200 @@ -137,11 +137,11 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/mangle.c --- a/dmd/mangle.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/mangle.c Fri Jun 27 22:04:35 2008 +0200 @@ -213,7 +213,7 @@ 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/mars.h --- a/dmd/mars.h Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/mars.h Fri Jun 27 22:04:35 2008 +0200 @@ -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 @@ #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 -r 3ebc136702dd -r 2b72433d5c8c dmd/mtype.c --- a/dmd/mtype.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/mtype.c Fri Jun 27 22:04:35 2008 +0200 @@ -1653,7 +1653,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/optimize.c --- a/dmd/optimize.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/optimize.c Fri Jun 27 22:04:35 2008 +0200 @@ -234,7 +234,7 @@ 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 @@ 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/root.c --- a/dmd/root.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/root.c Fri Jun 27 22:04:35 2008 +0200 @@ -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::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 -r 3ebc136702dd -r 2b72433d5c8c dmd/statement.c --- a/dmd/statement.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/statement.c Fri Jun 27 22:04:35 2008 +0200 @@ -3519,6 +3519,7 @@ this->lblock = NULL; this->isReturnLabel = 0; this->llvmBB = NULL; + this->asmLabel = false; } Statement *LabelStatement::syntaxCopy() @@ -3546,6 +3547,10 @@ if (statement) statement = statement->semantic(sc); sc->pop(); + + // LLVMDC put in labmap + fd->labmap[ident->toChars()] = this; + return this; } @@ -3605,7 +3610,6 @@ : Dsymbol(ident) { statement = NULL; - asmLabel = false; } LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()? diff -r 3ebc136702dd -r 2b72433d5c8c dmd/statement.h --- a/dmd/statement.h Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/statement.h Fri Jun 27 22:04:35 2008 +0200 @@ -761,13 +761,12 @@ // 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c dmd/template.c --- a/dmd/template.c Wed Jun 25 23:42:38 2008 +0200 +++ b/dmd/template.c Fri Jun 27 22:04:35 2008 +0200 @@ -3444,7 +3444,7 @@ //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 @@ else { char *p = sa->mangle(); - buf.printf("%zu%s", strlen(p), p); + buf.printf("%"PRIuSIZE"%s", strlen(p), p); } } else if (va) diff -r 3ebc136702dd -r 2b72433d5c8c gen/asmstmt.cpp --- a/gen/asmstmt.cpp Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/asmstmt.cpp Fri Jun 27 22:04:35 2008 +0200 @@ -461,16 +461,24 @@ // 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 @@ 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 @@ 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 @@ { // 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c gen/d-asm-i386.h --- a/gen/d-asm-i386.h Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/d-asm-i386.h Fri Jun 27 22:04:35 2008 +0200 @@ -1420,6 +1420,8 @@ } void addLabel(char* id) { + insnTemplate->writestring(sc->func->mangle()); + insnTemplate->writestring("_"); insnTemplate->writestring(id); } @@ -1902,7 +1904,7 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c gen/irstate.h --- a/gen/irstate.h Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/irstate.h Fri Jun 27 22:04:35 2008 +0200 @@ -74,7 +74,7 @@ std::vector in; // if this is nonzero, it contains the target label - LabelDsymbol* isBranchToLabel; + Identifier* isBranchToLabel; }; struct IRAsmBlock diff -r 3ebc136702dd -r 2b72433d5c8c gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/llvmhelpers.cpp Fri Jun 27 22:04:35 2008 +0200 @@ -152,33 +152,56 @@ /****************************************************************************************/ /*//////////////////////////////////////////////////////////////////////////////////////// +// 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 -r 3ebc136702dd -r 2b72433d5c8c gen/llvmhelpers.h --- a/gen/llvmhelpers.h Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/llvmhelpers.h Fri Jun 27 22:04:35 2008 +0200 @@ -13,8 +13,10 @@ // 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 -r 3ebc136702dd -r 2b72433d5c8c gen/statements.cpp --- a/gen/statements.cpp Wed Jun 25 23:42:38 2008 +0200 +++ b/gen/statements.cpp Fri Jun 27 22:04:35 2008 +0200 @@ -1045,6 +1045,8 @@ 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 @@ } 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 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c tango/lib/compiler/llvmdc/lifetime.d --- a/tango/lib/compiler/llvmdc/lifetime.d Wed Jun 25 23:42:38 2008 +0200 +++ b/tango/lib/compiler/llvmdc/lifetime.d Fri Jun 27 22:04:35 2008 +0200 @@ -29,9 +29,6 @@ //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 @@ if (length == 0 || size == 0) return null; - version (Asm86) + version (D_InlineAsm_X86) { asm { @@ -252,7 +249,7 @@ auto initializer = ti.next.init(); auto isize = initializer.length; auto q = initializer.ptr; - version (Asm86) + version (D_InlineAsm_X86) { asm { @@ -515,7 +512,7 @@ if (newlength) { - version (Asm86) + version (D_InlineAsm_X86) { size_t newsize = void; @@ -614,7 +611,7 @@ if (newlength) { - version (Asm86) + version (D_InlineAsm_X86) { size_t newsize = void; diff -r 3ebc136702dd -r 2b72433d5c8c tango/lib/compiler/llvmdc/llvmdc.mak --- a/tango/lib/compiler/llvmdc/llvmdc.mak Wed Jun 25 23:42:38 2008 +0200 +++ b/tango/lib/compiler/llvmdc/llvmdc.mak Fri Jun 27 22:04:35 2008 +0200 @@ -24,10 +24,10 @@ 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 -r 3ebc136702dd -r 2b72433d5c8c tango/lib/gc/basic/gc.d --- a/tango/lib/gc/basic/gc.d Wed Jun 25 23:42:38 2008 +0200 +++ b/tango/lib/gc/basic/gc.d Fri Jun 27 22:04:35 2008 +0200 @@ -70,8 +70,7 @@ // 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 -r 3ebc136702dd -r 2b72433d5c8c tangotests/asm7.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tangotests/asm7.d Fri Jun 27 22:04:35 2008 +0200 @@ -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 -r 3ebc136702dd -r 2b72433d5c8c test/arrays.d --- a/test/arrays.d Wed Jun 25 23:42:38 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -module arrays; - -extern(C) int printf(char*, ...); - -void integer() -{ - auto arr = new int[16]; - arr[1] = 42; - arr[6] = 555; - print_int(arr); - delete arr; -} - -void floating() -{ - auto arr = new float[6]; - arr[1] = 3.14159265; - arr[3] = 1.61803399; - print_float(arr); - delete arr; -} - -void print_int(int[] arr) -{ - printf("arr[%lu] = [", arr.length); - for (auto i=0; i