summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/5c/5.out.h4
-rw-r--r--utils/5c/cgen.c104
-rw-r--r--utils/5c/gc.h9
-rw-r--r--utils/5c/mkfile8
-rw-r--r--utils/5c/reg.c9
-rw-r--r--utils/5c/sgen.c394
-rw-r--r--utils/5c/swt.c137
-rw-r--r--utils/5c/txt.c10
-rw-r--r--utils/kc/gc.h9
-rw-r--r--utils/kc/mkfile8
-rw-r--r--utils/kc/sgen.c352
-rw-r--r--utils/kc/swt.c128
-rw-r--r--utils/vc/cgen.c2
-rw-r--r--utils/vc/gc.h9
-rw-r--r--utils/vc/mkfile8
-rw-r--r--utils/vc/peep.c2
-rw-r--r--utils/vc/sgen.c353
-rw-r--r--utils/vc/swt.c138
18 files changed, 142 insertions, 1542 deletions
diff --git a/utils/5c/5.out.h b/utils/5c/5.out.h
index ae856e28..dad2c336 100644
--- a/utils/5c/5.out.h
+++ b/utils/5c/5.out.h
@@ -9,7 +9,9 @@
#define REGRET 0
#define REGARG 0
/* compiler allocates R1 up as temps */
-/* compiler allocates register variables R3 up */
+/* compiler allocates register variables R2 up */
+#define REGMIN 2
+#define REGMAX 8
#define REGEXT 10
/* compiler allocates external registers R10 down */
#define REGTMP 11
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);
diff --git a/utils/5c/gc.h b/utils/5c/gc.h
index cbaf7a87..fa93cd0a 100644
--- a/utils/5c/gc.h
+++ b/utils/5c/gc.h
@@ -62,6 +62,7 @@ struct Case
long val;
long label;
char def;
+ char isv;
};
#define C ((Case*)0)
@@ -134,6 +135,7 @@ struct Rgn
};
EXTERN long breakpc;
+EXTERN long nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
@@ -145,7 +147,6 @@ EXTERN Prog* lastp;
EXTERN long maxargsafe;
EXTERN int mnstring;
EXTERN Multab multab[20];
-EXTERN int retok;
EXTERN int hintabsize;
EXTERN Node* nodrat;
EXTERN Node* nodret;
@@ -216,7 +217,8 @@ int bcomplex(Node*, Node*);
/*
* cgen.c
*/
-void cgen(Node*, Node*, int);
+void cgen(Node*, Node*);
+void cgenrel(Node*, Node*, int);
void reglcgen(Node*, Node*, Node*);
void lcgen(Node*, Node*);
void bcgen(Node*, int);
@@ -265,7 +267,8 @@ void gpseudo(int, Sym*, Node*);
*/
int swcmp(const void*, const void*);
void doswit(Node*);
-void swit1(C1*, int, long, Node*, Node*);
+void swit1(C1*, int, long, Node*);
+void swit2(C1*, int, long, Node*, Node*);
void casf(void);
void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
diff --git a/utils/5c/mkfile b/utils/5c/mkfile
index a0f53c45..b6230e70 100644
--- a/utils/5c/mkfile
+++ b/utils/5c/mkfile
@@ -8,6 +8,8 @@ OFILES=\
list.$O\
mul.$O\
peep.$O\
+ pgen.$O\
+ pswt.$O\
reg.$O\
sgen.$O\
swt.$O\
@@ -28,3 +30,9 @@ $ROOT/$OBJDIR/lib/libcc.a:
cd ../cc
mk $MKFLAGS install
mk $MKFLAGS clean
+
+%.$O: ../cc/%.c
+ $CC $CFLAGS -I. ../cc/$stem.c
+
+#enam.c: 5.out.h
+# rc mkenam
diff --git a/utils/5c/reg.c b/utils/5c/reg.c
index 19c8a7b6..43c78712 100644
--- a/utils/5c/reg.c
+++ b/utils/5c/reg.c
@@ -789,6 +789,7 @@ loopit(Reg *r, long nr)
idom = alloc(nr * sizeof(long));
maxnr = nr;
}
+
d = postorder(r, rpo2r, 0);
if(d > nr)
fatal(Z, "too many reg nodes");
@@ -1116,15 +1117,15 @@ long
RtoB(int r)
{
- if(r < 2 || r >= REGTMP)
- return 0;
- return 1L << r;
+ if(r >= REGMIN && r <= REGMAX)
+ return 1L << r;
+ return 0;
}
int
BtoR(long b)
{
- b &= 0x07fcL;
+ b &= 0x01fcL;
if(b == 0)
return 0;
return bitno(b);
diff --git a/utils/5c/sgen.c b/utils/5c/sgen.c
index e5d48eeb..d376a341 100644
--- a/utils/5c/sgen.c
+++ b/utils/5c/sgen.c
@@ -1,382 +1,6 @@
#include "gc.h"
void
-codgen(Node *n, Node *nn)
-{
- Prog *sp;
- Node *n1, nod, nod1;
-
- cursafe = 0;
- curarg = 0;
- maxargsafe = 0;
-
- /*
- * isolate name
- */
- for(n1 = nn;; n1 = n1->left) {
- if(n1 == Z) {
- diag(nn, "cant find function name");
- return;
- }
- if(n1->op == ONAME)
- break;
- }
- nearln = nn->lineno;
- gpseudo(ATEXT, n1->sym, nodconst(stkoff));
- sp = p;
-
- /*
- * isolate first argument
- */
- if(REGARG >= 0) {
- if(typesuv[thisfn->link->etype]) {
- nod1 = *nodret->left;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- } else
- if(firstarg && typechlp[firstargtype->etype]) {
- nod1 = *nodret->left;
- nod1.sym = firstarg;
- nod1.type = firstargtype;
- nod1.xoffset = align(0, firstargtype, Aarg1);
- nod1.etype = firstargtype->etype;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- }
- }
-
- retok = 0;
- gen(n);
- if(!retok)
- if(thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", n1->sym->name);
- noretval(3);
- gbranch(ORETURN);
-
- if(!debug['N'] || debug['R'] || debug['P'])
- regopt(sp);
-
- sp->to.offset += maxargsafe;
-}
-
-void
-supgen(Node *n)
-{
- long spc;
- Prog *sp;
-
- if(n == Z)
- return;
- suppress++;
- spc = pc;
- sp = lastp;
- gen(n);
- lastp = sp;
- pc = spc;
- sp->link = nil;
- suppress--;
-}
-
-void
-gen(Node *n)
-{
- Node *l, nod;
- Prog *sp, *spc, *spb;
- Case *cn;
- long sbc, scc;
- int o, f;
-
-loop:
- if(n == Z)
- return;
- nearln = n->lineno;
- o = n->op;
- if(debug['G'])
- if(o != OLIST)
- print("%L %O\n", nearln, o);
-
- retok = 0;
- switch(o) {
-
- default:
- complex(n);
- cgen(n, Z, 0);
- break;
-
- case OLIST:
- gen(n->left);
-
- rloop:
- n = n->right;
- goto loop;
-
- case ORETURN:
- retok = 1;
- complex(n);
- if(n->type == T)
- break;
- l = n->left;
- if(l == Z) {
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- if(typesuv[n->type->etype]) {
- sugen(l, nodret, n->type->width);
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- regret(&nod, n);
- cgen(l, &nod, 0);
- regfree(&nod);
- if(typefd[n->type->etype])
- noretval(1);
- else
- noretval(2);
- gbranch(ORETURN);
- break;
-
- case OLABEL:
- l = n->left;
- if(l) {
- l->pc = pc;
- if(l->label)
- patch(l->label, pc);
- }
- gbranch(OGOTO); /* prevent self reference in reg */
- patch(p, pc);
- goto rloop;
-
- case OGOTO:
- retok = 1;
- n = n->left;
- if(n == Z)
- return;
- if(n->complex == 0) {
- diag(Z, "label undefined: %s", n->sym->name);
- return;
- }
- if(suppress)
- return;
- gbranch(OGOTO);
- if(n->pc) {
- patch(p, n->pc);
- return;
- }
- if(n->label)
- patch(n->label, pc-1);
- n->label = p;
- return;
-
- case OCASE:
- l = n->left;
- if(cases == C)
- diag(n, "case/default outside a switch");
- if(l == Z) {
- casf();
- cases->val = 0;
- cases->def = 1;
- cases->label = pc;
- goto rloop;
- }
- complex(l);
- if(l->type == T)
- goto rloop;
- if(l->op == OCONST)
- if(typechl[l->type->etype]) {
- casf();
- cases->val = l->vconst;
- cases->def = 0;
- cases->label = pc;
- goto rloop;
- }
- diag(n, "case expression must be integer constant");
- goto rloop;
-
- case OSWITCH:
- l = n->left;
- complex(l);
- if(l->type == T)
- break;
- if(!typechl[l->type->etype]) {
- diag(n, "switch expression must be integer");
- break;
- }
-
- gbranch(OGOTO); /* entry */
- sp = p;
-
- cn = cases;
- cases = C;
- casf();
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- gen(n->right);
- gbranch(OGOTO);
- patch(p, breakpc);
-
- patch(sp, pc);
- regalloc(&nod, l, Z);
- nod.type = types[TLONG];
- cgen(l, &nod, 0);
- doswit(&nod);
- regfree(&nod);
- patch(spb, pc);
-
- cases = cn;
- breakpc = sbc;
- break;
-
- case OWHILE:
- case ODWHILE:
- l = n->left;
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- if(n->op == OWHILE)
- patch(sp, pc);
- bcomplex(l, Z); /* test */
- patch(p, breakpc);
-
- if(n->op == ODWHILE)
- patch(sp, pc);
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OFOR:
- l = n->left;
- gen(l->right->left); /* init */
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- gen(l->right->right); /* inc */
- patch(sp, pc);
- if(l->left != Z) { /* test */
- bcomplex(l->left, Z);
- patch(p, breakpc);
- }
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OCONTINUE:
- if(continpc < 0) {
- diag(n, "continue not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, continpc);
- break;
-
- case OBREAK:
- if(breakpc < 0) {
- diag(n, "break not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, breakpc);
- break;
-
- case OIF:
- l = n->left;
- if(bcomplex(l, n->right)) {
- if(typefd[l->type->etype])
- f = !l->fconst;
- else
- f = !l->vconst;
- if(debug['c'])
- print("%L const if %s\n", nearln, f ? "false" : "true");
- if(f) {
- supgen(n->right->left);
- gen(n->right->right);
- }
- else {
- gen(n->right->left);
- supgen(n->right->right);
- }
- }
- else {
- sp = p;
- if(n->right->left != Z)
- gen(n->right->left);
- if(n->right->right != Z) {
- gbranch(OGOTO);
- patch(sp, pc);
- sp = p;
- gen(n->right->right);
- }
- patch(sp, pc);
- }
- break;
-
- case OSET:
- case OUSED:
- usedset(n->left, o);
- break;
- }
-}
-
-void
-usedset(Node *n, int o)
-{
- if(n->op == OLIST) {
- usedset(n->left, o);
- usedset(n->right, o);
- return;
- }
- complex(n);
- switch(n->op) {
- case OADDR: /* volatile */
- gins(ANOP, n, Z);
- break;
- case ONAME:
- if(o == OSET)
- gins(ANOP, Z, n);
- else
- gins(ANOP, n, Z);
- break;
- }
-}
-
-void
noretval(int n)
{
@@ -593,21 +217,3 @@ xcom(Node *n)
break;
}
}
-
-int
-bcomplex(Node *n, Node *c)
-{
-
- complex(n);
- if(n->type != T)
- if(tcompat(n, T, n->type, tnot))
- n->type = T;
- if(n->type != T) {
- if(c != Z && n->op == OCONST && deadheads(c))
- return 1;
- bool64(n);
- boolgen(n, 1, Z);
- } else
- gbranch(OGOTO);
- return 0;
-}
diff --git a/utils/5c/swt.c b/utils/5c/swt.c
index 87b34458..ccc63ee7 100644
--- a/utils/5c/swt.c
+++ b/utils/5c/swt.c
@@ -1,62 +1,17 @@
#include "gc.h"
-int
-swcmp(const void *a1, const void *a2)
-{
- C1 *p1, *p2;
-
- p1 = (C1*)a1;
- p2 = (C1*)a2;
- if(p1->val < p2->val)
- return -1;
- return p1->val > p2->val;
-}
-
void
-doswit(Node *n)
+swit1(C1 *q, int nc, long def, Node *n)
{
- Case *c;
- C1 *q, *iq;
- long def, nc, i;
Node tn;
-
- def = 0;
- nc = 0;
- for(c = cases; c->link != C; c = c->link) {
- if(c->def) {
- if(def)
- diag(n, "more than one default in switch");
- def = c->label;
- continue;
- }
- nc++;
- }
-
- iq = alloc(nc*sizeof(C1));
- q = iq;
- for(c = cases; c->link != C; c = c->link) {
- if(c->def)
- continue;
- q->label = c->label;
- q->val = c->val;
- q++;
- }
- qsort(iq, nc, sizeof(C1), swcmp);
- if(debug['W'])
- for(i=0; i<nc; i++)
- print("case %2ld: = %.8lux\n", i, iq[i].val);
- if(def == 0)
- def = breakpc;
- for(i=0; i<nc-1; i++)
- if(iq[i].val == iq[i+1].val)
- diag(n, "duplicate cases in switch %ld", iq[i].val);
+
regalloc(&tn, &regnode, Z);
- swit1(iq, nc, def, n, &tn);
+ swit2(q, nc, def, n, &tn);
regfree(&tn);
}
void
-swit1(C1 *q, int nc, long def, Node *n, Node *tn)
+swit2(C1 *q, int nc, long def, Node *n, Node *tn)
{
C1 *r;
int i;
@@ -89,12 +44,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn)
sp = p;
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
patch(p, r->label);
- swit1(q, i, def, n, tn);
+ swit2(q, i, def, n, tn);
if(debug['W'])
print("case < %.8lux\n", r->val);
patch(sp, pc);
- swit1(r+1, nc-i-1, def, n, tn);
+ swit2(r+1, nc-i-1, def, n, tn);
return;
direct:
@@ -123,16 +78,6 @@ direct:
}
void
-casf(void)
-{
- Case *c;
-
- c = alloc(sizeof(*c));
- c->link = cases;
- cases = c;
-}
-
-void
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
{
int sh;
@@ -153,7 +98,7 @@ bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
gopcode(OAS, n3, Z, n1);
} else {
regalloc(n1, l, nn);
- cgen(l, n1, 0);
+ cgen(l, n1);
}
if(b->type->shift == 0 && typeu[b->type->etype]) {
v = ~0 + (1L << b->type->nbits);
@@ -229,33 +174,6 @@ outstring(char *s, long n)
return r;
}
-long
-outlstring(ushort *s, long n)
-{
- char buf[2];
- int c;
- long r;
-
- if(suppress)
- return nstring;
- while(nstring & 1)
- outstring("", 1);
- r = nstring;
- while(n > 0) {
- c = *s++;
- if(align(0, types[TCHAR], Aarg1)) {
- buf[0] = c>>8;
- buf[1] = c;
- } else {
- buf[0] = c;
- buf[1] = c>>8;
- }
- outstring(buf, 2);
- n -= sizeof(ushort);
- }
- return r;
-}
-
int
mulcon(Node *n, Node *nn)
{
@@ -297,7 +215,7 @@ mulcon(Node *n, Node *nn)
if(p[1] == 'i')
p += 2;
regalloc(&nod1, n, nn);
- cgen(l, &nod1, 0);
+ cgen(l, &nod1);
vs = v;
regalloc(&nod2, n, Z);
@@ -351,16 +269,6 @@ loop:
}
void
-nullwarn(Node *l, Node *r)
-{
- warn(Z, "result of operation not used");
- if(l != Z)
- cgen(l, Z, 0);
- if(r != Z)
- cgen(r, Z, 0);
-}
-
-void
sextern(Sym *s, Node *a, long o, long w)
{
long e, lw;
@@ -651,35 +559,6 @@ zaddr(char *bp, Adr *a, int s)
return bp;
}
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldnt use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l <<= 16;
- ieee->l |= (long)(fr*f);
-}
-
long
align(long i, Type *t, int op)
{
diff --git a/utils/5c/txt.c b/utils/5c/txt.c
index af53e1de..f97eb61a 100644
--- a/utils/5c/txt.c
+++ b/utils/5c/txt.c
@@ -170,7 +170,7 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
nod.left = *fnxp;
nod.right = n;
nod.type = n->type;
- cgen(&nod, Z, 0);
+ cgen(&nod, Z);
(*fnxp)++;
}
return;
@@ -187,18 +187,18 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
regaalloc1(tn1, n);
if(n->complex >= FNX) {
- cgen(*fnxp, tn1, 0);
+ cgen(*fnxp, tn1);
(*fnxp)++;
} else
- cgen(n, tn1, 0);
+ cgen(n, tn1);
return;
}
regalloc(tn1, n, Z);
if(n->complex >= FNX) {
- cgen(*fnxp, tn1, 0);
+ cgen(*fnxp, tn1);
(*fnxp)++;
} else
- cgen(n, tn1, 0);
+ cgen(n, tn1);
regaalloc(tn2, n);
gopcode(OAS, tn1, Z, tn2);
regfree(tn1);
diff --git a/utils/kc/gc.h b/utils/kc/gc.h
index 577ba83d..1ff5a633 100644
--- a/utils/kc/gc.h
+++ b/utils/kc/gc.h
@@ -57,6 +57,7 @@ struct Case
long val;
long label;
char def;
+ char isv;
};
#define C ((Case*)0)
@@ -128,6 +129,7 @@ struct Rgn
};
EXTERN long breakpc;
+EXTERN long nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
@@ -140,7 +142,6 @@ EXTERN int hintabsize;
EXTERN long maxargsafe;
EXTERN Multab multab[20];
EXTERN int mnstring;
-EXTERN int retok;
EXTERN Node* nodrat;
EXTERN Node* nodret;
EXTERN Node* nodsafe;
@@ -183,6 +184,7 @@ EXTERN long regbits;
EXTERN long exregbits;
EXTERN int change;
+EXTERN int suppress;
EXTERN Reg* firstr;
EXTERN Reg* lastr;
@@ -204,7 +206,7 @@ void gen(Node*);
void usedset(Node*, int);
void noretval(int);
void xcom(Node*);
-void bcomplex(Node*);
+int bcomplex(Node*, Node*);
/*
* cgen.c
@@ -255,7 +257,8 @@ void gpseudo(int, Sym*, Node*);
*/
int swcmp(const void*, const void*);
void doswit(Node*);
-void swit1(C1*, int, long, Node*, Node*);
+void swit1(C1*, int, long, Node*);
+void swit2(C1*, int, long, Node*, Node*);
void casf(void);
void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
diff --git a/utils/kc/mkfile b/utils/kc/mkfile
index 26f16f10..584143cd 100644
--- a/utils/kc/mkfile
+++ b/utils/kc/mkfile
@@ -4,6 +4,8 @@ TARG=kc
OFILES=\
peep.$O\
+ pgen.$O\
+ pswt.$O\
reg.$O\
cgen.$O\
enam.$O\
@@ -30,3 +32,9 @@ $ROOT/$OBJDIR/lib/libcc.a:
cd ../cc
mk $MKFLAGS install
mk $MKFLAGS clean
+
+%.$O: ../cc/%.c
+ $CC $CFLAGS -I. ../cc/$stem.c
+
+#enam.c: k.out.h
+# rc mkenam
diff --git a/utils/kc/sgen.c b/utils/kc/sgen.c
index 105efcce..c8e894c6 100644
--- a/utils/kc/sgen.c
+++ b/utils/kc/sgen.c
@@ -1,344 +1,6 @@
#include "gc.h"
void
-codgen(Node *n, Node *nn)
-{
- Prog *sp;
- Node *n1, nod, nod1;
-
- cursafe = 0;
- curarg = 0;
- maxargsafe = 0;
-
- /*
- * isolate name
- */
- for(n1 = nn;; n1 = n1->left) {
- if(n1 == Z) {
- diag(nn, "cant find function name");
- return;
- }
- if(n1->op == ONAME)
- break;
- }
- nearln = nn->lineno;
- gpseudo(ATEXT, n1->sym, nodconst(stkoff));
- sp = p;
-
- /*
- * isolate first argument
- */
- if(REGARG) {
- if(typesuv[thisfn->link->etype]) {
- nod1 = *nodret->left;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- } else
- if(firstarg && typechlp[firstargtype->etype]) {
- nod1 = *nodret->left;
- nod1.sym = firstarg;
- nod1.type = firstargtype;
- nod1.xoffset = align(0, firstargtype, Aarg1);
- nod1.etype = firstargtype->etype;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- }
- }
-
- retok = 0;
- gen(n);
- if(!retok)
- if(thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", n1->sym->name);
- noretval(3);
- gbranch(ORETURN);
-
- if(!debug['N'] || debug['R'] || debug['P'])
- regopt(sp);
-
- sp->to.offset += maxargsafe;
-}
-
-void
-gen(Node *n)
-{
- Node *l, nod;
- Prog *sp, *spc, *spb;
- Case *cn;
- long sbc, scc;
- int o;
-
-loop:
- if(n == Z)
- return;
- nearln = n->lineno;
- o = n->op;
- if(debug['G'])
- if(o != OLIST)
- print("%L %O\n", nearln, o);
- retok = 0;
- switch(o) {
-
- default:
- complex(n);
- cgen(n, Z);
- break;
-
- case OLIST:
- gen(n->left);
-
- rloop:
- n = n->right;
- goto loop;
-
- case ORETURN:
- retok = 1;
- complex(n);
- if(n->type == T)
- break;
- l = n->left;
- if(l == Z) {
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- if(typesuv[n->type->etype]) {
- sugen(l, nodret, n->type->width);
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- regret(&nod, n);
- cgen(l, &nod);
- regfree(&nod);
- if(typefd[n->type->etype])
- noretval(1);
- else
- noretval(2);
- gbranch(ORETURN);
- break;
-
- case OLABEL:
- l = n->left;
- if(l) {
- l->xoffset = pc;
- if(l->label)
- patch(l->label, pc);
- }
- gbranch(OGOTO); /* prevent self reference in reg */
- patch(p, pc);
- goto rloop;
-
- case OGOTO:
- retok = 1;
- n = n->left;
- if(n == Z)
- return;
- if(n->complex == 0) {
- diag(Z, "label undefined: %s", n->sym->name);
- return;
- }
- gbranch(OGOTO);
- if(n->xoffset) {
- patch(p, n->xoffset);
- return;
- }
- if(n->label)
- patch(n->label, pc-1);
- n->label = p;
- return;
-
- case OCASE:
- l = n->left;
- if(cases == C)
- diag(n, "case/default outside a switch");
- if(l == Z) {
- casf();
- cases->val = 0;
- cases->def = 1;
- cases->label = pc;
- goto rloop;
- }
- complex(l);
- if(l->type == T)
- goto rloop;
- if(l->op == OCONST)
- if(typechl[l->type->etype]) {
- casf();
- cases->val = l->vconst;
- cases->def = 0;
- cases->label = pc;
- goto rloop;
- }
- diag(n, "case expression must be integer constant");
- goto rloop;
-
- case OSWITCH:
- l = n->left;
- complex(l);
- if(l->type == T)
- break;
- if(!typechl[l->type->etype]) {
- diag(n, "switch expression must be integer");
- break;
- }
-
- gbranch(OGOTO); /* entry */
- sp = p;
-
- cn = cases;
- cases = C;
- casf();
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- gen(n->right);
- gbranch(OGOTO);
- patch(p, breakpc);
-
- patch(sp, pc);
- regalloc(&nod, l, Z);
- nod.type = types[TLONG];
- cgen(l, &nod);
- doswit(&nod);
- regfree(&nod);
- patch(spb, pc);
-
- cases = cn;
- breakpc = sbc;
- break;
-
- case OWHILE:
- case ODWHILE:
- l = n->left;
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- if(n->op == OWHILE)
- patch(sp, pc);
- bcomplex(l); /* test */
- patch(p, breakpc);
-
- if(n->op == ODWHILE)
- patch(sp, pc);
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OFOR:
- l = n->left;
- gen(l->right->left); /* init */
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- gen(l->right->right); /* inc */
- patch(sp, pc);
- if(l->left != Z) { /* test */
- bcomplex(l->left);
- patch(p, breakpc);
- }
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OCONTINUE:
- if(continpc < 0) {
- diag(n, "continue not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, continpc);
- break;
-
- case OBREAK:
- if(breakpc < 0) {
- diag(n, "break not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, breakpc);
- break;
-
- case OIF:
- l = n->left;
- bcomplex(l);
- sp = p;
- if(n->right->left != Z)
- gen(n->right->left);
- if(n->right->right != Z) {
- gbranch(OGOTO);
- patch(sp, pc);
- sp = p;
- gen(n->right->right);
- }
- patch(sp, pc);
- break;
-
- case OSET:
- case OUSED:
- usedset(n->left, o);
- break;
- }
-}
-
-void
-usedset(Node *n, int o)
-{
- if(n->op == OLIST) {
- usedset(n->left, o);
- usedset(n->right, o);
- return;
- }
- complex(n);
- switch(n->op) {
- case OADDR: /* volatile */
- gins(ANOP, n, Z);
- break;
- case ONAME:
- if(o == OSET)
- gins(ANOP, Z, n);
- else
- gins(ANOP, n, Z);
- break;
- }
-}
-
-void
noretval(int n)
{
@@ -574,17 +236,3 @@ xcom(Node *n)
}
}
-void
-bcomplex(Node *n)
-{
-
- complex(n);
- if(n->type != T)
- if(tcompat(n, T, n->type, tnot))
- n->type = T;
- if(n->type != T) {
- bool64(n);
- boolgen(n, 1, Z);
- } else
- gbranch(OGOTO);
-}
diff --git a/utils/kc/swt.c b/utils/kc/swt.c
index 61633e91..05727dd8 100644
--- a/utils/kc/swt.c
+++ b/utils/kc/swt.c
@@ -1,59 +1,17 @@
#include "gc.h"
-int
-swcmp(const void *a1, const void *a2)
-{
- C1 *p1, *p2;
-
- p1 = (C1*)a1;
- p2 = (C1*)a2;
- if(p1->val < p2->val)
- return -1;
- return p1->val > p2->val;
-}
-
void
-doswit(Node *n)
+swit1(C1 *q, int nc, long def, Node *n)
{
- Case *c;
- C1 *q, *iq;
- long def, nc, i;
Node tn;
-
- def = 0;
- nc = 0;
- for(c = cases; c->link != C; c = c->link) {
- if(c->def) {
- if(def)
- diag(n, "more than one default in switch");
- def = c->label;
- continue;
- }
- nc++;
- }
-
- iq = alloc(nc*sizeof(C1));
- q = iq;
- for(c = cases; c->link != C; c = c->link) {
- if(c->def)
- continue;
- q->label = c->label;
- q->val = c->val;
- q++;
- }
- qsort(iq, nc, sizeof(C1), swcmp);
- if(def == 0)
- def = breakpc;
- for(i=0; i<nc-1; i++)
- if(iq[i].val == iq[i+1].val)
- diag(n, "duplicate cases in switch %ld", iq[i].val);
+
regalloc(&tn, &regnode, Z);
- swit1(iq, nc, def, n, &tn);
+ swit2(q, nc, def, n, &tn);
regfree(&tn);
}
void
-swit1(C1 *q, int nc, long def, Node *n, Node *tn)
+swit2(C1 *q, int nc, long def, Node *n, Node *tn)
{
C1 *r;
int i;
@@ -87,20 +45,10 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn)
gbranch(OGOTO);
p->as = ABE;
patch(p, r->label);
- swit1(q, i, def, n, tn);
+ swit2(q, i, def, n, tn);
patch(sp, pc);
- swit1(r+1, nc-i-1, def, n, tn);
-}
-
-void
-casf(void)
-{
- Case *c;
-
- c = alloc(sizeof(*c));
- c->link = cases;
- cases = c;
+ swit2(r+1, nc-i-1, def, n, tn);
}
void
@@ -198,31 +146,6 @@ outstring(char *s, long n)
return r;
}
-long
-outlstring(ushort *s, long n)
-{
- char buf[2];
- int c;
- long r;
-
- while(nstring & 1)
- outstring("", 1);
- r = nstring;
- while(n > 0) {
- c = *s++;
- if(align(0, types[TCHAR], Aarg1)) {
- buf[0] = c>>8;
- buf[1] = c;
- } else {
- buf[0] = c;
- buf[1] = c>>8;
- }
- outstring(buf, 2);
- n -= sizeof(ushort);
- }
- return r;
-}
-
int
mulcon(Node *n, Node *nn)
{
@@ -313,16 +236,6 @@ loop:
}
void
-nullwarn(Node *l, Node *r)
-{
- warn(Z, "result of operation not used");
- if(l != Z)
- cgen(l, Z);
- if(r != Z)
- cgen(r, Z);
-}
-
-void
sextern(Sym *s, Node *a, long o, long w)
{
long e, lw;
@@ -609,35 +522,6 @@ zaddr(Biobuf *b, Adr *a, int s)
}
}
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldnt use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l <<= 16;
- ieee->l |= (long)(fr*f);
-}
-
long
align(long i, Type *t, int op)
{
diff --git a/utils/vc/cgen.c b/utils/vc/cgen.c
index 5d5262db..faaa0ade 100644
--- a/utils/vc/cgen.c
+++ b/utils/vc/cgen.c
@@ -497,6 +497,8 @@ cgen(Node *n, Node *nn)
} 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)
diff --git a/utils/vc/gc.h b/utils/vc/gc.h
index 71aec5c1..29fc0bc5 100644
--- a/utils/vc/gc.h
+++ b/utils/vc/gc.h
@@ -58,6 +58,7 @@ struct Case
long val;
long label;
char def;
+ char isv;
};
#define C ((Case*)0)
@@ -129,6 +130,7 @@ struct Rgn
};
EXTERN long breakpc;
+EXTERN long nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
@@ -140,7 +142,6 @@ EXTERN Prog* lastp;
EXTERN long maxargsafe;
EXTERN int mnstring;
EXTERN Multab multab[20];
-EXTERN int retok;
EXTERN int hintabsize;
EXTERN Node* nodrat;
EXTERN Node* nodret;
@@ -184,6 +185,7 @@ EXTERN long regbits;
EXTERN long exregbits;
EXTERN int change;
+EXTERN int suppress;
EXTERN Reg* firstr;
EXTERN Reg* lastr;
@@ -204,7 +206,7 @@ void codgen(Node*, Node*);
void gen(Node*);
void noretval(int);
void xcom(Node*);
-void bcomplex(Node*);
+int bcomplex(Node*, Node*);
void usedset(Node*, int);
/*
@@ -256,7 +258,8 @@ void gpseudo(int, Sym*, Node*);
*/
int swcmp(const void*, const void*);
void doswit(Node*);
-void swit1(C1*, int, long, Node*, Node*);
+void swit1(C1*, int, long, Node*);
+void swit2(C1*, int, long, Node*, Node*);
void casf(void);
void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
diff --git a/utils/vc/mkfile b/utils/vc/mkfile
index f17af88d..71adf1f4 100644
--- a/utils/vc/mkfile
+++ b/utils/vc/mkfile
@@ -7,6 +7,8 @@ OFILES=\
enam.$O\
list.$O\
peep.$O\
+ pgen.$O\
+ pswt.$O\
reg.$O\
sgen.$O\
swt.$O\
@@ -30,3 +32,9 @@ $ROOT/$OBJDIR/lib/libcc.a:
cd ../cc
mk $MKFLAGS install
mk $MKFLAGS clean
+
+%.$O: ../cc/%.c
+ $CC $CFLAGS -I. ../cc/$stem.c
+
+#enam.c: v.out.h
+# rc mkenam
diff --git a/utils/vc/peep.c b/utils/vc/peep.c
index 1feff699..5f635571 100644
--- a/utils/vc/peep.c
+++ b/utils/vc/peep.c
@@ -569,7 +569,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
return 0;
}
- return 0;
+ /* not reached */
}
int
diff --git a/utils/vc/sgen.c b/utils/vc/sgen.c
index c0fec8a3..6e70748b 100644
--- a/utils/vc/sgen.c
+++ b/utils/vc/sgen.c
@@ -1,345 +1,6 @@
#include "gc.h"
void
-codgen(Node *n, Node *nn)
-{
- Prog *sp;
- Node *n1, nod, nod1;
-
- cursafe = 0;
- curarg = 0;
- maxargsafe = 0;
-
- /*
- * isolate name
- */
- for(n1 = nn;; n1 = n1->left) {
- if(n1 == Z) {
- diag(nn, "cant find function name");
- return;
- }
- if(n1->op == ONAME)
- break;
- }
- nearln = nn->lineno;
- gpseudo(ATEXT, n1->sym, nodconst(stkoff));
- sp = p;
-
- /*
- * isolate first argument
- */
- if(REGARG) {
- if(typesuv[thisfn->link->etype]) {
- nod1 = *nodret->left;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- } else
- if(firstarg && typechlp[firstargtype->etype]) {
- nod1 = *nodret->left;
- nod1.sym = firstarg;
- nod1.type = firstargtype;
- nod1.xoffset = align(0, firstargtype, Aarg1);
- nod1.etype = firstargtype->etype;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- }
- }
-
- retok = 0;
- gen(n);
- if(!retok)
- if(thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", n1->sym->name);
- noretval(3);
- gbranch(ORETURN);
-
- if(!debug['N'] || debug['R'] || debug['P'])
- regopt(sp);
-
- sp->to.offset += maxargsafe;
-}
-
-void
-gen(Node *n)
-{
- Node *l, nod;
- Prog *sp, *spc, *spb;
- Case *cn;
- long sbc, scc;
- int o;
-
-loop:
- if(n == Z)
- return;
- nearln = n->lineno;
- o = n->op;
- if(debug['G'])
- if(o != OLIST)
- print("%L %O\n", nearln, o);
-
- retok = 0;
- switch(o) {
-
- default:
- complex(n);
- cgen(n, Z);
- break;
-
- case OLIST:
- gen(n->left);
-
- rloop:
- n = n->right;
- goto loop;
-
- case ORETURN:
- retok = 1;
- complex(n);
- if(n->type == T)
- break;
- l = n->left;
- if(l == Z) {
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- if(typesuv[n->type->etype]) {
- sugen(l, nodret, n->type->width);
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- regret(&nod, n);
- cgen(l, &nod);
- regfree(&nod);
- if(typefd[n->type->etype])
- noretval(1);
- else
- noretval(2);
- gbranch(ORETURN);
- break;
-
- case OLABEL:
- l = n->left;
- if(l) {
- l->pc = pc;
- if(l->label)
- patch(l->label, pc);
- }
- gbranch(OGOTO); /* prevent self reference in reg */
- patch(p, pc);
- goto rloop;
-
- case OGOTO:
- retok = 1;
- n = n->left;
- if(n == Z)
- return;
- if(n->complex == 0) {
- diag(Z, "label undefined: %s", n->sym->name);
- return;
- }
- gbranch(OGOTO);
- if(n->pc) {
- patch(p, n->pc);
- return;
- }
- if(n->label)
- patch(n->label, pc-1);
- n->label = p;
- return;
-
- case OCASE:
- l = n->left;
- if(cases == C)
- diag(n, "case/default outside a switch");
- if(l == Z) {
- casf();
- cases->val = 0;
- cases->def = 1;
- cases->label = pc;
- goto rloop;
- }
- complex(l);
- if(l->type == T)
- goto rloop;
- if(l->op == OCONST)
- if(typechl[l->type->etype]) {
- casf();
- cases->val = l->vconst;
- cases->def = 0;
- cases->label = pc;
- goto rloop;
- }
- diag(n, "case expression must be integer constant");
- goto rloop;
-
- case OSWITCH:
- l = n->left;
- complex(l);
- if(l->type == T)
- break;
- if(!typechl[l->type->etype]) {
- diag(n, "switch expression must be integer");
- break;
- }
-
- gbranch(OGOTO); /* entry */
- sp = p;
-
- cn = cases;
- cases = C;
- casf();
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- gen(n->right);
- gbranch(OGOTO);
- patch(p, breakpc);
-
- patch(sp, pc);
- regalloc(&nod, l, Z);
- nod.type = types[TLONG];
- cgen(l, &nod);
- doswit(&nod);
- regfree(&nod);
- patch(spb, pc);
-
- cases = cn;
- breakpc = sbc;
- break;
-
- case OWHILE:
- case ODWHILE:
- l = n->left;
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- if(n->op == OWHILE)
- patch(sp, pc);
- bcomplex(l); /* test */
- patch(p, breakpc);
-
- if(n->op == ODWHILE)
- patch(sp, pc);
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OFOR:
- l = n->left;
- gen(l->right->left); /* init */
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- gen(l->right->right); /* inc */
- patch(sp, pc);
- if(l->left != Z) { /* test */
- bcomplex(l->left);
- patch(p, breakpc);
- }
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OCONTINUE:
- if(continpc < 0) {
- diag(n, "continue not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, continpc);
- break;
-
- case OBREAK:
- if(breakpc < 0) {
- diag(n, "break not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, breakpc);
- break;
-
- case OIF:
- l = n->left;
- bcomplex(l);
- sp = p;
- if(n->right->left != Z)
- gen(n->right->left);
- if(n->right->right != Z) {
- gbranch(OGOTO);
- patch(sp, pc);
- sp = p;
- gen(n->right->right);
- }
- patch(sp, pc);
- break;
-
- case OSET:
- case OUSED:
- usedset(n->left, o);
- break;
- }
-}
-
-void
-usedset(Node *n, int o)
-{
- if(n->op == OLIST) {
- usedset(n->left, o);
- usedset(n->right, o);
- return;
- }
- complex(n);
- switch(n->op) {
- case OADDR: /* volatile */
- gins(ANOP, n, Z);
- break;
- case ONAME:
- if(o == OSET)
- gins(ANOP, Z, n);
- else
- gins(ANOP, n, Z);
- break;
- }
-}
-
-void
noretval(int n)
{
@@ -564,17 +225,3 @@ xcom(Node *n)
}
}
-void
-bcomplex(Node *n)
-{
-
- complex(n);
- if(n->type != T)
- if(tcompat(n, T, n->type, tnot))
- n->type = T;
- if(n->type != T) {
- bool64(n);
- boolgen(n, 1, Z);
- } else
- gbranch(OGOTO);
-}
diff --git a/utils/vc/swt.c b/utils/vc/swt.c
index d5c72dc1..cdc58e1b 100644
--- a/utils/vc/swt.c
+++ b/utils/vc/swt.c
@@ -1,62 +1,17 @@
#include "gc.h"
-int
-swcmp(const void *a1, const void *a2)
-{
- C1 *p1, *p2;
-
- p1 = (C1*)a1;
- p2 = (C1*)a2;
- if(p1->val < p2->val)
- return -1;
- return p1->val > p2->val;
-}
-
void
-doswit(Node *n)
+swit1(C1 *q, int nc, long def, Node *n)
{
- Case *c;
- C1 *q, *iq;
- long def, nc, i;
Node tn;
-
- def = 0;
- nc = 0;
- for(c = cases; c->link != C; c = c->link) {
- if(c->def) {
- if(def)
- diag(n, "more than one default in switch");
- def = c->label;
- continue;
- }
- nc++;
- }
-
- iq = alloc(nc*sizeof(C1));
- q = iq;
- for(c = cases; c->link != C; c = c->link) {
- if(c->def)
- continue;
- q->label = c->label;
- q->val = c->val;
- q++;
- }
- qsort(iq, nc, sizeof(C1), swcmp);
- if(debug['W'])
- for(i=0; i<nc; i++)
- print("case %2ld: = %.8lux\n", i, iq[i].val);
- if(def == 0)
- def = breakpc;
- for(i=0; i<nc-1; i++)
- if(iq[i].val == iq[i+1].val)
- diag(n, "duplicate cases in switch %ld", iq[i].val);
+
regalloc(&tn, &regnode, Z);
- swit1(iq, nc, def, n, &tn);
+ swit2(q, nc, def, n, &tn);
regfree(&tn);
}
void
-swit1(C1 *q, int nc, long def, Node *n, Node *tn)
+swit2(C1 *q, int nc, long def, Node *n, Node *tn)
{
C1 *r;
int i;
@@ -84,22 +39,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn)
sp = p;
gopcode(OEQ, n, tn, Z);
patch(p, r->label);
- swit1(q, i, def, n, tn);
+ swit2(q, i, def, n, tn);
if(debug['W'])
print("case < %.8lux\n", r->val);
patch(sp, pc);
- swit1(r+1, nc-i-1, def, n, tn);
-}
-
-void
-casf(void)
-{
- Case *c;
-
- c = alloc(sizeof(*c));
- c->link = cases;
- cases = c;
+ swit2(r+1, nc-i-1, def, n, tn);
}
void
@@ -197,31 +142,6 @@ outstring(char *s, long n)
return r;
}
-long
-outlstring(ushort *s, long n)
-{
- char buf[2];
- int c;
- long r;
-
- while(nstring & 1)
- outstring("", 1);
- r = nstring;
- while(n > 0) {
- c = *s++;
- if(align(0, types[TCHAR], Aarg1)) {
- buf[0] = c>>8;
- buf[1] = c;
- } else {
- buf[0] = c;
- buf[1] = c>>8;
- }
- outstring(buf, 2);
- n -= sizeof(ushort);
- }
- return r;
-}
-
int
mulcon(Node *n, Node *nn)
{
@@ -314,16 +234,6 @@ loop:
}
void
-nullwarn(Node *l, Node *r)
-{
- warn(Z, "result of operation not used");
- if(l != Z)
- cgen(l, Z);
- if(r != Z)
- cgen(r, Z);
-}
-
-void
sextern(Sym *s, Node *a, long o, long w)
{
long e, lw;
@@ -615,35 +525,6 @@ zaddr(char *bp, Adr *a, int s)
return bp;
}
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldnt use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l <<= 16;
- ieee->l |= (long)(fr*f);
-}
-
long
align(long i, Type *t, int op)
{
@@ -660,6 +541,8 @@ align(long i, Type *t, int op)
case Asu2: /* padding at end of a struct */
w = SZ_LONG;
+ if(packflg)
+ w = packflg;
break;
case Ael1: /* initial allign of struct element */
@@ -668,6 +551,8 @@ align(long i, Type *t, int op)
w = ewidth[v->etype];
if(w <= 0 || w >= SZ_LONG)
w = SZ_LONG;
+ if(packflg)
+ w = packflg;
break;
case Ael2: /* width of a struct element */
@@ -687,7 +572,8 @@ align(long i, Type *t, int op)
w = SZ_LONG;
break;
}
- o += SZ_LONG - w; /* big endian adjustment */
+ if(thechar == 'v')
+ o += SZ_LONG - w; /* big endian adjustment */
w = 1;
break;