# HG changeset patch # User korDen # Date 1282584065 -14400 # Node ID f708f0452e81063f668c5cc9b4afd447f39892c8 # Parent efb1e5bdf63c8aba7da3996cc761a26cf97c0f3c some of the backend/codegen stuff implemented diff -r efb1e5bdf63c -r f708f0452e81 dmd/InExp.d --- a/dmd/InExp.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/InExp.d Mon Aug 23 21:21:05 2010 +0400 @@ -15,6 +15,11 @@ import dmd.expression.util.arrayTypeCompatible; import dmd.backend.elem; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; +import dmd.backend.Symbol; +import dmd.backend.Util; class InExp : BinExp { @@ -75,7 +80,31 @@ elem* toElem(IRState* irs) { - assert(false); + elem* e; + elem* key = e1.toElem(irs); + elem* aa = e2.toElem(irs); + elem* ep; + elem* keyti; + TypeAArray taa = cast(TypeAArray)e2.type.toBasetype(); + + + // set to: + // aaIn(aa, keyti, key); + + if (tybasic(key.Ety) == TYstruct) + { + key = el_una(OPstrpar, TYstruct, key); + key.Enumbytes = key.E1.Enumbytes; + assert(key.Enumbytes); + } + + Symbol* s = taa.aaGetSymbol("In", 0); + keyti = taa.index.getInternalTypeInfo(null).toElem(irs); + ep = el_params(key, keyti, aa, null); + e = el_bin(OPcall, type.totym(), el_var(s), ep); + + el_setLoc(e,loc); + return e; } } diff -r efb1e5bdf63c -r f708f0452e81 dmd/ModAssignExp.d --- a/dmd/ModAssignExp.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/ModAssignExp.d Mon Aug 23 21:21:05 2010 +0400 @@ -10,6 +10,7 @@ import dmd.Identifier; import dmd.IRState; import dmd.TOK; +import dmd.backend.OPER; import dmd.Id; import dmd.backend.elem; @@ -48,6 +49,6 @@ elem* toElem(IRState* irs) { - assert(false); + return toElemBin(irs,OPmodass); } } diff -r efb1e5bdf63c -r f708f0452e81 dmd/ReturnStatement.d --- a/dmd/ReturnStatement.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/ReturnStatement.d Mon Aug 23 21:21:05 2010 +0400 @@ -34,6 +34,7 @@ import dmd.VarDeclaration; import dmd.GlobalExpressions; import dmd.BE; + import dmd.codegen.Util; import dmd.backend.Blockx; @@ -44,6 +45,8 @@ import dmd.backend.mTY; import dmd.backend.BC; +import core.stdc.string; + class ReturnStatement : Statement { Expression exp; @@ -417,17 +420,15 @@ */ if (exp.op == TOK.TOKstructliteral) { - assert(false); - /* - StructLiteralExp se = cast(StructLiteralExp)exp; - char save[(StructLiteralExp).sizeof]; - memcpy(save, se, sizeof(StructLiteralExp)); + scope StructLiteralExp se = cast(StructLiteralExp)exp; + enum objectSize = __traits(classInstanceSize, StructLiteralExp); + ubyte save[objectSize]; + memcpy(save.ptr, cast(void*)se, objectSize); se.sym = irs.shidden; se.soffset = 0; se.fillHoles = 1; e = exp.toElem(irs); - memcpy(se, save, sizeof(StructLiteralExp)); - */ + memcpy(cast(void*)se, save.ptr, objectSize); } else e = exp.toElem(irs); diff -r efb1e5bdf63c -r f708f0452e81 dmd/StructInitializer.d --- a/dmd/StructInitializer.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/StructInitializer.d Mon Aug 23 21:21:05 2010 +0400 @@ -2,6 +2,7 @@ import dmd.Initializer; import dmd.TOK; +import dmd.TypeSArray; import dmd.FuncLiteralDeclaration; import dmd.TypeFunction; import dmd.StructDeclaration; @@ -27,6 +28,7 @@ import dmd.LINK; import dmd.backend.dt_t; +import dmd.backend.Util; class StructInitializer : Initializer { @@ -219,7 +221,122 @@ dt_t* toDt() { - assert(false); + scope Array dts = new Array(); + uint i; + uint j; + dt_t* dt; + dt_t* d; + dt_t** pdtend; + uint offset; + + //printf("StructInitializer.toDt('%s')\n", toChars()); + dts.setDim(ad.fields.dim); + dts.zero(); + + for (i = 0; i < vars.dim; i++) + { + VarDeclaration v = cast(VarDeclaration)vars.data[i]; + Initializer val = cast(Initializer)value.data[i]; + + //printf("vars[%d] = %s\n", i, v.toChars()); + + for (j = 0; 1; j++) + { + assert(j < dts.dim); + //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields.data[j]).toChars()); + if (cast(VarDeclaration)ad.fields.data[j] == v) + { + if (dts.data[j]) + error(loc, "field %s of %s already initialized", v.toChars(), ad.toChars()); + dts.data[j] = cast(void*)val.toDt(); + break; + } + } + } + + dt = null; + pdtend = &dt; + offset = 0; + for (j = 0; j < dts.dim; j++) + { + VarDeclaration v = cast(VarDeclaration)ad.fields.data[j]; + + d = cast(dt_t*)dts.data[j]; + if (!d) + { + // An instance specific initializer was not provided. + // Look to see if there's a default initializer from the + // struct definition + if (v.init) + { + d = v.init.toDt(); + } + else if (v.offset >= offset) + { + uint k; + uint offset2 = v.offset + cast(uint)v.type.size(); + // Make sure this field does not overlap any explicitly + // initialized field. + for (k = j + 1; 1; k++) + { + if (k == dts.dim) // didn't find any overlap + { + v.type.toDt(&d); + break; + } + VarDeclaration v2 = cast(VarDeclaration)ad.fields.data[k]; + + if (v2.offset < offset2 && dts.data[k]) + break; // overlap + } + } + } + if (d) + { + if (v.offset < offset) + error(loc, "duplicate union initialization for %s", v.toChars()); + else + { + uint sz = dt_size(d); + uint vsz = cast(uint)v.type.size(); + uint voffset = v.offset; + + uint dim = 1; + for (Type vt = v.type.toBasetype(); + vt.ty == Tsarray; + vt = vt.nextOf().toBasetype()) + { + TypeSArray tsa = cast(TypeSArray)vt; + dim *= tsa.dim.toInteger(); + } + assert(sz == vsz || sz * dim <= vsz); + + for (size_t k = 0; k < dim; k++) + { + if (offset < voffset) + pdtend = dtnzeros(pdtend, voffset - offset); + if (!d) + { + if (v.init) + d = v.init.toDt(); + else + v.type.toDt(&d); + } + pdtend = dtcat(pdtend, d); + d = null; + offset = voffset + sz; + voffset += vsz / dim; + if (sz == vsz) + break; + } + } + } + } + + if (offset < ad.structsize) + dtnzeros(pdtend, ad.structsize - offset); + + return dt; } StructInitializer isStructInitializer() { return this; } diff -r efb1e5bdf63c -r f708f0452e81 dmd/StructLiteralExp.d --- a/dmd/StructLiteralExp.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/StructLiteralExp.d Mon Aug 23 21:21:05 2010 +0400 @@ -3,11 +3,14 @@ import dmd.Expression; import dmd.MOD; import dmd.TypeStruct; +import dmd.TypeSArray; import dmd.expression.Util; import dmd.ErrorExp; import dmd.Dsymbol; import dmd.VarDeclaration; import dmd.StructDeclaration; +import dmd.FuncDeclaration; +import dmd.ThisDeclaration; import dmd.backend.elem; import dmd.InterState; import dmd.MATCH; @@ -27,6 +30,13 @@ import dmd.ArrayTypes; import dmd.TOK; +import dmd.codegen.Util; +import dmd.backend.Util; +import dmd.backend.RTLSYM; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; + class StructLiteralExp : Expression { @@ -158,7 +168,169 @@ elem* toElem(IRState* irs) { - assert(false); + elem* e; + size_t dim; + + //printf("StructLiteralExp.toElem() %s\n", toChars()); + + // struct symbol to initialize with the literal + Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype()); + + e = null; + + if (fillHoles) + { + /* Initialize all alignment 'holes' to zero. + * Do before initializing fields, as the hole filling process + * can spill over into the fields. + */ + size_t offset = 0; + for (size_t i = 0; i < sd.fields.dim; i++) + { + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + + e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize)); + size_t vend = v.offset + cast(uint)v.type.size(); + if (offset < vend) + offset = vend; + } + e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize)); + } + + if (elements) + { + dim = elements.dim; + assert(dim <= sd.fields.dim); + for (size_t i = 0; i < dim; i++) + { + Expression el = cast(Expression)elements.data[i]; + if (!el) + continue; + + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + assert(!v.isThisDeclaration()); + + elem* e1; + if (tybasic(stmp.Stype.Tty) == TYnptr) + { + e1 = el_var(stmp); + e1.EV.sp.Voffset = soffset; + } + else + { + e1 = el_ptr(stmp); + if (soffset) + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); + elem* ec = e1; // pointer to destination + + elem* ep = el.toElem(irs); + + Type t1b = v.type.toBasetype(); + Type t2b = el.type.toBasetype(); + if (t1b.ty == Tsarray) + { + if (t2b.implicitConvTo(t1b)) + { + ///version (DMDV2) { + // Determine if postblit is needed + int postblit = 0; + if (needsPostblit(t1b)) + postblit = 1; + + if (postblit) + { + /* Generate: + * _d_arrayctor(ti, From: ep, To: e1) + */ + Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null); + elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger()); + e1 = el_pair(TYdarray, esize, e1); + ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep)); + ep = el_params(e1, ep, ti.toElem(irs), null); + int rtl = RTLSYM_ARRAYCTOR; + e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep); + } + else + ///} + { + elem* esize = el_long(TYsize_t, t1b.size()); + ep = array_toPtr(el.type, ep); + e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); + } + } + else + { + elem* edim = el_long(TYsize_t, t1b.size() / t2b.size()); + e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); + } + } + else + { + tym_t ty = v.type.totym(); + e1 = el_una(OPind, ty, e1); + if (tybasic(ty) == TYstruct) + e1.Enumbytes = cast(uint)v.type.size(); + e1 = el_bin(OPeq, ty, e1, ep); + if (tybasic(ty) == TYstruct) + { + e1.Eoper = OPstreq; + e1.Enumbytes = cast(uint)v.type.size(); + } +version (DMDV2) { + /* Call postblit() on e1 + */ + StructDeclaration sd = needsPostblit(v.type); + if (sd) + { + FuncDeclaration fd = sd.postblit; + ec = el_copytree(ec); + ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null); + e1 = el_bin(OPcomma, ec.Ety, e1, ec); + } +} + } + e = el_combine(e, e1); + } + } + +version (DMDV2) { + if (sd.isnested) + { // Initialize the hidden 'this' pointer + assert(sd.fields.dim); + Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1]; + ThisDeclaration v = s.isThisDeclaration(); + assert(v); + + elem* e1; + if (tybasic(stmp.Stype.Tty) == TYnptr) + { + e1 = el_var(stmp); + e1.EV.sp.Voffset = soffset; + } + else + { + e1 = el_ptr(stmp); + if (soffset) + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); + e1 = setEthis(loc, irs, e1, sd); + + e = el_combine(e, e1); + } +} + + elem* ev = el_var(stmp); + ev.Enumbytes = sd.structsize; + e = el_combine(e, ev); + el_setLoc(e,loc); + return e; } bool checkSideEffect(int flag) diff -r efb1e5bdf63c -r f708f0452e81 dmd/TypeAArray.d --- a/dmd/TypeAArray.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/TypeAArray.d Mon Aug 23 21:21:05 2010 +0400 @@ -7,6 +7,7 @@ import dmd.Expression; import dmd.Scope; import dmd.Loc; +import dmd.Global; import dmd.Dsymbol; import dmd.Type; import dmd.TypeSArray; @@ -31,6 +32,7 @@ import dmd.backend.LIST; import dmd.backend.TYM; import dmd.backend.TF; +import dmd.backend.Classsym; import dmd.backend.mTYman; import core.stdc.stdio; @@ -434,6 +436,60 @@ type* toCtype() { - assert(false); + type* t; + + if (ctype) + return ctype; + + if (0 && global.params.symdebug) + { + /* An associative array is represented by: + * struct AArray { size_t length; void* ptr; } + */ + + static Symbol* s; + + if (!s) + { + s = symbol_calloc("_AArray"); + s.Sclass = SCstruct; + s.Sstruct = struct_calloc(); + s.Sstruct.Sflags |= 0; + s.Sstruct.Salignsize = alignsize(); + s.Sstruct.Sstructalign = cast(ubyte)global.structalign; + s.Sstruct.Sstructsize = cast(uint)size(Loc(0)); + slist_add(s); + + Symbol* s1 = symbol_name("length", SCmember, Type.tsize_t.toCtype()); + list_append(&s.Sstruct.Sfldlst, s1); + + Symbol* s2 = symbol_name("data", SCmember, Type.tvoidptr.toCtype()); + s2.Smemoff = cast(uint)Type.tsize_t.size(); + list_append(&s.Sstruct.Sfldlst, s2); + } + + t = type_alloc(TYstruct); + t.Ttag = cast(Classsym*)s; // structure tag name + t.Tcount++; + s.Stype = t; + } + else + { + if (global.params.symdebug == 1) + { + /* Generate D symbolic debug info, rather than C + * Tnext: element type + * Tkey: key type + */ + t = type_allocn(TYaarray, next.toCtype()); + t.Tkey = index.toCtype(); + t.Tkey.Tcount++; + } + else + t = type_fake(TYaarray); + } + t.Tcount++; + ctype = t; + return t; } } diff -r efb1e5bdf63c -r f708f0452e81 dmd/TypeInfoTupleDeclaration.d --- a/dmd/TypeInfoTupleDeclaration.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/TypeInfoTupleDeclaration.d Mon Aug 23 21:21:05 2010 +0400 @@ -2,7 +2,16 @@ import dmd.Type; import dmd.TypeInfoDeclaration; +import dmd.WANT; +import dmd.TypeTuple; +import dmd.Argument; +import dmd.Expression; +import dmd.TY; +import dmd.backend.TYM; +import dmd.backend.Symbol; import dmd.backend.dt_t; +import dmd.backend.Util; +import dmd.codegen.Util; class TypeInfoTupleDeclaration : TypeInfoDeclaration { @@ -13,6 +22,31 @@ void toDt(dt_t **pdt) { - assert(false); + //printf("TypeInfoTupleDeclaration.toDt() %s\n", tinfo.toChars()); + dtxoff(pdt, Type.typeinfotypelist.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface + dtdword(pdt, 0); // monitor + + assert(tinfo.ty == Ttuple); + + TypeTuple tu = cast(TypeTuple)tinfo; + + size_t dim = tu.arguments.dim; + dtdword(pdt, dim); // elements.length + + dt_t* d = null; + for (size_t i = 0; i < dim; i++) + { + Argument arg = cast(Argument)tu.arguments.data[i]; + Expression e = arg.type.getTypeInfo(null); + e = e.optimize(WANTvalue); + e.toDt(&d); + } + + Symbol *s; + s = static_sym(); + s.Sdt = d; + outdata(s); + + dtxoff(pdt, s, 0, TYnptr); // elements.ptr } } \ No newline at end of file diff -r efb1e5bdf63c -r f708f0452e81 dmd/TypeSArray.d --- a/dmd/TypeSArray.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/TypeSArray.d Mon Aug 23 21:21:05 2010 +0400 @@ -306,7 +306,13 @@ void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { - assert(false); + if (mod != this.mod) + { + toCBuffer3(buf, hgs, mod); + return; + } + next.toCBuffer2(buf, hgs, this.mod); + buf.printf("[%s]", dim.toChars()); } Expression dotExp(Scope sc, Expression e, Identifier ident) diff -r efb1e5bdf63c -r f708f0452e81 dmd/TypeTypedef.d --- a/dmd/TypeTypedef.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/TypeTypedef.d Mon Aug 23 21:21:05 2010 +0400 @@ -81,7 +81,14 @@ void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { - assert(false); + //printf("TypeTypedef.toCBuffer2() '%s'\n", sym.toChars()); + if (mod != this.mod) + { + toCBuffer3(buf, hgs, mod); + return; + } + + buf.writestring(sym.toChars()); } Expression dotExp(Scope sc, Expression e, Identifier ident) diff -r efb1e5bdf63c -r f708f0452e81 dmd/UnrolledLoopStatement.d --- a/dmd/UnrolledLoopStatement.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/UnrolledLoopStatement.d Mon Aug 23 21:21:05 2010 +0400 @@ -14,6 +14,11 @@ import dmd.InlineScanState; import dmd.BE; +import dmd.backend.BC; +import dmd.backend.Blockx; +import dmd.backend.block; +import dmd.backend.Util; + class UnrolledLoopStatement : Statement { Statements statements; @@ -115,7 +120,38 @@ void toIR(IRState* irs) { - assert(false); + Blockx* blx = irs.blx; + + IRState mystate = IRState(irs, this); + mystate.breakBlock = block_calloc(blx); + + block* bpre = blx.curblock; + block_next(blx, BCgoto, null); + + block* bdo = blx.curblock; + list_append(&bpre.Bsucc, bdo); + + block* bdox; + + size_t dim = statements.dim; + for (size_t i = 0 ; i < dim ; i++) + { + Statement s = cast(Statement)statements.data[i]; + if (s !is null) + { + mystate.contBlock = block_calloc(blx); + + s.toIR(&mystate); + + bdox = blx.curblock; + block_next(blx, BCgoto, mystate.contBlock); + list_append(&bdox.Bsucc, mystate.contBlock); + } + } + + bdox = blx.curblock; + block_next(blx, BCgoto, mystate.breakBlock); + list_append(&bdox.Bsucc, mystate.breakBlock); } } diff -r efb1e5bdf63c -r f708f0452e81 dmd/XorExp.d --- a/dmd/XorExp.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/XorExp.d Mon Aug 23 21:21:05 2010 +0400 @@ -16,7 +16,8 @@ import dmd.TOK; import dmd.TY; -import dmd.backend.elem; +import dmd.backend.elem; +import dmd.backend.OPER; import dmd.expression.Util; import dmd.expression.Xor; @@ -127,7 +128,7 @@ elem* toElem(IRState* irs) { - assert(false); + return toElemBin(irs,OPxor); } } diff -r efb1e5bdf63c -r f708f0452e81 dmd/backend/dt_t.d --- a/dmd/backend/dt_t.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/backend/dt_t.d Mon Aug 23 21:21:05 2010 +0400 @@ -39,6 +39,8 @@ } } +extern (C++) extern uint dt_size(dt_t* dtstart); + import std.stdio; void dumpDt(dt_t* foo) diff -r efb1e5bdf63c -r f708f0452e81 dmd/codegen/Util.d --- a/dmd/codegen/Util.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/codegen/Util.d Mon Aug 23 21:21:05 2010 +0400 @@ -1151,3 +1151,52 @@ } return s.lblock; } + +/******************************************* + * Generate elem to zero fill contents of Symbol stmp + * from *poffset..offset2. + * May store anywhere from 0..maxoff, as this function + * tries to use aligned int stores whereever possible. + * Update *poffset to end of initialized hole; *poffset will be >= offset2. + */ + +elem* fillHole(Symbol* stmp, size_t* poffset, size_t offset2, size_t maxoff) +{ + elem* e = null; + int basealign = 1; + + while (*poffset < offset2) + { + tym_t ty; + elem* e1; + + if (tybasic(stmp.Stype.Tty) == TYnptr) + e1 = el_var(stmp); + else + e1 = el_ptr(stmp); + + if (basealign) + *poffset &= ~3; + + basealign = 1; + size_t sz = maxoff - *poffset; + switch (sz) + { + case 1: ty = TYchar; break; + case 2: ty = TYshort; break; + case 3: + ty = TYshort; + basealign = 0; + break; + default: + ty = TYlong; + break; + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, *poffset)); + e1 = el_una(OPind, ty, e1); + e1 = el_bin(OPeq, ty, e1, el_long(ty, 0)); + e = el_combine(e, e1); + *poffset += tysize[ty]; + } + return e; +} \ No newline at end of file