diff options
Diffstat (limited to 'src/cmd/8g')
-rw-r--r-- | src/cmd/8g/Makefile | 11 | ||||
-rw-r--r-- | src/cmd/8g/cgen.c | 40 | ||||
-rw-r--r-- | src/cmd/8g/gg.h | 1 | ||||
-rw-r--r-- | src/cmd/8g/ggen.c | 140 | ||||
-rw-r--r-- | src/cmd/8g/gsubr.c | 71 | ||||
-rw-r--r-- | src/cmd/8g/reg.c | 111 |
6 files changed, 214 insertions, 160 deletions
diff --git a/src/cmd/8g/Makefile b/src/cmd/8g/Makefile index 09cf8d4e3..b459782a3 100644 --- a/src/cmd/8g/Makefile +++ b/src/cmd/8g/Makefile @@ -15,15 +15,16 @@ HFILES=\ OFILES=\ ../8l/enam.$O\ - list.$O\ - galign.$O\ - gobj.$O\ - ggen.$O\ - gsubr.$O\ cgen.$O\ cgen64.$O\ cplx.$O\ + galign.$O\ + ggen.$O\ + gobj.$O\ + gsubr.$O\ + list.$O\ peep.$O\ + pgen.$O\ reg.$O\ LIB=\ diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c index 596824a6c..1614a2d77 100644 --- a/src/cmd/8g/cgen.c +++ b/src/cmd/8g/cgen.c @@ -232,6 +232,7 @@ cgen(Node *n, Node *res) cgen(nl, res); break; } + tempname(&n2, n->type); mgen(nl, &n1, res); gmove(&n1, &n2); @@ -277,15 +278,10 @@ cgen(Node *n, Node *res) if(istype(nl->type, TSTRING) || isslice(nl->type)) { // both slice and string have len one pointer into the struct. igen(nl, &n1, res); - n1.op = OREGISTER; // was OINDREG - regalloc(&n2, types[TUINT32], &n1); - n1.op = OINDREG; n1.type = types[TUINT32]; - n1.xoffset = Array_nel; - gmove(&n1, &n2); - gmove(&n2, res); + n1.xoffset += Array_nel; + gmove(&n1, res); regfree(&n1); - regfree(&n2); break; } fatal("cgen: OLEN: unknown type %lT", nl->type); @@ -594,9 +590,10 @@ agen(Node *n, Node *res) gmove(&n1, &n3); } - nodconst(&n2, types[tptr], v*w); - gins(optoas(OADD, types[tptr]), &n2, &n3); - + if (v*w != 0) { + nodconst(&n2, types[tptr], v*w); + gins(optoas(OADD, types[tptr]), &n2, &n3); + } gmove(&n3, res); regfree(&n3); break; @@ -729,7 +726,27 @@ void igen(Node *n, Node *a, Node *res) { Node n1; - + Type *fp; + Iter flist; + + switch(n->op) { + case ONAME: + if((n->class&PHEAP) || n->class == PPARAMREF) + break; + *a = *n; + return; + + case OCALLFUNC: + fp = structfirst(&flist, getoutarg(n->left->type)); + cgen_call(n, 0); + memset(a, 0, sizeof *a); + a->op = OINDREG; + a->val.u.reg = D_SP; + a->addable = 1; + a->xoffset = fp->width; + a->type = n->type; + return; + } // release register for now, to avoid // confusing tempname. if(res != N && res->op == OREGISTER) @@ -919,6 +936,7 @@ bgen(Node *n, int true, Prog *to) n2 = n1; n2.op = OINDREG; n2.xoffset = Array_array; + n2.type = types[tptr]; nodconst(&tmp, types[tptr], 0); gins(optoas(OCMP, types[tptr]), &n2, &tmp); patch(gbranch(a, types[tptr]), to); diff --git a/src/cmd/8g/gg.h b/src/cmd/8g/gg.h index 57cd1b56b..7da60d767 100644 --- a/src/cmd/8g/gg.h +++ b/src/cmd/8g/gg.h @@ -25,6 +25,7 @@ struct Addr Sym* gotype; Sym* sym; + Node* node; int width; uchar type; uchar index; diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c index 920725c3e..25adb38c0 100644 --- a/src/cmd/8g/ggen.c +++ b/src/cmd/8g/ggen.c @@ -7,106 +7,9 @@ #include "gg.h" #include "opt.h" -static Prog *pret; - void -compile(Node *fn) +defframe(Prog *ptxt) { - Plist *pl; - Node nod1; - Prog *ptxt; - int32 lno; - Type *t; - Iter save; - - if(newproc == N) { - newproc = sysfunc("newproc"); - deferproc = sysfunc("deferproc"); - deferreturn = sysfunc("deferreturn"); - panicindex = sysfunc("panicindex"); - panicslice = sysfunc("panicslice"); - throwreturn = sysfunc("throwreturn"); - } - - if(fn->nbody == nil) - return; - - // set up domain for labels - clearlabels(); - - lno = setlineno(fn); - - curfn = fn; - dowidth(curfn->type); - - if(curfn->type->outnamed) { - // add clearing of the output parameters - t = structfirst(&save, getoutarg(curfn->type)); - while(t != T) { - if(t->nname != N) - curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody); - t = structnext(&save); - } - } - - hasdefer = 0; - walk(curfn); - if(nerrors != 0 || isblank(curfn->nname)) - goto ret; - - allocparams(); - - continpc = P; - breakpc = P; - - pl = newplist(); - pl->name = curfn->nname; - - setlineno(curfn); - - nodconst(&nod1, types[TINT32], 0); - ptxt = gins(ATEXT, curfn->nname, &nod1); - afunclit(&ptxt->from); - - ginit(); - genlist(curfn->enter); - - pret = nil; - if(hasdefer || curfn->exit) { - Prog *p1; - - p1 = gjmp(nil); - pret = gjmp(nil); - patch(p1, pc); - } - - genlist(curfn->nbody); - gclean(); - checklabels(); - if(nerrors != 0) - goto ret; - if(curfn->endlineno) - lineno = curfn->endlineno; - - if(curfn->type->outtuple != 0) - ginscall(throwreturn, 0); - - if(pret) - patch(pret, pc); - ginit(); - if(hasdefer) - ginscall(deferreturn, 0); - if(curfn->exit) - genlist(curfn->exit); - gclean(); - if(nerrors != 0) - goto ret; - pc->as = ARET; // overwrite AEND - pc->lineno = lineno; - - if(!debug['N'] || debug['R'] || debug['P']) { - regopt(ptxt); - } // fill in argument size ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr); @@ -115,12 +18,6 @@ compile(Node *fn) maxstksize = stksize; ptxt->to.offset = rnd(maxstksize+maxarg, widthptr); maxstksize = 0; - - if(debug['f']) - frame(0); - -ret: - lineno = lno; } void @@ -200,7 +97,7 @@ ginscall(Node *f, int proc) if(proc == 2) { nodreg(®, types[TINT64], D_AX); gins(ATESTL, ®, ®); - patch(gbranch(AJNE, T), pret); + patch(gbranch(AJNE, T), retpc); } break; } @@ -391,8 +288,8 @@ void cgen_ret(Node *n) { genlist(n->list); // copy out args - if(pret) - gjmp(pret); + if(retpc) + gjmp(retpc); else gins(ARET, N, N); } @@ -915,7 +812,7 @@ cgen_inline(Node *n, Node *res) Node nodes[5]; Node n1, n2, nres, ntemp; vlong v; - int i, narg; + int i, narg, nochk; if(n->op != OCALLFUNC) goto no; @@ -953,6 +850,7 @@ slicearray: // len = hb[3] - lb[2] (destroys hb) n2 = *res; n2.xoffset += Array_nel; + n2.type = types[TUINT32]; if(smallintconst(&nodes[3]) && smallintconst(&nodes[2])) { v = mpgetfix(nodes[3].val.u.xval) - @@ -971,6 +869,7 @@ slicearray: // cap = nel[1] - lb[2] (destroys nel) n2 = *res; n2.xoffset += Array_cap; + n2.type = types[TUINT32]; if(smallintconst(&nodes[1]) && smallintconst(&nodes[2])) { v = mpgetfix(nodes[1].val.u.xval) - @@ -999,6 +898,7 @@ slicearray: // ary = old[0] + (lb[2] * width[4]) (destroys old) n2 = *res; n2.xoffset += Array_array; + n2.type = types[tptr]; if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) { v = mpgetfix(nodes[2].val.u.xval) * @@ -1026,6 +926,7 @@ slicearray: sliceslice: if(!fix64(n->list, narg)) goto no; + nochk = n->etype; // skip bounds checking ntemp.op = OXXX; if(!sleasy(n->list->n->right)) { Node *n0; @@ -1055,11 +956,13 @@ sliceslice: n2 = nodes[0]; n2.xoffset += Array_nel; n2.type = types[TUINT32]; - cmpandthrow(&nodes[1], &n2); + if(!nochk) + cmpandthrow(&nodes[1], &n2); // ret.nel = old.nel[0]-lb[1]; n2 = nodes[0]; n2.xoffset += Array_nel; + n2.type = types[TUINT32]; regalloc(&n1, types[TUINT32], N); gins(optoas(OAS, types[TUINT32]), &n2, &n1); @@ -1068,22 +971,25 @@ sliceslice: n2 = nres; n2.xoffset += Array_nel; + n2.type = types[TUINT32]; gins(optoas(OAS, types[TUINT32]), &n1, &n2); regfree(&n1); } else { // old[lb:hb] - // if(hb[2] > old.cap[0]) goto throw; n2 = nodes[0]; n2.xoffset += Array_cap; n2.type = types[TUINT32]; - cmpandthrow(&nodes[2], &n2); - - // if(lb[1] > hb[2]) goto throw; - cmpandthrow(&nodes[1], &nodes[2]); + if (!nochk) { + // if(hb[2] > old.cap[0]) goto throw; + cmpandthrow(&nodes[2], &n2); + // if(lb[1] > hb[2]) goto throw; + cmpandthrow(&nodes[1], &nodes[2]); + } // ret.len = hb[2]-lb[1]; (destroys hb[2]) n2 = nres; n2.xoffset += Array_nel; - + n2.type = types[TUINT32]; + if(smallintconst(&nodes[2]) && smallintconst(&nodes[1])) { v = mpgetfix(nodes[2].val.u.xval) - mpgetfix(nodes[1].val.u.xval); @@ -1102,6 +1008,7 @@ sliceslice: // ret.cap = old.cap[0]-lb[1]; (uses hb[2]) n2 = nodes[0]; n2.xoffset += Array_cap; + n2.type = types[TUINT32]; regalloc(&n1, types[TUINT32], &nodes[2]); gins(optoas(OAS, types[TUINT32]), &n2, &n1); @@ -1110,12 +1017,14 @@ sliceslice: n2 = nres; n2.xoffset += Array_cap; + n2.type = types[TUINT32]; gins(optoas(OAS, types[TUINT32]), &n1, &n2); regfree(&n1); // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1]) n2 = nodes[0]; n2.xoffset += Array_array; + n2.type = types[tptr]; regalloc(&n1, types[tptr], &nodes[1]); if(smallintconst(&nodes[1]) && smallintconst(&nodes[3])) { @@ -1135,6 +1044,7 @@ sliceslice: n2 = nres; n2.xoffset += Array_array; + n2.type = types[tptr]; gins(optoas(OAS, types[tptr]), &n1, &n2); regfree(&n1); diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index ae9901eeb..a8d65cf22 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -736,7 +736,6 @@ ginit(void) reg[i] = 1; for(i=D_AL; i<=D_DI; i++) reg[i] = 0; - for(i=0; i<nelem(resvd); i++) reg[resvd[i]]++; } @@ -827,6 +826,8 @@ err: return; out: + if (i == D_SP) + print("alloc SP\n"); if(reg[i] == 0) { regpc[i] = (ulong)__builtin_return_address(0); if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) { @@ -842,10 +843,14 @@ void regfree(Node *n) { int i; - + + if(n->op == ONAME) + return; if(n->op != OREGISTER && n->op != OINDREG) fatal("regfree: not a register"); i = n->val.u.reg; + if(i == D_SP) + return; if(i < 0 || i >= sizeof(reg)) fatal("regfree: reg out of range"); if(reg[i] <= 0) @@ -1167,6 +1172,9 @@ gmove(Node *f, Node *t) case CASE(TINT8, TUINT8): case CASE(TUINT8, TINT8): case CASE(TUINT8, TUINT8): + a = AMOVB; + break; + case CASE(TINT16, TINT8): // truncate case CASE(TUINT16, TINT8): case CASE(TINT32, TINT8): @@ -1176,7 +1184,7 @@ gmove(Node *f, Node *t) case CASE(TINT32, TUINT8): case CASE(TUINT32, TUINT8): a = AMOVB; - break; + goto rsrc; case CASE(TINT64, TINT8): // truncate low word case CASE(TUINT64, TINT8): @@ -1184,7 +1192,7 @@ gmove(Node *f, Node *t) case CASE(TUINT64, TUINT8): split64(f, &flo, &fhi); nodreg(&r1, t->type, D_AX); - gins(AMOVB, &flo, &r1); + gmove(&flo, &r1); gins(AMOVB, &r1, t); splitclean(); return; @@ -1193,12 +1201,15 @@ gmove(Node *f, Node *t) case CASE(TINT16, TUINT16): case CASE(TUINT16, TINT16): case CASE(TUINT16, TUINT16): + a = AMOVW; + break; + case CASE(TINT32, TINT16): // truncate case CASE(TUINT32, TINT16): case CASE(TINT32, TUINT16): case CASE(TUINT32, TUINT16): a = AMOVW; - break; + goto rsrc; case CASE(TINT64, TINT16): // truncate low word case CASE(TUINT64, TINT16): @@ -1206,7 +1217,7 @@ gmove(Node *f, Node *t) case CASE(TUINT64, TUINT16): split64(f, &flo, &fhi); nodreg(&r1, t->type, D_AX); - gins(AMOVW, &flo, &r1); + gmove(&flo, &r1); gins(AMOVW, &r1, t); splitclean(); return; @@ -1224,7 +1235,7 @@ gmove(Node *f, Node *t) case CASE(TUINT64, TUINT32): split64(f, &flo, &fhi); nodreg(&r1, t->type, D_AX); - gins(AMOVL, &flo, &r1); + gmove(&flo, &r1); gins(AMOVL, &r1, t); splitclean(); return; @@ -1378,14 +1389,14 @@ gmove(Node *f, Node *t) case TUINT8: gins(ATESTL, ncon(0xffffff00), &t1); p1 = gbranch(AJEQ, T); - gins(AMOVB, ncon(0), &t1); + gins(AMOVL, ncon(0), &t1); patch(p1, pc); gmove(&t1, t); break; case TUINT16: gins(ATESTL, ncon(0xffff0000), &t1); p1 = gbranch(AJEQ, T); - gins(AMOVW, ncon(0), &t1); + gins(AMOVL, ncon(0), &t1); patch(p1, pc); gmove(&t1, t); break; @@ -1456,11 +1467,11 @@ gmove(Node *f, Node *t) split64(t, &tlo, &thi); gins(AXORL, ncon(0x80000000), &thi); // + 2^63 patch(p3, pc); - patch(p1, pc); splitclean(); - // restore rounding mode gins(AFLDCW, &t1, N); + + patch(p1, pc); return; /* @@ -1609,6 +1620,14 @@ gmove(Node *f, Node *t) gins(a, f, t); return; +rsrc: + // requires register source + regalloc(&r1, f->type, t); + gmove(f, &r1); + gins(a, &r1, t); + regfree(&r1); + return; + rdst: // requires register destination regalloc(&r1, t->type, t); @@ -1661,6 +1680,7 @@ gins(int as, Node *f, Node *t) { Prog *p; Addr af, at; + int w; if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER) fatal("gins MOVF reg, reg"); @@ -1686,6 +1706,26 @@ gins(int as, Node *f, Node *t) p->to = at; if(debug['g']) print("%P\n", p); + + w = 0; + switch(as) { + case AMOVB: + w = 1; + break; + case AMOVW: + w = 2; + break; + case AMOVL: + w = 4; + break; + } + + if(1 && w != 0 && f != N && (af.width > w || at.width > w)) { + dump("bad width from:", f); + dump("bad width to:", t); + fatal("bad width: %P (%d, %d)\n", p, af.width, at.width); + } + return p; } @@ -1718,6 +1758,7 @@ naddr(Node *n, Addr *a, int canemitcode) a->index = D_NONE; a->type = D_NONE; a->gotype = S; + a->node = N; if(n == N) return; @@ -1775,6 +1816,8 @@ naddr(Node *n, Addr *a, int canemitcode) break; case PAUTO: a->type = D_AUTO; + if (n->sym) + a->node = n->orig; break; case PPARAM: case PPARAMOUT: @@ -1837,8 +1880,9 @@ naddr(Node *n, Addr *a, int canemitcode) naddr(n->left, a, canemitcode); if(a->type == D_CONST && a->offset == 0) break; // len(nil) - a->etype = TUINT; + a->etype = TUINT32; a->offset += Array_nel; + a->width = 4; if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) checkoffset(a, canemitcode); break; @@ -1848,8 +1892,9 @@ naddr(Node *n, Addr *a, int canemitcode) naddr(n->left, a, canemitcode); if(a->type == D_CONST && a->offset == 0) break; // cap(nil) - a->etype = TUINT; + a->etype = TUINT32; a->offset += Array_cap; + a->width = 4; if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) checkoffset(a, canemitcode); break; diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c index 1465d372c..a2f3def37 100644 --- a/src/cmd/8g/reg.c +++ b/src/cmd/8g/reg.c @@ -33,6 +33,8 @@ #define EXTERN #include "opt.h" +#define NREGVAR 8 +#define REGBITS ((uint32)0xff) #define P2R(p) (Reg*)(p->reg) static int first = 1; @@ -114,6 +116,8 @@ setaddrs(Bits bit) } } +static char* regname[] = { ".ax", ".cx", ".dx", ".bx", ".sp", ".bp", ".si", ".di" }; + void regopt(Prog *firstp) { @@ -142,7 +146,17 @@ regopt(Prog *firstp) r1 = R; firstr = R; lastr = R; - nvar = 0; + + /* + * control flow is more complicated in generated go code + * than in generated c code. define pseudo-variables for + * registers, so we have complete register usage information. + */ + nvar = NREGVAR; + memset(var, 0, NREGVAR*sizeof var[0]); + for(i=0; i<NREGVAR; i++) + var[i].sym = lookup(regname[i]); + regbits = RtoB(D_SP); for(z=0; z<BITS; z++) { externs.b[z] = 0; @@ -249,14 +263,19 @@ regopt(Prog *firstp) /* * right side write */ + case AFSTSW: + case ALEAL: case ANOP: case AMOVL: case AMOVB: case AMOVW: case AMOVBLSX: case AMOVBLZX: + case AMOVBWSX: + case AMOVBWZX: case AMOVWLSX: case AMOVWLZX: + case APOPL: for(z=0; z<BITS; z++) r->set.b[z] |= bit.b[z]; break; @@ -321,6 +340,23 @@ regopt(Prog *firstp) case AADCL: case ASBBL: + case ASETCC: + case ASETCS: + case ASETEQ: + case ASETGE: + case ASETGT: + case ASETHI: + case ASETLE: + case ASETLS: + case ASETLT: + case ASETMI: + case ASETNE: + case ASETOC: + case ASETOS: + case ASETPC: + case ASETPL: + case ASETPS: + case AXCHGB: case AXCHGW: case AXCHGL: @@ -349,20 +385,32 @@ regopt(Prog *firstp) if(p->to.type != D_NONE) break; - case AIDIVB: case AIDIVL: case AIDIVW: - case AIMULB: - case ADIVB: case ADIVL: case ADIVW: - case AMULB: case AMULL: case AMULW: + r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX); + r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DX); + break; + + case AIDIVB: + case AIMULB: + case ADIVB: + case AMULB: + r->set.b[0] |= RtoB(D_AX); + r->use1.b[0] |= RtoB(D_AX); + break; case ACWD: + r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX); + r->use1.b[0] |= RtoB(D_AX); + break; + case ACDQ: - r->regu |= RtoB(D_AX) | RtoB(D_DX); + r->set.b[0] |= RtoB(D_DX); + r->use1.b[0] |= RtoB(D_AX); break; case AREP: @@ -370,7 +418,8 @@ regopt(Prog *firstp) case ALOOP: case ALOOPEQ: case ALOOPNE: - r->regu |= RtoB(D_CX); + r->set.b[0] |= RtoB(D_CX); + r->use1.b[0] |= RtoB(D_CX); break; case AMOVSB: @@ -379,7 +428,8 @@ regopt(Prog *firstp) case ACMPSB: case ACMPSL: case ACMPSW: - r->regu |= RtoB(D_SI) | RtoB(D_DI); + r->set.b[0] |= RtoB(D_SI) | RtoB(D_DI); + r->use1.b[0] |= RtoB(D_SI) | RtoB(D_DI); break; case ASTOSB: @@ -388,16 +438,22 @@ regopt(Prog *firstp) case ASCASB: case ASCASL: case ASCASW: - r->regu |= RtoB(D_AX) | RtoB(D_DI); + r->set.b[0] |= RtoB(D_DI); + r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DI); break; case AINSB: case AINSL: case AINSW: + r->set.b[0] |= RtoB(D_DX) | RtoB(D_DI); + r->use1.b[0] |= RtoB(D_DI); + break; + case AOUTSB: case AOUTSL: case AOUTSW: - r->regu |= RtoB(D_DI) | RtoB(D_DX); + r->set.b[0] |= RtoB(D_DI); + r->use1.b[0] |= RtoB(D_DX) | RtoB(D_DI); break; } } @@ -504,6 +560,24 @@ loop2: dumpit("pass4", firstr); /* + * pass 4.5 + * move register pseudo-variables into regu. + */ + for(r = firstr; r != R; r = r->link) { + r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS; + + r->set.b[0] &= ~REGBITS; + r->use1.b[0] &= ~REGBITS; + r->use2.b[0] &= ~REGBITS; + r->refbehind.b[0] &= ~REGBITS; + r->refahead.b[0] &= ~REGBITS; + r->calbehind.b[0] &= ~REGBITS; + r->calahead.b[0] &= ~REGBITS; + r->regdiff.b[0] &= ~REGBITS; + r->act.b[0] &= ~REGBITS; + } + + /* * pass 5 * isolate regions * calculate costs (paint1) @@ -656,6 +730,7 @@ addmove(Reg *r, int bn, int rn, int f) a->etype = v->etype; a->type = v->name; a->gotype = v->gotype; + a->node = v->node; // need to clean this up with wptr and // some of the defaults @@ -732,7 +807,7 @@ Bits mkvar(Reg *r, Adr *a) { Var *v; - int i, t, n, et, z, w, flag; + int i, t, n, et, z, w, flag, regu; int32 o; Bits bit; Sym *s; @@ -744,14 +819,17 @@ mkvar(Reg *r, Adr *a) if(t == D_NONE) goto none; - if(r != R) { - r->regu |= doregbits(t); - r->regu |= doregbits(a->index); - } + if(r != R) + r->use1.b[0] |= doregbits(a->index); switch(t) { default: - goto none; + regu = doregbits(t); + if(regu == 0) + goto none; + bit = zbits; + bit.b[0] = regu; + return bit; case D_ADDR: a->type = a->index; @@ -821,6 +899,7 @@ mkvar(Reg *r, Adr *a) v->etype = et; v->width = w; v->addr = flag; // funny punning + v->node = a->node; if(debug['R']) print("bit=%2d et=%2d w=%d %S %D flag=%d\n", i, et, w, s, a, v->addr); |