summaryrefslogtreecommitdiff
path: root/utils/8c
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2010-04-27 21:15:13 +0100
committerforsyth <forsyth@vitanuova.com>2010-04-27 21:15:13 +0100
commitc0927006217e7a7e0214add5828659287c7498d6 (patch)
tree528acb9e0df2d33eaa2481b8e3ff37c252082fd2 /utils/8c
parent2303ddadf6e5cbf9705ccf25abe6114af1126b79 (diff)
20100427-2115
Diffstat (limited to 'utils/8c')
-rw-r--r--utils/8c/8.out.h2
-rw-r--r--utils/8c/cgen.c2
-rw-r--r--utils/8c/cgen64.c14
-rw-r--r--utils/8c/gc.h3
-rw-r--r--utils/8c/mkfile8
-rw-r--r--utils/8c/peep.c2
-rw-r--r--utils/8c/sgen.c412
-rw-r--r--utils/8c/swt.c128
-rw-r--r--utils/8c/txt.c60
9 files changed, 58 insertions, 573 deletions
diff --git a/utils/8c/8.out.h b/utils/8c/8.out.h
index fdfd0ca7..c38ab83f 100644
--- a/utils/8c/8.out.h
+++ b/utils/8c/8.out.h
@@ -420,7 +420,7 @@ enum
T_SYM = 1<<4,
T_SCONST = 1<<5,
- REGARG = 0,
+ REGARG = -1,
REGRET = D_AX,
FREGRET = D_F0,
REGSP = D_SP,
diff --git a/utils/8c/cgen.c b/utils/8c/cgen.c
index 81521666..c8511e2c 100644
--- a/utils/8c/cgen.c
+++ b/utils/8c/cgen.c
@@ -895,7 +895,7 @@ cgen(Node *n, Node *nn)
regfree(&nod);
} else
gopcode(OFUNC, n->type, Z, l);
- if(REGARG && reg[REGARG])
+ if(REGARG>=0 && reg[REGARG])
reg[REGARG]--;
if(nn != Z) {
regret(&nod, n);
diff --git a/utils/8c/cgen64.c b/utils/8c/cgen64.c
index 6a1e835e..dd82adfa 100644
--- a/utils/8c/cgen64.c
+++ b/utils/8c/cgen64.c
@@ -2681,7 +2681,19 @@ void
testv(Node *n, int true)
{
Type *t;
- Node *nn, nod;
+ 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:
diff --git a/utils/8c/gc.h b/utils/8c/gc.h
index b6050d82..b7257962 100644
--- a/utils/8c/gc.h
+++ b/utils/8c/gc.h
@@ -64,6 +64,7 @@ struct Case
long val;
long label;
char def;
+ char isv;
};
#define C ((Case*)0)
@@ -131,6 +132,7 @@ struct Rgn
};
EXTERN long breakpc;
+EXTERN long nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
@@ -141,7 +143,6 @@ EXTERN Prog* firstp;
EXTERN Prog* lastp;
EXTERN long maxargsafe;
EXTERN int mnstring;
-EXTERN int retok;
EXTERN Node* nodrat;
EXTERN Node* nodret;
EXTERN Node* nodsafe;
diff --git a/utils/8c/mkfile b/utils/8c/mkfile
index 729cff24..2bafc9ee 100644
--- a/utils/8c/mkfile
+++ b/utils/8c/mkfile
@@ -11,6 +11,8 @@ OFILES=\
txt.$O\
reg.$O\
peep.$O\
+ pgen.$O\
+ pswt.$O\
machcap.$O\
cgen64.$O\
div.$O\
@@ -33,3 +35,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: 8.out.h
+# rc mkenam
diff --git a/utils/8c/peep.c b/utils/8c/peep.c
index 8a2d79b7..ed3e6b78 100644
--- a/utils/8c/peep.c
+++ b/utils/8c/peep.c
@@ -669,7 +669,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
case ACALL: /* funny */
- if(REGARG && v->type == REGARG)
+ if(REGARG>=0 && v->type == REGARG)
return 2;
if(s != A) {
diff --git a/utils/8c/sgen.c b/utils/8c/sgen.c
index e6282b21..df12f903 100644
--- a/utils/8c/sgen.c
+++ b/utils/8c/sgen.c
@@ -1,385 +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));
-
- /*
- * isolate first argument
- */
- if(REGARG) {
- if(typesuv[thisfn->link->etype]) {
- nod1 = *nodret->left;
- nodreg(&nod, &nod1, REGARG);
- gmove(&nod, &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);
- gmove(&nod, &nod1);
- }
- }
-
- sp = p;
- 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);
- if(thisfn && thisfn->link && typefd[thisfn->link->etype])
- gins(AFLDZ, Z, Z);
- 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 f, 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);
- if(typefd[n->type->etype])
- gins(AFLDZ, Z, Z);
- 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;
- }
- if(suppress)
- 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, 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)
{
@@ -391,6 +12,9 @@ noretval(int n)
gins(ANOP, Z, Z);
p->to.type = FREGRET;
}
+ if((n&3) == 3)
+ if(thisfn && thisfn->link && typefd[thisfn->link->etype])
+ gins(AFLDZ, Z, Z);
}
/* welcome to commute */
@@ -810,33 +434,3 @@ indx(Node *n)
prtree(idx.basetree, "base");
}
}
-
-int
-bcomplex(Node *n, Node *c)
-{
- Node *b, nod;
-
- 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;
- if(typev[n->type->etype] && machcap(Z)) {
- b = &nod;
- b->op = ONE;
- 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 0;
- }
- bool64(n);
- boolgen(n, 1, Z);
- } else
- gbranch(OGOTO);
- return 0;
-}
diff --git a/utils/8c/swt.c b/utils/8c/swt.c
index a29b95c7..46fd71eb 100644
--- a/utils/8c/swt.c
+++ b/utils/8c/swt.c
@@ -1,57 +1,5 @@
#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)
-{
- Case *c;
- C1 *q, *iq;
- long def, nc, i;
-
- 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);
- swit1(iq, nc, def, n);
-}
-
void
swit1(C1 *q, int nc, long def, Node *n)
{
@@ -89,16 +37,6 @@ swit1(C1 *q, int nc, long def, Node *n)
}
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;
@@ -189,43 +127,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;
-}
-
-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)
{
@@ -542,35 +443,6 @@ zaddr(Biobuf *b, Adr *a, int s)
Bputc(b, a->type);
}
-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/8c/txt.c b/utils/8c/txt.c
index 841116ab..44413d81 100644
--- a/utils/8c/txt.c
+++ b/utils/8c/txt.c
@@ -203,7 +203,7 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
sugen(n, tn2, n->type->width);
return;
}
- if(REGARG && curarg == 0 && typeilp[n->type->etype]) {
+ if(REGARG>=0 && curarg == 0 && typeilp[n->type->etype]) {
regaalloc1(tn1, n);
if(n->complex >= FNX) {
cgen(*fnxp, tn1);
@@ -306,6 +306,7 @@ regalloc(Node *n, Node *tn, Node *o)
if(reg[i] == 0)
goto out;
diag(tn, "out of fixed registers");
+abort();
goto err;
case TFLOAT:
@@ -321,6 +322,7 @@ out:
if(i)
reg[i]++;
nodreg(n, tn, i);
+//print("+ %R %d\n", i, reg[i]);
}
void
@@ -347,6 +349,7 @@ regfree(Node *n)
if(reg[i] <= 0)
goto err;
reg[i]--;
+//print("- %R %d\n", i, reg[i]);
return;
err:
diag(n, "error in regfree: %R", i);
@@ -367,11 +370,19 @@ regsalloc(Node *n, Node *nn)
void
regaalloc1(Node *n, Node *nn)
{
+ USED(nn);
+
+ if(REGARG < 0) {
+ diag(n, "regaalloc1");
+ return;
+ }
+/* not reached
nodreg(n, nn, REGARG);
reg[REGARG]++;
curarg = align(curarg, nn->type, Aarg1);
curarg = align(curarg, nn->type, Aarg2);
maxargsafe = maxround(maxargsafe, cursafe+curarg);
+*/
}
void
@@ -412,6 +423,7 @@ naddr(Node *n, Adr *a)
default:
bad:
diag(n, "bad in naddr: %O %D", n->op, a);
+//prtree(n, "naddr");
break;
case OREGISTER:
@@ -787,9 +799,7 @@ gmove(Node *f, Node *t)
case CASE( TFLOAT, TSHORT):
case CASE( TFLOAT, TUSHORT):
case CASE( TFLOAT, TINT):
- case CASE( TFLOAT, TUINT):
case CASE( TFLOAT, TLONG):
- case CASE( TFLOAT, TULONG):
case CASE( TFLOAT, TIND):
case CASE( TDOUBLE,TCHAR):
@@ -797,20 +807,8 @@ gmove(Node *f, Node *t)
case CASE( TDOUBLE,TSHORT):
case CASE( TDOUBLE,TUSHORT):
case CASE( TDOUBLE,TINT):
- case CASE( TDOUBLE,TUINT):
case CASE( TDOUBLE,TLONG):
- case CASE( TDOUBLE,TULONG):
case CASE( TDOUBLE,TIND):
-
- case CASE( TVLONG, TCHAR):
- case CASE( TVLONG, TUCHAR):
- case CASE( TVLONG, TSHORT):
- case CASE( TVLONG, TUSHORT):
- case CASE( TVLONG, TINT):
- case CASE( TVLONG, TUINT):
- case CASE( TVLONG, TLONG):
- case CASE( TVLONG, TULONG):
- case CASE( TVLONG, TIND):
if(fproundflg) {
regsalloc(&nod, &regnode);
gins(AFMOVLP, f, &nod);
@@ -830,13 +828,26 @@ gmove(Node *f, Node *t)
return;
/*
+ * float to ulong
+ */
+ case CASE( TDOUBLE, TULONG):
+ case CASE( TFLOAT, TULONG):
+ case CASE( TDOUBLE, TUINT):
+ case CASE( TFLOAT, TUINT):
+ regsalloc(&nod, &regnode);
+ gmove(f, &fregnode0);
+ gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
+ gins(AFMOVLP, f, &nod);
+ gins(ASUBL, nodconst(-2147483648), &nod);
+ gmove(&nod, t);
+ return;
+
+/*
* ulong to float
*/
case CASE( TULONG, TDOUBLE):
- case CASE( TULONG, TVLONG):
case CASE( TULONG, TFLOAT):
case CASE( TUINT, TDOUBLE):
- case CASE( TUINT, TVLONG):
case CASE( TUINT, TFLOAT):
regalloc(&nod, f, f);
gmove(f, &nod);
@@ -869,14 +880,6 @@ gmove(Node *f, Node *t)
case CASE( TINT, TDOUBLE):
case CASE( TLONG, TDOUBLE):
case CASE( TIND, TDOUBLE):
-
- case CASE( TCHAR, TVLONG):
- case CASE( TUCHAR, TVLONG):
- case CASE( TSHORT, TVLONG):
- case CASE( TUSHORT,TVLONG):
- case CASE( TINT, TVLONG):
- case CASE( TLONG, TVLONG):
- case CASE( TIND, TVLONG):
regsalloc(&nod, &regnode);
gmove(f, &nod);
gins(AFMOVL, &nod, &fregnode0);
@@ -887,15 +890,9 @@ gmove(Node *f, Node *t)
*/
case CASE( TFLOAT, TFLOAT):
case CASE( TDOUBLE,TFLOAT):
- case CASE( TVLONG, TFLOAT):
case CASE( TFLOAT, TDOUBLE):
case CASE( TDOUBLE,TDOUBLE):
- case CASE( TVLONG, TDOUBLE):
-
- case CASE( TFLOAT, TVLONG):
- case CASE( TDOUBLE,TVLONG):
- case CASE( TVLONG, TVLONG):
a = AFMOVD; break;
}
if(a == AMOVL || a == AFMOVD)
@@ -923,6 +920,7 @@ print("botch in doindex\n");
if(n->left->op == OCONST)
idx.ptr = D_CONST;
else if(n->left->op == OREGISTER)
+// else if(n->left->op == OREGISTER && typeil[n->left->type->etype])
idx.ptr = n->left->reg;
else if(n->left->op != OADDR) {
reg[D_BP]++; // cant be used as a base