changeset 305:2b72433d5c8c trunk

[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.
author lindquist
date Fri, 27 Jun 2008 22:04:35 +0200
parents 3ebc136702dd
children 0baca2feb554
files dmd/constfold.c dmd/declaration.c dmd/declaration.h dmd/dump.c dmd/expression.c dmd/func.c dmd/init.c dmd/lexer.c dmd/mangle.c dmd/mars.h dmd/mtype.c dmd/optimize.c dmd/root.c dmd/statement.c dmd/statement.h dmd/template.c gen/asmstmt.cpp gen/d-asm-i386.h gen/irstate.h gen/llvmhelpers.cpp gen/llvmhelpers.h gen/statements.cpp tango/lib/compiler/llvmdc/lifetime.d tango/lib/compiler/llvmdc/llvmdc.mak tango/lib/gc/basic/gc.d tangotests/asm7.d test/arrays.d test/arrays15.d
diffstat 28 files changed, 229 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- 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();
--- 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);
--- 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 <set>
+#include <map>
 
 #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<VarDeclaration*> nestedVars;
+
+    // we keep our own table of label statements as LabelDsymbolS
+    // don't always carry their corresponding statement along ...
+    typedef std::map<const char*, LabelStatement*> LabelMap;
+    LabelMap labmap;
 };
 
 struct FuncAliasDeclaration : FuncDeclaration
--- 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)
--- 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;
 	}
--- 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;
--- 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;
 }
 
--- 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
--- 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);
--- 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 <stdint.h>
-#include <string>
-#include <cstdarg>
+#include <stdarg.h>
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+#include <stdarg.h>
 
 #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
--- 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;
 	    }
 
--- 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)
--- 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()
--- 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()?
--- 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
--- 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)
--- 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<int, LabelDsymbol*> valToGoto;
+    std::map<int, Identifier*> 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 $<<in" << n_goto << ">>, $<<out0>> ; ";
             //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<int, LabelDsymbol*>::iterator it, end = valToGoto.end();
+        std::map<int, Identifier*>::iterator it, end = valToGoto.end();
         for(it = valToGoto.begin(); it != end; ++it)
         {
             llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb);
--- 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());
--- 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<LLValue*> in;
 
     // if this is nonzero, it contains the target label
-    LabelDsymbol* isBranchToLabel;
+    Identifier* isBranchToLabel;
 };
 
 struct IRAsmBlock
--- 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());
 }
 
 /****************************************************************************************/
--- 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
--- 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);
 }
--- 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;
 
--- 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
 
--- 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();
 }
--- /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");
+}
--- 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<arr.length; i++)
-        printf("%d,", arr[i]);
-    printf("\b]\n");
-}
-
-void print_float(float[] arr)
-{
-    printf("arr[%lu] = [", arr.length);
-    for (auto i=0; i<arr.length; i++)
-        printf("%f,", arr[i]);
-    printf("\b]\n");
-}
-
-void main()
-{
-    integer();
-    floating();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/arrays15.d	Fri Jun 27 22:04:35 2008 +0200
@@ -0,0 +1,43 @@
+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<arr.length; i++)
+        printf("%d,", arr[i]);
+    printf("\b]\n");
+}
+
+void print_float(float[] arr)
+{
+    printf("arr[%lu] = [", arr.length);
+    for (auto i=0; i<arr.length; i++)
+        printf("%f,", arr[i]);
+    printf("\b]\n");
+}
+
+void main()
+{
+    integer();
+    floating();
+}