📄 cgen.c
字号:
if(n->addable < INDEXED) { cgen(n, &fregnode0); gins(AFLDZ, Z, Z); fgopcode(o, &fregnode0, &fregnode1, 1, 1); } else { gins(AFLDZ, Z, Z); fgopcode(o, n, &fregnode0, 0, 1); } goto com; } /* bad, 13 is address of external that becomes constant */ if(n->addable >= INDEXED && n->addable != 13) { gopcode(o, n->type, n, nodconst(0)); goto com; } regalloc(&nod, n, nn); cgen(n, &nod); gopcode(o, n->type, &nod, nodconst(0)); regfree(&nod); goto com; case OCONST: o = vconst(n); if(!true) o = !o; gbranch(OGOTO); if(o) { p1 = p; gbranch(OGOTO); patch(p1, pc); } goto com; case OCOMMA: cgen(l, Z); boolgen(r, true, nn); break; case ONOT: boolgen(l, !true, nn); break; case OCOND: bcgen(l, 1); p1 = p; bcgen(r->left, true); p2 = p; gbranch(OGOTO); patch(p1, pc); p1 = p; bcgen(r->right, !true); patch(p2, pc); p2 = p; gbranch(OGOTO); patch(p1, pc); patch(p2, pc); goto com; case OANDAND: if(!true) goto caseor; caseand: bcgen(l, true); p1 = p; bcgen(r, !true); p2 = p; patch(p1, pc); gbranch(OGOTO); patch(p2, pc); goto com; case OOROR: if(!true) goto caseand; caseor: bcgen(l, !true); p1 = p; bcgen(r, !true); p2 = p; gbranch(OGOTO); patch(p1, pc); patch(p2, pc); goto com; case OEQ: case ONE: case OLE: case OLT: case OGE: case OGT: case OHI: case OHS: case OLO: case OLS: o = n->op; if(typev[l->type->etype]) { if(!true) n->op = comrel[relindex(o)]; cgen64(n, Z); goto com; } if(true) o = comrel[relindex(o)]; if(l->complex >= FNX && r->complex >= FNX) { regret(&nod, r); cgen(r, &nod); regsalloc(&nod1, r); gmove(&nod, &nod1); regfree(&nod); nod = *n; nod.right = &nod1; boolgen(&nod, true, nn); break; } if(typefd[l->type->etype]) { if(l->complex >= r->complex) { cgen(l, &fregnode0); if(r->addable < INDEXED) { cgen(r, &fregnode0); o = invrel[relindex(o)]; fgopcode(o, &fregnode0, &fregnode1, 1, 1); } else fgopcode(o, r, &fregnode0, 0, 1); } else { o = invrel[relindex(o)]; cgen(r, &fregnode0); if(l->addable < INDEXED) { cgen(l, &fregnode0); o = invrel[relindex(o)]; fgopcode(o, &fregnode0, &fregnode1, 1, 1); } else fgopcode(o, l, &fregnode0, 0, 1); } goto com; } if(l->op == OCONST) { o = invrel[relindex(o)]; /* bad, 13 is address of external that becomes constant */ if(r->addable < INDEXED || r->addable == 13) { regalloc(&nod, r, nn); cgen(r, &nod); gopcode(o, l->type, &nod, l); regfree(&nod); } else gopcode(o, l->type, r, l); goto com; } if(l->complex >= r->complex) { regalloc(&nod, l, nn); cgen(l, &nod); if(r->addable < INDEXED) { regalloc(&nod1, r, Z); cgen(r, &nod1); gopcode(o, l->type, &nod, &nod1); regfree(&nod1); } else gopcode(o, l->type, &nod, r); regfree(&nod); goto com; } regalloc(&nod, r, nn); cgen(r, &nod); if(l->addable < INDEXED || l->addable == 13) { regalloc(&nod1, l, Z); cgen(l, &nod1); if(typechlp[l->type->etype]) gopcode(o, types[TINT], &nod1, &nod); else gopcode(o, l->type, &nod1, &nod); regfree(&nod1); } else gopcode(o, l->type, l, &nod); regfree(&nod); com: if(nn != Z) { p1 = p; gmove(nodconst(1L), nn); gbranch(OGOTO); p2 = p; patch(p1, pc); gmove(nodconst(0L), nn); patch(p2, pc); } break; } cursafe = curs;}voidsugen(Node *n, Node *nn, long w){ Prog *p1; Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r; Type *t; int c, v, x; if(n == Z || n->type == T) return; if(debug['g']) { prtree(nn, "sugen lhs"); prtree(n, "sugen"); } if(nn == nodrat) if(w > nrathole) nrathole = w; switch(n->op) { case OIND: if(nn == Z) { nullwarn(n->left, Z); break; } default: goto copy; case OCONST: if(n->type && typev[n->type->etype]) { if(nn == Z) { nullwarn(n->left, Z); break; } if(nn->op == OREGPAIR) { loadpair(n, nn); break; } else if(!vaddr(nn, 0)) { t = nn->type; nn->type = types[TLONG]; reglcgen(&nod1, nn, Z); nn->type = t; gmove(lo64(n), &nod1); nod1.xoffset += SZ_LONG; gmove(hi64(n), &nod1); regfree(&nod1); } else { gins(AMOVL, lo64(n), nn); nn->xoffset += SZ_LONG; gins(AMOVL, hi64(n), nn); nn->xoffset -= SZ_LONG; break; } break; } goto copy; case ODOT: l = n->left; sugen(l, nodrat, l->type->width); if(nn == Z) break; warn(n, "non-interruptable temporary"); nod1 = *nodrat; r = n->right; if(!r || r->op != OCONST) { diag(n, "DOT and no offset"); break; } nod1.xoffset += (long)r->vconst; nod1.type = n->type; sugen(&nod1, nn, w); break; case OSTRUCT: /* * rewrite so lhs has no fn call */ if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); regret(&nod2, &nod1); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); cgen(&nod2, &nod0); regfree(&nod2); nod1 = *n; nod1.op = OIND; nod1.left = &nod0; nod1.right = Z; nod1.complex = 1; sugen(n, &nod1, w); return; } r = n->left; for(t = n->type->link; t != T; t = t->down) { l = r; if(r->op == OLIST) { l = r->left; r = r->right; } if(nn == Z) { cgen(l, nn); continue; } /* * hand craft *(&nn + o) = l */ nod0 = znode; nod0.op = OAS; nod0.type = t; nod0.left = &nod1; nod0.right = nil; nod1 = znode; nod1.op = OIND; nod1.type = t; nod1.left = &nod2; nod2 = znode; nod2.op = OADD; nod2.type = typ(TIND, t); nod2.left = &nod3; nod2.right = &nod4; nod3 = znode; nod3.op = OADDR; nod3.type = nod2.type; nod3.left = nn; nod4 = znode; nod4.op = OCONST; nod4.type = nod2.type; nod4.vconst = t->offset; ccom(&nod0); acom(&nod0); xcom(&nod0); nod0.addable = 0; nod0.right = l; /* prtree(&nod0, "hand craft"); /* */ cgen(&nod0, Z); } break; case OAS: if(nn == Z) { if(n->addable < INDEXED) sugen(n->right, n->left, w); break; } sugen(n->right, nodrat, w); warn(n, "non-interruptable temporary"); sugen(nodrat, n->left, w); sugen(nodrat, nn, w); break; case OFUNC: if(nn == Z) { sugen(n, nodrat, w); break; } h = nn; if(nn->op == OREGPAIR) { regsalloc(&nod1, nn); nn = &nod1; } if(nn->op != OIND) { nn = new1(OADDR, nn, Z); nn->type = types[TIND]; nn->addable = 0; } else nn = nn->left; n = new(OFUNC, n->left, new(OLIST, nn, n->right)); n->type = types[TVOID]; n->left->type = types[TVOID]; cgen(n, Z); if(h->op == OREGPAIR) loadpair(nn->left, h); break; case OCOND: bcgen(n->left, 1); p1 = p; sugen(n->right->left, nn, w); gbranch(OGOTO); patch(p1, pc); p1 = p; sugen(n->right->right, nn, w); patch(p1, pc); break; case OCOMMA: cgen(n->left, Z); sugen(n->right, nn, w); break; } return;copy: if(nn == Z) { switch(n->op) { case OASADD: case OASSUB: case OASAND: case OASOR: case OASXOR: case OASMUL: case OASLMUL: case OASASHL: case OASASHR: case OASLSHR: break; case OPOSTINC: case OPOSTDEC: case OPREINC: case OPREDEC: break; default: return; } } if(n->complex >= FNX && nn != nil && nn->complex >= FNX) { t = nn->type; nn->type = types[TLONG]; regialloc(&nod1, nn, Z); lcgen(nn, &nod1); regsalloc(&nod2, nn); nn->type = t; gins(AMOVL, &nod1, &nod2); regfree(&nod1); nod2.type = typ(TIND, t); nod1 = nod2; nod1.op = OIND; nod1.left = &nod2; nod1.right = Z; nod1.complex = 1; nod1.type = t; sugen(n, &nod1, w); return; } x = 0; v = w == 8; if(v) { c = cursafe; if(n->left != Z && n->left->complex >= FNX && n->right != Z && n->right->complex >= FNX) {// warn(n, "toughie"); regsalloc(&nod1, n->right); cgen(n->right, &nod1); nod2 = *n; nod2.right = &nod1; cgen(&nod2, nn); cursafe = c; return; } if(cgen64(n, nn)) { cursafe = c; return; } if(n->op == OCOM) { n = n->left; x = 1; } } /* botch, need to save in .safe */ c = 0; if(n->complex > nn->complex) { t = n->type; n->type = types[TLONG]; if(v) { regalloc(&nod0, n, Z); if(!vaddr(n, 0)) { reglcgen(&nod1, n, Z); n->type = t; n = &nod1; } else n->type = t; } else { nodreg(&nod1, n, D_SI); if(reg[D_SI]) { gins(APUSHL, &nod1, Z); c |= 1; reg[D_SI]++; } lcgen(n, &nod1); n->type = t; } t = nn->type; nn->type = types[TLONG]; if(v) { if(!vaddr(nn, 0)) { reglcgen(&nod2, nn, Z); nn->type = t; nn = &nod2; } else nn->type = t; } else { nodreg(&nod2, nn, D_DI); if(reg[D_DI]) { gins(APUSHL, &nod2, Z); c |= 2; reg[D_DI]++; } lcgen(nn, &nod2); nn->type = t; } } else { t = nn->type; nn->type = types[TLONG]; if(v) { regalloc(&nod0, nn, Z); if(!vaddr(nn, 0)) { reglcgen(&nod2, nn, Z); nn->type = t; nn = &nod2; } else nn->type = t; } else { nodreg(&nod2, nn, D_DI); if(reg[D_DI]) { gins(APUSHL, &nod2, Z); c |= 2; reg[D_DI]++; } lcgen(nn, &nod2); nn->type = t; } t = n->type; n->type = types[TLONG]; if(v) { if(!vaddr(n, 0)) { reglcgen(&nod1, n, Z); n->type = t; n = &nod1; } else n->type = t; } else { nodreg(&nod1, n, D_SI); if(reg[D_SI]) { gins(APUSHL, &nod1, Z); c |= 1; reg[D_SI]++; } lcgen(n, &nod1); n->type = t; } } if(v) { gins(AMOVL, n, &nod0); if(x) gins(ANOTL, Z, &nod0); gins(AMOVL, &nod0, nn); n->xoffset += SZ_LONG; nn->xoffset += SZ_LONG; gins(AMOVL, n, &nod0); if(x) gins(ANOTL, Z, &nod0); gins(AMOVL, &nod0, nn); n->xoffset -= SZ_LONG; nn->xoffset -= SZ_LONG; if(nn == &nod2) regfree(&nod2); if(n == &nod1) regfree(&nod1); regfree(&nod0); return; } nodreg(&nod3, n, D_CX); if(reg[D_CX]) { gins(APUSHL, &nod3, Z); c |= 4; reg[D_CX]++; } gins(AMOVL, nodconst(w/SZ_LONG), &nod3); gins(ACLD, Z, Z); gins(AREP, Z, Z); gins(AMOVSL, Z, Z); if(c & 4) { gins(APOPL, Z, &nod3); reg[D_CX]--; } if(c & 2) { gins(APOPL, Z, &nod2); reg[nod2.reg]--; } if(c & 1) { gins(APOPL, Z, &nod1); reg[nod1.reg]--; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -