📄 cgen64.c
字号:
l = t; } break; case IMM(0, 1): if(dr) t = nn; else t = regpair(Z, n); sugen(l, t, 8); l = t; break; case IMM(1, 0): if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) { lri = IMM(0, 0); goto bin00; } if(dr) t = nn; else t = regpair(Z, n); sugen(r, t, 8); r = t; break; case IMM(1, 1): break; }#define WW(l, r) ((l) | ((r) << 2)) d = Z; dt = nn->type; nn->type = types[TLONG]; switch(lri) { case IMM(0, 0): biggen(l, r, Z, 0, binop00, args); break; case IMM(0, 1): switch(ri) { case WNONE: diag(r, "bad whatof\n"); break; case WCONST: biggen(l, r, Z, 0, optab[B0c], args); break; case WHARD: reglcgen(&nod2, r, Z); r = &nod2; /* fall thru */ case WADDR: biggen(l, r, Z, 0, binoptmp, args); if(ri == WHARD) regfree(r); break; } break; case IMM(1, 0): if(n->op == OSUB) { switch(li) { case WNONE: diag(l, "bad whatof\n"); break; case WHARD: reglcgen(&nod2, l, Z); l = &nod2; /* fall thru */ case WADDR: case WCONST: biggen(l, r, Z, 0, sub10, args); break; } if(li == WHARD) regfree(l); } else { switch(li) { case WNONE: diag(l, "bad whatof\n"); break; case WCONST: biggen(r, l, Z, 0, optab[B0c], args); break; case WHARD: reglcgen(&nod2, l, Z); l = &nod2; /* fall thru */ case WADDR: biggen(r, l, Z, 0, binoptmp, args); if(li == WHARD) regfree(l); break; } } break; case IMM(1, 1): switch(WW(li, ri)) { case WW(WCONST, WHARD): if(r->op == ONAME && n->op == OAND && reduxv(l)) ri = WADDR; break; case WW(WHARD, WCONST): if(l->op == ONAME && n->op == OAND && reduxv(r)) li = WADDR; break; } if(li == WHARD) { reglcgen(&nod3, l, Z); l = &nod3; } if(ri == WHARD) { reglcgen(&nod2, r, Z); r = &nod2; } d = regpair(nn, n); instpair(d, Z); switch(WW(li, ri)) { case WW(WCONST, WADDR): case WW(WCONST, WHARD): biggen(l, r, d, 0, optab[Bca], args); break; case WW(WADDR, WCONST): case WW(WHARD, WCONST): biggen(l, r, d, 0, optab[Bac], args); break; case WW(WADDR, WADDR): case WW(WADDR, WHARD): case WW(WHARD, WADDR): case WW(WHARD, WHARD): biggen(l, r, d, 0, binop11, args); break; default: diag(r, "bad whatof pair %d %d\n", li, ri); break; } if(li == WHARD) regfree(l); if(ri == WHARD) regfree(r); break; } nn->type = dt; if(d != Z) goto finished; switch(lri) { case IMM(0, 0): freepair(r); /* fall thru */; case IMM(0, 1): if(!dr) storepair(l, nn, 1); break; case IMM(1, 0): if(!dr) storepair(r, nn, 1); break; case IMM(1, 1): break; } return 1; shift: c = Z; /* evaluate hard subexps, stealing nn if possible. */ /* must also secure CX. not as many optims as binop. */ switch(lri) { case IMM(0, 0): imm00: if(l->complex + 1 > r->complex) { if(dr) t = nn; else t = regpair(Z, l); sugen(l, t, 8); l = t; t = &nod1; c = snarfreg(l, t, D_CX, r, &nod2); cgen(r, t); r = t; } else { t = &nod1; c = snarfreg(nn, t, D_CX, r, &nod2); cgen(r, t); r = t; if(dr) t = nn; else t = regpair(Z, l); sugen(l, t, 8); l = t; } break; case IMM(0, 1): imm01: if(ri != WCONST) { lri = IMM(0, 0); goto imm00; } if(dr) t = nn; else t = regpair(Z, n); sugen(l, t, 8); l = t; break; case IMM(1, 0): imm10: if(li != WCONST) { lri = IMM(0, 0); goto imm00; } t = &nod1; c = snarfreg(nn, t, D_CX, r, &nod2); cgen(r, t); r = t; break; case IMM(1, 1): if(ri != WCONST) { lri = IMM(1, 0); goto imm10; } if(li == WHARD) { lri = IMM(0, 1); goto imm01; } break; } d = Z; switch(lri) { case IMM(0, 0): biggen(l, r, Z, 0, optab[S00], args); break; case IMM(0, 1): switch(ri) { case WNONE: case WADDR: case WHARD: diag(r, "bad whatof\n"); break; case WCONST: m = r->vconst & 63; s = nodconst(m); if(m < 32) cp = optab[Sc0]; else if(m == 32) cp = optab[Sc1]; else cp = optab[Sc2]; biggen(l, s, Z, 0, cp, args); break; } break; case IMM(1, 0): /* left is const */ d = regpair(nn, n); instpair(d, Z); biggen(l, r, d, 0, optab[S10], args); regfree(r); break; case IMM(1, 1): d = regpair(nn, n); instpair(d, Z); switch(WW(li, ri)) { case WW(WADDR, WCONST): m = r->vconst & 63; s = nodconst(m); if(m < 32) { loadpair(l, d); l = d; cp = optab[Sc0]; } else if(m == 32) cp = optab[Sac3]; else cp = optab[Sac4]; biggen(l, s, d, 0, cp, args); break; default: diag(r, "bad whatof pair %d %d\n", li, ri); break; } break; } if(c != Z) { gins(AMOVL, c, r); regfree(c); } if(d != Z) goto finished; switch(lri) { case IMM(0, 0): regfree(r); /* fall thru */ case IMM(0, 1): if(!dr) storepair(l, nn, 1); break; case IMM(1, 0): regfree(r); break; case IMM(1, 1): break; } return 1; cmp: op = n->op; /* evaluate hard subexps */ switch(lri) { case IMM(0, 0): if(l->complex > r->complex) { t = regpair(Z, l); sugen(l, t, 8); l = t; t = regpair(Z, r); sugen(r, t, 8); r = t; } else { t = regpair(Z, r); sugen(r, t, 8); r = t; t = regpair(Z, l); sugen(l, t, 8); l = t; } break; case IMM(1, 0): t = r; r = l; l = t; ri = li; op = invrel[relindex(op)]; /* fall thru */ case IMM(0, 1): t = regpair(Z, l); sugen(l, t, 8); l = t; break; case IMM(1, 1): break; } true = 1; optab = cmptab; switch(op) { case OEQ: optab = NEtab; true = 0; break; case ONE: optab = NEtab; break; case OLE: args = GTargs; true = 0; break; case OGT: args = GTargs; break; case OLS: args = HIargs; true = 0; break; case OHI: args = HIargs; break; case OLT: args = GEargs; true = 0; break; case OGE: args = GEargs; break; case OLO: args = HSargs; true = 0; break; case OHS: args = HSargs; break; default: diag(n, "bad cmp\n"); SET(optab); } switch(lri) { case IMM(0, 0): biggen(l, r, Z, true, optab[T0i], args); break; case IMM(0, 1): case IMM(1, 0): switch(ri) { case WNONE: diag(l, "bad whatof\n"); break; case WCONST: biggen(l, r, Z, true, optab[T0i], args); break; case WHARD: reglcgen(&nod2, r, Z); r = &nod2; /* fall thru */ case WADDR: biggen(l, r, Z, true, optab[T0i], args); if(ri == WHARD) regfree(r); break; } break; case IMM(1, 1): if(li == WHARD) { reglcgen(&nod3, l, Z); l = &nod3; } if(ri == WHARD) { reglcgen(&nod2, r, Z); r = &nod2; } biggen(l, r, Z, true, optab[Tii], args); if(li == WHARD) regfree(l); if(ri == WHARD) regfree(r); break; } switch(lri) { case IMM(0, 0): freepair(r); /* fall thru */; case IMM(0, 1): case IMM(1, 0): freepair(l); break; case IMM(1, 1): break; } return 1; case OASMUL: case OASLMUL: m = 0; goto mulop; case OMUL: case OLMUL: m = 1; goto mulop; mulop: dr = nn != Z && nn->op == OREGPAIR; l = vfunc(n->left, nn); r = vfunc(n->right, nn); if(r->op != OCONST) { if(l->complex > r->complex) { if(m) { t = l; l = r; r = t; } else if(!vaddr(l, 1)) { reglcgen(&nod5, l, Z); l = &nod5; evacaxdx(l); } } t = regpair(Z, n); sugen(r, t, 8); r = t; evacaxdx(r->left); evacaxdx(r->right); if(l->complex <= r->complex && !m && !vaddr(l, 1)) { reglcgen(&nod5, l, Z); l = &nod5; evacaxdx(l); } } if(dr) t = nn; else t = regpair(Z, n); c = Z; d = Z; if(!nodreg(&nod1, t->left, D_AX)) { if(t->left->reg != D_AX){ t->left->reg = D_AX; reg[D_AX]++; }else if(reg[D_AX] == 0) fatal(Z, "vlong mul AX botch"); } if(!nodreg(&nod2, t->right, D_DX)) { if(t->right->reg != D_DX){ t->right->reg = D_DX; reg[D_DX]++; }else if(reg[D_DX] == 0) fatal(Z, "vlong mul DX botch"); } if(m) sugen(l, t, 8); else loadpair(l, t); if(t->left->reg != D_AX) { c = &nod3; regsalloc(c, t->left); gmove(&nod1, c); gmove(t->left, &nod1); zapreg(t->left); } if(t->right->reg != D_DX) { d = &nod4; regsalloc(d, t->right); gmove(&nod2, d); gmove(t->right, &nod2); zapreg(t->right); } if(c != Z || d != Z) { s = regpair(Z, n); s->left = &nod1; s->right = &nod2; } else s = t; if(r->op == OCONST) { if(hi64v(r) == 0) biggen(s, r, Z, 0, mulc32, nil); else biggen(s, r, Z, 0, mulc64, nil); } else biggen(s, r, Z, 0, mull, nil); instpair(t, Z); if(c != Z) { gmove(&nod1, t->left); gmove(&nod3, &nod1); } if(d != Z) { gmove(&nod2, t->right); gmove(&nod4, &nod2); } if(r->op == OREGPAIR) freepair(r); if(!m) storepair(t, l, 0); if(l == &nod5) regfree(l); if(!dr) { if(nn != Z) storepair(t, nn, 1); else freepair(t); } return 1; case OASADD: args = ADDargs; goto vasop; case OASAND: args = ANDargs; goto vasop; case OASOR: args = ORargs; goto vasop; case OASSUB: args = SUBargs; goto vasop; case OASXOR: args = XORargs; goto vasop; vasop: l = n->left; r = n->right; dr = nn != Z && nn->op == OREGPAIR; m = 0; if(l->complex > r->complex) { if(!vaddr(l, 1)) { reglcgen(&nod1, l, Z); l = &nod1; } if(!vaddr(r, 1) || nn != Z || r->op == OCONST) { if(dr) t = nn; else t = regpair(Z, r); sugen(r, t, 8); r = t; m = 1; } } else { if(!vaddr(r, 1) || nn != Z || r->op == OCONST) { if(dr) t = nn; else t = regpair(Z, r); sugen(r, t, 8); r = t; m = 1; } if(!vaddr(l, 1)) { reglcgen(&nod1, l, Z); l = &nod1; } } if(nn != Z) { if(n->op == OASSUB) biggen(l, r, Z, 0, sub10, args); else biggen(r, l, Z, 0, binoptmp, args); storepair(r, l, 0); } else { if(m) biggen(l, r, Z, 0, binop00, args); else biggen(l, r, Z, 0, binoptmp, args); } if(l == &nod1) regfree(&nod1); if(m) { if(nn == Z) freepair(r); else if(!dr) storepair(r, nn, 1); } return 1; case OASASHL: args = nil; optab = asshlltab; goto assh; case OASLSHR: args = shrlargs; optab = asshrltab; goto assh; case OASASHR: args = sarlargs; optab = asshrltab; goto assh; assh: c = Z; l = n->left; r = n->right; if(r->op == OCONST) { m = r->vconst & 63; if(m < 32) m = SAclo; else if(m == 32) m = SAc32; else m = SAchi; } else m = SAgen; if(l->complex > r->complex) { if(!vaddr(l, 0)) { reglcgen(&nod1, l, Z); l = &nod1; } if(m == SAgen) { t = &nod2; if(l->reg == D_CX) { regalloc(t, r, Z); gmove(l, t); l->reg = t->reg; t->reg = D_CX; } else c = snarfreg(nn, t, D_CX, r, &nod3); cgen(r, t); r = t; } } else { if(m == SAgen) { t = &nod2; c = snarfreg(nn, t, D_CX, r, &nod3); cgen(r, t); r = t; } if(!vaddr(l, 0)) { reglcgen(&nod1, l, Z); l = &nod1; } } if(nn != Z) { m += SAdgen - SAgen; d = regpair(nn, n); instpair(d, Z); biggen(l, r, d, 0, optab[m], args); if(l == &nod1) { regfree(&nod1); l = Z; } if(r == &nod2 && c == Z) { regfree(&nod2); r = Z; } if(d != nn) storepair(d, nn, 1); } else biggen(l, r, Z, 0, optab[m], args); if(c != Z) { gins(AMOVL, c, r); regfree(c); } if(l == &nod1) regfree(&nod1); if(r == &nod2) regfree(&nod2); return 1; case OPOSTINC: args = ADDargs; cp = incdecpost; goto vinc; case OPOSTDEC: args = SUBargs; cp = incdecpost; goto vinc; case OPREINC: args = ADDargs; cp = incdecpre; goto vinc; case OPREDEC: args = SUBargs; cp = incdecpre; goto vinc; vinc: l = n->left; if(!vaddr(l, 1)) { reglcgen(&nod1, l, Z); l = &nod1; } if(nn != Z) { d = regpair(nn, n); instpair(d, Z); biggen(l, Z, d, 0, cp, args); if(l == &nod1) { regfree(&nod1); l = Z; } if(d != nn) storepair(d, nn, 1); } else biggen(l, Z, Z, 0, incdec, args); if(l == &nod1) regfree(&nod1); return 1; case OCAST: l = n->left; if(typev[l->type->etype]) { if(!vaddr(l, 1)) { if(l->complex + 1 > nn->complex) { d = regpair(Z, l); sugen(l, d, 8); if(!vaddr(nn, 1)) { reglcgen(&nod1, nn, Z); r = &nod1; } else r = nn; } else { if(!vaddr(nn, 1)) { reglcgen(&nod1, nn, Z); r = &nod1; } else r = nn; d = regpair(Z, l); sugen(l, d, 8); }// d->left->type = r->type; d->left->type = types[TLONG]; gmove(d->left, r); freepair(d); } else { if(nn->op != OREGISTER && !vaddr(nn, 1)) { reglcgen(&nod1, nn, Z); r = &nod1; } else r = nn;// l->type = r->type; l->type = types[TLONG]; gmove(l, r); } if(r != nn) regfree(r); } else { if(typeu[l->type->etype] || cond(l->op)) si = TUNSIGNED; else si = TSIGNED; regalloc(&nod1, l, Z); cgen(l, &nod1); if(nn->op == OREGPAIR) { m = instpair(nn, &nod1); biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil); } else { m = 0; if(!vaddr(nn, si != TSIGNED)) { dt = nn->type; nn->type = types[TLONG]; reglcgen(&nod2, nn, Z); nn->type = dt; nn = &nod2; } dt = nn->type; nn->type = types[TLONG]; biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil); nn->type = dt; if(nn == &nod2) regfree(&nod2); } if(!m) regfree(&nod1); } return 1; default: if(n->op == OREGPAIR) { storepair(n, nn, 1); return 1; } if(nn->op == OREGPAIR) { loadpair(n, nn); return 1; } return 0; }finished: if(d != nn) storepair(d, nn, 1); return 1;}voidtestv(Node *n, int true){ Type *t; Node *nn, nod, *b; if(machcap(Z)) { b = &nod; b->op = true ? ONE : OEQ; b->left = n; b->right = new(0, Z, Z); *b->right = *nodconst(0); b->right->type = n->type; b->type = types[TLONG]; cgen64(b, Z); return; } switch(n->op) { case OINDREG: case ONAME: biggen(n, Z, Z, true, testi, nil); break; default: n = vfunc(n, n); if(n->addable >= INDEXED) { t = n->type; n->type = types[TLONG]; reglcgen(&nod, n, Z); n->type = t; n = &nod; biggen(n, Z, Z, true, testi, nil); if(n == &nod) regfree(n); } else { nn = regpair(Z, n); sugen(n, nn, 8); biggen(nn, Z, Z, true, testi, nil); freepair(nn); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -