diff options
| author | forsyth <forsyth@vitanuova.com> | 2010-04-27 22:08:33 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2010-04-27 22:08:33 +0100 |
| commit | f8af978a60a0a00813e7a57f93d9a5ba4df44069 (patch) | |
| tree | d51effe94b54eb087d5436dad8469f548b3f42b6 /utils/5c/cgen.c | |
| parent | 4206ee1aeaccb7703f3f3613a98a5447f51d6367 (diff) | |
20100427-2208
Diffstat (limited to 'utils/5c/cgen.c')
| -rw-r--r-- | utils/5c/cgen.c | 104 |
1 files changed, 58 insertions, 46 deletions
diff --git a/utils/5c/cgen.c b/utils/5c/cgen.c index 01bdb7e2..c639b180 100644 --- a/utils/5c/cgen.c +++ b/utils/5c/cgen.c @@ -1,7 +1,13 @@ #include "gc.h" void -cgen(Node *n, Node *nn, int inrel) +cgen(Node *n, Node *nn) +{ + cgenrel(n, nn, 0); +} + +void +cgenrel(Node *n, Node *nn, int inrel) { Node *l, *r; Prog *p1; @@ -45,7 +51,7 @@ cgen(Node *n, Node *nn, int inrel) switch(o) { default: regret(&nod, r); - cgen(r, &nod, 0); + cgen(r, &nod); regsalloc(&nod1, r); gopcode(OAS, &nod, Z, &nod1); @@ -53,7 +59,7 @@ cgen(Node *n, Node *nn, int inrel) regfree(&nod); nod = *n; nod.right = &nod1; - cgen(&nod, nn, 0); + cgen(&nod, nn); return; case OFUNC: @@ -79,7 +85,7 @@ cgen(Node *n, Node *nn, int inrel) regret(&nod, r); else regalloc(&nod, r, nn); - cgen(r, &nod, 0); + cgen(r, &nod); gmove(&nod, l); if(nn != Z) gmove(&nod, nn); @@ -98,10 +104,10 @@ cgen(Node *n, Node *nn, int inrel) break; } regalloc(&nod, r, nn); - cgen(r, &nod, 0); + cgen(r, &nod); } else { regalloc(&nod, r, nn); - cgen(r, &nod, 0); + cgen(r, &nod); reglcgen(&nod1, l, Z); } gmove(&nod, &nod1); @@ -114,9 +120,9 @@ cgen(Node *n, Node *nn, int inrel) regalloc(&nod, r, nn); if(l->complex >= r->complex) { reglcgen(&nod1, n, Z); - cgen(r, &nod, 0); + cgen(r, &nod); } else { - cgen(r, &nod, 0); + cgen(r, &nod); reglcgen(&nod1, n, Z); } regalloc(&nod2, n, Z); @@ -139,7 +145,7 @@ cgen(Node *n, Node *nn, int inrel) if(nn != Z) if((t = vlog(r)) >= 0) { /* signed div/mod by constant power of 2 */ - cgen(l, nn, 0); + cgen(l, nn); gopcode(OGE, nodconst(0), nn, Z); p1 = p; if(o == ODIV) { @@ -164,7 +170,7 @@ cgen(Node *n, Node *nn, int inrel) if(nn != Z) if(l->op == OCONST) if(!typefd[n->type->etype]) { - cgen(r, nn, 0); + cgen(r, nn); gopcode(o, Z, l, nn); break; } @@ -181,7 +187,7 @@ cgen(Node *n, Node *nn, int inrel) if(nn != Z) if(r->op == OCONST) if(!typefd[n->type->etype]) { - cgen(l, nn, 0); + cgen(l, nn); if(r->vconst == 0) if(o != OAND) break; @@ -205,15 +211,15 @@ cgen(Node *n, Node *nn, int inrel) } if(l->complex >= r->complex) { regalloc(&nod, l, nn); - cgen(l, &nod, 0); + cgen(l, &nod); regalloc(&nod1, r, Z); - cgen(r, &nod1, 0); + cgen(r, &nod1); gopcode(o, &nod1, Z, &nod); } else { regalloc(&nod, r, nn); - cgen(r, &nod, 0); + cgen(r, &nod); regalloc(&nod1, l, Z); - cgen(l, &nod1, 0); + cgen(l, &nod1); gopcode(o, &nod, &nod1, &nod); } gopcode(OAS, &nod, Z, nn); @@ -263,10 +269,10 @@ cgen(Node *n, Node *nn, int inrel) else nod2 = *l; regalloc(&nod1, r, Z); - cgen(r, &nod1, 0); + cgen(r, &nod1); } else { regalloc(&nod1, r, Z); - cgen(r, &nod1, 0); + cgen(r, &nod1); if(l->addable < INDEXED) reglcgen(&nod2, l, Z); else @@ -290,10 +296,10 @@ cgen(Node *n, Node *nn, int inrel) if(l->complex >= r->complex) { bitload(l, &nod, &nod1, &nod2, &nod4); regalloc(&nod3, r, Z); - cgen(r, &nod3, 0); + cgen(r, &nod3); } else { regalloc(&nod3, r, Z); - cgen(r, &nod3, 0); + cgen(r, &nod3); bitload(l, &nod, &nod1, &nod2, &nod4); } gmove(&nod, &nod4); @@ -318,7 +324,7 @@ cgen(Node *n, Node *nn, int inrel) diag(n, "bad function call"); regret(&nod, l->left); - cgen(l->left, &nod, 0); + cgen(l->left, &nod); regsalloc(&nod1, l->left); gopcode(OAS, &nod, Z, &nod1); regfree(&nod); @@ -328,7 +334,7 @@ cgen(Node *n, Node *nn, int inrel) nod2 = *l; nod2.left = &nod1; nod2.complex = 1; - cgen(&nod, nn, 0); + cgen(&nod, nn); return; } @@ -363,11 +369,11 @@ cgen(Node *n, Node *nn, int inrel) if(sconst(r) && (v = r->vconst+nod.xoffset) > -4096 && v < 4096) { v = r->vconst; r->vconst = 0; - cgen(l, &nod, 0); + cgen(l, &nod); nod.xoffset += v; r->vconst = v; } else - cgen(l, &nod, 0); + cgen(l, &nod); regind(&nod, n); gopcode(OAS, &nod, Z, nn); regfree(&nod); @@ -406,8 +412,8 @@ cgen(Node *n, Node *nn, int inrel) break; case OCOMMA: - cgen(l, Z, 0); - cgen(r, nn, 0); + cgen(l, Z); + cgen(r, nn); break; case OCAST: @@ -420,12 +426,12 @@ cgen(Node *n, Node *nn, int inrel) */ if(nocast(l->type, n->type)) { if(nocast(n->type, nn->type)) { - cgen(l, nn, 0); + cgen(l, nn); break; } } regalloc(&nod, l, nn); - cgen(l, &nod, 0); + cgen(l, &nod); regalloc(&nod1, n, &nod); if(inrel) gmover(&nod, &nod1); @@ -447,18 +453,18 @@ cgen(Node *n, Node *nn, int inrel) } nod.xoffset += (long)r->vconst; nod.type = n->type; - cgen(&nod, nn, 0); + cgen(&nod, nn); } break; case OCOND: bcgen(l, 1); p1 = p; - cgen(r->left, nn, 0); + cgen(r->left, nn); gbranch(OGOTO); patch(p1, pc); p1 = p; - cgen(r->right, nn, 0); + cgen(r->right, nn); patch(p1, pc); break; @@ -533,6 +539,8 @@ cgen(Node *n, Node *nn, int inrel) } else gopcode(OADD, nodconst(v), Z, &nod); gopcode(OAS, &nod, Z, &nod2); + if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */ + gins(ANOP, l, Z); regfree(&nod); if(l->addable < INDEXED) @@ -579,7 +587,7 @@ reglcgen(Node *t, Node *n, Node *nn) } else if(n->op == OINDREG) { if((v = n->xoffset) > -4096 && v < 4096) { n->op = OREGISTER; - cgen(n, t, 0); + cgen(n, t); t->xoffset += v; n->op = OINDREG; regind(t, n); @@ -638,12 +646,12 @@ lcgen(Node *n, Node *nn) break; case OCOMMA: - cgen(n->left, n->left, 0); + cgen(n->left, n->left); lcgen(n->right, nn); break; case OIND: - cgen(n->left, nn, 0); + cgen(n->left, nn); break; case OCOND: @@ -688,7 +696,7 @@ boolgen(Node *n, int true, Node *nn) default: regalloc(&nod, n, nn); - cgen(n, &nod, 0); + cgen(n, &nod); o = ONE; if(true) o = comrel[relindex(o)]; @@ -712,7 +720,7 @@ boolgen(Node *n, int true, Node *nn) goto com; case OCOMMA: - cgen(l, Z, 0); + cgen(l, Z); boolgen(r, true, nn); break; @@ -779,7 +787,7 @@ boolgen(Node *n, int true, Node *nn) o = comrel[relindex(o)]; if(l->complex >= FNX && r->complex >= FNX) { regret(&nod, r); - cgen(r, &nod, 1); + cgenrel(r, &nod, 1); regsalloc(&nod1, r); gopcode(OAS, &nod, Z, &nod1); regfree(&nod); @@ -790,7 +798,7 @@ boolgen(Node *n, int true, Node *nn) } if(sconst(l)) { regalloc(&nod, r, nn); - cgen(r, &nod, 1); + cgenrel(r, &nod, 1); o = invrel[relindex(o)]; gopcode(o, l, &nod, Z); regfree(&nod); @@ -798,21 +806,21 @@ boolgen(Node *n, int true, Node *nn) } if(sconst(r)) { regalloc(&nod, l, nn); - cgen(l, &nod, 1); + cgenrel(l, &nod, 1); gopcode(o, r, &nod, Z); regfree(&nod); goto com; } if(l->complex >= r->complex) { regalloc(&nod1, l, nn); - cgen(l, &nod1, 1); + cgenrel(l, &nod1, 1); regalloc(&nod, r, Z); - cgen(r, &nod, 1); + cgenrel(r, &nod, 1); } else { regalloc(&nod, r, nn); - cgen(r, &nod, 1); + cgenrel(r, &nod, 1); regalloc(&nod1, l, Z); - cgen(l, &nod1, 1); + cgenrel(l, &nod1, 1); } gopcode(o, &nod, &nod1, Z); regfree(&nod); @@ -936,7 +944,7 @@ sugen(Node *n, Node *nn, long w) r = r->right; } if(nn == Z) { - cgen(l, nn, 0); + cgen(l, nn); continue; } /* @@ -974,7 +982,7 @@ sugen(Node *n, Node *nn, long w) xcom(&nod0); nod0.addable = 0; - cgen(&nod0, Z, 0); + cgen(&nod0, Z); } break; @@ -1004,7 +1012,7 @@ sugen(Node *n, Node *nn, long w) n = new(OFUNC, n->left, new(OLIST, nn, n->right)); n->type = types[TVOID]; n->left->type = types[TVOID]; - cgen(n, Z, 0); + cgen(n, Z); break; case OCOND: @@ -1019,7 +1027,7 @@ sugen(Node *n, Node *nn, long w) break; case OCOMMA: - cgen(n->left, Z, 0); + cgen(n->left, Z); sugen(n->right, nn, w); break; } @@ -1063,6 +1071,10 @@ copy: } regalloc(&nod3, ®node, Z); regalloc(&nod4, ®node, Z); + if(nod3.reg > nod4.reg){ + /* code below assumes nod3 loaded first */ + Node t = nod3; nod3 = nod4; nod4 = t; + } nod0 = *nodconst((1<<nod3.reg)|(1<<nod4.reg)); if(w == 2 && nod1.xoffset == 0) gmovm(&nod1, &nod0, 0); |
