summaryrefslogtreecommitdiff
path: root/utils/5c/cgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/5c/cgen.c')
-rw-r--r--utils/5c/cgen.c104
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, &regnode, Z);
regalloc(&nod4, &regnode, 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);