From 8811896597d83fca02e5a6389908f5802e1f6aab Mon Sep 17 00:00:00 2001 From: Kai Backman Date: Wed, 19 Aug 2009 20:17:09 -0700 Subject: [PATCH] more work on adding in pieces. fixed my bad assumptions about signed and unsigned integer conversions. R=rsc APPROVED=rsc DELTA=398 (40 added, 230 deleted, 128 changed) OCL=33546 CL=33569 --- src/cmd/5g/cgen.c | 23 +--- src/cmd/5g/gg.h | 3 - src/cmd/5g/ggen.c | 219 ++++++-------------------------------- src/cmd/5g/gobj.c | 8 +- src/cmd/5g/gsubr.c | 257 +++++++++++++++++++++------------------------ 5 files changed, 160 insertions(+), 350 deletions(-) diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c index cee5d78a69..c988882559 100644 --- a/src/cmd/5g/cgen.c +++ b/src/cmd/5g/cgen.c @@ -201,6 +201,8 @@ cgen(Node *n, Node *res) // asymmetric binary case OSUB: + case OLSH: + case ORSH: a = optoas(n->op, nl->type); goto abop; @@ -294,17 +296,8 @@ cgen(Node *n, Node *res) case OMOD: case ODIV: - if(isfloat[n->type->etype]) { - a = optoas(n->op, nl->type); - goto abop; - } - cgen_div(n->op, nl, nr, res); - break; - - case OLSH: - case ORSH: - cgen_shift(n->op, nl, nr, res); - break; + a = optoas(n->op, nl->type); + goto abop; } goto ret; @@ -343,14 +336,6 @@ abop: // asymmetric binary regfree(&n2); goto ret; -uop: // unary - regalloc(&n1, nl->type, res); - cgen(nl, &n1); - gins(a, N, &n1); - gmove(&n1, res); - regfree(&n1); - goto ret; - ret: ; } diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h index b3186eba95..e40be11af5 100644 --- a/src/cmd/5g/gg.h +++ b/src/cmd/5g/gg.h @@ -76,9 +76,6 @@ void cgen_callmeth(Node*, int); void cgen_callinter(Node*, Node*, int); void cgen_proc(Node*, int); void cgen_callret(Node*, Node*); -void cgen_div(int, Node*, Node*, Node*); -void cgen_bmul(int, Node*, Node*, Node*); -void cgen_shift(int, Node*, Node*, Node*); void cgen_dcl(Node*); int needconvert(Type*, Type*); void genconv(Type*, Type*); diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c index 5e9806b91a..6eeb17bfcd 100644 --- a/src/cmd/5g/ggen.c +++ b/src/cmd/5g/ggen.c @@ -392,7 +392,6 @@ cgen_asop(Node *n) } hard: - fatal("cgen_asop hard not implemented"); if(nr->ullman > nl->ullman) { regalloc(&n2, nr->type, N); cgen(nr, &n2); @@ -432,200 +431,52 @@ samereg(Node *a, Node *b) return 1; } -/* - * generate division according to op, one of: - * res = nl / nr - * res = nl % nr - */ -// TODO(kaib): rip out and just insert into cgen -void -cgen_div(int op, Node *nl, Node *nr, Node *res) -{ - Node nod, nod1; - Prog* p; - Addr ta; - if(res == Z) { - // TODO(kaib): add back warning for null -// nullwarn(l, r); - return; - } - if(nl->ullman >= nr->ullman) { - regalloc(&nod, nl->type, res); - cgen(nl, &nod); - regalloc(&nod1, nr->type, Z); - cgen(nr, &nod1); - gins(optoas(op, nod1.type), &nod1, &nod); - } else { - regalloc(&nod, nr->type, res); - cgen(nr, &nod); - regalloc(&nod1, nl->type, Z); - cgen(nl, &nod1); - p = gins(optoas(op, nod.type), &nod, &nod); - naddr(&nod1, &ta); - p->reg = ta.reg; - } - gins(optoas(OAS, nod.type), &nod, res); - regfree(&nod); - regfree(&nod1); -} - -/* - * generate shift according to op, one of: - * res = nl << nr - * res = nl >> nr - */ -// TODO(kaib): rip out and replace with simple isntruction -void -cgen_shift(int op, Node *nl, Node *nr, Node *res) -{ - fatal("cgen_shift not implemented"); -// Node n1, n2, n3; -// int a; -// Prog *p1; - -// a = optoas(op, nl->type); - -// if(nr->op == OLITERAL) { -// regalloc(&n1, nl->type, res); -// cgen(nl, &n1); -// if(mpgetfix(nr->val.u.xval) >= nl->type->width*8) { -// // large shift gets 2 shifts by width -// nodconst(&n3, types[TUINT32], nl->type->width*8-1); -// gins(a, &n3, &n1); -// gins(a, &n3, &n1); -// } else -// gins(a, nr, &n1); -// gmove(&n1, res); -// regfree(&n1); -// goto ret; -// } - -// nodreg(&n1, types[TUINT32], D_CX); -// regalloc(&n1, nr->type, &n1); // to hold the shift type in CX -// regalloc(&n3, types[TUINT64], &n1); // to clear high bits of CX - -// regalloc(&n2, nl->type, res); -// if(nl->ullman >= nr->ullman) { -// cgen(nl, &n2); -// cgen(nr, &n1); -// gmove(&n1, &n3); -// } else { -// cgen(nr, &n1); -// gmove(&n1, &n3); -// cgen(nl, &n2); -// } -// regfree(&n3); - -// // test and fix up large shifts -// nodconst(&n3, types[TUINT64], nl->type->width*8); -// gins(optoas(OCMP, types[TUINT64]), &n1, &n3); -// p1 = gbranch(optoas(OLT, types[TUINT64]), T); -// if(op == ORSH && issigned[nl->type->etype]) { -// nodconst(&n3, types[TUINT32], nl->type->width*8-1); -// gins(a, &n3, &n2); -// } else { -// nodconst(&n3, nl->type, 0); -// gmove(&n3, &n2); -// } -// patch(p1, pc); -// gins(a, &n1, &n2); - -// gmove(&n2, res); - -// regfree(&n1); -// regfree(&n2); - -//ret: -// ; -} - -/* - * generate byte multiply: - * res = nl * nr - * no byte multiply instruction so have to do - * 16-bit multiply and take bottom half. - */ -// TODO(kaib): figure out if we can replace this normal multiply -void -cgen_bmul(int op, Node *nl, Node *nr, Node *res) -{ - fatal("cgen_bmul not implemented"); -// Node n1b, n2b, n1w, n2w; -// Type *t; -// int a; - -// if(nl->ullman >= nr->ullman) { -// regalloc(&n1b, nl->type, res); -// cgen(nl, &n1b); -// regalloc(&n2b, nr->type, N); -// cgen(nr, &n2b); -// } else { -// regalloc(&n2b, nr->type, N); -// cgen(nr, &n2b); -// regalloc(&n1b, nl->type, res); -// cgen(nl, &n1b); -// } - -// // copy from byte to short registers -// t = types[TUINT16]; -// if(issigned[nl->type->etype]) -// t = types[TINT16]; - -// regalloc(&n2w, t, &n2b); -// cgen(&n2b, &n2w); - -// regalloc(&n1w, t, &n1b); -// cgen(&n1b, &n1w); - -// a = optoas(op, t); -// gins(a, &n2w, &n1w); -// cgen(&n1w, &n1b); -// cgen(&n1b, res); - -// regfree(&n1w); -// regfree(&n2w); -// regfree(&n1b); -// regfree(&n2b); -} - void clearfat(Node *nl) { - fatal("clearfat not implemented"); -// uint32 w, c, q; -// Node n1; + uint32 w, c, q; + Node dst, nc, nz; + Prog *p; -// /* clear a fat object */ -// if(debug['g']) -// dump("\nclearfat", nl); + /* clear a fat object */ + if(debug['g']) + dump("\nclearfat", nl); -// w = nl->type->width; -// c = w % 8; // bytes -// q = w / 8; // quads + w = nl->type->width; + c = w % 4; // bytes + q = w / 4; // quads -// gconreg(AMOVQ, 0, D_AX); -// nodreg(&n1, types[tptr], D_DI); -// agen(nl, &n1); + regalloc(&dst, types[tptr], N); + agen(nl, &dst); + nodconst(&nc, types[TUINT32], 0); + regalloc(&nz, types[TUINT32], 0); + cgen(&nc, &nz); -// if(q >= 4) { + if(q >= 4) { + fatal("clearfat q >=4 not implemented"); // gconreg(AMOVQ, q, D_CX); // gins(AREP, N, N); // repeat // gins(ASTOSQ, N, N); // STOQ AL,*(DI)+ -// } else -// while(q > 0) { -// gins(ASTOSQ, N, N); // STOQ AL,*(DI)+ -// q--; -// } + } else + while(q > 0) { + p = gins(AMOVW, &nz, &dst); + p->to.type = D_OREG; + p->to.offset = 4; + p->scond |= C_PBIT; +//print("1. %P\n", p); + q--; + } -// if(c >= 4) { -// gconreg(AMOVQ, c, D_CX); -// gins(AREP, N, N); // repeat -// gins(ASTOSB, N, N); // STOB AL,*(DI)+ -// } else -// while(c > 0) { -// gins(ASTOSB, N, N); // STOB AL,*(DI)+ -// c--; -// } + while(c > 0) { + gins(AMOVBU, &nz, &dst); + p->to.type = D_OREG; + p->to.offset = 1; + p->scond |= C_PBIT; +//print("2. %P\n", p); + c--; + } + regfree(&dst); + regfree(&nz); } int diff --git a/src/cmd/5g/gobj.c b/src/cmd/5g/gobj.c index 28cb10f6dd..4606a0e380 100644 --- a/src/cmd/5g/gobj.c +++ b/src/cmd/5g/gobj.c @@ -596,7 +596,7 @@ out: p->reg = 7; p->to.offset2 = 0; p->to.reg = NREG; -print("1. %P\n", p); +//print("1. %P\n", p); o = 0; for(c=d-1; c>=0; c--) { @@ -613,7 +613,7 @@ print("1. %P\n", p); p->from.offset = o; p->to.type = D_REG; p->to.reg = REGARG; -print("2. %P\n", p); +//print("2. %P\n", p); o = 0; } if(o != 0) { @@ -625,7 +625,7 @@ print("2. %P\n", p); p->from.offset = o; p->to.type = D_REG; p->to.reg = REGARG; -print("3. %P\n", p); +//print("3. %P\n", p); } f = dotlist[0].field; @@ -638,7 +638,7 @@ print("3. %P\n", p); p->to.reg = NREG; p->to.name = D_EXTERN; p->to.sym = methodsym(method->sym, ptrto(f->type)); -print("4. %P\n", p); +//print("4. %P\n", p); pc->as = ARET; // overwrite AEND } diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index ea05e09812..3587703160 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -393,8 +393,8 @@ gconreg(int as, vlong c, int reg) { Node n1, n2; - nodconst(&n1, types[TINT64], c); - nodreg(&n2, types[TINT64], reg); + nodconst(&n1, types[TINT32], c); + nodreg(&n2, types[TINT32], reg); gins(as, &n1, &n2); } @@ -489,18 +489,21 @@ gmove(Node *f, Node *t) * integer copy and truncate */ case CASE(TINT8, TINT8): // same size - case CASE(TINT8, TUINT8): case CASE(TUINT8, TINT8): - case CASE(TUINT8, TUINT8): case CASE(TINT16, TINT8): // truncate case CASE(TUINT16, TINT8): case CASE(TINT32, TINT8): case CASE(TUINT32, TINT8): + a = AMOVB; + break; + + case CASE(TINT8, TUINT8): + case CASE(TUINT8, TUINT8): case CASE(TINT16, TUINT8): case CASE(TUINT16, TUINT8): case CASE(TINT32, TUINT8): case CASE(TUINT32, TUINT8): - a = AMOVB; + a = AMOVBU; break; case CASE(TINT64, TINT8): // truncate low word @@ -516,14 +519,17 @@ gmove(Node *f, Node *t) return; case CASE(TINT16, TINT16): // same size - case CASE(TINT16, TUINT16): case CASE(TUINT16, TINT16): - case CASE(TUINT16, TUINT16): case CASE(TINT32, TINT16): // truncate case CASE(TUINT32, TINT16): + a = AMOVH; + break; + + case CASE(TINT16, TUINT16): + case CASE(TUINT16, TUINT16): case CASE(TINT32, TUINT16): case CASE(TUINT32, TUINT16): - a = AMOVH; + a = AMOVHU; break; case CASE(TINT64, TINT16): // truncate low word @@ -582,45 +588,41 @@ gmove(Node *f, Node *t) /* * integer up-conversions */ -// case CASE(TINT8, TINT16): // sign extend int8 -// case CASE(TINT8, TUINT16): -// a = AMOVBWSX; -// goto rdst; -// case CASE(TINT8, TINT32): -// case CASE(TINT8, TUINT32): -// a = AMOVBLSX; -// goto rdst; + case CASE(TINT8, TINT16): // sign extend int8 + case CASE(TINT8, TUINT16): + case CASE(TINT8, TINT32): + case CASE(TINT8, TUINT32): + a = AMOVB; + goto rdst; // case CASE(TINT8, TINT64): // convert via int32 // case CASE(TINT8, TUINT64): // cvt = types[TINT32]; // goto hard; -// case CASE(TUINT8, TINT16): // zero extend uint8 -// case CASE(TUINT8, TUINT16): -// a = AMOVBWZX; -// goto rdst; -// case CASE(TUINT8, TINT32): -// case CASE(TUINT8, TUINT32): -// a = AMOVBLZX; -// goto rdst; + case CASE(TUINT8, TINT16): // zero extend uint8 + case CASE(TUINT8, TUINT16): + case CASE(TUINT8, TINT32): + case CASE(TUINT8, TUINT32): + a = AMOVBU; + goto rdst; // case CASE(TUINT8, TINT64): // convert via uint32 // case CASE(TUINT8, TUINT64): // cvt = types[TUINT32]; // goto hard; -// case CASE(TINT16, TINT32): // sign extend int16 -// case CASE(TINT16, TUINT32): -// a = AMOVWLSX; -// goto rdst; + case CASE(TINT16, TINT32): // sign extend int16 + case CASE(TINT16, TUINT32): + a = AMOVH; + goto rdst; // case CASE(TINT16, TINT64): // convert via int32 // case CASE(TINT16, TUINT64): // cvt = types[TINT32]; // goto hard; -// case CASE(TUINT16, TINT32): // zero extend uint16 -// case CASE(TUINT16, TUINT32): -// a = AMOVWLZX; -// goto rdst; + case CASE(TUINT16, TINT32): // zero extend uint16 + case CASE(TUINT16, TUINT32): + a = AMOVHU; + goto rdst; // case CASE(TUINT16, TINT64): // convert via uint32 // case CASE(TUINT16, TUINT64): // cvt = types[TUINT32]; @@ -728,7 +730,9 @@ gmove(Node *f, Node *t) gins(a, f, t); return; -//rdst: +rdst: + // TODO(kaib): we almost always require a register dest anyway, this can probably be + // removed. // requires register destination regalloc(&r1, t->type, t); gins(a, f, &r1); @@ -1221,21 +1225,15 @@ optoas(int op, Type *t) a = ASUBD; break; -// case CASE(OAND, TINT8): -// case CASE(OAND, TUINT8): -// a = AANDB; -// break; - -// case CASE(OAND, TINT16): -// case CASE(OAND, TUINT16): -// a = AANDW; -// break; - -// case CASE(OAND, TINT32): -// case CASE(OAND, TUINT32): -// case CASE(OAND, TPTR32): -// a = AANDL; -// break; + case CASE(OAND, TINT8): + case CASE(OAND, TUINT8): + case CASE(OAND, TINT16): + case CASE(OAND, TUINT16): + case CASE(OAND, TINT32): + case CASE(OAND, TUINT32): + case CASE(OAND, TPTR32): + a = AAND; + break; // case CASE(OAND, TINT64): // case CASE(OAND, TUINT64): @@ -1243,21 +1241,15 @@ optoas(int op, Type *t) // a = AANDQ; // break; -// case CASE(OOR, TINT8): -// case CASE(OOR, TUINT8): -// a = AORB; -// break; - -// case CASE(OOR, TINT16): -// case CASE(OOR, TUINT16): -// a = AORW; -// break; - -// case CASE(OOR, TINT32): -// case CASE(OOR, TUINT32): -// case CASE(OOR, TPTR32): -// a = AORL; -// break; + case CASE(OOR, TINT8): + case CASE(OOR, TUINT8): + case CASE(OOR, TINT16): + case CASE(OOR, TUINT16): + case CASE(OOR, TINT32): + case CASE(OOR, TUINT32): + case CASE(OOR, TPTR32): + a = AORR; + break; // case CASE(OOR, TINT64): // case CASE(OOR, TUINT64): @@ -1265,21 +1257,15 @@ optoas(int op, Type *t) // a = AORQ; // break; -// case CASE(OXOR, TINT8): -// case CASE(OXOR, TUINT8): -// a = AXORB; -// break; - -// case CASE(OXOR, TINT16): -// case CASE(OXOR, TUINT16): -// a = AXORW; -// break; - -// case CASE(OXOR, TINT32): -// case CASE(OXOR, TUINT32): -// case CASE(OXOR, TPTR32): -// a = AXORL; -// break; + case CASE(OXOR, TINT8): + case CASE(OXOR, TUINT8): + case CASE(OXOR, TINT16): + case CASE(OXOR, TUINT16): + case CASE(OXOR, TINT32): + case CASE(OXOR, TUINT32): + case CASE(OXOR, TPTR32): + a = AEOR; + break; // case CASE(OXOR, TINT64): // case CASE(OXOR, TUINT64): @@ -1287,21 +1273,15 @@ optoas(int op, Type *t) // a = AXORQ; // break; -// case CASE(OLSH, TINT8): -// case CASE(OLSH, TUINT8): -// a = ASHLB; -// break; - -// case CASE(OLSH, TINT16): -// case CASE(OLSH, TUINT16): -// a = ASHLW; -// break; - -// case CASE(OLSH, TINT32): -// case CASE(OLSH, TUINT32): -// case CASE(OLSH, TPTR32): -// a = ASHLL; -// break; + case CASE(OLSH, TINT8): + case CASE(OLSH, TUINT8): + case CASE(OLSH, TINT16): + case CASE(OLSH, TUINT16): + case CASE(OLSH, TINT32): + case CASE(OLSH, TUINT32): + case CASE(OLSH, TPTR32): + a = ASLL; + break; // case CASE(OLSH, TINT64): // case CASE(OLSH, TUINT64): @@ -1309,47 +1289,38 @@ optoas(int op, Type *t) // a = ASHLQ; // break; -// case CASE(ORSH, TUINT8): -// a = ASHRB; -// break; - -// case CASE(ORSH, TUINT16): -// a = ASHRW; -// break; - -// case CASE(ORSH, TUINT32): -// case CASE(ORSH, TPTR32): -// a = ASHRL; -// break; + case CASE(ORSH, TUINT8): + case CASE(ORSH, TUINT16): + case CASE(ORSH, TUINT32): + case CASE(ORSH, TPTR32): + a = ASRL; + break; // case CASE(ORSH, TUINT64): // case CASE(ORSH, TPTR64): // a = ASHRQ; // break; -// case CASE(ORSH, TINT8): -// a = ASARB; -// break; - -// case CASE(ORSH, TINT16): -// a = ASARW; -// break; - -// case CASE(ORSH, TINT32): -// a = ASARL; -// break; + case CASE(ORSH, TINT8): + case CASE(ORSH, TINT16): + case CASE(ORSH, TINT32): + a = ASRA; + break; // case CASE(ORSH, TINT64): // a = ASARQ; // break; - case CASE(OMUL, TINT8): case CASE(OMUL, TUINT8): - case CASE(OMUL, TINT16): case CASE(OMUL, TUINT16): - case CASE(OMUL, TINT32): case CASE(OMUL, TUINT32): case CASE(OMUL, TPTR32): + a = AMULU; + break; + + case CASE(OMUL, TINT8): + case CASE(OMUL, TINT16): + case CASE(OMUL, TINT32): a = AMUL; break; @@ -1359,31 +1330,37 @@ optoas(int op, Type *t) // a = AIMULQ; // break; -// case CASE(OMUL, TFLOAT32): -// a = AMULSS; -// break; + case CASE(OMUL, TFLOAT32): + a = AMULF; + break; -// case CASE(OMUL, TFLOAT64): -// a = AMULSD; -// break; + case CASE(OMUL, TFLOAT64): + a = AMULD; + break; - case CASE(ODIV, TINT8): case CASE(ODIV, TUINT8): - case CASE(ODIV, TINT16): case CASE(ODIV, TUINT16): - case CASE(ODIV, TINT32): case CASE(ODIV, TUINT32): case CASE(ODIV, TPTR32): + a = ADIVU; + break; + + case CASE(ODIV, TINT8): + case CASE(ODIV, TINT16): + case CASE(ODIV, TINT32): a = ADIV; break; - case CASE(OMOD, TINT8): case CASE(OMOD, TUINT8): - case CASE(OMOD, TINT16): case CASE(OMOD, TUINT16): - case CASE(OMOD, TINT32): case CASE(OMOD, TUINT32): case CASE(OMOD, TPTR32): + a = AMODU; + break; + + case CASE(OMOD, TINT8): + case CASE(OMOD, TINT16): + case CASE(OMOD, TINT32): a = AMOD; break; @@ -1411,13 +1388,13 @@ optoas(int op, Type *t) // a = ACQO; // break; -// case CASE(ODIV, TFLOAT32): -// a = ADIVSS; -// break; + case CASE(ODIV, TFLOAT32): + a = ADIVF; + break; -// case CASE(ODIV, TFLOAT64): -// a = ADIVSD; -// break; + case CASE(ODIV, TFLOAT64): + a = ADIVD; + break; } return a; @@ -1621,9 +1598,9 @@ oindex: n2.type = types[tptr]; n2.xoffset = Array_nel; } else { - nodconst(&n2, types[TUINT64], l->type->bound); + nodconst(&n2, types[TUINT32], l->type->bound); if(o & OPtrto) - nodconst(&n2, types[TUINT64], l->type->type->bound); + nodconst(&n2, types[TUINT32], l->type->type->bound); } gins(optoas(OCMP, types[TUINT32]), reg1, &n2); p1 = gbranch(optoas(OLT, types[TUINT32]), T); @@ -1666,7 +1643,7 @@ oindex_const: n1.op = OINDREG; n1.type = types[tptr]; n1.xoffset = Array_nel; - nodconst(&n2, types[TUINT64], v); + nodconst(&n2, types[TUINT32], v); gins(optoas(OCMP, types[TUINT32]), &n1, &n2); p1 = gbranch(optoas(OGT, types[TUINT32]), T); ginscall(throwindex, 0);