summaryrefslogtreecommitdiff
path: root/utils/1c
diff options
context:
space:
mode:
authorforsyth <forsyth@lavoro.terzarima.net>2013-06-03 21:01:14 +0000
committerforsyth <forsyth@lavoro.terzarima.net>2013-06-03 21:01:14 +0000
commit45a20ab721a513710138340faff3d59a31c3e01e (patch)
treeeea29d2684c51cc73725b8992a2125bede48e118 /utils/1c
parentcd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf (diff)
sync compilers with Plan 9
remove 1[acl] 2[acl]
Diffstat (limited to 'utils/1c')
-rw-r--r--utils/1c/cgen.c1396
-rw-r--r--utils/1c/enam.c425
-rw-r--r--utils/1c/gc.h339
-rw-r--r--utils/1c/list.c319
-rw-r--r--utils/1c/mkfile29
-rw-r--r--utils/1c/mul.c174
-rw-r--r--utils/1c/peep.c1057
-rw-r--r--utils/1c/reg.c1221
-rw-r--r--utils/1c/sgen.c694
-rw-r--r--utils/1c/swt.c964
-rw-r--r--utils/1c/txt.c903
11 files changed, 0 insertions, 7521 deletions
diff --git a/utils/1c/cgen.c b/utils/1c/cgen.c
deleted file mode 100644
index 2f121e51..00000000
--- a/utils/1c/cgen.c
+++ /dev/null
@@ -1,1396 +0,0 @@
-#include "gc.h"
-
-void
-cgen(Node *n, int result, Node *nn)
-{
- Node *l, *r, nod;
- int lg, rg, xg, yg, g, o;
- long v;
- Prog *p1;
-
- if(n == Z || n->type == T)
- return;
- if(typesuv[n->type->etype]) {
- sugen(n, result, nn, n->type->width);
- return;
- }
- if(debug['g']) {
- if(result == D_TREE)
- prtree(nn, "result");
- else
- print("result = %R\n", result);
- prtree(n, "cgen");
- }
- l = n->left;
- r = n->right;
- o = n->op;
- if(n->addable >= INDEXED) {
- if(result == D_NONE) {
- if(nn == Z)
- switch(o) {
- default:
- nullwarn(Z, Z);
- break;
- case OINDEX:
- nullwarn(l, r);
- break;
- }
- return;
- }
- gmove(n->type, nn->type, D_TREE, n, result, nn);
- return;
- }
-
- v = 0; /* set */
- switch(o) {
- default:
- diag(n, "unknown op in cgen: %O", o);
- break;
-
- case OAS:
- if(l->op == OBIT)
- goto bitas;
- /*
- * recursive use of result
- */
- if(result == D_NONE)
- if(l->addable > INDEXED)
- if(l->complex < FNX) {
- cgen(r, D_TREE, l);
- break;
- }
-
- /*
- * function calls on both sides
- */
- if(l->complex >= FNX && r->complex >= FNX) {
- cgen(r, D_TOS, r);
- v = argoff;
- lg = regaddr(result);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- adjsp(v - argoff);
- gmove(r->type, l->type, D_TOS, r, lg, l);
- if(result != D_NONE)
- gmove(l->type, nn->type, lg, l, result, nn);
- regfree(lg);
- break;
- }
-
- rg = D_TREE;
- lg = D_TREE;
- if(r->complex >= l->complex) {
- /*
- * right side before left
- */
- if(result != D_NONE) {
- rg = regalloc(n->type, result);
- cgen(r, rg, n);
- } else
- if(r->complex >= FNX || r->addable < INDEXED) {
- rg = regalloc(r->type, result);
- cgen(r, rg, r);
- }
- if(l->addable < INDEXED) {
- lg = regaddr(lg);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- }
- } else {
- /*
- * left before right
- */
- if(l->complex >= FNX || l->addable < INDEXED) {
- lg = regaddr(lg);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- }
- if(result != D_NONE) {
- rg = regalloc(n->type, result);
- cgen(r, rg, n);
- } else
- if(r->addable < INDEXED) {
- rg = regalloc(r->type, result);
- cgen(r, rg, r);
- }
- }
- if(result != D_NONE) {
- gmove(n->type, l->type, rg, r, lg, l);
- gmove(n->type, nn->type, rg, r, result, nn);
- } else
- gmove(r->type, l->type, rg, r, lg, l);
- regfree(lg);
- regfree(rg);
- break;
-
- bitas:
- n = l->left;
- rg = regalloc(tfield, result);
- if(l->complex >= r->complex) {
- lg = regaddr(D_NONE);
- lcgen(n, lg, Z);
- lg |= I_INDIR;
- cgen(r, rg, r);
- } else {
- cgen(r, rg, r);
- lg = regaddr(D_NONE);
- lcgen(n, lg, Z);
- lg |= I_INDIR;
- }
- g = regalloc(n->type, D_NONE);
- gmove(l->type, l->type, lg, l, g, l);
- bitstore(l, rg, lg, g, result, nn);
- break;
-
- case OBIT:
- if(result == D_NONE) {
- nullwarn(l, Z);
- break;
- }
- g = bitload(n, D_NONE, D_NONE, result, nn);
- gopcode(OAS, nn->type, g, n, result, nn);
- regfree(g);
- break;
-
- case ODOT:
- sugen(l, D_TREE, nodrat, l->type->width);
- if(result != D_NONE) {
- warn(n, "non-interruptable temporary");
- nod = *nodrat;
- if(!r || r->op != OCONST) {
- diag(n, "DOT and no offset");
- break;
- }
- nod.xoffset += r->vconst;
- nod.type = n->type;
- cgen(&nod, result, nn);
- }
- break;
-
- case OASLDIV:
- case OASLMOD:
- case OASDIV:
- case OASMOD:
- if(l->op == OBIT)
- goto asbitop;
- if(typefd[n->type->etype])
- goto asbinop;
- rg = D_TREE;
- if(l->complex >= FNX || r->complex >= FNX) {
- rg = D_TOS;
- cgen(r, rg, r);
- v = argoff;
- } else
- if(r->addable < INDEXED) {
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- }
- lg = D_TREE;
- if(!simplv(l)) {
- lg = regaddr(D_NONE);
- lcgen(l, lg, Z); /* destroys register optimization */
- lg |= I_INDIR;
- }
- g = regpair(result);
- gmove(l->type, n->type, lg, l, g, n);
- if(rg == D_TOS)
- adjsp(v - argoff);
- gopcode(o, n->type, rg, r, g, n);
- if(o == OASLMOD || o == OASMOD)
- gmove(n->type, l->type, g+1, n, lg, l);
- else
- gmove(n->type, l->type, g, n, lg, l);
- if(result != D_NONE)
- if(o == OASLMOD || o == OASMOD)
- gmove(n->type, nn->type, g+1, n, result, nn);
- else
- gmove(n->type, nn->type, g, n, result, nn);
- regfree(g);
- regfree(g+1);
- regfree(lg);
- regfree(rg);
- break;
-
- case OASXOR:
- case OASAND:
- case OASOR:
- if(l->op == OBIT)
- goto asbitop;
- if(l->complex >= FNX ||
- l->addable < INDEXED ||
- result != D_NONE ||
- typefd[n->type->etype])
- goto asbinop;
- rg = D_TREE;
- if(r->op != OCONST) {
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- }
- gopcode(o, l->type, rg, r, D_TREE, l);
- regfree(rg);
- break;
-
- case OASADD:
- case OASSUB:
- if(l->op == OBIT ||
- l->complex >= FNX ||
- l->addable < INDEXED ||
- result != D_NONE ||
- typefd[n->type->etype])
- goto asbinop;
- v = vconst(r);
- if(v > 0 && v <= 8) {
- gopcode(o, n->type, D_TREE, r, D_TREE, l);
- break;
- }
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- gopcode(o, n->type, rg, r, D_TREE, l);
- regfree(rg);
- break;
-
- case OASLSHR:
- case OASASHR:
- case OASASHL:
- if(l->op == OBIT ||
- l->complex >= FNX ||
- l->addable < INDEXED ||
- result != D_NONE ||
- typefd[n->type->etype])
- goto asbinop;
- rg = D_TREE;
- v = vconst(r);
- if(v <= 0 || v > 8) {
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- }
- lg = regalloc(n->type, D_NONE);
- cgen(l, lg, l);
- gopcode(o, n->type, rg, r, lg, l);
- gmove(n->type, n->type, lg, l, D_TREE, l);
- regfree(lg);
- regfree(rg);
- break;
-
- case OASLMUL:
- case OASMUL:
- asbinop:
- if(l->op == OBIT)
- goto asbitop;
- rg = D_TREE;
- if(l->complex >= FNX || r->complex >= FNX) {
- rg = D_TOS;
- cgen(r, rg, r);
- v = argoff;
- } else
- if(r->addable < INDEXED) {
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- } else {
- if(o == OASLSHR || o == OASASHR || o == OASASHL) {
- v = vconst(r);
- if(v <= 0 || v > 8) {
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- }
- }
- }
- lg = D_TREE;
- if(!simplv(l)) {
- lg = regaddr(D_NONE);
- lcgen(l, lg, Z); /* destroys register optimization */
- lg |= I_INDIR;
- }
- g = regalloc(n->type, result);
- gmove(l->type, n->type, lg, l, g, n);
- if(rg == D_TOS)
- adjsp(v - argoff);
- if(o == OASXOR)
- if(rg == D_TREE) {
- rg = regalloc(n->type, D_NONE);
- cgen(r, rg, r);
- }
- if(o == OASXOR || o == OASLSHR || o == OASASHR || o == OASASHL)
- if(rg == D_TOS) {
- rg = regalloc(n->type, D_NONE);
- gmove(n->type, n->type, D_TOS, n, rg, n);
- }
- gopcode(o, n->type, rg, r, g, n);
- gmove(n->type, l->type, g, n, lg, l);
- if(result != D_NONE)
- gmove(n->type, nn->type, g, n, result, nn);
- regfree(g);
- regfree(lg);
- regfree(rg);
- break;
-
- asbitop:
- rg = regaddr(D_NONE);
- lg = regalloc(tfield, D_NONE);
- if(l->complex >= r->complex) {
- g = bitload(l, lg, rg, result, nn);
- xg = regalloc(r->type, D_NONE);
- cgen(r, xg, nn);
- } else {
- xg = regalloc(r->type, D_NONE);
- cgen(r, xg, nn);
- g = bitload(l, lg, rg, result, nn);
- }
-
- if(!typefd[n->type->etype]) {
- if(o == OASLDIV || o == OASDIV) {
- yg = regpair(result);
- gmove(tfield, n->type, g, l, yg, n);
- gopcode(o, n->type, xg, r, yg, n);
- gmove(n->type, tfield, yg, n, g, l);
- regfree(yg);
- regfree(yg+1);
-
- regfree(xg);
- bitstore(l, g, rg, lg, D_NONE, nn);
- break;
- }
- if(o == OASLMOD || o == OASMOD) {
- yg = regpair(result);
- gmove(tfield, n->type, g, l, yg, n);
- gopcode(o, n->type, xg, r, yg, n);
- gmove(n->type, tfield, yg+1, n, g, l);
- regfree(yg);
- regfree(yg+1);
-
- regfree(xg);
- bitstore(l, g, rg, lg, D_NONE, nn);
- break;
- }
- }
-
- yg = regalloc(n->type, result);
- gmove(tfield, n->type, g, l, yg, n);
- gopcode(o, n->type, xg, r, yg, n);
- gmove(n->type, tfield, yg, n, g, l);
- regfree(yg);
-
- regfree(xg);
- bitstore(l, g, rg, lg, D_NONE, nn);
- break;
-
- case OCAST:
- if(result == D_NONE) {
- nullwarn(l, Z);
- break;
- }
- lg = result;
- if(l->complex >= FNX)
- lg = regret(l->type);
- lg = eval(l, lg);
- if(nocast(l->type, n->type)) {
- gmove(n->type, nn->type, lg, l, result, nn);
- regfree(lg);
- break;
- }
- if(nocast(n->type, nn->type)) {
- gmove(l->type, n->type, lg, l, result, nn);
- regfree(lg);
- break;
- }
- rg = regalloc(n->type, result);
- gmove(l->type, n->type, lg, l, rg, n);
- gmove(n->type, nn->type, rg, n, result, nn);
- regfree(rg);
- regfree(lg);
- break;
-
- case OCOND:
- doinc(l, PRE);
- boolgen(l, 1, D_NONE, Z, l);
- p1 = p;
-
- inargs++;
- doinc(r->left, PRE);
- cgen(r->left, result, nn);
- doinc(r->left, POST);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
-
- doinc(r->right, PRE);
- cgen(r->right, result, nn);
- doinc(r->right, POST);
- patch(p1, pc);
- inargs--;
- break;
-
- case OIND:
- if(result == D_NONE) {
- nullwarn(l, Z);
- break;
- }
- lg = nodalloc(types[TIND], result, &nod);
- nod.lineno = n->lineno;
- if(l->op == OADD) {
- if(l->left->op == OCONST) {
- nod.xoffset += l->left->vconst;
- l = l->right;
- } else
- if(l->right->op == OCONST) {
- nod.xoffset += l->right->vconst;
- l = l->left;
- }
- }
- cgen(l, lg, l);
- gmove(n->type, nn->type, D_TREE, &nod, result, nn);
- regfree(lg);
- break;
-
- case OFUNC:
- v = argoff;
- inargs++;
- gargs(r);
- lg = D_TREE;
- if(l->addable < INDEXED) {
- lg = regaddr(result);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- }
- inargs--;
- doinc(r, POST);
- doinc(l, POST);
- gopcode(OFUNC, types[TCHAR], D_NONE, Z, lg, l);
- regfree(lg);
- if(inargs)
- adjsp(v - argoff);
- if(result != D_NONE) {
- lg = regret(n->type);
- gmove(n->type, nn->type, lg, n, result, nn);
- }
- break;
-
- case OLDIV:
- case OLMOD:
- case ODIV:
- case OMOD:
- if(result == D_NONE) {
- nullwarn(l, r);
- break;
- }
- if(typefd[n->type->etype])
- goto binop;
- if(r->addable >= INDEXED && r->complex < FNX) {
- lg = regpair(result);
- cgen(l, lg, l);
- rg = D_TREE;
- } else {
- cgen(r, D_TOS, r);
- v = argoff;
- lg = regpair(result);
- cgen(l, lg, l);
- adjsp(v - argoff);
- rg = D_TOS;
- }
- gopcode(o, n->type, rg, r, lg, l);
- if(o == OMOD || o == OLMOD)
- gmove(l->type, nn->type, lg+1, l, result, nn);
- else
- gmove(l->type, nn->type, lg, l, result, nn);
- regfree(lg);
- regfree(lg+1);
- break;
-
- case OMUL:
- case OLMUL:
- if(l->op == OCONST)
- if(mulcon(r, l, result, nn))
- break;
- if(r->op == OCONST)
- if(mulcon(l, r, result, nn))
- break;
- if(debug['M'])
- print("%L multiply\n", n->lineno);
- goto binop;
-
- case OAND:
- if(r->op == OCONST)
- if(typeil[n->type->etype])
- if(l->op == OCAST) {
- if(typec[l->left->type->etype])
- if(!(r->vconst & ~0xff)) {
- l = l->left;
- goto binop;
- }
- if(typeh[l->left->type->etype])
- if(!(r->vconst & ~0xffff)) {
- l = l->left;
- goto binop;
- }
- }
- goto binop;
-
- case OADD:
- if(result == D_TOS)
- if(r->addable >= INDEXED)
- if(l->op == OCONST)
- if(typeil[l->type->etype]) {
- v = l->vconst;
- if(v > -32768 && v < 32768) {
- rg = regaddr(D_NONE);
- gmove(r->type, r->type, D_TREE, r, rg, r);
- gopcode(OADDR, types[TSHORT], D_NONE, Z, rg, r);
- p->to.offset = v;
- p->to.type |= I_INDIR;
- regfree(rg);
- break;
- }
- }
-
- case OSUB:
- if(result == D_TOS)
- if(l->addable >= INDEXED)
- if(r->op == OCONST)
- if(typeil[r->type->etype]) {
- v = r->vconst;
- if(v > -32768 && v < 32768) {
- if(n->op == OSUB)
- v = -v;
- lg = regaddr(D_NONE);
- gmove(l->type, l->type, D_TREE, l, lg, l);
- gopcode(OADDR, types[TSHORT], D_NONE, Z, lg, l);
- p->to.offset = v;
- p->to.type |= I_INDIR;
- regfree(lg);
- break;
- }
- }
- goto binop;
-
- case OOR:
- case OXOR:
- binop:
- if(result == D_NONE) {
- nullwarn(l, r);
- break;
- }
- if(l->complex >= FNX && r->complex >= FNX) {
- cgen(r, D_TOS, r);
- v = argoff;
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- adjsp(v - argoff);
- if(o == OXOR) {
- rg = regalloc(r->type, D_NONE);
- gmove(r->type, r->type, D_TOS, r, rg, r);
- gopcode(o, n->type, rg, r, lg, l);
- regfree(rg);
- } else
- gopcode(o, n->type, D_TOS, r, lg, l);
- gmove(n->type, nn->type, lg, l, result, nn);
- regfree(lg);
- break;
- }
- if(l->complex >= r->complex) {
- if(l->op == OADDR && (o == OADD || o == OSUB))
- lg = regaddr(result);
- else
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- rg = eval(r, D_NONE);
- } else {
- rg = regalloc(r->type, D_NONE);
- cgen(r, rg, r);
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- }
- if(o == OXOR) {
- if(rg == D_TREE) {
- rg = regalloc(r->type, D_NONE);
- cgen(r, rg, r);
- }
- if(rg == D_TOS) {
- rg = regalloc(r->type, D_NONE);
- gmove(r->type, r->type, D_TOS, r, rg, r);
- }
- }
- gopcode(o, n->type, rg, r, lg, l);
- gmove(n->type, nn->type, lg, l, result, nn);
- regfree(lg);
- regfree(rg);
- break;
-
- case OASHL:
- if(r->op == OCONST)
- if(shlcon(l, r, result, nn))
- break;
- case OLSHR:
- case OASHR:
- if(result == D_NONE) {
- nullwarn(l, r);
- break;
- }
-
- if(l->complex >= FNX && r->complex >= FNX) {
- cgen(r, D_TOS, r);
- v = argoff;
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- adjsp(v - argoff);
- rg = regalloc(r->type, D_NONE);
- gopcode(OAS, r->type, D_TOS, r, rg, r);
- gopcode(n->op, n->type, rg, r, lg, l);
- gmove(n->type, nn->type, lg, l, result, nn);
- regfree(lg);
- regfree(rg);
- break;
- }
- if(l->complex >= r->complex) {
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- v = vconst(r);
- if(v <= 0 || v > 8) {
- rg = regalloc(r->type, D_NONE);
- cgen(r, rg, r);
- } else
- rg = eval(r, D_NONE);
- } else {
- rg = regalloc(r->type, D_NONE);
- cgen(r, rg, r);
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- }
- gopcode(o, n->type, rg, r, lg, l);
- gmove(n->type, nn->type, lg, l, result, nn);
- regfree(lg);
- regfree(rg);
- break;
-
- case ONEG:
- case OCOM:
- if(result == D_NONE) {
- nullwarn(l, Z);
- break;
- }
- lg = regalloc(l->type, result);
- cgen(l, lg, l);
- gopcode(o, l->type, D_NONE, Z, lg, l);
- gmove(n->type, nn->type, lg, l, result, nn);
- regfree(lg);
- break;
-
- case OADDR:
- if(result == D_NONE) {
- nullwarn(l, Z);
- break;
- }
- lcgen(l, result, nn);
- break;
-
- case OEQ:
- case ONE:
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OLO:
- case OLS:
- case OHI:
- case OHS:
- if(result == D_NONE) {
- nullwarn(l, r);
- break;
- }
- boolgen(n, 1, result, nn, Z);
- break;
-
- case OANDAND:
- case OOROR:
- boolgen(n, 1, result, nn, Z);
- if(result == D_NONE)
- patch(p, pc);
- break;
-
- case OCOMMA:
- cgen(l, D_NONE, l);
- doinc(l, POST);
- doinc(r, PRE);
- cgen(r, result, nn);
- break;
-
- case ONOT:
- if(result == D_NONE) {
- nullwarn(l, Z);
- break;
- }
- boolgen(n, 1, result, nn, Z);
- break;
-
- case OPOSTINC:
- case OPOSTDEC:
- v = 1;
- if(l->type->etype == TIND)
- v = l->type->link->width;
- if(o == OPOSTDEC)
- v = -v;
- if(l->op == OBIT)
- goto bitinc;
- if(nn == Z)
- goto pre;
-
- lg = D_TREE;
- if(l->addable < INDEXED) {
- lg = regaddr(D_NONE);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- }
- if(result != D_NONE)
- gmove(l->type, nn->type, lg, l, result, nn);
- if(typefd[n->type->etype]) {
- rg = regalloc(n->type, D_NONE);
- gmove(l->type, l->type, lg, l, rg, l);
- gopcode(o, n->type, D_CONST, nodconst(1), rg, l);
- gmove(l->type, l->type, rg, l, lg, l);
- regfree(rg);
- } else {
- if(v < 0)
- gopcode(o, n->type, D_CONST, nodconst(-v), lg, l);
- else
- gopcode(o, n->type, D_CONST, nodconst(v), lg, l);
- }
- regfree(lg);
- break;
-
- case OPREINC:
- case OPREDEC:
- v = 1;
- if(l->type->etype == TIND)
- v = l->type->link->width;
- if(o == OPREDEC)
- v = -v;
- if(l->op == OBIT)
- goto bitinc;
-
- pre:
- lg = D_TREE;
- if(l->addable < INDEXED) {
- lg = regaddr(D_NONE);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- }
- if(typefd[n->type->etype]) {
- rg = regalloc(n->type, D_NONE);
- gmove(l->type, l->type, lg, l, rg, l);
- gopcode(o, n->type, D_CONST, nodconst(1), rg, l);
- gmove(l->type, l->type, rg, l, lg, l);
- regfree(rg);
- } else {
- if(v < 0)
- gopcode(o, n->type, D_CONST, nodconst(-v), lg, l);
- else
- gopcode(o, n->type, D_CONST, nodconst(v), lg, l);
- }
- if(result != D_NONE)
- gmove(l->type, nn->type, lg, l, result, nn);
- regfree(lg);
- break;
-
- bitinc:
- rg = regaddr(D_NONE);
- lg = regalloc(tfield, D_NONE);
- if(result != D_NONE && (o == OPOSTINC || o == OPOSTDEC)) {
- g = bitload(l, lg, rg, D_NONE, nn);
- if(nn != Z)
- gmove(l->type, nn->type, g, l, result, nn);
- if(v < 0)
- gopcode(o, n->type, D_CONST, nodconst(-v), g, n);
- else
- gopcode(o, n->type, D_CONST, nodconst(v), g, n);
- bitstore(l, g, rg, lg, D_NONE, nn);
- break;
- }
- g = bitload(l, lg, rg, result, nn);
- if(v < 0)
- gopcode(o, n->type, D_CONST, nodconst(-v), g, n);
- else
- gopcode(o, n->type, D_CONST, nodconst(v), g, n);
- if(result != D_NONE)
- gmove(l->type, nn->type, g, l, result, nn);
- bitstore(l, g, rg, lg, D_NONE, nn);
- break;
- }
-}
-
-void
-lcgen(Node *n, int result, Node *nn)
-{
- Node rn;
- Prog *p1;
- int lg;
-
- if(n == Z || n->type == T)
- return;
- if(debug['g']) {
- if(result == D_TREE)
- prtree(nn, "result");
- else
- print("result = %R\n", result);
- prtree(n, "lcgen");
- }
- if(nn == Z) {
- nn = &rn;
- nn->type = types[TIND];
- }
- switch(n->op) {
- case OCOMMA:
- cgen(n->left, D_NONE, n->left);
- doinc(n->left, POST);
- doinc(n->right, PRE);
- lcgen(n->right, result, nn);
- break;
-
- case OCOND:
- doinc(n->left, PRE);
- boolgen(n->left, 1, D_NONE, Z, n->left);
- p1 = p;
-
- inargs++;
- doinc(n->right->left, PRE);
- lcgen(n->right->left, result, nn);
- doinc(n->right->left, POST);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
-
- doinc(n->right->right, PRE);
- lcgen(n->right->right, result, nn);
- doinc(n->right->right, POST);
- patch(p1, pc);
- inargs--;
- break;
-
- case OIND:
- if(n->addable >= INDEXED) {
- if(result >= D_A0 && result < D_A0+NREG) {
- gopcode(OADDR, types[TLONG], D_TREE, n, result, nn);
- break;
- }
- if(result == D_TOS) {
- gopcode(OADDR, types[TSHORT], D_NONE, nn, D_TREE, n);
- break;
- }
- }
- cgen(n->left, result, nn);
- break;
-
- default:
- if(n->addable < INDEXED) {
- diag(n, "unknown op in lcgen: %O", n->op);
- break;
- }
- if(result >= D_A0 && result < D_A0+NREG) {
- gopcode(OADDR, types[TLONG], D_TREE, n, result, nn);
- break;
- }
- if(result == D_TOS) {
- gopcode(OADDR, types[TSHORT], D_NONE, nn, D_TREE, n);
- break;
- }
- lg = regaddr(result);
- gopcode(OADDR, types[TLONG], D_TREE, n, lg, nn);
- gopcode(OAS, nn->type, lg, nn, result, nn);
- regfree(lg);
- break;
- }
-}
-
-void
-bcgen(Node *n, int true)
-{
-
- boolgen(n, true, D_NONE, Z, Z);
-}
-
-void
-boolgen(Node *n, int true, int result, Node *nn, Node *post)
-{
- Prog *p1, *p2;
- Node *l, *r;
- int lg, rg, fp, o;
- long v;
-
- if(debug['g']) {
- if(result == D_TREE)
- prtree(nn, "result");
- else
- print("result = %R\n", result);
- prtree(n, "boolgen");
- }
- l = n->left;
- r = n->right;
- switch(n->op) {
-
- default:
- lg = eval(n, result);
- if(lg >= D_A0 && lg < D_A0+NREG) {
- rg = regalloc(types[TLONG], D_NONE);
- gopcode(OAS, types[TLONG], lg, n, rg, Z);
- regfree(rg);
- } else
- gopcode(OTST, n->type, D_NONE, Z, lg, n);
- regfree(lg);
- o = ONE;
- fp = typefd[n->type->etype];
- goto genbool;
-
- case OCONST:
- fp = vconst(n);
- if(!true)
- fp = !fp;
- gbranch(OGOTO);
- if(fp) {
- p1 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- }
- goto com;
-
- case ONOT:
- boolgen(l, !true, result, nn, post);
- break;
-
- case OCOND:
- doinc(l, PRE);
- boolgen(l, 1, D_NONE, Z, l);
- p1 = p;
-
- inargs++;
- doinc(r->left, PRE);
- boolgen(r->left, true, result, nn, r->left);
- if(result != D_NONE) {
- doinc(r->left, POST);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
-
- doinc(r->right, PRE);
- boolgen(r->right, !true, result, nn, r->right);
- doinc(r->right, POST);
- patch(p1, pc);
- inargs--;
- break;
- }
- p2 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
-
- doinc(r->right, PRE);
- boolgen(r->right, !true, result, nn, r->right);
- patch(p2, pc);
- p2 = p;
- if(doinc(post, POST|TEST)) {
- lg = regalloc(types[TSHORT], D_NONE);
- gopcode(OAS, types[TSHORT], D_CCR, Z, lg, Z);
- doinc(post, POST);
- gopcode(OAS, types[TSHORT], lg, Z, D_CCR, Z);
- regfree(lg);
- }
- gbranch(OGOTO);
- patch(p1, pc);
- patch(p2, pc);
- inargs--;
- goto com;
-
- case OANDAND:
- if(!true)
- goto caseor;
-
- caseand:
- doinc(l, PRE);
- boolgen(l, true, D_NONE, Z, l);
- p1 = p;
- inargs++;
- doinc(r, PRE);
- boolgen(r, !true, D_NONE, Z, r);
- p2 = p;
- patch(p1, pc);
- gbranch(OGOTO);
- patch(p2, pc);
- inargs--;
- goto com;
-
- case OOROR:
- if(!true)
- goto caseand;
-
- caseor:
- doinc(l, PRE);
- boolgen(l, !true, D_NONE, Z, l);
- p1 = p;
- inargs++;
- doinc(r, PRE);
- boolgen(r, !true, D_NONE, Z, r);
- p2 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- patch(p2, pc);
- inargs--;
- goto com;
-
- case OEQ:
- case ONE:
- if(vconst(l) == 0) {
- if(n->op == ONE) {
- boolgen(r, true, result, nn, post);
- break;
- }
- boolgen(r, !true, result, nn, post);
- break;
- }
-
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OHI:
- case OHS:
- case OLO:
- case OLS:
- fp = typefd[r->type->etype];
- if(l->op == OCONST) {
- v = vconst(l);
- if(v == 0) { /* tst instruction */
- o = invrel[relindex(n->op)];
- rg = eval(r, result);
- gopcode(OTST, r->type, D_NONE, Z, rg, r);
- regfree(rg);
- goto genbool;
- }
- if(!fp) { /* cmpi and movq, saves about .5% both time and space */
- if(v < 128 && v >= -128 &&
- ewidth[r->type->etype] == SZ_LONG) {
- rg = eval(r, result);
- lg = regalloc(l->type, D_NONE);
- cgen(l, lg, l);
- o = n->op;
- gopcode(o, l->type, lg, l, rg, r);
- regfree(lg);
- regfree(rg);
- goto genbool;
- }
- o = invrel[relindex(n->op)];
- rg = eval(r, result);
- gopcode(o, r->type, rg, r, D_TREE, l);
- regfree(rg);
- goto genbool;
- }
- }
- lg = D_TOS;
- if(r->complex < FNX)
- lg = regalloc(l->type, lg);
- cgen(l, lg, l);
- v = argoff;
- rg = eval(r, result);
- if(lg == D_TOS) {
- adjsp(v - argoff);
- lg = regalloc(l->type, lg);
- gopcode(OAS, l->type, D_TOS, l, lg, l);
- }
- o = n->op;
- gopcode(o, l->type, lg, l, rg, r);
- regfree(lg);
- regfree(rg);
-
- genbool:
- if(true)
- o = comrel[relindex(o)];
- if(doinc(post, POST|TEST)) {
- lg = regalloc(types[TSHORT], D_NONE);
- gopcode(OAS, types[TSHORT], D_CCR, Z, lg, Z);
- doinc(post, POST);
- gopcode(OAS, types[TSHORT], lg, Z, D_CCR, Z);
- regfree(lg);
- }
- gbranch(o);
- if(fp)
- fpbranch();
-
- com:
- if(result == D_NONE)
- break;
- p1 = p;
- gopcode(OAS, nn->type, D_CONST, nodconst(1), result, nn);
- gbranch(OGOTO);
- p2 = p;
- patch(p1, pc);
- gopcode(OAS, nn->type, D_CONST, nodconst(0), result, nn);
- patch(p2, pc);
- break;
- }
-}
-
-void
-sugen(Node *n, int result, Node *nn, long w)
-{
- long s, v, o;
- int lg, rg, ng;
- Prog *p1;
- Node *l, *r, nod;
- Type *t;
-
- if(n == Z || n->type == T)
- return;
- if(debug['g']) {
- if(result == D_TREE)
- prtree(nn, "result");
- else
- print("result = %R width = %ld\n", result, w);
- prtree(n, "sugen");
- }
- s = argoff;
- if(result == D_TREE) {
- if(nn == nodrat)
- if(w > nrathole)
- nrathole = w;
- }
-
- if(n->addable >= INDEXED && n->op != OCONST)
- goto copy;
- switch(n->op) {
- default:
- diag(n, "unknown op in sugen: %O", n->op);
- break;
-
- case OCONST:
- if(n->type && typev[n->type->etype]) {
- if(result == D_NONE) {
- nullwarn(n->left, Z);
- break;
- }
-
- lg = regaddr(D_NONE);
- if(result == D_TOS) {
- adjsp(s - argoff + w);
- gopcode(OADDR, types[TIND], result, nn, lg, n);
- } else
- if(result == D_TREE) {
- lcgen(nn, lg, Z);
- } else
- diag(n, "unknown su result: %R", result);
-
- gopcode(OAS, types[TLONG], D_CONST, nodconst((long)(n->vconst>>32)),
- lg|I_INDINC, n);
- gopcode(OAS, types[TLONG], D_CONST, nodconst((long)(n->vconst)),
- lg|I_INDINC, n);
- regfree(lg);
- break;
- }
- goto copy;
-
- case ODOT:
- l = n->left;
- sugen(l, D_TREE, nodrat, l->type->width);
- if(result != D_NONE) {
- warn(n, "non-interruptable temporary");
- nod = *nodrat;
- r = n->right;
- if(!r || r->op != OCONST) {
- diag(n, "DOT and no offset");
- break;
- }
- nod.xoffset += r->vconst;
- nod.type = n->type;
- sugen(&nod, result, nn, w);
- }
- break;
-
- case OIND:
- if(result == D_NONE) {
- nullwarn(n->left, Z);
- break;
- }
- goto copy;
-
- case OSTRUCT:
- lg = nodalloc(types[TIND], result, &nod);
- nod.lineno = n->lineno;
- if(result == D_TREE)
- lcgen(nn, lg, Z);
- else
- if(result == D_TOS) {
- adjsp(s - argoff + w);
- gopcode(OADDR, types[TIND], result, nn, lg, n);
- } else
- diag(n, "unknown su result: %R", result);
- o = 0;
- 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;
- }
- nod.type = t;
- if(l->complex < FNX) {
- nod.xoffset = 0;
- if(o != t->offset) {
- gopcode(OADD, types[TIND], D_CONST,
- nodconst(t->offset-o), lg, Z);
- o = t->offset;
- }
- cgen(l, D_TREE, &nod);
- continue;
- }
- nod.xoffset = t->offset - o;
- gopcode(OAS, types[TIND], lg, Z, D_TOS, Z);
- s = argoff;
- if(typesuv[t->etype]) {
- sugen(l, D_TREE, nodrat, t->width);
- adjsp(s - argoff);
- gopcode(OAS, types[TIND], D_TOS, Z, lg, Z);
- warn(n, "non-interruptable temporary");
- sugen(nodrat, D_TREE, &nod, t->width);
- continue;
- }
- rg = regalloc(t, D_NONE);
- cgen(l, rg, l);
- adjsp(s - argoff);
- gopcode(OAS, types[TIND], D_TOS, Z, lg, Z);
- gopcode(OAS, t, rg, Z, D_TREE, &nod);
- regfree(rg);
- }
- regfree(lg);
- break;
-
- case OAS:
- if(result == D_NONE) {
- sugen(n->right, D_TREE, n->left, w);
- break;
- }
- sugen(n->right, D_TREE, nodrat, w); /* could do better */
- warn(n, "non-interruptable temporary");
- sugen(nodrat, D_TREE, n->left, w);
- sugen(nodrat, result, nn, w);
- break;
-
- case OFUNC:
- if(result == D_NONE) {
- sugen(n, D_TREE, nodrat, w);
- break;
- }
- inargs++;
- /* prepare zero-th arg: address of result */
- if(result == D_TOS) {
- adjsp(s - argoff + w);
- v = argoff;
- gargs(n->right);
- gopcode(OADDR, types[TSHORT], D_NONE, nn, result, nn);
- p->to.type = D_STACK;
- p->to.offset = argoff - v;
- } else
- if(result == D_TREE) {
- v = argoff;
- gargs(n->right);
- if(nn->complex >= FNX) {
- rg = regalloc(types[TIND], regret(types[TIND]));
- lcgen(nn, rg, Z);
- gopcode(OAS, types[TIND], rg, Z, D_TOS, Z);
- regfree(rg);
- } else
- lcgen(nn, D_TOS, Z);
- } else {
- diag(n, "unknown result in FUNC sugen");
- break;
- }
- argoff += types[TIND]->width;
- l = n->left;
- lg = D_TREE;
- if(l->addable < INDEXED) {
- lg = regaddr(result);
- lcgen(l, lg, Z);
- lg |= I_INDIR;
- }
- inargs--;
- doinc(n->right, POST);
- doinc(n->left, POST);
- gopcode(OFUNC, types[TCHAR], D_NONE, Z, lg, l);
- regfree(lg);
- if(inargs)
- adjsp(v - argoff);
- break;
-
- case OCOND:
- doinc(n->left, PRE);
- boolgen(n->left, 1, D_NONE, Z, n->left);
- p1 = p;
-
- inargs++;
- doinc(n->right->left, PRE);
- sugen(n->right->left, result, nn, w);
- doinc(n->right->left, POST);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
-
- doinc(n->right->right, PRE);
- sugen(n->right->right, result, nn, w);
- doinc(n->right->right, POST);
- patch(p1, pc);
- inargs--;
- break;
-
- case OCOMMA:
- cgen(n->left, D_NONE, n->left);
- doinc(n->left, POST);
- doinc(n->right, PRE);
- sugen(n->right, result, nn, w);
- break;
- }
- return;
-
-copy:
- if(result == D_NONE)
- return;
- rg = regaddr(D_NONE);
- lcgen(n, rg, Z);
-
- lg = regaddr(D_NONE);
- if(result == D_TOS) {
- adjsp(s - argoff + w);
- gopcode(OADDR, types[TIND], result, nn, lg, n);
- } else
- if(result == D_TREE) {
- if(nn->complex >= FNX) {
- gopcode(OAS, types[TIND], rg, n, D_TOS, n);
- s = argoff;
- lcgen(nn, lg, Z);
- adjsp(s - argoff);
- gopcode(OAS, types[TIND], D_TOS, n, rg, n);
- } else
- lcgen(nn, lg, Z);
- } else
- diag(n, "unknown su result: %R", result);
-
- if(w % SZ_LONG)
- diag(Z, "sucopy width not 0%%%d", SZ_LONG);
- v = w / SZ_LONG;
- if(v & 1) {
- gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n);
- v--;
- }
- if(v > 6) {
- ng = regalloc(types[TLONG], D_NONE);
- gopcode(OAS, types[TLONG], D_CONST, nodconst(v/2-1), ng, n);
- v = pc;
- gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n);
- gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n);
- gbranch(OGT);
- patch(p, v);
- p->from.type = ng;
- p->as = ADBF;
- regfree(ng);
- } else
- while(v > 0) {
- gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n);
- v--;
- }
-
- regfree(lg);
- regfree(rg);
-}
diff --git a/utils/1c/enam.c b/utils/1c/enam.c
deleted file mode 100644
index be6917af..00000000
--- a/utils/1c/enam.c
+++ /dev/null
@@ -1,425 +0,0 @@
-char *anames[] =
-{
- "XXX",
- "ABCD",
- "ADDB",
- "ADDL",
- "ADDW",
- "ADDXB",
- "ADDXL",
- "ADDXW",
- "ADJSP",
- "ANDB",
- "ANDL",
- "ANDW",
- "ASLB",
- "ASLL",
- "ASLW",
- "ASRB",
- "ASRL",
- "ASRW",
- "BCASE",
- "BCC",
- "BCHG",
- "BCLR",
- "BCS",
- "BEQ",
- "BFCHG",
- "BFCLR",
- "BFEXTS",
- "BFEXTU",
- "BFFFO",
- "BFINS",
- "BFSET",
- "BFTST",
- "BGE",
- "BGT",
- "BHI",
- "BKPT",
- "BLE",
- "BLS",
- "BLT",
- "BMI",
- "BNE",
- "BPL",
- "BRA",
- "BSET",
- "BSR",
- "BTST",
- "BVC",
- "BVS",
- "CALLM",
- "CAS2B",
- "CAS2L",
- "CAS2W",
- "CASB",
- "CASEW",
- "CASL",
- "CASW",
- "CHK2B",
- "CHK2L",
- "CHK2W",
- "CHKL",
- "CHKW",
- "CLRB",
- "CLRL",
- "CLRW",
- "CMP2B",
- "CMP2L",
- "CMP2W",
- "CMPB",
- "CMPL",
- "CMPW",
- "DATA",
- "DBCC",
- "DBCS",
- "DBEQ",
- "DBF",
- "DBGE",
- "DBGT",
- "DBHI",
- "DBLE",
- "DBLS",
- "DBLT",
- "DBMI",
- "DBNE",
- "DBPL",
- "DBT",
- "DBVC",
- "DBVS",
- "DIVSL",
- "DIVSW",
- "DIVUL",
- "DIVUW",
- "END",
- "EORB",
- "EORL",
- "EORW",
- "EXG",
- "EXTBL",
- "EXTBW",
- "EXTWL",
- "FABSB",
- "FABSD",
- "FABSF",
- "FABSL",
- "FABSW",
- "FACOSB",
- "FACOSD",
- "FACOSF",
- "FACOSL",
- "FACOSW",
- "FADDB",
- "FADDD",
- "FADDF",
- "FADDL",
- "FADDW",
- "FASINB",
- "FASIND",
- "FASINF",
- "FASINL",
- "FASINW",
- "FATANB",
- "FATAND",
- "FATANF",
- "FATANHB",
- "FATANHD",
- "FATANHF",
- "FATANHL",
- "FATANHW",
- "FATANL",
- "FATANW",
- "FBEQ",
- "FBF",
- "FBGE",
- "FBGT",
- "FBLE",
- "FBLT",
- "FBNE",
- "FBT",
- "FCMPB",
- "FCMPD",
- "FCMPF",
- "FCMPL",
- "FCMPW",
- "FCOSB",
- "FCOSD",
- "FCOSF",
- "FCOSHB",
- "FCOSHD",
- "FCOSHF",
- "FCOSHL",
- "FCOSHW",
- "FCOSL",
- "FCOSW",
- "FDBEQ",
- "FDBF",
- "FDBGE",
- "FDBGT",
- "FDBLE",
- "FDBLT",
- "FDBNE",
- "FDBT",
- "FDIVB",
- "FDIVD",
- "FDIVF",
- "FDIVL",
- "FDIVW",
- "FETOXB",
- "FETOXD",
- "FETOXF",
- "FETOXL",
- "FETOXM1B",
- "FETOXM1D",
- "FETOXM1F",
- "FETOXM1L",
- "FETOXM1W",
- "FETOXW",
- "FGETEXPB",
- "FGETEXPD",
- "FGETEXPF",
- "FGETEXPL",
- "FGETEXPW",
- "FGETMANB",
- "FGETMAND",
- "FGETMANF",
- "FGETMANL",
- "FGETMANW",
- "FINTB",
- "FINTD",
- "FINTF",
- "FINTL",
- "FINTRZB",
- "FINTRZD",
- "FINTRZF",
- "FINTRZL",
- "FINTRZW",
- "FINTW",
- "FLOG10B",
- "FLOG10D",
- "FLOG10F",
- "FLOG10L",
- "FLOG10W",
- "FLOG2B",
- "FLOG2D",
- "FLOG2F",
- "FLOG2L",
- "FLOG2W",
- "FLOGNB",
- "FLOGND",
- "FLOGNF",
- "FLOGNL",
- "FLOGNP1B",
- "FLOGNP1D",
- "FLOGNP1F",
- "FLOGNP1L",
- "FLOGNP1W",
- "FLOGNW",
- "FMODB",
- "FMODD",
- "FMODF",
- "FMODL",
- "FMODW",
- "FMOVEB",
- "FMOVED",
- "FMOVEF",
- "FMOVEL",
- "FMOVEM",
- "FMOVEMC",
- "FMOVEW",
- "FMULB",
- "FMULD",
- "FMULF",
- "FMULL",
- "FMULW",
- "FNEGB",
- "FNEGD",
- "FNEGF",
- "FNEGL",
- "FNEGW",
- "FREMB",
- "FREMD",
- "FREMF",
- "FREML",
- "FREMW",
- "FRESTORE",
- "FSAVE",
- "FSCALEB",
- "FSCALED",
- "FSCALEF",
- "FSCALEL",
- "FSCALEW",
- "FSEQ",
- "FSF",
- "FSGE",
- "FSGT",
- "FSINB",
- "FSIND",
- "FSINF",
- "FSINHB",
- "FSINHD",
- "FSINHF",
- "FSINHL",
- "FSINHW",
- "FSINL",
- "FSINW",
- "FSLE",
- "FSLT",
- "FSNE",
- "FSQRTB",
- "FSQRTD",
- "FSQRTF",
- "FSQRTL",
- "FSQRTW",
- "FST",
- "FSUBB",
- "FSUBD",
- "FSUBF",
- "FSUBL",
- "FSUBW",
- "FTANB",
- "FTAND",
- "FTANF",
- "FTANHB",
- "FTANHD",
- "FTANHF",
- "FTANHL",
- "FTANHW",
- "FTANL",
- "FTANW",
- "FTENTOXB",
- "FTENTOXD",
- "FTENTOXF",
- "FTENTOXL",
- "FTENTOXW",
- "FTSTB",
- "FTSTD",
- "FTSTF",
- "FTSTL",
- "FTSTW",
- "FTWOTOXB",
- "FTWOTOXD",
- "FTWOTOXF",
- "FTWOTOXL",
- "FTWOTOXW",
- "GLOBL",
- "GOK",
- "HISTORY",
- "ILLEG",
- "INSTR",
- "JMP",
- "JSR",
- "LEA",
- "LINKL",
- "LINKW",
- "LOCATE",
- "LONG",
- "LSLB",
- "LSLL",
- "LSLW",
- "LSRB",
- "LSRL",
- "LSRW",
- "MOVB",
- "MOVEM",
- "MOVEPL",
- "MOVEPW",
- "MOVESB",
- "MOVESL",
- "MOVESW",
- "MOVL",
- "MOVW",
- "MULSL",
- "MULSW",
- "MULUL",
- "MULUW",
- "NAME",
- "NBCD",
- "NEGB",
- "NEGL",
- "NEGW",
- "NEGXB",
- "NEGXL",
- "NEGXW",
- "NOP",
- "NOTB",
- "NOTL",
- "NOTW",
- "ORB",
- "ORL",
- "ORW",
- "PACK",
- "PEA",
- "RESET",
- "ROTLB",
- "ROTLL",
- "ROTLW",
- "ROTRB",
- "ROTRL",
- "ROTRW",
- "ROXLB",
- "ROXLL",
- "ROXLW",
- "ROXRB",
- "ROXRL",
- "ROXRW",
- "RTD",
- "RTE",
- "RTM",
- "RTR",
- "RTS",
- "SBCD",
- "SCC",
- "SCS",
- "SEQ",
- "SF",
- "SGE",
- "SGT",
- "SHI",
- "SLE",
- "SLS",
- "SLT",
- "SMI",
- "SNE",
- "SPL",
- "ST",
- "STOP",
- "SUBB",
- "SUBL",
- "SUBW",
- "SUBXB",
- "SUBXL",
- "SUBXW",
- "SVC",
- "SVS",
- "SWAP",
- "SYS",
- "TAS",
- "TEXT",
- "TRAP",
- "TRAPCC",
- "TRAPCS",
- "TRAPEQ",
- "TRAPF",
- "TRAPGE",
- "TRAPGT",
- "TRAPHI",
- "TRAPLE",
- "TRAPLS",
- "TRAPLT",
- "TRAPMI",
- "TRAPNE",
- "TRAPPL",
- "TRAPT",
- "TRAPV",
- "TRAPVC",
- "TRAPVS",
- "TSTB",
- "TSTL",
- "TSTW",
- "UNLK",
- "UNPK",
- "WORD",
- "SIGNAME",
- "LAST",
-};
diff --git a/utils/1c/gc.h b/utils/1c/gc.h
deleted file mode 100644
index ca2c84fb..00000000
--- a/utils/1c/gc.h
+++ /dev/null
@@ -1,339 +0,0 @@
-#include "../cc/cc.h"
-#include "../2c/2.out.h"
-/*
- * 1c/68000
- * Motorola 68000
- */
-
-#define SZ_CHAR 1
-#define SZ_SHORT 2
-#define SZ_INT 4
-#define SZ_LONG 4
-#define SZ_IND 4
-#define SZ_FLOAT 4
-#define SZ_VLONG 8
-#define SZ_DOUBLE 8
-
-#define ALLOP OEND
-#define NRGN 300
-#define FNX 100
-#define INDEXED 9
-
-#define PRE 1
-#define POST 2
-#define TEST 4
-
-typedef struct Adr Adr;
-typedef struct Prog Prog;
-typedef struct Txt Txt;
-typedef struct Cases Case;
-typedef struct Reg Reg;
-typedef struct Rgn Rgn;
-typedef struct Var Var;
-typedef struct Multab Multab;
-typedef struct C1 C1;
-
-struct Adr
-{
- long displace;
- long offset;
-
- char sval[NSNAME];
- double dval;
-
- Sym* sym;
- short type;
- short field;
- short etype;
-};
-#define A ((Adr*)0)
-
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* link;
- long lineno;
- short as;
-};
-#define P ((Prog*)0)
-
-struct Txt
-{
- short movas;
- short postext;
- char preclr;
-};
-
-struct Cases
-{
- long val;
- long label;
- uchar def;
- Case* link;
-};
-#define C ((Case*)0)
-
-struct Var
-{
- long offset;
- Sym* sym;
- char type;
- char etype;
-};
-
-struct Reg
-{
- long pc;
- long rpo; /* reverse post ordering */
-
- Bits set;
- Bits use1;
- Bits use2;
-
- Bits refbehind;
- Bits refahead;
- Bits calbehind;
- Bits calahead;
- Bits regdiff;
- Bits act;
-
- ulong regu;
- long loop; /* could be shorter */
-
- Reg* log5;
- long active;
-
- Reg* p1;
- Reg* p2;
- Reg* p2link;
- Reg* s1;
- Reg* s2;
- Reg* link;
- Prog* prog;
-};
-#define R ((Reg*)0)
-
-struct Rgn
-{
- Reg* enter;
- short costr;
- short costa;
- short varno;
- short regno;
-};
-
-struct Multab
-{
- short val;
- char code[6];
-};
-
-struct C1
-{
- long val;
- long label;
-};
-
-#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
-#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
-#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
-#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
-
-#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32))
-
-#define CLOAD 8
-#define CREF 5
-#define CTEST 2
-#define CXREF 3
-#define CINF 1000
-#define LOOP 3
-
-EXTERN Bits externs;
-EXTERN Bits params;
-EXTERN Bits addrs;
-EXTERN ulong regbits;
-
-#define B_INDIR (1<<0)
-#define B_ADDR (1<<1)
-EXTERN int mvbits;
-EXTERN int changer;
-EXTERN int changea;
-
-EXTERN Txt txt[NTYPE][NTYPE];
-EXTERN short opxt[ALLOP][NTYPE];
-EXTERN Txt* txtp;
-EXTERN int multabsize;
-
-EXTERN Reg* firstr;
-EXTERN Reg* lastr;
-EXTERN Reg zreg;
-EXTERN Reg* freer;
-
-EXTERN long argoff;
-EXTERN long breakpc;
-EXTERN Case* cases;
-EXTERN long continpc;
-EXTERN Prog* firstp;
-EXTERN Reg* firstr;
-EXTERN int inargs;
-EXTERN Prog* lastp;
-EXTERN int retok;
-EXTERN long mnstring;
-EXTERN Node* nodrat;
-EXTERN Node* nodret;
-EXTERN long nrathole;
-EXTERN long nstatic;
-EXTERN int nregion;
-EXTERN long nstring;
-EXTERN int nvar;
-EXTERN Prog* p;
-EXTERN long pc;
-EXTERN Rgn region[NRGN];
-EXTERN Rgn* rgp;
-EXTERN char string[NSNAME];
-EXTERN Sym* symrathole;
-EXTERN Sym* symstatic;
-EXTERN Var var[NVAR];
-EXTERN long* idom;
-EXTERN Reg** rpo2r;
-EXTERN long maxnr;
-EXTERN Prog zprog;
-
-EXTERN uchar regused[NREG];
-EXTERN uchar aregused[NREG];
-EXTERN uchar fregused[NREG];
-EXTERN uchar regbase[I_MASK];
-EXTERN long exregoffset;
-EXTERN long exaregoffset;
-EXTERN long exfregoffset;
-extern char* anames[];
-extern Multab multab[];
-
-void cgen(Node*, int, Node*);
-void lcgen(Node*, int, Node*);
-void bcgen(Node*, int);
-void boolgen(Node*, int, int, Node*, Node*);
-void sugen(Node*, int, Node*, long);
-
-
-void listinit(void);
-int Bconv(Fmt*);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Xconv(Fmt*);
-int Dconv(Fmt*);
-int Rconv(Fmt*);
-int Sconv(Fmt*);
-
-void peep(void);
-void excise(Reg*);
-Reg* uniqp(Reg*);
-Reg* uniqs(Reg*);
-int findtst(Reg*, Prog*, int);
-int setcc(Prog*, Prog*);
-int compat(Adr*, Adr*);
-int aregind(Adr*);
-int asize(int);
-int usedin(int, Adr*);
-Reg* findccr(Reg*);
-int setccr(Prog*);
-Reg* findop(Reg*, int, int, int);
-int regtyp(int);
-int anyvar(Adr*);
-int subprop(Reg*);
-int copyprop(Reg*);
-int copy1(Adr*, Adr*, Reg*, int);
-int copyu(Prog*, Adr*, Adr*);
-int copyas(Adr*, Adr*);
-int tasas(Adr*, Adr*);
-int copyau(Adr*, Adr*);
-int copysub(Adr*, Adr*, Adr*, Prog*, int);
-
-ulong RtoB(int);
-ulong AtoB(int);
-ulong FtoB(int);
-int BtoR(ulong);
-int BtoA(ulong);
-int BtoF(ulong);
-
-Reg* rega(void);
-int rcmp(const void*, const void*);
-void regopt(Prog*);
-void addmove(Reg*, int, int, int);
-Bits mkvar(Adr*, int);
-void prop(Reg*, Bits, Bits);
-void loopit(Reg*, long);
-void synch(Reg*, Bits);
-ulong allreg(ulong, Rgn*);
-void paint1(Reg*, int);
-ulong paint2(Reg*, int);
-void paint3(Reg*, int, ulong, int);
-void addreg(Adr*, int);
-
-void codgen(Node*, Node*);
-void gen(Node*);
-void noretval(int);
-void usedset(Node*, int);
-Node* nodconst(long);
-
-int swcmp(const void*, const void*);
-void doswit(int, Node*);
-void swit1(C1*, int, long, int, Node*);
-void casf(void);
-int bitload(Node*, int, int, int, Node*);
-void bitstore(Node*, int, int, int, int, Node*);
-long outstring(char*, long);
-int doinc(Node*, int);
-void setsp(void);
-void adjsp(long);
-int simplv(Node*);
-int eval(Node*, int);
-void outcode(void);
-void ieeedtod(Ieee*, double);
-int nodalloc(Type*, int, Node*);
-int mulcon(Node*, Node*, int, Node*);
-int shlcon(Node*, Node*, int, Node*);
-int mulcon1(Node*, long, int, Node*);
-void nullwarn(Node*, Node*);
-
-void tindex(Type*, Type*);
-void ginit(void);
-void gclean(void);
-void oinit(int, int, int, int, int, int);
-Prog* prg(void);
-void nextpc(void);
-void gargs(Node*);
-void naddr(Node*, Adr*, int);
-int regalloc(Type*, int);
-int regaddr(int);
-int regpair(int);
-int regret(Type*);
-void regfree(int);
-void gmove(Type*, Type*, int, Node*, int, Node*);
-void gopcode(int, Type*, int, Node*, int, Node*);
-void asopt(void);
-int relindex(int);
-void gbranch(int);
-void fpbranch(void);
-void patch(Prog*, long);
-void gpseudo(int, Sym*, int, long);
-void gpseudotree(int, Sym*, Node*);
-
-void indx(Node*);
-void bcomplex(Node*);
-
-/*
- * com64
- */
-int com64(Node*);
-void com64init(void);
-void bool64(Node*);
-
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Adr*
-#pragma varargck type "N" Adr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "S" char*
-#pragma varargck type "R" int
diff --git a/utils/1c/list.c b/utils/1c/list.c
deleted file mode 100644
index f6bc2e62..00000000
--- a/utils/1c/list.c
+++ /dev/null
@@ -1,319 +0,0 @@
-#define EXTERN
-#include "gc.h"
-
-void
-listinit(void)
-{
-
- fmtinstall('R', Rconv);
- fmtinstall('A', Aconv);
- fmtinstall('D', Dconv);
- fmtinstall('P', Pconv);
- fmtinstall('S', Sconv);
- fmtinstall('B', Bconv);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == S) {
- sprint(ss, "$%ld", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ], s[20];
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- sprint(str, " %A %D,%D", p->as, &p->from, &p->to);
- if(p->from.field) {
- sprint(s, ",%d,%d", p->to.field, p->from.field);
- strcat(str, s);
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int r;
-
- r = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[r]);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[40], s[20];
- Adr *a;
- int i, j;
- long d;
-
- a = va_arg(fp->args, Adr*);
- i = a->type;
- j = i & I_MASK;
- if(j) {
- a->type = i & D_MASK;
- d = a->offset;
- a->offset = 0;
- switch(j) {
- case I_INDINC:
- sprint(str, "(%D)+", a);
- break;
-
- case I_INDDEC:
- sprint(str, "-(%D)", a);
- break;
-
- case I_INDIR:
- if(a->type == D_CONST)
- sprint(str, "%ld", d);
- else
- if(d)
- sprint(str, "%ld(%D)", d, a);
- else
- sprint(str, "(%D)", a);
- break;
-
- case I_ADDR:
- a->offset = d;
- sprint(str, "$%D", a);
- break;
- }
- a->type = i;
- a->offset = d;
- goto out;
- }
- switch(i) {
-
- default:
- sprint(str, "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- sprint(str, "%ld(PC)", a->offset-pc);
- break;
-
- case D_EXTERN:
- sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
- break;
-
- case D_STATIC:
- sprint(str, "%s<>+%ld(SB)", a->sym->name, a->offset);
- break;
-
- case D_AUTO:
- sprint(str, "%s-%ld(SP)", a->sym->name, -a->offset);
- break;
-
- case D_PARAM:
- sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
- break;
-
- case D_CONST:
- sprint(str, "$%ld", a->offset);
- break;
-
- case D_STACK:
- sprint(str, "TOS+%ld", a->offset);
- break;
-
- case D_FCONST:
- sprint(str, "$%.17e", a->dval);
- goto out;
-
- case D_SCONST:
- sprint(str, "$\"%S\"", a->sval);
- goto out;
- }
- if(a->displace) {
- sprint(s, "/%ld", a->displace);
- strcat(str, s);
- }
-out:
- return fmtstrcpy(fp, str);
-}
-
-int
-Rconv(Fmt *fp)
-{
- char str[20];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_R0 && r < D_R0+NREG)
- sprint(str, "R%d", r-D_R0);
- else
- if(r >= D_A0 && r < D_A0+NREG)
- sprint(str, "A%d", r-D_A0);
- else
- if(r >= D_F0 && r < D_F0+NREG)
- sprint(str, "F%d", r-D_F0);
- else
- switch(r) {
-
- default:
- sprint(str, "gok(%d)", r);
- break;
-
- case D_NONE:
- sprint(str, "NONE");
- break;
-
- case D_TOS:
- sprint(str, "TOS");
- break;
-
- case D_CCR:
- sprint(str, "CCR");
- break;
-
- case D_SR:
- sprint(str, "SR");
- break;
-
- case D_SFC:
- sprint(str, "SFC");
- break;
-
- case D_DFC:
- sprint(str, "DFC");
- break;
-
- case D_CACR:
- sprint(str, "CACR");
- break;
-
- case D_USP:
- sprint(str, "USP");
- break;
-
- case D_VBR:
- sprint(str, "VBR");
- break;
-
- case D_CAAR:
- sprint(str, "CAAR");
- break;
-
- case D_MSP:
- sprint(str, "MSP");
- break;
-
- case D_ISP:
- sprint(str, "ISP");
- break;
-
- case D_TREE:
- sprint(str, "TREE");
- break;
-
- case D_FPCR:
- sprint(str, "FPCR");
- break;
-
- case D_FPSR:
- sprint(str, "FPSR");
- break;
-
- case D_FPIAR:
- sprint(str, "FPIAR");
- break;
-
- case D_TC:
- sprint(str, "TC");
- break;
-
- case D_ITT0:
- sprint(str, "ITT0");
- break;
-
- case D_ITT1:
- sprint(str, "ITT1");
- break;
-
- case D_DTT0:
- sprint(str, "DTT0");
- break;
-
- case D_DTT1:
- sprint(str, "DTT1");
- break;
-
- case D_MMUSR:
- sprint(str, "MMUSR");
- break;
- case D_URP:
- sprint(str, "URP");
- break;
-
- case D_SRP:
- sprint(str, "SRP");
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(Fmt *fp)
-{
- int i, c;
- char str[30], *p, *s;
-
- s = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sizeof(double); i++) {
- c = s[i] & 0xff;
- if(c != '\\' && c != '"' && isprint(c)) {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- case 0:
- *p++ = '0';
- continue;
- case '\\':
- case '"':
- *p++ = c;
- continue;
- case '\n':
- *p++ = 'n';
- continue;
- case '\t':
- *p++ = 't';
- continue;
- }
- *p++ = ((c>>6) & 7) + '0';
- *p++ = ((c>>3) & 7) + '0';
- *p++ = ((c>>0) & 7) + '0';
- }
- *p = 0;
- return fmtstrcpy(fp, str);
-}
diff --git a/utils/1c/mkfile b/utils/1c/mkfile
deleted file mode 100644
index e5486b5c..00000000
--- a/utils/1c/mkfile
+++ /dev/null
@@ -1,29 +0,0 @@
-<../../mkconfig
-
-TARG=1c
-
-OFILES=\
- cgen.$O\
- reg.$O\
- txt.$O\
- peep.$O\
- swt.$O\
- sgen.$O\
- list.$O\
- enam.$O\
- mul.$O\
-
-HFILES= gc.h\
- ../2c/2.out.h\
- ../cc/cc.h\
-
-LIBS=cc bio 9 # order is important
-
-BIN=$ROOT/$OBJDIR/bin
-
-<$ROOT/mkfiles/mkone-$SHELLTYPE
-
-$ROOT/$OBJDIR/lib/libcc.a:
- cd ../cc
- mk $MKFLAGS install
- mk $MKFLAGS clean
diff --git a/utils/1c/mul.c b/utils/1c/mul.c
deleted file mode 100644
index 65ddda2f..00000000
--- a/utils/1c/mul.c
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "gc.h"
-
-/*
- * code sequences for multiply by constant
- * all sequences start with leading '0'.
- * if sequence starts with 'i', then the
- * leading '0' is suppressed.
- * '0' mov r0,r1
- * '1' sub r0,r1
- * '2' sub r1,r0
- * '3' add r0,r1
- * '4' add r1,r0
- * '5' add r0,r0
- * '6' add r1,r1
- * 'b' lsh $2,r0
- * 'c' lsh $3,r0
- * 'd'-'h' ...
- * 'j' lsh $2,r1
- * 'k'-'p' ...
- */
-Multab multab[] =
-{
- 2, "i5",
- 3, "64",
- 4, "i55",
- 5, "664",
- 6, "645",
- 7, "c2",
- 9, "k4",
- 10, "6645",
- 11, "66364",
- 12, "6455",
- 13, "66464",
- 14, "6d2",
- 15, "d2",
- 17, "l4",
- 18, "6d4",
- 19, "64k4",
- 20, "66455",
- 21, "664664",
- 22, "64c2",
- 23, "44c2",
- 24, "64c",
- 25, "63k4",
- 26, "64c4",
- 27, "663e2",
- 28, "66e2",
- 29, "63e2",
- 30, "6e2",
- 31, "e2",
- 33, "m4",
- 34, "6e4",
- 35, "64l4",
- 36, "66e4",
- 37, "664k4",
- 38, "64k45",
- 39, "454c2",
- 40, "664c",
- 41, "663k4",
- 42, "644c4",
- 43, "643k4",
- 44, "664c4",
- 45, "640d2",
- 46, "64d2",
- 47, "44d2",
- 48, "64d",
- 49, "63l4",
- 50, "64d4",
- 51, "640l4",
- 52, "646d4",
- 53, "643d4",
- 54, "6636f2",
- 55, "k3f2",
- 56, "kf2",
- 57, "k2k4",
- 58, "636f2",
- 59, "663f2",
- 60, "66f2",
- 61, "63f2",
- 62, "6f2",
- 63, "f2",
- 65, "n4",
- 66, "6f4",
- 67, "64m4",
- 68, "66f4",
- 69, "664l4",
- 70, "64l45",
- 71, "k1f4",
- 72, "k4c",
- 73, "k4k4",
- 74, "664k45",
- 75, "6640d2",
- 76, "664d2",
- 77, "434d2",
- 78, "644d2",
- 79, "454d2",
- 80, "664d",
- 81, "663l4",
- 82, "644d4",
- 83, "643l4",
- 84, "664d4",
- 85, "6640l4",
- 86, "6634l4",
- 87, "6443d4",
- 88, "6646d4",
- 89, "6643d4",
- 90, "6406e2",
- 91, "643e2",
- 92, "646e2",
- 93, "640e2",
- 94, "64e2",
- 95, "44e2",
- 96, "64e",
- 97, "63m4",
- 98, "64e4",
- 99, "640m4",
- 100, "646e4",
- 200, "66f364",
- 300, "j40jf2",
- 400, "64kg4",
- 500, "66h212",
- 600, "64m4c4",
- 700, "j4c4d2",
- 800, "64lh4",
- 900, "6464g4",
- 1000, "63g2c",
- 1100, "j4d2p4",
- 1200, "64k4f2",
- 1300, "j4n4b4",
- 1400, "64j4g2",
- 1600, "64d4e",
- 1800, "p4c2",
- 2000, "63g2d",
- 2100, "l4b2o4",
- 2200, "k4d4p4",
- 2300, "6644h2",
- 2400, "j4k4f4",
- 2500, "j4e2d4",
- 2600, "j40n4c",
- 3100, "jd12p2",
- 3200, "64d4f",
- 3600, "6d1p2",
- 3800, "e3k3g2",
- 3900, "jf20n4",
- 4000, "o4e2",
- 4100, "66p455",
- 4200, "l4c3e2",
- 4300, "l4b1f4",
- 4400, "64o4d4",
- 4600, "k45h2",
- 4700, "k3j4g2",
- 4800, "j40d2f",
- 5000, "l4c3m4",
- 5100, "j40h2b",
- 5200, "j40n4d",
- 6000, "d1o3h2",
- 6100, "o1l4b2",
- 6200, "ke12p2",
- 6400, "64d4g",
- 7200, "66e1p2",
- 7400, "m3m4c2",
- 7600, "l4f3c2",
- 7800, "kg20n4",
- 8000, "63g2f",
- 8100, "m2b4p4",
- 8200, "66p4c",
- 8700, "66f4g2",
- 8900, "l3j4g4",
- 9200, "k45h25",
- 9600, "j40d2g",
- 9800, "k4f3d4",
-};
-
-int multabsize = sizeof(multab) / sizeof(multab[0]);
diff --git a/utils/1c/peep.c b/utils/1c/peep.c
deleted file mode 100644
index 7583da5d..00000000
--- a/utils/1c/peep.c
+++ /dev/null
@@ -1,1057 +0,0 @@
-#include "gc.h"
-
-void
-peep(void)
-{
- Reg *r, *r1, *r2;
- Prog *p, *p1;
- int t, s;
-/*
- * complete R structure
- */
- t = 0;
- for(r=firstr; r!=R; r=r1) {
- r1 = r->link;
- if(r1 == R)
- break;
- p = r->prog->link;
- while(p != r1->prog)
- switch(p->as) {
- default:
- r2 = rega();
- r->link = r2;
- r2->link = r1;
-
- r2->prog = p;
- r2->p1 = r;
- r->s1 = r2;
- r2->s1 = r1;
- r1->p1 = r2;
-
- r = r2;
- t++;
-
- case ADATA:
- case AGLOBL:
- case ANAME:
- case ASIGNAME:
- p = p->link;
- }
- }
-
-loop1:
- /*
- * propigate move's by renaming
- */
- t = 0;
- for(r=firstr; r!=R; r=r->link) {
- p = r->prog;
- if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED)
- if(regtyp(p->from.type))
- if(anyvar(&p->to)) {
- if(copyprop(r)) {
- excise(r);
- t++;
- } else
- if(subprop(r) && copyprop(r)) {
- excise(r);
- t++;
- }
- }
- }
- if(t)
- goto loop1;
- for(r=firstr; r!=R; r=r->link) {
- p = r->prog;
- /*
- * convert (A) ... A++ into (A)++
- * and A-- ... (A) into --(A)
- */
- t = aregind(&p->from);
- if(t == D_NONE)
- goto out1;
- s = asize(p->as);
- if(s == 0)
- goto out1;
- r1 = findop(r, t, AADDL, s);
- if(r1 != R) {
- if(usedin(t, &p->to))
- goto out1;
- p->from.type += I_INDINC - I_INDIR;
- excise(r1);
- goto out1;
- }
- r1 = findop(r, t, ASUBL, s);
- if(r1 != R) {
- p->from.type += I_INDDEC - I_INDIR;
- excise(r1);
- }
- out1:
- t = aregind(&p->to);
- if(t == D_NONE)
- goto out2;
- s = asize(p->as);
- if(s == 0)
- goto out2;
- r1 = findop(r, t, AADDL, s);
- if(r1 != R) {
- p->to.type += I_INDINC - I_INDIR;
- excise(r1);
- goto out2;
- }
- r1 = findop(r, t, ASUBL, s);
- if(r1 != R) {
- if(usedin(t, &p->from))
- goto out2;
- p->to.type += I_INDDEC - I_INDIR;
- excise(r1);
- }
- out2:
- /*
- * get rid of unneeded save/restore CCR
- */
- if(p->from.type == D_CCR) {
- r1 = findccr(r);
- if(r1 != R) {
- excise(r);
- excise(r1);
- }
- }
- switch(p->as) {
- case ATSTB:
- case ATSTW:
- case ATSTL:
- if(findtst(r, r->prog, 0))
- excise(r);
- }
- /*
- * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP
- */
- if(p->as == ATSTB && (r1 = r->s1)) {
- if((r1->prog->as == ABLT && (r2 = r1->s1)) ||
- (r1->prog->as == ABGE && (r2 = r1->s2))) {
- p1 = r2->prog;
- if(p1->as == AORB)
- if(p1->from.type == D_CONST)
- if(p1->from.offset == 128)
- if(r1 == uniqp(r2))
- if(tasas(&p->to, &p1->to)) {
- p->as = ATAS;
- excise(r2);
- }
- }
- }
- }
-}
-
-void
-excise(Reg *r)
-{
-
- p = r->prog;
- p->as = ANOP;
- p->from = zprog.from;
- p->to = zprog.to;
-}
-
-Reg*
-uniqp(Reg *r)
-{
- Reg *r1;
-
- r1 = r->p1;
- if(r1 == R) {
- r1 = r->p2;
- if(r1 == R || r1->p2link != R)
- return R;
- } else
- if(r->p2 != R)
- return R;
- return r1;
-}
-
-Reg*
-uniqs(Reg *r)
-{
- Reg *r1;
-
- r1 = r->s1;
- if(r1 == R) {
- r1 = r->s2;
- if(r1 == R)
- return R;
- } else
- if(r->s2 != R)
- return R;
- return r1;
-}
-
-/*
- * chase backward all cc setting.
- * returns 1 if all set same.
- */
-int
-findtst(Reg *r0, Prog *rp, int n)
-{
- Reg *r;
- int c;
-
-loop:
- n++;
- if(n >= 10)
- return 0;
- for(r=r0->p2; r!=R; r=r->p2link) {
- c = setcc(r->prog, rp);
- if(c > 0)
- continue;
- if(c == 0)
- return 0;
- if(findtst(r, rp, n) == 0)
- return 0;
- }
- r = r0->p1;
- if(r == R)
- return 1;
- c = setcc(r->prog, rp);
- if(c > 0)
- return 1;
- if(c == 0)
- return 0;
- r0 = r;
- goto loop;
-}
-
-/*
- * tests cc
- * returns -1 if no change
- * returns 1 if set the same
- * returns 0 if set different
- */
-int
-setcc(Prog *p, Prog *rp)
-{
- int s;
-
- s = asize(rp->as);
- switch(p->as) {
- default:
- if(debug['P'])
- print("unknown setcc %A\n", p->as);
- break;
-
- case ACMPB:
- case ACMPW:
- case ACMPL:
- case ABSR:
- return 0;
-
- case ABRA:
- case ABGE:
- case ABNE:
- case ABLE:
- case ABEQ:
- case ABHI:
- case ABLS:
- case ABMI:
- case ABPL:
- case ABGT:
- case ABLT:
- case ABCC:
- case ABCS:
- case APEA:
- case ALEA:
- case ANOP:
-
- case AFADDD:
- case AFMULD:
- case AFDIVD:
- case AFSUBD:
- case AFADDF:
- case AFMULF:
- case AFDIVF:
- case AFSUBF:
- case AADJSP:
- return -1;
-
- case AADDW:
- case AADDL:
- case ASUBW:
- case ASUBL:
- case ACLRL:
- case ACLRW:
- if(p->to.type >= D_A0 && p->to.type < D_A0+8)
- goto areg;
-
- case AADDB:
- case ASUBB:
- case AANDB:
- case AANDW:
- case AANDL:
- case AORB:
- case AORW:
- case AORL:
- case AEORB:
- case AEORW:
- case AEORL:
- case ALSLB:
- case ALSLW:
- case ALSLL:
- case ALSRB:
- case ALSRW:
- case ALSRL:
- case AASLB:
- case AASLW:
- case AASLL:
- case AASRB:
- case AASRW:
- case AASRL:
- case ATSTB:
- case ATSTW:
- case ATSTL:
- case ANEGB:
- case ANEGW:
- case ANEGL:
- case ACLRB:
- if(asize(p->as) != s)
- break;
- if(compat(&rp->to, &p->to))
- return 1;
- break;
-
- case AMOVW:
- case AMOVL:
- if(p->to.type >= D_A0 && p->to.type < D_A0+8)
- goto areg;
- case AMOVB:
- if(asize(p->as) != s)
- break;
- if(compat(&rp->to, &p->to))
- return 1;
- if(compat(&rp->to, &p->from))
- return 1;
- }
- return 0;
-
-areg:
- if((rp->to.type&D_MASK) == p->to.type)
- return 0;
- return -1;
-}
-
-int
-compat(Adr *a, Adr *b)
-{
- int o;
-
- o = a->type;
- if((o >= D_R0 && o < D_R0+NREG) ||
- (o >= D_A0 && o < D_A0+NREG))
- return o == b->type;
- o &= D_MASK;
- if(o >= D_A0 && o < D_A0+NREG) {
- if(o != (b->type&D_MASK))
- return 0;
- if(a->offset != b->offset)
- return 0;
- o = a->type & I_MASK;
- if(o == I_INDIR) {
- o = b->type & I_MASK;
- if(o == I_INDIR || o == I_INDDEC)
- return 1;
- return 0;
- }
- if(o == I_INDINC) {
- o = b->type & I_MASK;
- if(o == I_INDIR) {
- b->type += I_INDINC-I_INDIR;
- return 1;
- }
- if(o == I_INDDEC) {
- b->type += I_INDIR-I_INDDEC;
- return 1;
- }
- return 0;
- }
- }
- return 0;
-}
-
-int
-aregind(Adr *a)
-{
- int t;
-
- t = a->type;
- if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR))
- while(a->offset == 0)
- return t & D_MASK;
- return D_NONE;
-}
-
-int
-asize(int a)
-{
-
- switch(a) {
- case AFTSTD:
- case AFMOVED:
- case AFADDD:
- case AFSUBD:
- case AFMULD:
- case AFDIVD:
- case AFCMPD:
- case AFNEGD:
- return 8;
-
- case AFTSTF:
- case AFMOVEF:
- case AFADDF:
- case AFSUBF:
- case AFMULF:
- case AFDIVF:
- case AFCMPF:
- case AFNEGF:
-
- case ACLRL:
- case ATSTL:
- case AMOVL:
- case AADDL:
- case ASUBL:
- case ACMPL:
- case AANDL:
- case AORL:
- case AEORL:
- case ALSLL:
- case ALSRL:
- case AASLL:
- case AASRL:
- case ANEGL:
- return 4;
-
- case ACLRW:
- case ATSTW:
- case AMOVW:
- case AADDW:
- case ASUBW:
- case ACMPW:
- case AANDW:
- case AORW:
- case AEORW:
- case ALSLW:
- case ALSRW:
- case AASLW:
- case AASRW:
- case ANEGW:
- return 2;
-
- case ACLRB:
- case ATSTB:
- case AMOVB:
- case AADDB:
- case ASUBB:
- case ACMPB:
- case AANDB:
- case AORB:
- case AEORB:
- case ALSLB:
- case ALSRB:
- case AASLB:
- case AASRB:
- case ANEGB:
- return 1;
- }
- if(debug['P'])
- print("unknown asize %A\n", p->as);
- return 0;
-}
-
-int
-usedin(int t, Adr *a)
-{
-
- if((a->type&D_MASK) == t)
- return 1;
- return 0;
-}
-
-Reg*
-findccr(Reg *r)
-{
- Prog *p;
-
- for(;;) {
- r = uniqs(r);
- if(r == R)
- break;
- p = r->prog;
- if(p->to.type == D_CCR)
- return r;
- if(setccr(p))
- break;
- }
- return R;
-}
-
-int
-setccr(Prog *p)
-{
-
- switch(p->as) {
- case ANOP:
- return 0;
-
- case AADDL:
- case AMOVL:
- case ACLRL:
- if(p->to.type >= D_A0 && p->to.type < D_A0+8)
- return 0;
- }
- return 1;
-}
-
-Reg*
-findop(Reg *r, int t, int o, int s)
-{
- Prog *p;
- Reg *r1;
-
- for(;;) {
- if(o == AADDL) {
- r1 = uniqs(r);
- if(r1 == R)
- break;
- if(uniqp(r1) != r)
- break;
- } else {
- r1 = uniqp(r);
- if(r1 == R)
- break;
- if(uniqs(r1) != r)
- break;
- }
- r = r1;
- p = r->prog;
- if(usedin(t, &p->from))
- break;
- if(usedin(t, &p->to)) {
- if(p->as == o)
- if(p->to.type == t)
- if(p->from.type == D_CONST)
- if(p->from.offset == s)
- return r;
- break;
- }
- }
- return R;
-}
-
-int
-regtyp(int t)
-{
-
- if(t >= D_R0 && t < D_R0+8)
- return 1;
- if(t >= D_A0 && t < D_A0+8)
- return 1;
- if(t >= D_F0 && t < D_F0+8)
- return 1;
- return 0;
-}
-
-int
-anyvar(Adr *a)
-{
-
- if(regtyp(a->type))
- return 1;
- return 0;
-}
-
-/*
- * the idea is to substitute
- * one register for another
- * from one MOV to another
- * MOV a, R0
- * ADD b, R0 / no use of R1
- * MOV R0, R1
- * would be converted to
- * MOV a, R1
- * ADD b, R1
- * MOV R1, R0
- * hopefully, then the former or latter MOVL
- * will be eliminated by copy propagation.
- */
-int
-subprop(Reg *r0)
-{
- Prog *p;
- Adr *v1, *v2;
- Reg *r;
- int t;
-
- p = r0->prog;
- v1 = &p->from;
- if(!regtyp(v1->type))
- return 0;
- v2 = &p->to;
- if(!regtyp(v2->type))
- return 0;
- for(r=uniqp(r0); r!=R; r=uniqp(r)) {
- if(uniqs(r) == R)
- break;
- p = r->prog;
- switch(p->as) {
- case ADIVUW: /* these set Rn and Rn+1 */
- case ADIVUL:
- case ADIVSW:
- case ADIVSL:
- case ABSR:
- return 0;
-
- case AFMOVED:
- case AFMOVEF:
- case AMOVL:
- if(p->to.type == v1->type)
- goto gotit;
- }
- if(copyau(&p->from, v2) || copyau(&p->to, v2))
- break;
- if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0))
- break;
- }
- return 0;
-
-gotit:
- copysub(&p->to, v1, v2, p, 1);
- if(debug['P']) {
- print("gotit: %D->%D\n%P", v1, v2, r->prog);
- if(p->from.type == v2->type)
- print(" excise");
- print("\n");
- }
- if(p->from.type == v2->type)
- excise(r);
- for(r=uniqs(r); r!=r0; r=uniqs(r)) {
- p = r->prog;
- copysub(&p->from, v1, v2, p, 1);
- copysub(&p->to, v1, v2, p, 1);
- if(debug['P'])
- print("%P\n", r->prog);
- }
- t = v1->type;
- v1->type = v2->type;
- v2->type = t;
- if(debug['P'])
- print("%P last\n", r->prog);
- return 1;
-}
-
-/*
- * The idea is to remove redundant copies.
- * v1->v2 F=0
- * (use v2 s/v2/v1/)*
- * set v1 F=1
- * use v2 return fail
- * -----------------
- * v1->v2 F=0
- * (use v2 s/v2/v1/)*
- * set v1 F=1
- * set v2 return success
- */
-int
-copyprop(Reg *r0)
-{
- Prog *p;
- Adr *v1, *v2;
- Reg *r;
-
- p = r0->prog;
- v1 = &p->from;
- v2 = &p->to;
- if(copyas(v1, v2))
- return 1;
- for(r=firstr; r!=R; r=r->link)
- r->active = 0;
- return copy1(v1, v2, r0->s1, 0);
-}
-
-int
-copy1(Adr *v1, Adr *v2, Reg *r, int f)
-{
- int t;
-
- if(r->active) {
- if(debug['P'])
- print("copyret 1\n");
- return 1;
- }
- r->active = 1;
- if(debug['P'])
- print("copy %D->%D\n", v1, v2);
- for(; r != R; r = r->s1) {
- if(debug['P'])
- print("%P", r->prog);
- if(!f && uniqp(r) == R) {
- f = 1;
- if(debug['P'])
- print("; merge; f=%d", f);
- }
- t = copyu(r->prog, v2, A);
- switch(t) {
- case 2: /* rar, cant split */
- if(debug['P'])
- print("; rar return 0\n");
- return 0;
- case 3: /* set */
- if(debug['P'])
- print("; set; return 1\n");
- return 1;
- case 1: /* used, substitute */
- case 4: /* use and set */
- if(f) {
- if(debug['P'])
- print("; used and f; return 0\n");
- return 0;
- }
- if(copyu(r->prog, v2, v1)) {
- if(debug['P'])
- print("; sub fail; return 0\n");
- return 0;
- }
- if(debug['P'])
- print("; substitute");
- if(t == 4) {
- if(debug['P'])
- print("; used and set; return 1\n");
- return 1;
- }
- break;
- }
- if(!f) {
- t = copyu(r->prog, v1, A);
- if(!f && (t == 2 || t == 3 || t == 4)) {
- if(debug['P'])
- print("; f set used");
- f = 1;
- }
- }
- if(debug['P'])
- print("\n");
- if(r->s2)
- if(!copy1(v1, v2, r->s2, f))
- return 0;
- }
- return 1;
-}
-
-/*
- * return
- * 1 if v only used (and substitute),
- * 2 if read-alter-rewrite
- * 3 if set
- * 4 if set and used
- * 0 otherwise (not touched)
- */
-int
-copyu(Prog *p, Adr *v, Adr *s)
-{
- int t;
-
- switch(p->as) {
-
- default:
- if(debug['P'])
- print("unknown op %A\n", p->as);
- return 2;
-
- case APEA: /* rhs addr */
- if(copyas(&p->to, v))
- return 2;
- goto caseread;
-
- case ALEA: /* lhs addr, rhs store */
- if(copyas(&p->from, v))
- return 2;
-
- case AMOVL: /* rhs store */
- case ACLRL:
- case AFMOVEF:
- case AFMOVED:
- case AFMOVEB:
- case AFMOVEW:
- case AFMOVEL:
- case ANOP:
- if(copyas(&p->to, v)) {
- if(s != A)
- return copysub(&p->from, v, s, p, 1);
- if(copyau(&p->from, v))
- return 4;
- return 3;
- }
- goto caseread;
-
- case AADDL: /* rhs rar */
- case AADDW:
- case AADDB:
- case ASUBL:
- case ASUBW:
- case ASUBB:
- case AANDL:
- case AANDW:
- case AANDB:
- case AORL:
- case AORW:
- case AORB:
- case AEORL:
- case AEORW:
- case AEORB:
- case AASRL:
- case AASRW:
- case AASRB:
- case AASLL:
- case AASLW:
- case AASLB:
- case ALSRL:
- case ALSRW:
- case ALSRB:
- case ANOTL:
- case ANOTW:
- case ANOTB:
- case ANEGL:
- case ANEGW:
- case ANEGB:
- case AEXTBL:
- case AEXTWL:
- case AEXTBW:
-
- case AMULSL:
- case AMULUL:
-
- case AMOVW: /* only sets part of register */
- case AMOVB:
- case ACLRW:
- case ACLRB:
-
- case AFADDD:
- case AFMULD:
- case AFDIVD:
- case AFSUBD:
- case AFNEGD:
- case AFADDF:
- case AFMULF:
- case AFDIVF:
- case AFSUBF:
- case AFNEGF:
- if(copyas(&p->to, v))
- return 2;
- goto caseread;
-
- case ADBF: /* lhs rar */
- if(copyas(&p->from, v))
- return 2;
- goto caseread;
-
- case ACMPL: /* read only */
- case ACMPW:
- case ACMPB:
- case AFCMPF:
- case AFCMPD:
- case ATSTL:
- case ATSTW:
- case ATSTB:
- case AFTSTF:
- case AFTSTD:
- caseread:
- if(s != A) {
- if(copysub(&p->from, v, s, p, 1))
- return 1;
- return copysub(&p->to, v, s, p, 1);
- }
- if(copyau(&p->from, v))
- return 1;
- if(copyau(&p->to, v))
- return 1;
- break;
-
- case ABRA: /* no reference */
- case ABGE:
- case ABNE:
- case ABLE:
- case ABEQ:
- case ABHI:
- case ABLS:
- case ABMI:
- case ABPL:
- case ABGT:
- case ABLT:
- case ABCC:
- case ABCS:
-
- case AFBEQ:
- case AFBNE:
- case AFBGT:
- case AFBGE:
- case AFBLE:
- case AFBLT:
-
- case AADJSP:
- case ACASEW:
- break;
-
- case ADIVUW: /* these set Rn and Rn+1 */
- case ADIVUL:
- case ADIVSW:
- case ADIVSL:
- t = v->type;
- if(t == p->to.type || t == p->to.type+1)
- return 2;
- goto caseread;
-
- case ARTS: /* funny */
- t = v->type;
- if(t == D_R0 || t == D_F0)
- return 2;
- if(t >= D_R0 && t < D_R0+NREG)
- if(t-D_R0 > exregoffset)
- return 2;
- if(t >= D_A0 && t < D_A0+NREG)
- if(t-D_A0 > exaregoffset)
- return 2;
- if(t >= D_F0 && t < D_F0+NREG)
- if(t-D_F0 > exfregoffset)
- return 2;
- return 3;
-
- case ABSR: /* funny */
- t = v->type;
- if(t >= D_R0 && t < D_R0+NREG)
- if(t-D_R0 > exregoffset)
- return 2;
- if(t >= D_A0 && t < D_A0+NREG)
- if(t-D_A0 > exaregoffset)
- return 2;
- if(t >= D_F0 && t < D_F0+NREG)
- if(t-D_F0 > exfregoffset)
- return 2;
- if(copyau(&p->to, v))
- return 2;
- return 3;
- }
- return 0;
-}
-
-/*
- * direct reference,
- * could be set/use depending on
- * semantics
- */
-int
-copyas(Adr *a, Adr *v)
-{
-
- if(a->type != v->type)
- return 0;
- if(regtyp(v->type))
- return 1;
- if(v->type == D_AUTO || v->type == D_PARAM) {
- if(v->offset == a->offset)
- return 1;
- return 0;
- }
- return 0;
-}
-
-/*
- * indirect
- */
-int
-tasas(Adr *a, Adr *v)
-{
- int t;
-
- t = a->type;
- if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8)
- return 0;
- if(v->type != t)
- return 0;
- if(a->displace != v->displace)
- return 0;
- return 1;
-}
-
-/*
- * either direct or indirect
- */
-int
-copyau(Adr *a, Adr *v)
-{
- int t;
-
- if(copyas(a, v))
- return 1;
- t = v->type;
- if(regtyp(t)) {
- if((a->type & D_MASK) == t)
- return 1;
- }
- return 0;
-}
-
-/*
- * substitute s for v in a
- * return failure to substitute
- */
-int
-copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f)
-{
- int t;
-
- if(copyas(a, v)) {
- t = s->type;
- if(t >= D_F0 && t < D_F0+8) {
- if(f)
- a->type = t;
- return 0;
- }
- if(t >= D_R0 && t < D_R0+8) {
- if(f)
- a->type = t;
- return 0;
- }
- if(!(t >= D_A0 && t < D_A0+8))
- return 1;
- switch(p->as) {
- default:
- return 1;
-
- case AMOVL:
- case AMOVW:
- case ACMPL:
- case ACMPW:
- break;
-
- case AADDL:
- case AADDW:
- case ASUBL:
- case ASUBW:
- if(a == &p->from && !regtyp(p->to.type))
- return 1;
- break;
- }
- if(f)
- a->type = t;
- return 0;
- }
- t = v->type;
- if(regtyp(t)) {
- if((a->type & D_MASK) == t) {
- if((s->type ^ t) & ~(NREG-1))
- return 1;
- if(f)
- a->type = (a->type & ~D_MASK) | s->type;
- return 0;
- }
- return 0;
- }
- return 0;
-}
diff --git a/utils/1c/reg.c b/utils/1c/reg.c
deleted file mode 100644
index ad4231c0..00000000
--- a/utils/1c/reg.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-#include "gc.h"
-
-Reg*
-rega(void)
-{
- Reg *r;
-
- r = freer;
- if(r == R) {
- r = alloc(sizeof(*r));
- } else
- freer = r->link;
-
- *r = zreg;
- return r;
-}
-
-int
-rcmp(const void *a1, const void *a2)
-{
- Rgn *p1, *p2;
- int c1, c2;
-
- p1 = (Rgn*)a1;
- p2 = (Rgn*)a2;
- c1 = p2->costr;
- if(p2->costa > c1)
- c1 = p2->costa;
- c2 = p1->costr;
- if(p1->costa > c2)
- c2 = p1->costa;
- if(c1 -= c2)
- return c1;
- return p2->varno - p1->varno;
-}
-
-void
-regopt(Prog *p)
-{
- Reg *r, *r1, *r2;
- Prog *p1;
- int i, z;
- long val, initpc, npc;
- ulong vreg;
- Bits bit;
- Var *v;
- struct {
- long m;
- long c;
- Reg* p;
- } log5[6], *lp;
-
- firstr = R;
- lastr = R;
- nvar = 0;
- for(z=0; z<BITS; z++) {
- externs.b[z] = 0;
- params.b[z] = 0;
- addrs.b[z] = 0;
- }
- regbits = RtoB(0) | /* return reg */
- AtoB(6) | AtoB(7) | /* sp and sb */
- FtoB(0) | FtoB(1); /* floating return reg */
- for(i=0; i<NREG; i++) {
- if(regused[i])
- regbits |= RtoB(i);
- if(fregused[i])
- regbits |= FtoB(i);
- if(aregused[i])
- regbits |= AtoB(i);
- }
-
- /*
- * pass 1
- * build aux data structure
- * allocate pcs
- * find use and set of variables
- */
- val = 5L * 5L * 5L * 5L * 5L;
- lp = log5;
- for(i=0; i<5; i++) {
- lp->m = val;
- lp->c = 0;
- lp->p = R;
- val /= 5L;
- lp++;
- }
- val = 0;
- for(; p != P; p = p->link) {
- switch(p->as) {
- case ADATA:
- case AGLOBL:
- case ANAME:
- case ASIGNAME:
- continue;
- }
- r = rega();
- if(firstr == R) {
- firstr = r;
- lastr = r;
- } else {
- lastr->link = r;
- r->p1 = lastr;
- lastr->s1 = r;
- lastr = r;
- }
- r->prog = p;
- r->pc = val;
- val++;
-
- lp = log5;
- for(i=0; i<5; i++) {
- lp->c--;
- if(lp->c <= 0) {
- lp->c = lp->m;
- if(lp->p != R)
- lp->p->log5 = r;
- lp->p = r;
- (lp+1)->c = 0;
- break;
- }
- lp++;
- }
-
- r1 = r->p1;
- if(r1 != R)
- switch(r1->prog->as) {
- case ABRA:
- case ARTS:
- case ARTE:
- r->p1 = R;
- r1->s1 = R;
- }
-
- bit = mkvar(&p->from, AGOK);
- if(bany(&bit))
- switch(p->as) {
- case ALEA:
- if(!(mvbits & B_INDIR))
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
-
- default:
- if(mvbits & B_ADDR)
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
- for(z=0; z<BITS; z++)
- r->use1.b[z] |= bit.b[z];
- }
-
- bit = mkvar(&p->to, p->as);
- if(bany(&bit))
- switch(p->as) {
- case ABSR: /* funny */
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
- goto def;
-
- case APEA:
- if(!(mvbits & B_INDIR))
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
-
- def:
- case ACMPB: case ACMPW: case ACMPL:
- case AFCMPF: case AFCMPD:
- case ATSTB: case ATSTW: case ATSTL:
- case AFTSTF: case AFTSTD:
- case ABFEXTU: case ABFEXTS:
- if(mvbits & B_ADDR)
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
- for(z=0; z<BITS; z++)
- r->use2.b[z] |= bit.b[z];
- break;
-
- default:
- diag(Z, "reg: unknown asop: %A", p->as);
-
- case AADDB: case AADDW: case AADDL:
- case ASUBB: case ASUBW: case ASUBL:
- case AANDB: case AANDW: case AANDL:
- case AORB: case AORW: case AORL:
- case AEORB: case AEORW: case AEORL:
- case ABFINS:
- for(z=0; z<BITS; z++)
- r->use2.b[z] |= bit.b[z];
-
- case ANOP:
- case AMOVB: case AMOVW: case AMOVL:
- case AFMOVEB: case AFMOVEW: case AFMOVEL:
- case ACLRB: case ACLRW: case ACLRL:
- case AFMOVEF: case AFMOVED:
- if(mvbits & B_INDIR)
- for(z=0; z<BITS; z++)
- r->use2.b[z] |= bit.b[z];
- else
- for(z=0; z<BITS; z++)
- r->set.b[z] |= bit.b[z];
- break;
-
- }
- }
- if(firstr == R)
- return;
- initpc = pc - val;
- npc = val;
-
- /*
- * pass 2
- * turn branch references to pointers
- * build back pointers
- */
- for(r = firstr; r != R; r = r->link) {
- p = r->prog;
- if(p->to.type == D_BRANCH) {
- val = p->to.offset - initpc;
- r1 = firstr;
- while(r1 != R) {
- r2 = r1->log5;
- if(r2 != R && val >= r2->pc) {
- r1 = r2;
- continue;
- }
- if(r1->pc == val)
- break;
- r1 = r1->link;
- }
- if(r1 == R) {
- diag(Z, "ref not found\n%L:%P", p->lineno, p);
- continue;
- }
- if(r1 == r) {
- diag(Z, "ref to self");
- continue;
- }
- r->s2 = r1;
- r->p2link = r1->p2;
- r1->p2 = r;
- }
- }
- if(debug['R'])
- print("\n%L %D\n", firstr->prog->lineno, &firstr->prog->from);
-
- /*
- * pass 2.5
- * find looping structure
- */
- for(r = firstr; r != R; r = r->link)
- r->active = 0;
- changer = 0;
- loopit(firstr, npc);
- if(debug['R'] && debug['v']) {
- print("\nlooping structure:\n");
- for(r = firstr; r != R; r = r->link) {
- print("%ld:%P", r->loop, r->prog);
- for(z=0; z<BITS; z++)
- bit.b[z] = r->use1.b[z] |
- r->use2.b[z] | r->set.b[z];
- if(bany(&bit)) {
- print("\t");
- if(bany(&r->use1))
- print(" u1=%B", r->use1);
- if(bany(&r->use2))
- print(" u2=%B", r->use2);
- if(bany(&r->set))
- print(" st=%B", r->set);
- }
- print("\n");
- }
- }
-
- /*
- * pass 3
- * iterate propagating usage
- * back until flow graph is complete
- */
-loop1:
- changer = 0;
- for(r = firstr; r != R; r = r->link)
- r->active = 0;
- for(r = firstr; r != R; r = r->link)
- if(r->prog->as == ARTS)
- prop(r, zbits, zbits);
-loop11:
- /* pick up unreachable code */
- i = 0;
- for(r = firstr; r != R; r = r1) {
- r1 = r->link;
- if(r1 && r1->active && !r->active) {
- prop(r, zbits, zbits);
- i = 1;
- }
- }
- if(i)
- goto loop11;
- if(changer)
- goto loop1;
-
- /*
- * pass 4
- * iterate propagating register/variable synchrony
- * forward until graph is complete
- */
-loop2:
- changer = 0;
- for(r = firstr; r != R; r = r->link)
- r->active = 0;
- synch(firstr, zbits);
- if(changer)
- goto loop2;
-
-
- /*
- * pass 5
- * isolate regions
- * calculate costs (paint1)
- */
- r = firstr;
- if(r) {
- for(z=0; z<BITS; z++)
- bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
- ~(externs.b[z] | params.b[z] | addrs.b[z]);
- if(bany(&bit)) {
- nearln = r->prog->lineno;
- warn(Z, "used and not set: %B", bit);
- if(debug['R'] && !debug['w'])
- print("used and not set: %B\n", bit);
-
- /*
- * 68040 'feature':
- * load of a denormalized fp will trap
- */
- while(bany(&bit)) {
- i = bnum(bit);
- bit.b[i/32] &= ~(1L << (i%32));
- v = var + i;
- if(v->type == D_AUTO) {
- r->set.b[i/32] |= (1L << (i%32));
- if(typefd[v->etype])
- addmove(r, i, NREG+NREG, 1);
- }
- }
- }
- }
- if(debug['R'] && debug['v'])
- print("\nprop structure:\n");
- for(r = firstr; r != R; r = r->link) {
- if(debug['R'] && debug['v'])
- print("%P\n set = %B; rah = %B; cal = %B\n",
- r->prog, r->set, r->refahead, r->calahead);
- r->act = zbits;
- }
- rgp = region;
- nregion = 0;
- for(r = firstr; r != R; r = r->link) {
- for(z=0; z<BITS; z++)
- bit.b[z] = r->set.b[z] &
- ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
- if(bany(&bit)) {
- nearln = r->prog->lineno;
- warn(Z, "set and not used: %B", bit);
- if(debug['R'])
- print("set an not used: %B\n", bit);
- excise(r);
- }
- for(z=0; z<BITS; z++)
- bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
- while(bany(&bit)) {
- i = bnum(bit);
- rgp->enter = r;
- rgp->varno = i;
- changer = 0;
- changea = 0;
- if(debug['R'] && debug['v'])
- print("\n");
- paint1(r, i);
- bit.b[i/32] &= ~(1L<<(i%32));
- if(changer <= 0 && changea <= 0) {
- if(debug['R'])
- print("%L$%d.%d: %B\n",
- r->prog->lineno,
- changer, changea, blsh(i));
- continue;
- }
- rgp->costr = changer;
- rgp->costa = changea;
- nregion++;
- if(nregion >= NRGN) {
- warn(Z, "too many regions");
- goto brk;
- }
- rgp++;
- }
- }
-brk:
- qsort(region, nregion, sizeof(region[0]), rcmp);
-
- /*
- * pass 6
- * determine used registers (paint2)
- * replace code (paint3)
- */
- rgp = region;
- for(i=0; i<nregion; i++) {
- bit = blsh(rgp->varno);
- vreg = paint2(rgp->enter, rgp->varno);
- vreg = allreg(vreg, rgp);
- if(debug['R'])
- print("%L$%d.%d %R: %B\n",
- rgp->enter->prog->lineno,
- rgp->costr, rgp->costa,
- rgp->regno,
- bit);
- if(rgp->regno != D_NONE)
- paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
- rgp++;
- }
- /*
- * pass 7
- * peep-hole on basic block
- */
- if(!debug['R'] || debug['P'])
- peep();
-
- /*
- * pass 8
- * recalculate pc
- */
- val = initpc;
- for(r = firstr; r != R; r = r1) {
- r->pc = val;
- p = r->prog;
- p1 = P;
- r1 = r->link;
- if(r1 != R)
- p1 = r1->prog;
- for(; p != p1; p = p->link) {
- switch(p->as) {
- default:
- val++;
- break;
-
- case ANOP:
- case ADATA:
- case AGLOBL:
- case ANAME:
- case ASIGNAME:
- break;
- }
- }
- }
- pc = val;
-
- /*
- * fix up branches
- */
- if(debug['R'])
- if(bany(&addrs))
- print("addrs: %B\n", addrs);
-
- r1 = 0; /* set */
- for(r = firstr; r != R; r = r->link) {
- p = r->prog;
- if(p->to.type == D_BRANCH)
- p->to.offset = r->s2->pc;
- r1 = r;
- }
-
- /*
- * last pass
- * eliminate nops
- * free aux structures
- */
- for(p = firstr->prog; p != P; p = p->link){
- while(p->link && p->link->as == ANOP)
- p->link = p->link->link;
- }
- if(r1 != R) {
- r1->link = freer;
- freer = firstr;
- }
-}
-
-/*
- * add mov b,rn
- * just after r
- */
-void
-addmove(Reg *r, int bn, int rn, int f)
-{
- Prog *p, *p1;
- Var *v;
- int badccr;
-
- badccr = 0;
- p = r->prog;
- p1 = p->link;
- if(p1)
- switch(p1->as) {
- case AMOVW:
- if(p1->from.type == D_CCR)
- p = p1;
- break;
-
- case ABEQ:
- case ABNE:
- case ABLE:
- case ABLS:
- case ABLT:
- case ABMI:
- case ABGE:
- case ABPL:
- case ABGT:
- case ABHI:
- case ABCC:
- case ABCS:
- p1 = prg();
- p1->link = p->link;
- p->link = p1;
- p1->lineno = p->lineno;
-
- p1->from.type = D_CCR;
- p1->to.type = D_TOS;
- p1->as = AMOVW;
- p = p1;
- badccr = 1;
- }
- p1 = prg();
- p1->link = p->link;
- p->link = p1;
- p1->lineno = p->lineno;
-
- v = var + bn;
- p1->from.sym = v->sym;
- p1->from.type = v->type;
- p1->from.offset = v->offset;
- p1->from.etype = v->etype;
- p1->to.type = rn;
- if(f) {
- p1->to = p1->from;
- p1->from = zprog.from;
- p1->from.type = rn;
- }
- p1->as = opxt[OAS][v->etype];
- if(badccr) {
- p = p1;
- p1 = prg();
- p1->link = p->link;
- p->link = p1;
- p1->lineno = p->lineno;
-
- p1->from.type = D_TOS;
- p1->to.type = D_CCR;
- p1->as = AMOVW;
- }
- if(debug['R'])
- print("%P\t.a%P\n", p, p1);
-}
-
-Bits
-mkvar(Adr *a, int as)
-{
- Var *v;
- int i, t, z;
- long o;
- Bits bit;
- Sym *s;
-
- mvbits = 0;
- t = a->type & D_MASK;
- switch(t) {
-
- default:
- if(t >= D_R0 && t < D_R0+NREG) {
- regbits |= RtoB(t-D_R0);
- if(as == ADIVUL || as == ADIVSL)
- regbits |= RtoB(t-D_R0+1);
- }
- if(t >= D_A0 && t < D_A0+NREG)
- regbits |= AtoB(t-D_A0);
- if(t >= D_F0 && t < D_F0+NREG)
- regbits |= FtoB(t-D_F0);
- goto none;
-
- case D_EXTERN:
- case D_STATIC:
- case D_AUTO:
- case D_PARAM:
- break;
- }
- s = a->sym;
- if(s == S)
- goto none;
-
- if((a->type & I_MASK) == I_ADDR)
- mvbits |= B_ADDR;
-
- o = a->offset;
- v = var;
- for(i=0; i<nvar; i++) {
- if(s == v->sym)
- if(t == v->type)
- if(o == v->offset)
- goto out;
- v++;
- }
- if(s)
- if(s->name[0] == '.')
- goto none;
- if(nvar >= NVAR) {
- if(debug['w'] > 1 && s)
- warn(Z, "variable not optimized: %s", s->name);
- goto none;
- }
- i = nvar;
- nvar++;
- v = &var[i];
- v->sym = s;
- v->offset = o;
- v->etype = a->etype;
- v->type = t;
- if(debug['R'])
- print("bit=%2d et=%2d %s (%p,%d,%ld)\n",
- i, a->etype, s->name,
- v->sym, v->type, v->offset);
-
-out:
- bit = blsh(i);
- if(t == D_EXTERN || t == D_STATIC)
- for(z=0; z<BITS; z++)
- externs.b[z] |= bit.b[z];
- if(t == D_PARAM)
- for(z=0; z<BITS; z++)
- params.b[z] |= bit.b[z];
- if(a->etype != v->etype || !typechlpfd[a->etype])
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z]; /* funny punning */
- return bit;
-
-none:
- return zbits;
-}
-
-void
-prop(Reg *r, Bits ref, Bits cal)
-{
- Reg *r1, *r2;
- int z;
-
- for(r1 = r; r1 != R; r1 = r1->p1) {
- for(z=0; z<BITS; z++) {
- ref.b[z] |= r1->refahead.b[z];
- if(ref.b[z] != r1->refahead.b[z]) {
- r1->refahead.b[z] = ref.b[z];
- changer++;
- }
- cal.b[z] |= r1->calahead.b[z];
- if(cal.b[z] != r1->calahead.b[z]) {
- r1->calahead.b[z] = cal.b[z];
- changer++;
- }
- }
- switch(r1->prog->as) {
- case ABSR:
- for(z=0; z<BITS; z++) {
- cal.b[z] |= ref.b[z] | externs.b[z];
- ref.b[z] = 0;
- }
- break;
-
- case ATEXT:
- for(z=0; z<BITS; z++) {
- cal.b[z] = 0;
- ref.b[z] = 0;
- }
- break;
-
- case ARTS:
- for(z=0; z<BITS; z++) {
- cal.b[z] = externs.b[z];
- ref.b[z] = 0;
- }
- }
- for(z=0; z<BITS; z++) {
- ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
- r1->use1.b[z] | r1->use2.b[z];
- cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
- r1->refbehind.b[z] = ref.b[z];
- r1->calbehind.b[z] = cal.b[z];
- }
- if(r1->active)
- break;
- r1->active = 1;
- }
- for(; r != r1; r = r->p1)
- for(r2 = r->p2; r2 != R; r2 = r2->p2link)
- prop(r2, r->refbehind, r->calbehind);
-}
-
-/*
- * find looping structure
- *
- * 1) find reverse postordering
- * 2) find approximate dominators,
- * the actual dominators if the flow graph is reducible
- * otherwise, dominators plus some other non-dominators.
- * See Matthew S. Hecht and Jeffrey D. Ullman,
- * "Analysis of a Simple Algorithm for Global Data Flow Problems",
- * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
- * Oct. 1-3, 1973, pp. 207-217.
- * 3) find all nodes with a predecessor dominated by the current node.
- * such a node is a loop head.
- * recursively, all preds with a greater rpo number are in the loop
- */
-long
-postorder(Reg *r, Reg **rpo2r, long n)
-{
- Reg *r1;
-
- r->rpo = 1;
- r1 = r->s1;
- if(r1 && !r1->rpo)
- n = postorder(r1, rpo2r, n);
- r1 = r->s2;
- if(r1 && !r1->rpo)
- n = postorder(r1, rpo2r, n);
- rpo2r[n] = r;
- n++;
- return n;
-}
-
-long
-rpolca(long *idom, long rpo1, long rpo2)
-{
- long t;
-
- if(rpo1 == -1)
- return rpo2;
- while(rpo1 != rpo2){
- if(rpo1 > rpo2){
- t = rpo2;
- rpo2 = rpo1;
- rpo1 = t;
- }
- while(rpo1 < rpo2){
- t = idom[rpo2];
- if(t >= rpo2)
- fatal(Z, "bad idom");
- rpo2 = t;
- }
- }
- return rpo1;
-}
-
-int
-doms(long *idom, long r, long s)
-{
- while(s > r)
- s = idom[s];
- return s == r;
-}
-
-int
-loophead(long *idom, Reg *r)
-{
- long src;
-
- src = r->rpo;
- if(r->p1 != R && doms(idom, src, r->p1->rpo))
- return 1;
- for(r = r->p2; r != R; r = r->p2link)
- if(doms(idom, src, r->rpo))
- return 1;
- return 0;
-}
-
-void
-loopmark(Reg **rpo2r, long head, Reg *r)
-{
- if(r->rpo < head || r->active == head)
- return;
- r->active = head;
- r->loop += LOOP;
- if(r->p1 != R)
- loopmark(rpo2r, head, r->p1);
- for(r = r->p2; r != R; r = r->p2link)
- loopmark(rpo2r, head, r);
-}
-
-void
-loopit(Reg *r, long nr)
-{
- Reg *r1;
- long i, d, me;
-
- if(nr > maxnr) {
- rpo2r = alloc(nr * sizeof(Reg*));
- idom = alloc(nr * sizeof(long));
- maxnr = nr;
- }
-
- d = postorder(r, rpo2r, 0);
- if(d > nr)
- fatal(Z, "too many reg nodes");
- nr = d;
- for(i = 0; i < nr / 2; i++){
- r1 = rpo2r[i];
- rpo2r[i] = rpo2r[nr - 1 - i];
- rpo2r[nr - 1 - i] = r1;
- }
- for(i = 0; i < nr; i++)
- rpo2r[i]->rpo = i;
-
- idom[0] = 0;
- for(i = 0; i < nr; i++){
- r1 = rpo2r[i];
- me = r1->rpo;
- d = -1;
- if(r1->p1 != R && r1->p1->rpo < me)
- d = r1->p1->rpo;
- for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
- if(r1->rpo < me)
- d = rpolca(idom, d, r1->rpo);
- idom[i] = d;
- }
-
- for(i = 0; i < nr; i++){
- r1 = rpo2r[i];
- r1->loop++;
- if(r1->p2 != R && loophead(idom, r1))
- loopmark(rpo2r, i, r1);
- }
-}
-
-void
-synch(Reg *r, Bits dif)
-{
- Reg *r1;
- int z;
-
- for(r1 = r; r1 != R; r1 = r1->s1) {
- for(z=0; z<BITS; z++) {
- dif.b[z] = (dif.b[z] &
- ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
- r1->set.b[z] | r1->regdiff.b[z];
- if(dif.b[z] != r1->regdiff.b[z]) {
- r1->regdiff.b[z] = dif.b[z];
- changer++;
- }
- }
- if(r1->active)
- break;
- r1->active = 1;
- for(z=0; z<BITS; z++)
- dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
- if(r1->s2 != R)
- synch(r1->s2, dif);
- }
-}
-
-ulong
-allreg(ulong b, Rgn *r)
-{
- Var *v;
- int i, j;
-
- v = var + r->varno;
- r->regno = D_NONE;
- switch(v->etype) {
-
- default:
- diag(Z, "unknown etype");
- break;
-
- case TCHAR:
- case TUCHAR:
- case TSHORT:
- case TUSHORT:
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TIND:
- i = BtoR(~b);
- j = BtoA(~b);
- if(r->costa == r->costr)
- if(i > j)
- i = NREG;
- if(j < NREG && r->costa > 0)
- if(r->costa > r->costr || i >= NREG) {
- r->regno = D_A0 + j;
- return AtoB(j);
- }
- if(i < NREG && r->costr > 0) {
- r->regno = D_R0 + i;
- return RtoB(i);
- }
- break;
-
- case TDOUBLE:
- case TFLOAT:
- i = BtoF(~b);
- if(i < NREG) {
- r->regno = D_F0 + i;
- return FtoB(i);
- }
- break;
- }
- return 0;
-}
-
-void
-paint1(Reg *r, int bn)
-{
- Reg *r1;
- Prog *p;
- int z;
- ulong bb;
- int x;
-
- z = bn/32;
- bb = 1L<<(bn%32);
- if(r->act.b[z] & bb)
- return;
- for(;;) {
- if(!(r->refbehind.b[z] & bb))
- break;
- r1 = r->p1;
- if(r1 == R)
- break;
- if(!(r1->refahead.b[z] & bb))
- break;
- if(r1->act.b[z] & bb)
- break;
- r = r1;
- }
- if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
- changer -= CLOAD * r->loop;
- changea -= CLOAD * r->loop;
- if(debug['R'] && debug['v'])
- print("%ld%P\tld %B $%d.%d\n", r->loop,
- r->prog, blsh(bn), changer, changea);
- }
- for(;;) {
- r->act.b[z] |= bb;
- p = r->prog;
-
- if(r->use1.b[z] & bb) {
- changer += CREF * r->loop;
- changea += CREF * r->loop;
- switch(p->as) {
- default:
- changea = -CINF;
- case AADDL:
- case ASUBL:
- case AMOVL:
- case ACMPL:
- break;
- }
- if(p->as == AMOVL) {
- x = p->to.type;
- if(x >= D_R0 && x < D_R0+NREG)
- changer += r->loop;
- if(x >= D_A0 && x < D_A0+NREG)
- changea += r->loop;
- }
- if(debug['R'] && debug['v'])
- print("%ld%P\tu1 %B $%d.%d\n", r->loop,
- p, blsh(bn), changer, changea);
- }
- if((r->use2.b[z]|r->set.b[z]) & bb) {
- changer += CREF * r->loop;
- changea += CREF * r->loop;
- switch(p->as) {
- default:
- changea = -CINF;
- break;
- case AMOVL:
- case AADDL:
- case ACMPL:
- case ASUBL:
- case ACLRL: /* can be faked */
- case ATSTL: /* can be faked */
- break;
- }
- if(p->as == AMOVL) {
- x = p->from.type;
- if(x >= D_R0 && x < D_R0+NREG)
- changer += r->loop;
- if(x >= D_A0 && x < D_A0+NREG)
- changea += r->loop;
- }
- if(debug['R'] && debug['v'])
- print("%ld%P\tu2 %B $%d.%d\n", r->loop,
- p, blsh(bn), changer, changea);
- }
- if(STORE(r) & r->regdiff.b[z] & bb) {
- changer -= CLOAD * r->loop;
- changea -= CLOAD * r->loop;
- if(debug['R'] && debug['v'])
- print("%ld%P\tst %B $%d.%d\n", r->loop,
- p, blsh(bn), changer, changea);
- }
-
- if(r->refbehind.b[z] & bb)
- for(r1 = r->p2; r1 != R; r1 = r1->p2link)
- if(r1->refahead.b[z] & bb)
- paint1(r1, bn);
-
- if(!(r->refahead.b[z] & bb))
- break;
- r1 = r->s2;
- if(r1 != R)
- if(r1->refbehind.b[z] & bb)
- paint1(r1, bn);
- r = r->s1;
- if(r == R)
- break;
- if(r->act.b[z] & bb)
- break;
- if(!(r->refbehind.b[z] & bb))
- break;
- }
-}
-
-ulong
-paint2(Reg *r, int bn)
-{
- Reg *r1;
- int z;
- ulong bb, vreg;
-
- z = bn/32;
- bb = 1L << (bn%32);
- vreg = regbits;
- if(!(r->act.b[z] & bb))
- return vreg;
- for(;;) {
- if(!(r->refbehind.b[z] & bb))
- break;
- r1 = r->p1;
- if(r1 == R)
- break;
- if(!(r1->refahead.b[z] & bb))
- break;
- if(!(r1->act.b[z] & bb))
- break;
- r = r1;
- }
- for(;;) {
- r->act.b[z] &= ~bb;
-
- vreg |= r->regu;
-
- if(r->refbehind.b[z] & bb)
- for(r1 = r->p2; r1 != R; r1 = r1->p2link)
- if(r1->refahead.b[z] & bb)
- vreg |= paint2(r1, bn);
-
- if(!(r->refahead.b[z] & bb))
- break;
- r1 = r->s2;
- if(r1 != R)
- if(r1->refbehind.b[z] & bb)
- vreg |= paint2(r1, bn);
- r = r->s1;
- if(r == R)
- break;
- if(!(r->act.b[z] & bb))
- break;
- if(!(r->refbehind.b[z] & bb))
- break;
- }
- return vreg;
-}
-
-void
-paint3(Reg *r, int bn, ulong rb, int rn)
-{
- Reg *r1;
- Prog *p;
- int z;
- ulong bb;
-
- z = bn/32;
- bb = 1L << (bn%32);
- if(r->act.b[z] & bb)
- return;
- for(;;) {
- if(!(r->refbehind.b[z] & bb))
- break;
- r1 = r->p1;
- if(r1 == R)
- break;
- if(!(r1->refahead.b[z] & bb))
- break;
- if(r1->act.b[z] & bb)
- break;
- r = r1;
- }
- if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
- addmove(r, bn, rn, 0);
- for(;;) {
- r->act.b[z] |= bb;
- p = r->prog;
-
- if(r->use1.b[z] & bb) {
- if(debug['R'])
- print("%P", p);
- addreg(&p->from, rn);
- if(debug['R'])
- print("\t.c%P\n", p);
- }
- if((r->use2.b[z]|r->set.b[z]) & bb) {
- if(debug['R'])
- print("%P", p);
- addreg(&p->to, rn);
- if(debug['R'])
- print("\t.c%P\n", p);
- }
- if(STORE(r) & r->regdiff.b[z] & bb)
- addmove(r, bn, rn, 1);
- r->regu |= rb;
-
- if(r->refbehind.b[z] & bb)
- for(r1 = r->p2; r1 != R; r1 = r1->p2link)
- if(r1->refahead.b[z] & bb)
- paint3(r1, bn, rb, rn);
-
- if(!(r->refahead.b[z] & bb))
- break;
- r1 = r->s2;
- if(r1 != R)
- if(r1->refbehind.b[z] & bb)
- paint3(r1, bn, rb, rn);
- r = r->s1;
- if(r == R)
- break;
- if(r->act.b[z] & bb)
- break;
- if(!(r->refbehind.b[z] & bb))
- break;
- }
-}
-
-void
-addreg(Adr *a, int rn)
-{
- a->sym = 0;
- if(rn >= D_R0 && rn < D_R0+NREG)
- goto addr;
- a->type = rn | (a->type & I_INDIR);
- return;
-
-addr:
- a->type = rn | (a->type & I_INDIR);
-}
-
-/*
- * bit reg
- * 0-7 R0-R7
- * 8-15 A0-A7
- * 16-23 F0-F7
- */
-ulong
-RtoB(int r)
-{
-
- if(r < 0 || r >= NREG)
- return 0;
- return 1L << (r + 0);
-}
-
-int
-BtoR(ulong b)
-{
-
- b &= 0x0000ffL;
- if(b == 0)
- return NREG;
- return bitno(b) - 0;
-}
-
-ulong
-AtoB(int a)
-{
-
- if(a < 0 || a >= NREG)
- return 0;
- return 1L << (a + NREG);
-}
-
-int
-BtoA(ulong b)
-{
-
- b &= 0x00ff00L;
- if(b == 0)
- return NREG;
- return bitno(b) - NREG;
-}
-
-ulong
-FtoB(int f)
-{
-
- if(f < 0 || f >= NREG)
- return 0;
- return 1L << (f + NREG+NREG);
-}
-
-int
-BtoF(ulong b)
-{
-
- b &= 0xff0000L;
- if(b == 0)
- return NREG;
- return bitno(b) - NREG-NREG;
-}
diff --git a/utils/1c/sgen.c b/utils/1c/sgen.c
deleted file mode 100644
index cb289eaa..00000000
--- a/utils/1c/sgen.c
+++ /dev/null
@@ -1,694 +0,0 @@
-#include "gc.h"
-
-void
-codgen(Node *n, Node *nn)
-{
- Prog *sp;
-
- argoff = 0;
- inargs = 0;
- for(;; nn = nn->left) {
- if(nn == Z) {
- diag(Z, "cant find function name");
- return;
- }
- if(nn->op == ONAME)
- break;
- }
- nearln = nn->lineno;
- gpseudo(ATEXT, nn->sym, D_CONST, stkoff);
- sp = p;
-
- retok = 0;
- gen(n);
- if(!retok)
- if(thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", nn->sym->name);
-
- noretval(3);
- gbranch(ORETURN);
- if(!debug['N'] || debug['R'] || debug['P'])
- regopt(sp);
-}
-
-void
-gen(Node *n)
-{
- Node *l;
- Prog *sp, *spc, *spb;
- Case *cn;
- long sbc, scc;
- int g, 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);
- doinc(n, PRE);
- cgen(n, D_NONE, n);
- doinc(n, POST);
- 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;
- }
- doinc(l, PRE);
- if(typesuv[n->type->etype]) {
- sugen(l, D_TREE, nodret, n->type->width);
- doinc(l, POST);
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- g = regalloc(n->type, regret(n->type));
- cgen(l, g, n);
- doinc(l, POST);
- if(typefd[n->type->etype])
- noretval(1);
- else
- noretval(2);
- gbranch(ORETURN);
- regfree(g);
- 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;
- setsp();;
- 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;
- setsp();
- goto rloop;
- }
- diag(n, "case expression must be integer constant");
- goto rloop;
-
- case OSWITCH:
- l = n->left;
- complex(l);
- doinc(l, PRE);
- if(l->type == T)
- break;
- if(!typechl[l->type->etype]) {
- diag(n, "switch expression must be integer");
- break;
- }
- g = regalloc(types[TLONG], D_NONE);
- n->type = types[TLONG];
- cgen(l, g, n);
- regfree(g);
- doinc(l, POST);
- setsp();
- 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);
- doswit(g, l);
-
- patch(spb, pc);
- cases = cn;
- breakpc = sbc;
- setsp();
- 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 */
- gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z);
- p->as = ANOP;
- break;
- case ONAME:
- if(o == OSET)
- gopcode(OTST, types[TINT], D_NONE, Z, D_TREE, n);
- else
- gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z);
- p->as = ANOP;
- break;
- }
-}
-
-void
-noretval(int n)
-{
-
- if(n & 1) {
- gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TLONG]), Z);
- p->as = ANOP;
- }
- if(n & 2) {
- gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TDOUBLE]), Z);
- p->as = ANOP;
- }
-}
-
-/*
- * calculate addressability as follows
- * REGISTER ==> 12 register
- * NAME ==> 11 name+value(SB/SP)
- * note that 10 is no longer generated
- * CONST ==> 20 $value
- * *(20) ==> 21 value
- * &(10) ==> 12 $name+value(SB)
- * &(11) ==> 1 $name+value(SP)
- * (12) + (20) ==> 12 fold constants
- * (1) + (20) ==> 1 fold constants
- * *(12) ==> 10 back to name
- * *(1) ==> 11 back to name
- *
- * (2,10,11) + (20) ==> 2 indirect w offset
- * (2) ==> &13
- * *(10,11) ==> 13 indirect, no index
- *
- * (20) * (X) ==> 7 multiplier in indexing
- * (X,7) + (12,1) ==> 8 adder in indexing (addresses)
- * (X,7) + (10,11,2) ==> 8 adder in indexing (names)
- * (8) ==> &9 index, almost addressable
- *
- * (X)++ ==> X fake addressability
- *
- * calculate complexity (number of registers)
- */
-void
-xcom(Node *n)
-{
- Node *l, *r;
- int g;
-
- if(n == Z)
- return;
- l = n->left;
- r = n->right;
- n->complex = 0;
- n->addable = 0;
- switch(n->op) {
- case OCONST:
- n->addable = 20;
- break;
-
- case ONAME:
- n->addable = 11; /* difference to make relocatable */
- break;
-
- case OREGISTER:
- n->addable = 12;
- break;
-
- case OADDR:
- xcom(l);
- if(l->addable == 10)
- n->addable = 12;
- else
- if(l->addable == 11)
- n->addable = 1;
- break;
-
- case OADD:
- xcom(l);
- xcom(r);
- if(n->type->etype != TIND)
- break;
-
- if(l->addable == 20)
- switch(r->addable) {
- case 12:
- case 1:
- n->addable = r->addable;
- goto brk;
- }
- if(r->addable == 20)
- switch(l->addable) {
- case 12:
- case 1:
- n->addable = l->addable;
- goto brk;
- }
- break;
-
- case OIND:
- xcom(l);
- if(l->op == OADDR) {
- l = l->left;
- l->type = n->type;
- *n = *l;
- return;
- }
- switch(l->addable) {
- case 20:
- n->addable = 21;
- break;
- case 1:
- n->addable = 11;
- break;
- case 12:
- n->addable = 10;
- break;
- }
- break;
-
- case OASHL:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- g = vconst(r);
- if(g >= 0 && g < 4)
- n->addable = 7;
- break;
-
- case OMUL:
- case OLMUL:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- g = vlog(r);
- if(g >= 0) {
- n->op = OASHL;
- r->vconst = g;
- if(g < 4)
- n->addable = 7;
- break;
- }
- g = vlog(l);
- if(g >= 0) {
- n->left = r;
- n->right = l;
- l = r;
- r = n->right;
- n->op = OASHL;
- r->vconst = g;
- if(g < 4)
- n->addable = 7;
- break;
- }
- break;
-
- case ODIV:
- case OLDIV:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- g = vlog(r);
- if(g >= 0) {
- if(n->op == ODIV)
- n->op = OASHR;
- else
- n->op = OLSHR;
- r->vconst = g;
- }
- break;
-
- case OSUB:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- if(vconst(l) == 0) {
- n->op = ONEG;
- n->left = r;
- n->right = Z;
- }
- break;
-
- case OXOR:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- if(vconst(l) == -1) {
- n->op = OCOM;
- n->left = r;
- n->right = Z;
- }
- break;
-
- case OASMUL:
- case OASLMUL:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- g = vlog(r);
- if(g >= 0) {
- n->op = OASASHL;
- r->vconst = g;
- }
- goto aseae;
-
- case OASDIV:
- case OASLDIV:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
- g = vlog(r);
- if(g >= 0) {
- if(n->op == OASDIV)
- n->op = OASASHR;
- else
- n->op = OASLSHR;
- r->vconst = g;
- }
- goto aseae;
-
- case OASLMOD:
- case OASMOD:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
-
- aseae: /* hack that there are no byte/short mul/div operators */
- if(n->type->etype == TCHAR || n->type->etype == TSHORT) {
- n->right = new1(OCAST, n->right, Z);
- n->right->type = types[TLONG];
- n->type = types[TLONG];
- }
- if(n->type->etype == TUCHAR || n->type->etype == TUSHORT) {
- n->right = new1(OCAST, n->right, Z);
- n->right->type = types[TULONG];
- n->type = types[TULONG];
- }
- goto asop;
-
- case OASXOR:
- case OASOR:
- case OASADD:
- case OASSUB:
- case OASLSHR:
- case OASASHR:
- case OASASHL:
- case OASAND:
- case OAS:
- xcom(l);
- xcom(r);
- if(typev[n->type->etype])
- break;
-
- asop:
- if(l->addable > INDEXED &&
- l->complex < FNX &&
- r && r->complex < FNX)
- n->addable = l->addable;
- break;
-
- case OPOSTINC:
- case OPREINC:
- case OPOSTDEC:
- case OPREDEC:
- xcom(l);
- if(typev[n->type->etype])
- break;
- if(l->addable > INDEXED &&
- l->complex < FNX)
- n->addable = l->addable;
- break;
-
- default:
- if(l != Z)
- xcom(l);
- if(r != Z)
- xcom(r);
- break;
- }
-
-brk:
- n->complex = 0;
- if(n->addable >= 10)
- return;
- if(l != Z)
- n->complex = l->complex;
- if(r != Z) {
- if(r->complex == n->complex)
- n->complex = r->complex+1;
- else
- if(r->complex > n->complex)
- n->complex = r->complex;
- }
- if(n->complex == 0)
- n->complex++;
-
- if(com64(n))
- return;
-
- switch(n->op) {
-
- case OFUNC:
- n->complex = FNX;
- break;
-
- case OADD:
- case OMUL:
- case OLMUL:
- case OXOR:
- case OAND:
- case OOR:
- /*
- * symmetric operators, make right side simple
- * if same, put constant on left to get movq
- */
- if(r->complex > l->complex ||
- (r->complex == l->complex && r->addable == 20)) {
- n->left = r;
- n->right = l;
- }
- break;
-
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OEQ:
- case ONE:
- /*
- * relational operators, make right side simple
- * if same, put constant on left to get movq
- */
- if(r->complex > l->complex || r->addable == 20) {
- n->left = r;
- n->right = l;
- n->op = invrel[relindex(n->op)];
- }
- break;
- }
-}
-
-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);
- doinc(n, PRE);
- boolgen(n, 1, D_NONE, Z, n);
- } else
- gbranch(OGOTO);
-}
-
-Node*
-nodconst(long v)
-{
-
- return (Node*)v;
-}
diff --git a/utils/1c/swt.c b/utils/1c/swt.c
deleted file mode 100644
index 34daeb1e..00000000
--- a/utils/1c/swt.c
+++ /dev/null
@@ -1,964 +0,0 @@
-#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(int g, 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(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, g, n);
-}
-
-#define N1 4 /* ncase: always linear */
- /* else binary */
-void
-swit1(C1 *q, int nc, long def, int g, Node *n)
-{
- C1 *r;
- int i;
- long v;
- Prog *sp1, *sp2;
-
- /* note that g and g+1 are not allocated */
- if(nc <= N1)
- goto linear;
-
- /*
- * divide and conquer
- */
- i = nc / 2;
- r = q+i;
- v = r->val;
- /* compare median */
- if(v >= -128 && v < 128) {
- gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
- gopcode(OEQ, n->type, g, n, g+1, n);
- } else
- gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
- gbranch(OLT);
- sp1 = p;
- gbranch(OGT);
- sp2 = p;
- gbranch(OGOTO);
- patch(p, r->label);
-
- patch(sp1, pc);
- swit1(q, i, def, g, n);
-
- patch(sp2, pc);
- swit1(r+1, nc-i-1, def, g, n);
- return;
-
-linear:
- for(i=0; i<nc; i++) {
- v = q->val;
- if(v >= -128 && v < 128) {
- gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
- gopcode(OEQ, n->type, g+1, n, g, n);
- } else
- gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
- gbranch(OEQ);
- patch(p, q->label);
- q++;
- }
- gbranch(OGOTO);
- patch(p, def);
-}
-
-void
-casf(void)
-{
- Case *c;
-
- c = alloc(sizeof(*c));
- c->link = cases;
- cases = c;
-}
-
-
-int
-bitload(Node *b, int n1, int n2, int n3, Node *nn)
-{
- int sh, g, gs;
- long v;
- Node *l;
- Type *t;
-
- /*
- * n1 gets adjusted/masked value
- * n2 gets address of cell
- * n3 gets contents of cell
- */
- gs = 0;
- t = tfield;
-
- l = b->left;
- g = regalloc(t, n3);
- if(n2 != D_NONE) {
- lcgen(l, n2, Z);
- n2 |= I_INDIR;
- gmove(t, t, n2, l, g, l);
- gmove(t, t, g, l, n1, l);
- } else
- cgen(l, g, nn);
- if(b->type->shift == 0 && typeu[b->type->etype]) {
- v = ~0 + (1L << b->type->nbits);
- gopcode(OAND, t, D_CONST, nodconst(v), g, l);
- } else {
- sh = 32 - b->type->shift - b->type->nbits;
- if(sh > 0)
- if(sh >= 8) {
- gs = regalloc(t, D_NONE);
- gmove(t, t, D_CONST, nodconst(sh), gs, l);
- gopcode(OASHL, t, gs, l, g, l);
- if(b->type->shift)
- regfree(gs);
- } else
- gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);
- sh += b->type->shift;
- if(sh > 0) {
- if(sh >= 8) {
- if(b->type->shift) {
- gs = regalloc(t, D_NONE);
- gmove(t, t, D_CONST, nodconst(sh), gs, l);
- }
- if(typeu[b->type->etype])
- gopcode(OLSHR, t, gs, l, g, l);
- else
- gopcode(OASHR, t, gs, l, g, l);
- regfree(gs);
- } else {
- if(typeu[b->type->etype])
- gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l);
- else
- gopcode(OASHR, t, D_CONST, nodconst(sh), g, l);
- }
- }
- }
- return g;
-}
-
-void
-bitstore(Node *b, int n1, int n2, int n3, int result, Node *nn)
-{
- long v;
- Node *l;
- Type *t;
- int sh, g, gs;
-
- /*
- * n1 has adjusted/masked value
- * n2 has address of cell
- * n3 has contents of cell
- */
- t = tfield;
-
- l = b->left;
- g = regalloc(t, D_NONE);
- v = ~0 + (1L << b->type->nbits);
- gopcode(OAND, t, D_CONST, nodconst(v), n1, l);
- gmove(t, t, n1, l, g, l);
- if(result != D_NONE)
- gmove(t, nn->type, n1, l, result, nn);
- sh = b->type->shift;
- if(sh > 0) {
- if(sh >= 8) {
- gs = regalloc(t, D_NONE);
- gmove(t, t, D_CONST, nodconst(sh), gs, l);
- gopcode(OASHL, t, gs, l, g, l);
- regfree(gs);
- } else
- gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);
- }
- v <<= sh;
- gopcode(OAND, t, D_CONST, nodconst(~v), n3, l);
- gopcode(OOR, t, n3, l, g, l);
- gmove(t, t, g, l, n2|I_INDIR, l);
-
- regfree(g);
- regfree(n1);
- regfree(n2);
- regfree(n3);
-}
-
-long
-outstring(char *s, long n)
-{
- long r;
-
- r = nstring;
- while(n) {
- string[mnstring] = *s++;
- mnstring++;
- nstring++;
- if(mnstring >= NSNAME) {
- gpseudo(ADATA, symstring, D_SCONST, 0L);
- memmove(p->to.sval, string, NSNAME);
- p->from.offset = nstring - NSNAME;
- p->from.displace = NSNAME;
- mnstring = 0;
- }
- 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
-doinc(Node *n, int f)
-{
- Node *l;
- int a;
-
-loop:
- if(n == Z)
- return 0;
- l = n->left;
- switch(n->op) {
-
- case OPOSTINC:
- case OPOSTDEC:
- if(f & POST) {
- a = n->addable;
- if(a >= INDEXED) {
- if(f & TEST)
- return 1;
- n->addable = 0;
- cgen(n, D_NONE, n);
- n->addable = a;
- }
- }
- break;
-
- case OAS:
- case OASLMUL:
- case OASLDIV:
- case OASLMOD:
- case OASMUL:
- case OASDIV:
- case OASMOD:
- case OASXOR:
- case OASOR:
- case OASADD:
- case OASSUB:
- case OASLSHR:
- case OASASHR:
- case OASASHL:
- case OASAND:
-
- case OPREINC:
- case OPREDEC:
- if(f & PRE) {
- a = n->addable;
- if(a >= INDEXED) {
- if(f & TEST)
- return 1;
- n->addable = 0;
- doinc(n, PRE);
- cgen(n, D_NONE, n);
- n->addable = a;
- return 0;
- }
- }
- break;
-
- case OFUNC:
- if(f & PRE)
- break;
- return 0;
-
- case ONAME:
- case OREGISTER:
- case OSTRING:
- case OCONST:
-
- case OANDAND:
- case OOROR:
- return 0;
-
- case OCOND:
- return 0;
-
- case OCOMMA:
- n = n->right;
- if(f & PRE)
- n = l;
- goto loop;
- }
- if(l != Z)
- if(doinc(l, f))
- return 1;
- n = n->right;
- goto loop;
-}
-
-void
-setsp(void)
-{
-
- nextpc();
- p->as = AADJSP;
- p->from.type = D_CONST;
- p->from.offset = 0;
-}
-
-void
-adjsp(long o)
-{
-
- if(o != 0) {
- nextpc();
- p->as = AADJSP;
- p->from.type = D_CONST;
- p->from.offset = o;
- argoff += o;
- }
-}
-
-int
-simplv(Node *n)
-{
-
- if(n->addable <= INDEXED)
- return 0;
- while(n->op == OIND)
- n = n->left;
- if(n->op == ONAME)
- return 1;
- return 0;
-}
-
-int
-eval(Node *n, int g)
-{
-
- if(n->addable >= INDEXED)
- return D_TREE;
- g = regalloc(n->type, g);
- cgen(n, g, n);
- return g;
-}
-
-void outhist(Biobuf*);
-void zname(Biobuf*, Sym*, int);
-void zaddr(Biobuf*, Adr*, int);
-void zwrite(Biobuf*, Prog*, int, int);
-
-void
-outcode(void)
-{
- struct { Sym *sym; short type; } h[NSYM];
- Prog *p;
- Sym *s;
- int f, sf, st, t, sym;
- Biobuf b;
-
- if(debug['S']) {
- for(p = firstp; p != P; p = p->link)
- if(p->as != ADATA && p->as != AGLOBL)
- pc--;
- for(p = firstp; p != P; p = p->link) {
- print("%P\n", p);
- if(p->as != ADATA && p->as != AGLOBL)
- pc++;
- }
- }
- f = open(outfile, OWRITE);
- if(f < 0) {
- diag(Z, "cant open %s", outfile);
- errorexit();
- }
- Binit(&b, f, OWRITE);
- Bseek(&b, 0L, 2);
- outhist(&b);
- for(sym=0; sym<NSYM; sym++) {
- h[sym].sym = S;
- h[sym].type = 0;
- }
- sym = 1;
- for(p = firstp; p != P; p = p->link) {
- jackpot:
- sf = 0;
- s = p->from.sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = p->from.type & D_MASK;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- s->sym = sym;
- zname(&b, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = p->to.sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = p->to.type & D_MASK;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- s->sym = sym;
- zname(&b, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- zwrite(&b, p, sf, st);
- }
- Bflush(&b);
- close(f);
- firstp = P;
- lastp = P;
-}
-
-void
-zwrite(Biobuf *b, Prog *p, int sf, int st)
-{
- long l;
-
- l = p->as;
- Bputc(b, l);
- Bputc(b, l>>8);
- l = p->lineno;
- Bputc(b, l);
- Bputc(b, l>>8);
- Bputc(b, l>>16);
- Bputc(b, l>>24);
- zaddr(b, &p->from, sf);
- zaddr(b, &p->to, st);
-}
-
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- char *n;
- ulong sig;
-
- if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
- sig = sign(s);
- Bputc(b, ASIGNAME);
- Bputc(b, ASIGNAME>>8);
- Bputc(b, sig);
- Bputc(b, sig>>8);
- Bputc(b, sig>>16);
- Bputc(b, sig>>24);
- s->sig = SIGDONE;
- }
- else{
- Bputc(b, ANAME); /* as */
- Bputc(b, ANAME>>8); /* as */
- }
- Bputc(b, t); /* type */
- Bputc(b, s->sym); /* sym */
- n = s->name;
- while(*n) {
- Bputc(b, *n);
- n++;
- }
- Bputc(b, 0);
-}
-
-void
-zaddr(Biobuf *b, Adr *a, int s)
-{
- long l;
- int i, t;
- char *n;
- Ieee e;
-
- t = 0;
- if(a->field)
- t |= T_FIELD;
- if(s)
- t |= T_SYM;
-
- switch(a->type) {
- default:
- if(a->offset)
- t |= T_OFFSET;
- if(a->displace)
- t |= T_INDEX;
- if(a->type & ~0xff)
- t |= T_TYPE;
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- }
- Bputc(b, t);
-
- if(t & T_FIELD) { /* implies field */
- i = a->field;
- Bputc(b, i);
- Bputc(b, i>>8);
- }
- if(t & T_INDEX) { /* implies index, scale, displace */
- i = D_NONE;
- Bputc(b, i);
- Bputc(b, i>>8);
- Bputc(b, 0);
- l = a->displace;
- Bputc(b, l);
- Bputc(b, l>>8);
- Bputc(b, l>>16);
- Bputc(b, l>>24);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- Bputc(b, l);
- Bputc(b, l>>8);
- Bputc(b, l>>16);
- Bputc(b, l>>24);
- }
- if(t & T_SYM) /* implies sym */
- Bputc(b, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->dval);
- l = e.l;
- Bputc(b, l);
- Bputc(b, l>>8);
- Bputc(b, l>>16);
- Bputc(b, l>>24);
- l = e.h;
- Bputc(b, l);
- Bputc(b, l>>8);
- Bputc(b, l>>16);
- Bputc(b, l>>24);
- return;
- }
- if(t & T_SCONST) {
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- Bputc(b, *n);
- n++;
- }
- return;
- }
- i = a->type;
- Bputc(b, i);
- if(t & T_TYPE)
- Bputc(b, i>>8);
-}
-
-
-
-void
-outhist(Biobuf *b)
-{
- Hist *h;
- char *p, *q, *op, c;
- Prog pg;
- int n;
-
- pg = zprog;
- pg.as = AHISTORY;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- op = 0;
- /* on windows skip drive specifier in pathname */
- if(systemtype(Windows) && p && p[1] == ':'){
- p += 2;
- c = *p;
- }
- if(p && p[0] != c && h->offset == 0 && pathname){
- /* on windows skip drive specifier in pathname */
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname+2;
- c = *p;
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = utfrune(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- Bputc(b, ANAME);
- Bputc(b, ANAME>>8);
- Bputc(b, D_FILE);
- Bputc(b, 1);
- Bputc(b, '<');
- Bwrite(b, p, n);
- Bputc(b, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- pg.lineno = h->line;
- pg.to.type = zprog.to.type;
- pg.to.offset = h->offset;
- if(h->offset)
- pg.to.type = D_CONST;
-
- zwrite(b, &pg, 0, 0);
- }
-}
-
-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);
-}
-
-int
-nodalloc(Type *t, int g, Node *n)
-{
-
- n->type = t;
- n->op = OREGISTER;
- n->addable = 12;
- n->complex = 0;
- g = regaddr(g);
- n->reg = g | I_INDIR;
- n->xoffset = 0;
- return g;
-}
-
-int
-mulcon(Node *n, Node *c, int result, Node *nn)
-{
- long v;
-
- if(typefd[n->type->etype])
- return 0;
- v = c->vconst;
- if(mulcon1(n, v, result, nn))
- return 1;
- return 0;
-}
-
-int
-shlcon(Node *n, Node *c, int result, Node *nn)
-{
- long v;
-
- v = 1L << c->vconst;
- return mulcon1(n, v, result, nn);
-}
-
-int
-mulcon1(Node *n, long v, int result, Node *nn)
-{
- int g, g1, a1, a2, neg;
- int o;
- char code[10], *p;
-
- if(result == D_NONE)
- return 0;
- neg = 0;
- if(v < 0) {
- v = -v;
- neg++;
- }
- a1 = 0;
- a2 = multabsize;
- for(;;) {
- if(a1 >= a2)
- return 0;
- g1 = (a2 + a1)/2;
- if(v < multab[g1].val) {
- a2 = g1;
- continue;
- }
- if(v > multab[g1].val) {
- a1 = g1+1;
- continue;
- }
- break;
- }
- strcpy(code, "0");
- strncat(code, multab[g1].code, sizeof(multab[0].code));
- p = code;
- if(p[1] == 'i')
- p += 2;
- g = regalloc(n->type, result);
- cgen(n, g, n);
- if(neg)
- gopcode(ONEG, n->type, D_NONE, n, g, n);
- g1 = regalloc(n->type, D_NONE);
-loop:
- switch(*p) {
- case 0:
- regfree(g1);
- gmove(n->type, nn->type, g, n, result, nn);
- regfree(g);
- return 1;
- case '0':
- o = OAS;
- *p -= '0';
- goto com;
- case '1':
- case '2':
- o = OSUB;
- *p -= '1';
- goto com;
- case '3':
- case '4':
- case '5':
- case '6':
- o = OADD;
- *p -= '3';
- com:
- a1 = g;
- if(*p == 1 || *p == 3)
- a1 = g1;
- a2 = g;
- if(*p == 0 || *p == 3)
- a2 = g1;
- gopcode(o, n->type, a1, n, a2, n);
- p++;
- break;
- default:
- a1 = *p++ - 'a' + 1;
- a2 = g;
- if(a1 > 8) {
- a2 = g1;
- a1 -= 8;
- }
- gopcode(OASHL, n->type, D_CONST, nodconst(a1), a2, n);
- break;
- }
- goto loop;
-}
-
-void
-nullwarn(Node *l, Node *r)
-{
- warn(Z, "result of operation not used");
- if(l != Z)
- cgen(l, D_NONE, Z);
- if(r != Z)
- cgen(r, D_NONE, Z);
-}
-
-void
-sextern(Sym *s, Node *a, long o, long w)
-{
- long e, lw;
-
- for(e=0; e<w; e+=NSNAME) {
- lw = NSNAME;
- if(w-e < lw)
- lw = w-e;
- gpseudo(ADATA, s, D_SCONST, 0L);
- p->from.offset += o+e;
- p->from.displace = lw;
- memmove(p->to.sval, a->cstring+e, lw);
- }
-}
-
-void
-gextern(Sym *s, Node *a, long o, long w)
-{
- if(a->op == OCONST && typev[a->type->etype]) {
- gpseudo(ADATA, s, D_CONST, (long)(a->vconst>>32));
- p->from.offset += o;
- p->from.displace = 4;
- gpseudo(ADATA, s, D_CONST, (long)(a->vconst));
- p->from.offset += o + 4;
- p->from.displace = 4;
- return;
- }
- gpseudotree(ADATA, s, a);
- p->from.offset += o;
- p->from.displace = w;
-}
-
-long
-align(long i, Type *t, int op)
-{
- long o;
- Type *v;
- int w;
-
- o = i;
- w = 1;
- switch(op) {
- default:
- diag(Z, "unknown align opcode %d", op);
- break;
-
- case Asu2: /* padding at end of a struct */
- w = SZ_LONG;
- if(packflg)
- w = packflg;
- break;
-
- case Ael1: /* initial allign of struct element */
- for(v=t; v->etype==TARRAY; v=v->link)
- ;
- w = ewidth[v->etype];
- if(w <= 0 || w >= SZ_SHORT)
- w = SZ_SHORT;
- if(packflg)
- w = packflg;
- break;
-
- case Ael2: /* width of a struct element */
- o += t->width;
- break;
-
- case Aarg0: /* initial passbyptr argument in arg list */
- if(typesuv[t->etype]) {
- o = align(o, types[TIND], Aarg1);
- o = align(o, types[TIND], Aarg2);
- }
- break;
-
- case Aarg1: /* initial allign of parameter */
- w = ewidth[t->etype];
- if(w <= 0 || w >= SZ_LONG) {
- w = SZ_LONG;
- break;
- }
- o += SZ_LONG - w; /* big endian adjustment */
- w = 1;
- break;
-
- case Aarg2: /* width of a parameter */
- o += t->width;
- w = SZ_LONG;
- break;
-
- case Aaut3: /* total allign of automatic */
- o = align(o, t, Ael1);
- o = align(o, t, Ael2);
- break;
- }
- o = round(o, w);
- if(debug['A'])
- print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
- return o;
-}
-
-long
-maxround(long max, long v)
-{
- v += SZ_LONG-1;
- if(v > max)
- max = round(v, SZ_LONG);
- return max;
-}
diff --git a/utils/1c/txt.c b/utils/1c/txt.c
deleted file mode 100644
index e439c40c..00000000
--- a/utils/1c/txt.c
+++ /dev/null
@@ -1,903 +0,0 @@
-#include "gc.h"
-
-void
-tindex(Type *tf, Type *tt)
-{
- int i, j;
-
- j = 0;
- if(tt != T) {
- j = tt->etype;
- if(j >= NTYPE)
- j = 0;
- }
- i = 0;
- if(tf != T) {
- i = tf->etype;
- if(i >= NTYPE)
- if(typesu[i])
- i = j;
- else
- i = 0;
- }
- txtp = &txt[i][j];
-}
-
-void
-ginit(void)
-{
- int i, j, si, sj;
-
- thestring = "68000";
- thechar = '1';
- exregoffset = 7;
- exaregoffset = 5;
- exfregoffset = 7;
- listinit();
- for(i=0; i<NREG; i++) {
- regused[i] = 0;
- fregused[i] = 0;
- aregused[i] = 0;
- }
- regaddr(D_A0+6);
- regaddr(D_A0+7);
- for(i=0; i<sizeof(regbase); i++)
- regbase[i] = D_NONE;
- for(i=0; i<NREG; i++) {
- regbase[D_R0+i] = D_R0+i;
- regbase[D_A0+i] = D_A0+i;
- regbase[D_F0+i] = D_F0+i;
- }
- regbase[D_TOS] = D_TOS;
-
- for(i=0; i<NTYPE; i++)
- for(j=0; j<NTYPE; j++) {
- txtp = &txt[i][j];
- txtp->movas = AGOK;
- txtp->preclr = 0;
- txtp->postext = AGOK;
- if(!(typechlp[i] && typechlp[j]))
- continue;
- si = types[i]->width;
- sj = types[j]->width;
- if(sj < si)
- txtp->preclr = -1;
- if(sj > si) {
- if(typeu[i]) {
- txtp->preclr = 1;
- } else {
- if(sj == 2)
- txtp->postext = AEXTBW;
- else
- if(sj == 4)
- if(si == 1)
- txtp->postext = AEXTBL;
- else
- txtp->postext = AEXTWL;
- }
- sj = si;
- }
- if(sj == 1)
- txtp->movas = AMOVB;
- if(sj == 2)
- txtp->movas = AMOVW;
- if(sj == 4)
- txtp->movas = AMOVL;
- }
-
- for(i=0; i<ALLOP; i++)
- for(j=0; j<NTYPE; j++)
- opxt[i][j] = AGOK;
- oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK);
-
- oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED);
- oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED);
- oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK);
- oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
- oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
- oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
- oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
- oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD);
- oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK);
- oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
- oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
- oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK);
- oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK);
- oinit(OOR, AORB, AORW, AORL, AGOK, AGOK);
- oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK);
- oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
- oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
- oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD);
- oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK);
- oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD);
- oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
- oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
- oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
- oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
- oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
- oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
- oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK);
-
- nstring = 0;
- mnstring = 0;
- nrathole = 0;
- nstatic = 0;
- pc = 0;
- breakpc = -1;
- continpc = -1;
- cases = C;
- firstp = P;
- lastp = P;
- tfield = types[TLONG];
-
- zprog.link = P;
- zprog.as = AGOK;
- zprog.from.type = D_NONE;
- zprog.to = zprog.from;
-
- nodret = new(ONAME, Z, Z);
- nodret->sym = slookup(".ret");
- nodret->type = types[TIND];
- nodret->etype = types[TIND]->etype;
- nodret->class = CPARAM;
- nodret = new(OIND, nodret, Z);
- complex(nodret);
-
- symrathole = slookup(".rathole");
- symrathole->class = CGLOBL;
- symrathole->type = typ(TARRAY, types[TCHAR]);
- nodrat = new(ONAME, Z, Z);
- nodrat->sym = symrathole;
- nodrat->type = types[TIND];
- nodrat->etype = TVOID;
- nodrat->class = CGLOBL;
- complex(nodrat);
- nodrat->type = symrathole->type;
-
- com64init();
-
- symstatic = slookup(".static");
- symstatic->class = CSTATIC;
- symstatic->type = typ(TARRAY, types[TLONG]);
-}
-
-void
-gclean(void)
-{
- int i;
- Sym *s;
-
- regfree(D_A0+6);
- regfree(D_A0+7);
- for(i=0; i<NREG; i++) {
- if(regused[i])
- diag(Z, "missing R%d", i);
- if(aregused[i])
- diag(Z, "missing A%d", i);
- if(fregused[i])
- diag(Z, "missing F%d", i);
- }
-
- while(mnstring)
- outstring("", 1L);
- symstring->type->width = nstring;
- symstatic->type->width = nstatic;
- symrathole->type->width = nrathole;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->link) {
- if(s->type == T)
- continue;
- if(s->type->width == 0)
- continue;
- if(s->class != CGLOBL && s->class != CSTATIC)
- continue;
- if(s->type == types[TENUM])
- continue;
- gpseudo(AGLOBL, s, D_CONST, s->type->width);
- pc--;
- }
- nextpc();
- p->as = AEND;
- outcode();
-}
-
-void
-oinit(int o, int ab, int aw, int al, int af, int ad)
-{
- int i;
-
- i = o;
- if(i >= ALLOP) {
- diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP);
- errorexit();
- }
- opxt[i][TCHAR] = ab;
- opxt[i][TUCHAR] = ab;
- opxt[i][TSHORT] = aw;
- opxt[i][TUSHORT] = aw;
- opxt[i][TINT] = al;
- opxt[i][TUINT] = al;
- opxt[i][TLONG] = al;
- opxt[i][TULONG] = al;
- opxt[i][TIND] = al;
- opxt[i][TFLOAT] = af;
- opxt[i][TDOUBLE] = ad;
-}
-
-Prog*
-prg(void)
-{
- Prog *p;
-
- p = alloc(sizeof(*p));
- *p = zprog;
- return p;
-}
-
-void
-nextpc(void)
-{
-
- p = prg();
- pc++;
- p->lineno = nearln;
- if(firstp == P) {
- firstp = p;
- lastp = p;
- return;
- }
- lastp->link = p;
- lastp = p;
-}
-
-void
-gargs(Node *n)
-{
- long s;
-
-loop:
- if(n == Z)
- return;
- if(n->op == OLIST) {
- gargs(n->right);
- n = n->left;
- goto loop;
- }
- s = argoff;
- cgen(n, D_TOS, n);
- argoff = s + n->type->width;
-}
-
-void
-naddr(Node *n, Adr *a, int x)
-{
- Node *l;
- long v;
-
- switch(n->op) {
- default:
- bad:
- diag(n, "bad in naddr: %O", n->op);
- break;
-
- case OADDR:
- case OIND:
- naddr(n->left, a, x);
- goto noadd;
-
- case OREGISTER:
- a->sym = S;
- a->type = n->reg;
- a->offset = n->xoffset;
- a->displace = 0;
- break;
-
- case ONAME:
- a->etype = n->etype;
- a->displace = 0;
- a->sym = n->sym;
- a->offset = n->xoffset;
- a->type = D_STATIC;
- if(n->class == CSTATIC)
- break;
- if(n->class == CEXTERN || n->class == CGLOBL) {
- a->type = D_EXTERN;
- break;
- }
- if(n->class == CAUTO) {
- a->type = D_AUTO;
- break;
- }
- if(n->class == CPARAM) {
- a->type = D_PARAM;
- break;
- }
- goto bad;
-
- case OCONST:
- a->displace = 0;
- if(typefd[n->type->etype]) {
- a->type = D_FCONST;
- a->dval = n->fconst;
- break;
- }
- a->type = D_CONST;
- a->offset = n->vconst;
- break;
-
- case OADD:
- l = n->left;
- if(l->addable == 20) {
- v = l->vconst;
- naddr(n->right, a, x);
- goto add;
- }
- l = n->right;
- if(l->addable == 20) {
- v = l->vconst;
- naddr(n->left, a, x);
- goto add;
- }
- goto bad;
-
- noadd:
- v = 0;
- add:
- switch(n->addable) {
- default:
- goto bad;
- case 2:
- a->displace += v;
- break;
- case 21:
- a->type &= D_MASK;
- a->type |= I_INDIR;
- break;
- case 1:
- case 12:
- a->offset += v;
- a->type &= D_MASK;
- a->type |= I_ADDR;
- break;
- case 10:
- case 11:
- case 20:
- a->type &= D_MASK;
- a->type |= I_DIR;
- break;
- }
- break;
-
- case OPREINC:
- case OPREDEC:
- case OPOSTINC:
- case OPOSTDEC:
-
- case OAS:
- case OASLMUL:
- case OASLDIV:
- case OASLMOD:
- case OASMUL:
- case OASDIV:
- case OASMOD:
- case OASXOR:
- case OASOR:
- case OASADD:
- case OASSUB:
- case OASLSHR:
- case OASASHR:
- case OASASHL:
- case OASAND:
- naddr(n->left, a, x);
- break;
- }
-}
-
-int
-regalloc(Type *t, int g)
-{
-
- if(t == T)
- return D_NONE;
- g &= D_MASK;
- if(typefd[t->etype]) {
- if(g >= D_F0 && g < D_F0+NREG) {
- fregused[g-D_F0]++;
- return g;
- }
- for(g=0; g<NREG; g++)
- if(fregused[g] == 0) {
- fregused[g]++;
- return g + D_F0;
- }
- } else {
- if(g >= D_R0 && g < D_R0+NREG) {
- regused[g-D_R0]++;
- return g;
- }
- for(g=0; g<NREG; g++)
- if(regused[g] == 0) {
- regused[g]++;
- return g + D_R0;
- }
- }
- diag(Z, "out of registers");
- return D_TOS;
-}
-
-int
-regaddr(int g)
-{
-
- if(g >= D_A0 && g < D_A0+NREG) {
- aregused[g-D_A0]++;
- return g;
- }
- for(g=0; g<NREG; g++)
- if(aregused[g] == 0) {
- aregused[g]++;
- return g + D_A0;
- }
- diag(Z, "out of addr registers");
- return D_TOS;
-}
-
-int
-regpair(int g)
-{
-
- if(g >= D_R0+1 && g < D_R0+NREG)
- if(!regused[g-D_R0-1]) {
- regused[g-D_R0-1]++;
- regused[g-D_R0]++;
- return g-1;
- }
- if(g >= D_R0 && g < D_R0+NREG-1)
- if(!regused[g-D_R0+1]) {
- regused[g-D_R0+1]++;
- regused[g-D_R0]++;
- return g;
- }
- for(g = 0; g < NREG-1; g++)
- if(!regused[g])
- if(!regused[g+1]) {
- regused[g]++;
- regused[g+1]++;
- return g + D_R0;
- }
- diag(Z, "out of register pairs");
- return D_TOS;
-}
-
-int
-regret(Type *t)
-{
-
- if(t == T)
- return D_NONE;
- if(typefd[t->etype])
- return D_F0;
- return D_R0;
-}
-
-void
-regfree(int g)
-{
-
- g &= D_MASK;
- if(g == D_TOS || g == D_TREE || g == D_NONE)
- return;
- if(g >= D_R0 && g < D_R0+NREG) {
- regused[g-D_R0]--;
- return;
- }
- if(g >= D_A0 && g < D_A0+NREG) {
- aregused[g-D_A0]--;
- return;
- }
- if(g >= D_F0 && g < D_F0+NREG) {
- fregused[g-D_F0]--;
- return;
- }
- diag(Z, "bad in regfree: %d", g);
-}
-
-void
-gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t)
-{
- int g, a, b;
- Prog *p1;
-
- tindex(tf, tt);
- if(txtp->preclr) {
- if(gf >= D_R0 && gf < D_R0+NREG)
- if(txtp->preclr < 0) {
- gmove(tt, tt, gf, f, gt, t);
- return;
- }
- g = regalloc(types[TLONG], gt);
- if(g == gf) {
- g = regalloc(types[TLONG], D_NONE);
- regfree(gf);
- }
- if(txtp->preclr > 0)
- gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z);
- gopcode(OAS, tf, gf, f, g, Z);
- if(g != gt)
- gopcode(OAS, tt, g, Z, gt, t);
- regfree(g);
- return;
- }
- a = txtp->postext;
- if(a != AGOK) {
- if(gf >= D_R0 && gf < D_R0+NREG)
- g = regalloc(types[TLONG], gf);
- else
- g = regalloc(types[TLONG], gt);
- if(g != gf)
- gopcode(OAS, tf, gf, f, g, Z);
- nextpc();
- p->as = a;
- p->to.type = g;
- if(debug['g'])
- print("%P\n", p);
- if(g != gt)
- gopcode(OAS, tt, g, Z, gt, t);
- regfree(g);
- return;
- }
- if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) ||
- (gf == D_TREE && gt == D_TREE && f == t))
- return;
- if(typefd[tf->etype] || typefd[tt->etype]) {
- if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */
- a = regalloc(types[TLONG], D_NONE);
- gmove(tf, types[TLONG], gf, f, a, t);
- if(tf->etype == TULONG) {
- b = regalloc(types[TDOUBLE], D_NONE);
- gmove(types[TLONG], tt, a, t, b, t);
- gopcode(OTST, types[TLONG], D_NONE, Z, a, t);
- gbranch(OGE);
- p1 = p;
- gopcode(OASADD, types[TDOUBLE],
- D_CONST, nodconst(100), b, t);
- p->from.dval = 4294967296.;
- patch(p1, pc);
- gmove(types[TDOUBLE], tt, b, t, gt, t);
- regfree(b);
- } else
- gmove(types[TLONG], tt, a, t, gt, t);
- regfree(a);
- return;
- }
- if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
- a = regalloc(types[TLONG], D_NONE);
- gopcode(OAS, types[TLONG], D_FPCR, t, a, t);
- gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t);
- }
- if(gf < D_F0 || gf >= D_F0+NREG) {
- g = regalloc(types[TDOUBLE], gt);
- gopcode(OFAS, tf, gf, f, g, t);
- if(g != gt)
- gopcode(OFAS, tt, g, t, gt, t);
- regfree(g);
- } else
- gopcode(OFAS, tt, gf, f, gt, t);
- if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
- gopcode(OAS, types[TLONG], a, t, D_FPCR, t);
- regfree(a);
- }
- return;
- }
- gopcode(OAS, tt, gf, f, gt, t);
-}
-
-void
-gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t)
-{
- int i, fidx, tidx;
-
- if(o == OAS)
- if(gf == gt)
- if(gf != D_TREE || f == t)
- return;
-
- fidx = D_NONE;
- tidx = D_NONE;
- i = 0;
- if(ty != T) {
- i = ty->etype;
- if(i >= NTYPE)
- i = 0;
- }
- nextpc();
- if(gf == D_TREE) {
- naddr(f, &p->from, fidx);
- } else {
- p->from.type = gf;
- if(gf == D_CONST) {
- p->from.offset = (long)(uintptr)f;
- if(typefd[i]) {
- p->from.type = D_FCONST;
- p->from.dval = (long)(uintptr)f;
- }
- }
- }
- p->as = opxt[o][i];
- if(gt == D_TREE) {
- naddr(t, &p->to, tidx);
- } else {
- p->to.type = gt;
- if(gt == D_CONST)
- p->to.offset = (long)(uintptr)t;
- }
- if(o == OBIT) {
- p->from.field = f->type->nbits;
- p->to.field = f->type->shift;
- if(p->from.field == 0)
- diag(Z, "BIT zero width bit field");
- }
- if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB)
- asopt();
- if(debug['g'])
- print("%P\n", p);
- if(p->as == AGOK)
- diag(Z, "GOK in gopcode: %s", onames[o]);
- if(fidx != D_NONE)
- regfree(fidx);
- if(tidx != D_NONE)
- regfree(tidx);
-}
-
-void
-asopt(void)
-{
- long v;
- int g;
- Prog *q;
-
- /*
- * mov $0, ...
- * ==>
- * clr , ...
- */
- v = 0;
- if(p->from.type == D_CONST) {
- v = p->from.offset;
- if(v == 0) {
- p->from.type = D_NONE;
- if(p->as == AMOVL)
- p->as = ACLRL;
- if(p->as == AMOVW)
- p->as = ACLRW;
- if(p->as == AMOVB)
- p->as = ACLRB;
- return;
- }
- }
- /*
- * mov ..., TOS
- * ==>
- * pea (...)
- */
- if(p->as == AMOVL && p->to.type == D_TOS)
- switch(p->from.type) {
- case D_CONST:
- p->from.type |= I_INDIR;
- p->to = p->from;
- p->from = zprog.from;
- p->as = APEA;
- return;
-
- case I_ADDR|D_EXTERN:
- case I_ADDR|D_STATIC:
- p->from.type &= ~I_ADDR;
- p->to = p->from;
- p->from = zprog.from;
- p->as = APEA;
- return;
- }
- /*
- * movL $Qx, ...
- * ==>
- * movL $Qx,R
- * movL R, ...
- */
- if(p->as == AMOVL && p->from.type == D_CONST)
- if(v >= -128 && v < 128)
- if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) {
- g = regalloc(types[TLONG], D_NONE);
- q = p;
- nextpc();
- p->as = AMOVL;
- p->from.type = g;
- p->to = q->to;
- q->to = p->from;
- regfree(g);
- if(debug['g'])
- print("%P\n", q);
- return;
- }
-}
-
-void
-gbranch(int o)
-{
- int a;
-
- a = ABNE;
- switch(o) {
- case ORETURN: a = ARTS; break;
- case OGOTO: a = ABRA; break;
- case OEQ: a = ABEQ; break;
- case ONE: a = ABNE; break;
- case OLE: a = ABLE; break;
- case OLS: a = ABLS; break;
- case OLT: a = ABLT; break;
- case OLO: a = ABCS; break;
- case OGE: a = ABGE; break;
- case OHS: a = ABCC; break;
- case OGT: a = ABGT; break;
- case OHI: a = ABHI; break;
- case OBIT: a = ABCS; break;
- case OCASE: a = ABCASE; break;
- }
- nextpc();
- p->from.type = D_NONE;
- p->to.type = D_NONE;
- p->as = a;
-}
-
-void
-fpbranch(void)
-{
- int a;
-
- a = p->as;
- switch(a) {
- case ABEQ: a = AFBEQ; break;
- case ABNE: a = AFBNE; break;
- case ABLE: a = AFBLE; break;
- case ABLT: a = AFBLT; break;
- case ABGE: a = AFBGE; break;
- case ABGT: a = AFBGT; break;
- }
- p->as = a;
-}
-
-void
-patch(Prog *op, long pc)
-{
-
- op->to.offset = pc;
- op->to.type = D_BRANCH;
-}
-
-void
-gpseudo(int a, Sym *s, int g, long v)
-{
-
- nextpc();
- if(a == ADATA)
- pc--;
- p->as = a;
- p->to.type = g;
- p->to.offset = v;
- p->from.sym = s;
- p->from.type = D_EXTERN;
- if(s->class == CSTATIC)
- p->from.type = D_STATIC;
-}
-
-void
-gpseudotree(int a, Sym *s, Node *n)
-{
-
- nextpc();
- if(a == ADATA)
- pc--;
- p->as = a;
- naddr(n, &p->to, D_NONE);
- p->from.sym = s;
- p->from.type = D_EXTERN;
- if(s->class == CSTATIC)
- p->from.type = D_STATIC;
-}
-
-long
-exreg(Type *t)
-{
- long o;
-
- if(typechl[t->etype]) {
- if(exregoffset <= 5)
- return 0;
- o = exregoffset + D_R0;
- exregoffset--;
- return o;
- }
- if(t->etype == TIND) {
- if(exaregoffset <= 3)
- return 0;
- o = exaregoffset + D_A0;
- exaregoffset--;
- return o;
- }
- if(typefd[t->etype]) {
- if(exfregoffset <= 5)
- return 0;
- o = exfregoffset + D_F0;
- exfregoffset--;
- return o;
- }
- return 0;
-}
-
-schar ewidth[NTYPE] =
-{
- -1, /* [TXXX] */
- SZ_CHAR, /* [TCHAR] */
- SZ_CHAR, /* [TUCHAR] */
- SZ_SHORT, /* [TSHORT] */
- SZ_SHORT, /* [TUSHORT] */
- SZ_INT, /* [TINT] */
- SZ_INT, /* [TUINT] */
- SZ_LONG, /* [TLONG] */
- SZ_LONG, /* [TULONG] */
- SZ_VLONG, /* [TVLONG] */
- SZ_VLONG, /* [TUVLONG] */
- SZ_FLOAT, /* [TFLOAT] */
- SZ_DOUBLE, /* [TDOUBLE] */
- SZ_IND, /* [TIND] */
- 0, /* [TFUNC] */
- -1, /* [TARRAY] */
- 0, /* [TVOID] */
- -1, /* [TSTRUCT] */
- -1, /* [TUNION] */
- SZ_INT, /* [TENUM] */
-};
-long ncast[NTYPE] =
-{
- 0, /* [TXXX] */
- BCHAR|BUCHAR, /* [TCHAR] */
- BCHAR|BUCHAR, /* [TUCHAR] */
- BSHORT|BUSHORT, /* [TSHORT] */
- BSHORT|BUSHORT, /* [TUSHORT] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
- BVLONG|BUVLONG, /* [TVLONG] */
- BVLONG|BUVLONG, /* [TUVLONG] */
- BFLOAT, /* [TFLOAT] */
- BDOUBLE, /* [TDOUBLE] */
- BLONG|BULONG|BIND, /* [TIND] */
- 0, /* [TFUNC] */
- 0, /* [TARRAY] */
- 0, /* [TVOID] */
- BSTRUCT, /* [TSTRUCT] */
- BUNION, /* [TUNION] */
- 0, /* [TENUM] */
-};