summaryrefslogtreecommitdiff
path: root/sys/src/cmd/7c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-05-04 16:11:48 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2016-05-04 16:11:48 +0200
commit986886f2b8ab4a7e1b3d66e99934d8fdab537be9 (patch)
treec49e9711e7229a8d12f5b5b0ab38b5bd6c27b711 /sys/src/cmd/7c
parentf7703d6971383c39f981f5676a4e28a6371c3997 (diff)
retire the dec alpha port
Diffstat (limited to 'sys/src/cmd/7c')
-rw-r--r--sys/src/cmd/7c/7.out.h265
-rw-r--r--sys/src/cmd/7c/cgen.c1067
-rw-r--r--sys/src/cmd/7c/enam.c165
-rw-r--r--sys/src/cmd/7c/gc.h343
-rw-r--r--sys/src/cmd/7c/list.c231
-rw-r--r--sys/src/cmd/7c/machcap.c9
-rw-r--r--sys/src/cmd/7c/mkenam15
-rw-r--r--sys/src/cmd/7c/mkfile39
-rw-r--r--sys/src/cmd/7c/mul.c608
-rw-r--r--sys/src/cmd/7c/peep.c759
-rw-r--r--sys/src/cmd/7c/reg.c1164
-rw-r--r--sys/src/cmd/7c/sgen.c235
-rw-r--r--sys/src/cmd/7c/swt.c578
-rw-r--r--sys/src/cmd/7c/txt.c1306
14 files changed, 0 insertions, 6784 deletions
diff --git a/sys/src/cmd/7c/7.out.h b/sys/src/cmd/7c/7.out.h
deleted file mode 100644
index 061890206..000000000
--- a/sys/src/cmd/7c/7.out.h
+++ /dev/null
@@ -1,265 +0,0 @@
-#define NSNAME 8
-#define NSYM 50
-#define NREG 32
-#define NOPROF (1<<0)
-#define DUPOK (1<<1)
-
-enum
-{
- REGRET = 0, /* return register and first temp, grows++ */
- REGARG = 0, /* first arg passed in */
- REGEXT = 15, /* first external register, grows-- */
-
- REGLINK = 26, /* subroutine linkage */
- REGTMP = 27, /* used by the loader */
- REGTMP2 = 28, /* used by the loader */
- REGSB = 29, /* static pointer */
- REGSP = 30, /* stack pointer */
- REGZERO = 31, /* always zero */
-
- FREGRET = 0,
- FREGEXT = 27, /* first external register */
- FREGHALF = 28, /* double */
- FREGONE = 29, /* double */
- FREGTWO = 30, /* double */
- FREGZERO = 31, /* both float and double */
-};
-
-enum as
-{
- AXXX,
- AGOK,
- ATEXT,
- ADATA,
- AGLOBL,
- AHISTORY,
- ANAME,
- AWORD,
-
- ANOP,
-
- AMOVL,
- AMOVLU,
- AMOVQ,
- AMOVQU,
- AMOVS,
- AMOVT,
-
- AMOVB,
- AMOVBU,
- AMOVW,
- AMOVWU,
-
- AMOVA,
- AMOVAH,
-
- AMOVLL,
- AMOVQL,
- AMOVLC,
- AMOVQC,
-
- AMOVQP,
- AMOVLP,
-
- AADDL,
- AADDLV,
- AADDQ,
- AADDQV,
- AS4ADDL,
- AS4ADDQ,
- AS8ADDL,
- AS8ADDQ,
- AS4SUBL,
- AS4SUBQ,
- AS8SUBL,
- AS8SUBQ,
- ASUBL,
- ASUBLV,
- ASUBQ,
- ASUBQV,
-
- ACMPEQ,
- ACMPGT,
- ACMPGE,
- ACMPUGT,
- ACMPUGE,
- ACMPBLE,
-
- AAND,
- AANDNOT,
- AOR,
- AORNOT,
- AXOR,
- AXORNOT,
-
- ACMOVEQ,
- ACMOVNE,
- ACMOVLT,
- ACMOVGE,
- ACMOVLE,
- ACMOVGT,
- ACMOVLBC,
- ACMOVLBS,
-
- AMULL,
- AMULQ,
- AMULLV,
- AMULQV,
- AUMULH,
- ADIVQ,
- AMODQ,
- ADIVQU,
- AMODQU,
- ADIVL,
- AMODL,
- ADIVLU,
- AMODLU,
-
- ASLLQ,
- ASRLQ,
- ASRAQ,
- ASLLL,
- ASRLL,
- ASRAL,
-
- AEXTBL,
- AEXTWL,
- AEXTLL,
- AEXTQL,
- AEXTWH,
- AEXTLH,
- AEXTQH,
-
- AINSBL,
- AINSWL,
- AINSLL,
- AINSQL,
- AINSWH,
- AINSLH,
- AINSQH,
-
- AMSKBL,
- AMSKWL,
- AMSKLL,
- AMSKQL,
- AMSKWH,
- AMSKLH,
- AMSKQH,
-
- AZAP,
- AZAPNOT,
-
- AJMP,
- AJSR,
- ARET,
-
- ABR,
- ABSR,
-
- ABEQ,
- ABNE,
- ABLT,
- ABGE,
- ABLE,
- ABGT,
- ABLBC,
- ABLBS,
-
- AFBEQ,
- AFBNE,
- AFBLT,
- AFBGE,
- AFBLE,
- AFBGT,
-
- ATRAPB,
- AMB,
- AFETCH,
- AFETCHM,
- ARPCC,
-
- ACPYS,
- ACPYSN,
- ACPYSE,
- ACVTLQ,
- ACVTQL,
- AFCMOVEQ,
- AFCMOVNE,
- AFCMOVLT,
- AFCMOVGE,
- AFCMOVLE,
- AFCMOVGT,
-
- AADDS,
- AADDT,
- ACMPTEQ,
- ACMPTGT,
- ACMPTGE,
- ACMPTUN,
- ACVTQS,
- ACVTQT,
- ACVTTS,
- ACVTTQ,
- ADIVS,
- ADIVT,
- AMULS,
- AMULT,
- ASUBS,
- ASUBT,
-
- ACALL_PAL,
- AREI,
-
- AEND,
-
- ADYNT,
- AINIT,
-
- ASIGNAME,
-
- ALAST,
-};
-
-/* type/name */
-enum
-{
- D_GOK = 0,
- D_NONE,
-
-/* name */
- D_EXTERN,
- D_STATIC,
- D_AUTO,
- D_PARAM,
-
-/* type */
- D_BRANCH,
- D_OREG,
- D_CONST,
- D_FCONST,
- D_SCONST,
- D_REG,
- D_FREG,
- D_FCREG,
- D_PREG,
- D_PCC,
- D_FILE,
- D_FILE1,
-};
-
-/*
- * this is the ranlib header
- */
-#define SYMDEF "__.SYMDEF"
-
-/*
- * this is the simulated IEEE floating point
- */
-typedef struct ieee Ieee;
-struct ieee
-{
- long l; /* contains ls-man 0xffffffff */
- long h; /* contains sign 0x80000000
- exp 0x7ff00000
- ms-man 0x000fffff */
-};
diff --git a/sys/src/cmd/7c/cgen.c b/sys/src/cmd/7c/cgen.c
deleted file mode 100644
index f2733a8aa..000000000
--- a/sys/src/cmd/7c/cgen.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-#include "gc.h"
-
-void
-cgen(Node *n, Node *nn)
-{
- Node *l, *r;
- Prog *p1;
- Node nod, nod1, nod2, nod3, nod4;
- int o;
- long v, curs;
-
- if(debug['g']) {
- prtree(nn, "cgen lhs");
- prtree(n, "cgen");
- }
- if(n == Z || n->type == T)
- return;
- if(typesu[n->type->etype]) {
- sugen(n, nn, n->type->width);
- return;
- }
- l = n->left;
- r = n->right;
- o = n->op;
- if(n->addable >= INDEXED) {
- if(nn == Z) {
- switch(o) {
- default:
- nullwarn(Z, Z);
- break;
- case OINDEX:
- nullwarn(l, r);
- break;
- }
- return;
- }
- gmove(n, nn);
- return;
- }
- curs = cursafe;
-
- if(n->complex >= FNX)
- if(l->complex >= FNX)
- if(r != Z && r->complex >= FNX)
- switch(o) {
- default:
- regret(&nod, r);
- cgen(r, &nod);
-
- regsalloc(&nod1, r);
- gopcode(OAS, &nod, Z, &nod1);
-
- regfree(&nod);
- nod = *n;
- nod.right = &nod1;
- cgen(&nod, nn);
- return;
-
- case OFUNC:
- case OCOMMA:
- case OANDAND:
- case OOROR:
- case OCOND:
- case ODOT:
- break;
- }
-
- switch(o) {
- default:
- diag(n, "unknown op in cgen: %O", o);
- break;
-
- case OAS:
- if(l->op == OBIT)
- goto bitas;
- if(l->addable >= INDEXED && l->complex < FNX) {
- if(nn != Z || r->addable < INDEXED) {
- regalloc(&nod, r, nn);
- cgen(r, &nod);
- gmove(&nod, l);
- regfree(&nod);
- } else
- gmove(r, l);
- break;
- }
- if(l->complex >= r->complex) {
- reglcgen(&nod1, l, Z);
- if(r->addable >= INDEXED) {
- gmove(r, &nod1);
- if(nn != Z)
- gmove(r, nn);
- regfree(&nod1);
- break;
- }
- regalloc(&nod, r, nn);
- cgen(r, &nod);
- } else {
- regalloc(&nod, r, nn);
- cgen(r, &nod);
- reglcgen(&nod1, l, Z);
- }
- gmove(&nod, &nod1);
- regfree(&nod);
- regfree(&nod1);
- break;
-
- bitas:
- n = l->left;
- regalloc(&nod, r, nn);
- if(l->complex >= r->complex) {
- reglcgen(&nod1, n, Z);
- cgen(r, &nod);
- } else {
- cgen(r, &nod);
- reglcgen(&nod1, n, Z);
- }
- regalloc(&nod2, n, Z);
- gopcode(OAS, &nod1, Z, &nod2);
- bitstore(l, &nod, &nod1, &nod2, nn);
- break;
-
- case OBIT:
- if(nn == Z) {
- nullwarn(l, Z);
- break;
- }
- bitload(n, &nod, Z, Z, nn);
- gopcode(OAS, &nod, Z, nn);
- regfree(&nod);
- break;
-
- case OADD:
- case OSUB:
- case OAND:
- case OOR:
- case OXOR:
- case OLSHR:
- case OASHL:
- case OASHR:
- case OLDIV:
- case OLMOD:
- case ODIV:
- case OMOD:
- case OMUL:
- case OLMUL:
- /*
- * immediate operands
- */
- if(nn != Z)
- if(r->op == OCONST)
- if(!typefd[n->type->etype]) {
- cgen(l, nn);
- if(r->vconst == 0)
- if(o != OAND)
- break;
- if(nn != Z)
- gopcode(o, r, Z, nn);
- break;
- }
-
- if(nn == Z) {
- nullwarn(l, r);
- break;
- }
-/* if(o == OMUL || o == OLMUL) {
- if(mulcon(n, nn))
- break;
- } */
- if(l->complex >= r->complex) {
- regalloc(&nod, l, nn);
- cgen(l, &nod);
- regalloc(&nod1, l, Z); /* note: l used for type, so shifts work! */
- cgen(r, &nod1);
- gopcode(o, &nod1, Z, &nod);
- } else {
- regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
- cgen(r, &nod);
- regalloc(&nod1, l, Z);
- cgen(l, &nod1);
- gopcode(o, &nod, &nod1, &nod);
- }
- gopcode(OAS, &nod, Z, nn);
- regfree(&nod);
- regfree(&nod1);
- break;
-
- case OASLSHR:
- case OASASHL:
- case OASASHR:
- case OASAND:
- case OASADD:
- case OASSUB:
- case OASXOR:
- case OASOR:
- case OASLDIV:
- case OASLMOD:
- case OASDIV:
- case OASMOD:
- case OASLMUL:
- case OASMUL:
- if(l->op == OBIT)
- goto asbitop;
- if(r->op == OCONST)
- if(!typefd[r->type->etype])
- if(!typefd[n->type->etype]) {
- if(l->addable < INDEXED)
- reglcgen(&nod2, l, Z);
- else
- nod2 = *l;
- regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
- gopcode(OAS, &nod2, Z, &nod);
- gopcode(o, r, Z, &nod);
- gopcode(OAS, &nod, Z, &nod2);
-
- regfree(&nod);
- if(l->addable < INDEXED)
- regfree(&nod2);
- break;
- }
-
- if(l->complex >= r->complex) {
- if(l->addable < INDEXED)
- reglcgen(&nod2, l, Z);
- else
- nod2 = *l;
- regalloc(&nod1, r, Z);
- cgen(r, &nod1);
- } else {
- regalloc(&nod1, r, Z);
- cgen(r, &nod1);
- if(l->addable < INDEXED)
- reglcgen(&nod2, l, Z);
- else
- nod2 = *l;
- }
-
- regalloc(&nod, n, nn);
- gmove(&nod2, &nod);
- if(nod1.type->etype != nod.type->etype){
- regalloc(&nod3, &nod, Z);
- gmove(&nod1, &nod3);
- regfree(&nod1);
- nod1 = nod3;
- }
- gopcode(o, &nod1, Z, &nod);
- gmove(&nod, &nod2);
- if(nn != Z)
- gopcode(OAS, &nod, Z, nn);
- regfree(&nod);
- regfree(&nod1);
- if(l->addable < INDEXED)
- regfree(&nod2);
- break;
-
- asbitop:
- regalloc(&nod4, n, nn);
- if(l->complex >= r->complex) {
- bitload(l, &nod, &nod1, &nod2, &nod4);
- regalloc(&nod3, r, Z);
- cgen(r, &nod3);
- } else {
- regalloc(&nod3, r, Z);
- cgen(r, &nod3);
- bitload(l, &nod, &nod1, &nod2, &nod4);
- }
- gmove(&nod, &nod4);
- gopcode(o, &nod3, Z, &nod4);
- regfree(&nod3);
- gmove(&nod4, &nod);
- regfree(&nod4);
- bitstore(l, &nod, &nod1, &nod2, nn);
- break;
-
- case OADDR:
- if(nn == Z) {
- nullwarn(l, Z);
- break;
- }
- lcgen(l, nn);
- break;
-
- case OFUNC:
- if(l->complex >= FNX) {
- if(l->op != OIND)
- diag(n, "bad function call");
-
- regret(&nod, l->left);
- cgen(l->left, &nod);
- regsalloc(&nod1, l->left);
- gopcode(OAS, &nod, Z, &nod1);
- regfree(&nod);
-
- nod = *n;
- nod.left = &nod2;
- nod2 = *l;
- nod2.left = &nod1;
- nod2.complex = 1;
- cgen(&nod, nn);
-
- return;
- }
- if(REGARG != NREG)
- o = reg[REGARG];
- gargs(r, &nod, &nod1);
- if(l->addable < INDEXED) {
- reglcgen(&nod, l, Z);
- gopcode(OFUNC, Z, Z, &nod);
- regfree(&nod);
- } else
- gopcode(OFUNC, Z, Z, l);
- if(REGARG != NREG)
- if(o != reg[REGARG])
- reg[REGARG]--;
- if(nn != Z) {
- regret(&nod, n);
- gopcode(OAS, &nod, Z, nn);
- regfree(&nod);
- }
- break;
-
- case OIND:
- if(nn == Z) {
- nullwarn(l, Z);
- break;
- }
- regialloc(&nod, n, nn);
- r = l;
- while(r->op == OADD)
- r = r->right;
- if(sconst(r)) {
- v = r->vconst;
- r->vconst = 0;
- cgen(l, &nod);
- nod.xoffset += v;
- r->vconst = v;
- } else
- cgen(l, &nod);
- regind(&nod, n);
- gopcode(OAS, &nod, Z, nn);
- regfree(&nod);
- break;
-
- case OEQ:
- case ONE:
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OLO:
- case OLS:
- case OHI:
- case OHS:
- if(nn == Z) {
- nullwarn(l, r);
- break;
- }
- boolgen(n, 1, nn);
- break;
-
- case OANDAND:
- case OOROR:
- boolgen(n, 1, nn);
- if(nn == Z)
- patch(p, pc);
- break;
-
- case ONOT:
- if(nn == Z) {
- nullwarn(l, Z);
- break;
- }
- boolgen(n, 1, nn);
- break;
-
- case OCOMMA:
- cgen(l, Z);
- cgen(r, nn);
- break;
-
- case OCAST:
- if(nn == Z) {
- nullwarn(l, Z);
- break;
- }
- /*
- * convert from types l->n->nn
- */
- if(nocast(l->type, n->type)) {
- if(nocast(n->type, nn->type)) {
- cgen(l, nn);
- break;
- }
- }
- regalloc(&nod, l, nn);
- cgen(l, &nod);
- regalloc(&nod1, n, &nod);
- gopcode(OAS, &nod, Z, &nod1);
- gopcode(OAS, &nod1, Z, nn);
- regfree(&nod1);
- regfree(&nod);
- break;
-
- case ODOT:
- sugen(l, nodrat, l->type->width);
- if(nn != Z) {
- warn(n, "non-interruptable temporary");
- nod = *nodrat;
- if(!r || r->op != OCONST) {
- diag(n, "DOT and no offset");
- break;
- }
- nod.xoffset += (long)r->vconst;
- nod.type = n->type;
- cgen(&nod, nn);
- }
- break;
-
- case OCOND:
- bcgen(l, 1);
- p1 = p;
- cgen(r->left, nn);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
- cgen(r->right, nn);
- patch(p1, pc);
- 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;
-
- if(l->addable < INDEXED)
- reglcgen(&nod2, l, Z);
- else
- nod2 = *l;
-
- regalloc(&nod, l, nn);
- gopcode(OAS, &nod2, Z, &nod);
- regalloc(&nod1, l, Z);
- if(typefd[l->type->etype]) {
- regalloc(&nod3, l, Z);
- if(v < 0) {
- gopcode(OAS, nodfconst(-v), Z, &nod3);
- gopcode(OSUB, &nod3, &nod, &nod1);
- } else {
- gopcode(OAS, nodfconst(v), Z, &nod3);
- gopcode(OADD, &nod3, &nod, &nod1);
- }
- regfree(&nod3);
- } else
- gopcode(OADD, nodconst(v), &nod, &nod1);
- gopcode(OAS, &nod1, Z, &nod2);
-
- regfree(&nod);
- regfree(&nod1);
- if(l->addable < INDEXED)
- regfree(&nod2);
- 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:
- if(l->addable < INDEXED)
- reglcgen(&nod2, l, Z);
- else
- nod2 = *l;
-
- regalloc(&nod, l, nn);
- gopcode(OAS, &nod2, Z, &nod);
- if(typefd[l->type->etype]) {
- regalloc(&nod3, l, Z);
- if(v < 0) {
- gopcode(OAS, nodfconst(-v), Z, &nod3);
- gopcode(OSUB, &nod3, Z, &nod);
- } else {
- gopcode(OAS, nodfconst(v), Z, &nod3);
- gopcode(OADD, &nod3, Z, &nod);
- }
- regfree(&nod3);
- } else
- gopcode(OADD, nodconst(v), Z, &nod);
- gopcode(OAS, &nod, Z, &nod2);
- if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
- gins(ANOP, l, Z);
-
- regfree(&nod);
- if(l->addable < INDEXED)
- regfree(&nod2);
- break;
-
- bitinc:
- if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
- bitload(l, &nod, &nod1, &nod2, Z);
- gopcode(OAS, &nod, Z, nn);
- gopcode(OADD, nodconst(v), Z, &nod);
- bitstore(l, &nod, &nod1, &nod2, Z);
- break;
- }
- bitload(l, &nod, &nod1, &nod2, nn);
- gopcode(OADD, nodconst(v), Z, &nod);
- bitstore(l, &nod, &nod1, &nod2, nn);
- break;
- }
- cursafe = curs;
- return;
-}
-
-void
-reglcgen(Node *t, Node *n, Node *nn)
-{
- Node *r;
- long v;
-
- regialloc(t, n, nn);
- if(n->op == OIND) {
- r = n->left;
- while(r->op == OADD)
- r = r->right;
- if(sconst(r)) {
- v = r->vconst;
- r->vconst = 0;
- lcgen(n, t);
- t->xoffset += v;
- r->vconst = v;
- regind(t, n);
- return;
- }
- }
- lcgen(n, t);
- regind(t, n);
-}
-
-void
-lcgen(Node *n, Node *nn)
-{
- Prog *p1;
- Node nod;
-
- if(debug['g']) {
- prtree(nn, "lcgen lhs");
- prtree(n, "lcgen");
- }
- if(n == Z || n->type == T)
- return;
- if(nn == Z) {
- nn = &nod;
- regalloc(&nod, n, Z);
- }
- switch(n->op) {
- default:
- if(n->addable < INDEXED) {
- diag(n, "unknown op in lcgen: %O", n->op);
- break;
- }
- nod = *n;
- nod.op = OADDR;
- nod.left = n;
- nod.right = Z;
- nod.type = types[TIND];
- gopcode(OAS, &nod, Z, nn);
- break;
-
- case OCOMMA:
- cgen(n->left, n->left);
- lcgen(n->right, nn);
- break;
-
- case OIND:
- cgen(n->left, nn);
- break;
-
- case OCOND:
- bcgen(n->left, 1);
- p1 = p;
- lcgen(n->right->left, nn);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
- lcgen(n->right->right, nn);
- patch(p1, pc);
- break;
- }
-}
-
-void
-bcgen(Node *n, int true)
-{
-
- if(n->type == T)
- gbranch(OGOTO);
- else
- boolgen(n, true, Z);
-}
-
-void
-boolgen(Node *n, int true, Node *nn)
-{
- int o;
- Prog *p1, *p2;
- Node *l, *r, nod, nod1;
- long curs;
-
- if(debug['g']) {
- prtree(nn, "boolgen lhs");
- prtree(n, "boolgen");
- }
- curs = cursafe;
- l = n->left;
- r = n->right;
- switch(n->op) {
-
- default:
- regalloc(&nod, n, nn);
- cgen(n, &nod);
- o = ONE;
- if(true)
- o = comrel[relindex(o)];
- if(typefd[n->type->etype]) {
- nodreg(&nod1, n, NREG+FREGZERO);
- gopcode(o, &nod, Z, &nod1);
- } else
- gopcode(o, &nod, Z, nodconst(0));
- regfree(&nod);
- goto com;
-
- case OCONST:
- o = vconst(n);
- if(!true)
- o = !o;
- gbranch(OGOTO);
- if(o) {
- p1 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- }
- goto com;
-
- case OCOMMA:
- cgen(l, Z);
- boolgen(r, true, nn);
- break;
-
- case ONOT:
- boolgen(l, !true, nn);
- break;
-
- case OCOND:
- bcgen(l, 1);
- p1 = p;
- bcgen(r->left, true);
- p2 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
- bcgen(r->right, !true);
- patch(p2, pc);
- p2 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- patch(p2, pc);
- goto com;
-
- case OANDAND:
- if(!true)
- goto caseor;
-
- caseand:
- bcgen(l, true);
- p1 = p;
- bcgen(r, !true);
- p2 = p;
- patch(p1, pc);
- gbranch(OGOTO);
- patch(p2, pc);
- goto com;
-
- case OOROR:
- if(!true)
- goto caseand;
-
- caseor:
- bcgen(l, !true);
- p1 = p;
- bcgen(r, !true);
- p2 = p;
- gbranch(OGOTO);
- patch(p1, pc);
- patch(p2, pc);
- goto com;
-
- case OEQ:
- case ONE:
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OHI:
- case OHS:
- case OLO:
- case OLS:
- o = n->op;
- if(true)
- o = comrel[relindex(o)];
- if(l->complex >= FNX && r->complex >= FNX) {
- regret(&nod, r);
- cgen(r, &nod);
- regsalloc(&nod1, r);
- gopcode(OAS, &nod, Z, &nod1);
- regfree(&nod);
- nod = *n;
- nod.right = &nod1;
- boolgen(&nod, true, nn);
- break;
- }
- if(bconst(r)) {
- regalloc(&nod, l, nn);
- cgen(l, &nod);
- gopcode(o, &nod, Z, r);
- regfree(&nod);
- goto com;
- }
- if(l->complex >= r->complex) {
- regalloc(&nod1, l, nn);
- cgen(l, &nod1);
- regalloc(&nod, r, Z);
- cgen(r, &nod);
- } else {
- regalloc(&nod, r, nn);
- cgen(r, &nod);
- regalloc(&nod1, l, Z);
- cgen(l, &nod1);
- }
- gopcode(o, &nod1, Z, &nod);
- regfree(&nod);
- regfree(&nod1);
-
- com:
- if(nn != Z) {
- p1 = p;
- gopcode(OAS, nodconst(1), Z, nn);
- gbranch(OGOTO);
- p2 = p;
- patch(p1, pc);
- gopcode(OAS, nodconst(0), Z, nn);
- patch(p2, pc);
- }
- break;
- }
- cursafe = curs;
-}
-
-void
-sugen(Node *n, Node *nn, long w)
-{
- Prog *p1;
- Node nod0, nod1, nod2, nod3, nod4, *l, *r;
- Type *t;
- long pc1;
- int i, m, c;
-
- if(n == Z || n->type == T)
- return;
- if(debug['g']) {
- prtree(nn, "sugen lhs");
- prtree(n, "sugen");
- }
- if(nn == nodrat)
- if(w > nrathole)
- nrathole = w;
- switch(n->op) {
- case OIND:
- if(nn == Z) {
- nullwarn(n->left, Z);
- break;
- }
-
- default:
- goto copy;
-
- case ODOT:
- l = n->left;
- sugen(l, nodrat, l->type->width);
- if(nn != Z) {
- warn(n, "non-interruptable temporary");
- nod1 = *nodrat;
- r = n->right;
- if(!r || r->op != OCONST) {
- diag(n, "DOT and no offset");
- break;
- }
- nod1.xoffset += (long)r->vconst;
- nod1.type = n->type;
- sugen(&nod1, nn, w);
- }
- break;
-
- case OSTRUCT:
- /*
- * rewrite so lhs has no fn call
- */
- if(nn != Z && nn->complex >= FNX) {
- nod1 = *n;
- nod1.type = typ(TIND, n->type);
- regret(&nod2, &nod1);
- lcgen(nn, &nod2);
- regsalloc(&nod0, &nod1);
- gopcode(OAS, &nod2, Z, &nod0);
- regfree(&nod2);
-
- nod1 = *n;
- nod1.op = OIND;
- nod1.left = &nod0;
- nod1.right = Z;
- nod1.complex = 1;
-
- sugen(n, &nod1, w);
- return;
- }
-
- 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;
- }
- if(nn == Z) {
- cgen(l, nn);
- continue;
- }
- /*
- * hand craft *(&nn + o) = l
- */
- nod0 = znode;
- nod0.op = OAS;
- nod0.type = t;
- nod0.left = &nod1;
- nod0.right = l;
-
- nod1 = znode;
- nod1.op = OIND;
- nod1.type = t;
- nod1.left = &nod2;
-
- nod2 = znode;
- nod2.op = OADD;
- nod2.type = typ(TIND, t);
- nod2.left = &nod3;
- nod2.right = &nod4;
-
- nod3 = znode;
- nod3.op = OADDR;
- nod3.type = nod2.type;
- nod3.left = nn;
-
- nod4 = znode;
- nod4.op = OCONST;
- nod4.type = nod2.type;
- nod4.vconst = t->offset;
-
- ccom(&nod0);
- acom(&nod0);
- xcom(&nod0);
- nod0.addable = 0;
-
- /* prtree(&nod0, "hand craft"); /* */
- cgen(&nod0, Z);
- }
- break;
-
- case OAS:
- if(nn == Z) {
- if(n->addable < INDEXED)
- sugen(n->right, n->left, w);
- break;
- }
- sugen(n->right, nodrat, w);
- warn(n, "non-interruptable temporary");
- sugen(nodrat, n->left, w);
- sugen(nodrat, nn, w);
- break;
-
- case OFUNC:
- if(nn == Z) {
- sugen(n, nodrat, w);
- break;
- }
- if(nn->op != OIND) {
- nn = new1(OADDR, nn, Z);
- nn->type = types[TIND];
- nn->addable = 0;
- } else
- nn = nn->left;
- n = new(OFUNC, n->left, new(OLIST, nn, n->right));
- n->type = types[TVOID];
- n->left->type = types[TVOID];
- cgen(n, Z);
- break;
-
- case OCOND:
- bcgen(n->left, 1);
- p1 = p;
- sugen(n->right->left, nn, w);
- gbranch(OGOTO);
- patch(p1, pc);
- p1 = p;
- sugen(n->right->right, nn, w);
- patch(p1, pc);
- break;
-
- case OCOMMA:
- cgen(n->left, Z);
- sugen(n->right, nn, w);
- break;
- }
- return;
-
-copy:
- if(nn == Z)
- return;
- if(n->complex >= FNX && nn->complex >= FNX) {
- t = nn->type;
- nn->type = types[TLONG];
- regialloc(&nod1, nn, Z);
- lcgen(nn, &nod1);
- regsalloc(&nod2, nn);
- nn->type = t;
-
- gopcode(OAS, &nod1, Z, &nod2);
- regfree(&nod1);
-
- nod2.type = typ(TIND, t);
-
- nod1 = nod2;
- nod1.op = OIND;
- nod1.left = &nod2;
- nod1.right = Z;
- nod1.complex = 1;
- nod1.type = t;
-
- sugen(n, &nod1, w);
- return;
- }
-
- if(n->complex > nn->complex) {
- t = n->type;
- n->type = types[TLONG];
- reglcgen(&nod1, n, Z);
- n->type = t;
-
- t = nn->type;
- nn->type = types[TLONG];
- reglcgen(&nod2, nn, Z);
- nn->type = t;
- } else {
- t = nn->type;
- nn->type = types[TLONG];
- reglcgen(&nod2, nn, Z);
- nn->type = t;
-
- t = n->type;
- n->type = types[TLONG];
- reglcgen(&nod1, n, Z);
- n->type = t;
- }
-
- w /= SZ_LONG;
- if(w <= 5) {
- layout(&nod1, &nod2, w, 0, Z);
- goto out;
- }
-
- /*
- * minimize space for unrolling loop
- * 3,4,5 times. (6 or more is never minimum)
- * if small structure, try 2 also.
- */
- c = 0; /* set */
- m = 100;
- i = 3;
- if(w <= 15)
- i = 2;
- for(; i<=5; i++)
- if(i + w%i <= m) {
- c = i;
- m = c + w%c;
- }
-
- regalloc(&nod3, &regnode, Z);
- layout(&nod1, &nod2, w%c, w/c, &nod3);
-
- pc1 = pc;
- layout(&nod1, &nod2, c, 0, Z);
-
- gopcode(OSUB, nodconst(1), Z, &nod3);
- nod1.op = OREGISTER;
- gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
- nod2.op = OREGISTER;
- gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
-
- gopcode(OGT, &nod3, Z, nodconst(0));
- patch(p, pc1);
-
- regfree(&nod3);
-out:
- regfree(&nod1);
- regfree(&nod2);
-}
-
-void
-layout(Node *f, Node *t, int c, int cv, Node *cn)
-{
- Node t1, t2;
-
- while(c > 3) {
- layout(f, t, 2, 0, Z);
- c -= 2;
- }
-
- regalloc(&t1, &regnode, Z);
- regalloc(&t2, &regnode, Z);
- if(c > 0) {
- gopcode(OAS, f, Z, &t1);
- f->xoffset += SZ_LONG;
- }
- if(cn != Z)
- gopcode(OAS, nodconst(cv), Z, cn);
- if(c > 1) {
- gopcode(OAS, f, Z, &t2);
- f->xoffset += SZ_LONG;
- }
- if(c > 0) {
- gopcode(OAS, &t1, Z, t);
- t->xoffset += SZ_LONG;
- }
- if(c > 2) {
- gopcode(OAS, f, Z, &t1);
- f->xoffset += SZ_LONG;
- }
- if(c > 1) {
- gopcode(OAS, &t2, Z, t);
- t->xoffset += SZ_LONG;
- }
- if(c > 2) {
- gopcode(OAS, &t1, Z, t);
- t->xoffset += SZ_LONG;
- }
- regfree(&t1);
- regfree(&t2);
-}
diff --git a/sys/src/cmd/7c/enam.c b/sys/src/cmd/7c/enam.c
deleted file mode 100644
index 1e4c6a06d..000000000
--- a/sys/src/cmd/7c/enam.c
+++ /dev/null
@@ -1,165 +0,0 @@
-char* anames[] =
-{
- "XXX",
- "GOK",
- "TEXT",
- "DATA",
- "GLOBL",
- "HISTORY",
- "NAME",
- "WORD",
- "NOP",
- "MOVL",
- "MOVLU",
- "MOVQ",
- "MOVQU",
- "MOVS",
- "MOVT",
- "MOVB",
- "MOVBU",
- "MOVW",
- "MOVWU",
- "MOVA",
- "MOVAH",
- "MOVLL",
- "MOVQL",
- "MOVLC",
- "MOVQC",
- "MOVQP",
- "MOVLP",
- "ADDL",
- "ADDLV",
- "ADDQ",
- "ADDQV",
- "S4ADDL",
- "S4ADDQ",
- "S8ADDL",
- "S8ADDQ",
- "S4SUBL",
- "S4SUBQ",
- "S8SUBL",
- "S8SUBQ",
- "SUBL",
- "SUBLV",
- "SUBQ",
- "SUBQV",
- "CMPEQ",
- "CMPGT",
- "CMPGE",
- "CMPUGT",
- "CMPUGE",
- "CMPBLE",
- "AND",
- "ANDNOT",
- "OR",
- "ORNOT",
- "XOR",
- "XORNOT",
- "CMOVEQ",
- "CMOVNE",
- "CMOVLT",
- "CMOVGE",
- "CMOVLE",
- "CMOVGT",
- "CMOVLBC",
- "CMOVLBS",
- "MULL",
- "MULQ",
- "MULLV",
- "MULQV",
- "UMULH",
- "DIVQ",
- "MODQ",
- "DIVQU",
- "MODQU",
- "DIVL",
- "MODL",
- "DIVLU",
- "MODLU",
- "SLLQ",
- "SRLQ",
- "SRAQ",
- "SLLL",
- "SRLL",
- "SRAL",
- "EXTBL",
- "EXTWL",
- "EXTLL",
- "EXTQL",
- "EXTWH",
- "EXTLH",
- "EXTQH",
- "INSBL",
- "INSWL",
- "INSLL",
- "INSQL",
- "INSWH",
- "INSLH",
- "INSQH",
- "MSKBL",
- "MSKWL",
- "MSKLL",
- "MSKQL",
- "MSKWH",
- "MSKLH",
- "MSKQH",
- "ZAP",
- "ZAPNOT",
- "JMP",
- "JSR",
- "RET",
- "BR",
- "BSR",
- "BEQ",
- "BNE",
- "BLT",
- "BGE",
- "BLE",
- "BGT",
- "BLBC",
- "BLBS",
- "FBEQ",
- "FBNE",
- "FBLT",
- "FBGE",
- "FBLE",
- "FBGT",
- "TRAPB",
- "MB",
- "FETCH",
- "FETCHM",
- "RPCC",
- "CPYS",
- "CPYSN",
- "CPYSE",
- "CVTLQ",
- "CVTQL",
- "FCMOVEQ",
- "FCMOVNE",
- "FCMOVLT",
- "FCMOVGE",
- "FCMOVLE",
- "FCMOVGT",
- "ADDS",
- "ADDT",
- "CMPTEQ",
- "CMPTGT",
- "CMPTGE",
- "CMPTUN",
- "CVTQS",
- "CVTQT",
- "CVTTS",
- "CVTTQ",
- "DIVS",
- "DIVT",
- "MULS",
- "MULT",
- "SUBS",
- "SUBT",
- "CALL_PAL",
- "REI",
- "END",
- "DYNT",
- "INIT",
- "LAST",
-};
diff --git a/sys/src/cmd/7c/gc.h b/sys/src/cmd/7c/gc.h
deleted file mode 100644
index f41384bd4..000000000
--- a/sys/src/cmd/7c/gc.h
+++ /dev/null
@@ -1,343 +0,0 @@
-#include "../cc/cc.h"
-#include "../7c/7.out.h"
-
-/*
- * 7c/alpha
- * DEC Alpha
- */
-#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 FNX 100
-
-typedef struct Adr Adr;
-typedef struct Prog Prog;
-typedef struct Case Case;
-typedef struct C1 C1;
-typedef struct Multab Multab;
-typedef struct Hintab Hintab;
-typedef struct Bits Bits;
-typedef struct Var Var;
-typedef struct Reg Reg;
-typedef struct Rgn Rgn;
-
-struct Adr
-{
- union
- {
- vlong offset;
- double dval;
- char sval[NSNAME];
- Ieee ieee;
- };
- Sym* sym;
- char type;
- char reg;
- char name;
- char etype;
-};
-#define A ((Adr*)0)
-
-#define INDEXED 9
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* link;
- long lineno;
- uchar as;
- char reg;
-};
-#define P ((Prog*)0)
-
-struct Case
-{
- Case* link;
- vlong val;
- long label;
- char def;
- char isv;
-};
-#define C ((Case*)0)
-
-struct C1
-{
- vlong val;
- long label;
-};
-
-struct Multab
-{
- long val;
- char code[20];
-};
-
-struct Hintab
-{
- ushort val;
- char hint[10];
-};
-
-struct Var
-{
- vlong offset;
- Sym* sym;
- char name;
- 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;
-
- long regu;
- long loop; /* could be shorter */
-
- union
- {
- Reg* log5;
- long active;
- };
- Reg* p1;
- Reg* p2;
- Reg* p2link;
- Reg* s1;
- Reg* s2;
- Reg* link;
- Prog* prog;
-};
-#define R ((Reg*)0)
-
-#define NRGN 600
-struct Rgn
-{
- Reg* enter;
- short cost;
- short varno;
- short regno;
-};
-
-EXTERN long breakpc;
-EXTERN long nbreak;
-EXTERN Case* cases;
-EXTERN Node constnode;
-EXTERN Node fconstnode;
-EXTERN long continpc;
-EXTERN long curarg;
-EXTERN long cursafe;
-EXTERN Prog* firstp;
-EXTERN Prog* lastp;
-EXTERN long maxargsafe;
-EXTERN int mnstring;
-EXTERN Multab multab[20];
-EXTERN int hintabsize;
-EXTERN Node* nodrat;
-EXTERN Node* nodret;
-EXTERN Node* nodsafe;
-EXTERN long nrathole;
-EXTERN long nstring;
-EXTERN Prog* p;
-EXTERN long pc;
-EXTERN Node regnode;
-EXTERN char string[NSNAME];
-EXTERN Sym* symrathole;
-EXTERN Node znode;
-EXTERN Prog zprog;
-EXTERN char reg[NREG+NREG];
-EXTERN long exregoffset;
-EXTERN long exfregoffset;
-
-#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 4
-#define CREF 5
-#define CINF 1000
-#define LOOP 3
-
-EXTERN Rgn region[NRGN];
-EXTERN Rgn* rgp;
-EXTERN int nregion;
-EXTERN int nvar;
-
-EXTERN Bits externs;
-EXTERN Bits params;
-EXTERN Bits consts;
-EXTERN Bits addrs;
-EXTERN Bits zbits;
-
-EXTERN long regbits;
-EXTERN long exregbits;
-
-EXTERN int change;
-EXTERN int suppress;
-
-EXTERN Reg* firstr;
-EXTERN Reg* lastr;
-EXTERN Reg zreg;
-EXTERN Reg* freer;
-EXTERN Var var[NVAR];
-EXTERN long* idom;
-EXTERN Reg** rpo2r;
-EXTERN long maxnr;
-
-extern char* anames[];
-extern Hintab hintab[];
-
-/*
- * sgen.c
- */
-void codgen(Node*, Node*);
-void gen(Node*);
-void usedset(Node*, int);
-void noretval(int);
-void xcom(Node*);
-int bcomplex(Node*, Node*);
-
-/*
- * cgen.c
- */
-void cgen(Node*, Node*);
-void reglcgen(Node*, Node*, Node*);
-void lcgen(Node*, Node*);
-void bcgen(Node*, int);
-void boolgen(Node*, int, Node*);
-void sugen(Node*, Node*, long);
-void layout(Node*, Node*, int, int, Node*);
-
-/*
- * txt.c
- */
-void ginit(void);
-void gclean(void);
-void nextpc(void);
-void gargs(Node*, Node*, Node*);
-void garg1(Node*, Node*, Node*, int, Node**);
-Node* nodconst(long);
-Node* nod32const(vlong);
-Node* nodfconst(double);
-void nodreg(Node*, Node*, int);
-void regret(Node*, Node*);
-void regalloc(Node*, Node*, Node*);
-void regfree(Node*);
-void regialloc(Node*, Node*, Node*);
-void regsalloc(Node*, Node*);
-void regaalloc1(Node*, Node*);
-void regaalloc(Node*, Node*);
-void regind(Node*, Node*);
-void gprep(Node*, Node*);
-void raddr(Node*, Prog*);
-void naddr(Node*, Adr*);
-void gmove(Node*, Node*);
-void gins(int a, Node*, Node*);
-void gopcode(int, Node*, Node*, Node*);
-int samaddr(Node*, Node*);
-void gbranch(int);
-void patch(Prog*, long);
-int bconst(Node*);
-int sconst(Node*);
-int bval(vlong);
-int sval(long);
-void gpseudo(int, Sym*, Node*);
-
-/*
- * swt.c
- */
-int swcmp(void*, void*);
-void doswit(Node*);
-void swit1(C1*, int, long, Node*);
-void swit2(C1*, int, long, Node*, Node*);
-void casf(void);
-void bitload(Node*, Node*, Node*, Node*, Node*);
-void bitstore(Node*, Node*, Node*, Node*, Node*);
-long outstring(char*, long);
-int vlog(Node*);
-int mulcon(Node*, Node*);
-Multab* mulcon0(long);
-void nullwarn(Node*, Node*);
-void sextern(Sym*, Node*, long, long);
-void gextern(Sym*, Node*, long, long);
-void outcode(void);
-void ieeedtod(Ieee*, double);
-
-/*
- * list
- */
-void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Nconv(Fmt*);
-int Bconv(Fmt*);
-
-/*
- * reg.c
- */
-Reg* rega(void);
-int rcmp(void*, 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, long, int);
-void addreg(Adr*, int);
-
-/*
- * peep.c
- */
-void peep(void);
-void excise(Reg*);
-Reg* uniqp(Reg*);
-Reg* uniqs(Reg*);
-int regtyp(Adr*);
-int regzer(Adr*);
-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 copyau(Adr*, Adr*);
-int copyau1(Prog*, Adr*);
-int copysub(Adr*, Adr*, Adr*, int);
-int copysub1(Prog*, Adr*, Adr*, int);
-
-long RtoB(int);
-long FtoB(int);
-int BtoR(long);
-int BtoF(long);
-
-#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*
diff --git a/sys/src/cmd/7c/list.c b/sys/src/cmd/7c/list.c
deleted file mode 100644
index c2ebdbf1f..000000000
--- a/sys/src/cmd/7c/list.c
+++ /dev/null
@@ -1,231 +0,0 @@
-#define EXTERN
-#include "gc.h"
-
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv);
- fmtinstall('P', Pconv);
- fmtinstall('S', Sconv);
- fmtinstall('N', Nconv);
- fmtinstall('B', Bconv);
- fmtinstall('D', Dconv);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- memset(str, 0, sizeof str);
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strncat(str, " ", sizeof str - 1);
- if(var[i].sym == S) {
- snprint(ss, sizeof ss, "$%lld", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- strncat(str, s, sizeof str - 1);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
- int a;
-
- p = va_arg(fp->args, Prog*);
- a = p->as;
- if(a == ADATA)
- snprint(str, sizeof str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
- else
- if(p->as == ATEXT)
- snprint(str, sizeof str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
- else
- if(p->reg == NREG)
- snprint(str, sizeof str, " %A %D,%D", a, &p->from, &p->to);
- else
- if(p->from.type != D_FREG)
- snprint(str, sizeof str, " %A %D,R%d,%D", a, &p->from, p->reg, &p->to);
- else
- snprint(str, sizeof str, " %A %D,F%d,%D", a, &p->from, p->reg, &p->to);
- return fmtstrcpy(fp, str);
-}
-
-int
-Aconv(Fmt *fp)
-{
- char *s;
- int a;
-
- a = va_arg(fp->args, int);
- s = "???";
- if(a >= AXXX && a < ALAST)
- s = anames[a];
- return fmtstrcpy(fp, s);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Adr *a;
-
- a = va_arg(fp->args, Adr*);
- switch(a->type) {
-
- default:
- snprint(str, sizeof str, "GOK-type(%d)", a->type);
- break;
-
- case D_NONE:
- str[0] = 0;
- if(a->name != D_NONE || a->reg != NREG || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
- break;
-
- case D_CONST:
- if(a->reg != NREG)
- snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
- else
- snprint(str, sizeof str, "$%N", a);
- break;
-
- case D_OREG:
- if(a->reg != NREG)
- snprint(str, sizeof str, "%N(R%d)", a, a->reg);
- else
- snprint(str, sizeof str, "%N", a);
- break;
-
- case D_REG:
- snprint(str, sizeof str, "R%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_FREG:
- snprint(str, sizeof str, "F%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_FCREG:
- snprint(str, sizeof str, "FPCR");
- if(a->reg != 0 || a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(FPCR%d)(REG)", a, a->reg);
- break;
-
- case D_BRANCH:
- snprint(str, sizeof str, "%lld(PC)", a->offset-pc);
- break;
-
- case D_FCONST:
- snprint(str, sizeof str, "$%.17e", a->dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof str, "$\"%S\"", a->sval);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<NSNAME; i++) {
- c = a[i] & 0xff;
- if(c >= 'a' && c <= 'z' ||
- c >= 'A' && c <= 'Z' ||
- c >= '0' && c <= '9' ||
- c == ' ' || c == '%') {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- case 0:
- *p++ = 'z';
- continue;
- case '\\':
- case '"':
- *p++ = c;
- continue;
- case '\n':
- *p++ = 'n';
- continue;
- case '\t':
- *p++ = 't';
- continue;
- case '\r':
- *p++ = 'r';
- continue;
- case '\f':
- *p++ = 'f';
- continue;
- }
- *p++ = (c>>6) + '0';
- *p++ = ((c>>3) & 7) + '0';
- *p++ = (c & 7) + '0';
- }
- *p = 0;
- return fmtstrcpy(fp, str);
-}
-
-int
-Nconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Adr *a;
- Sym *s;
-
- a = va_arg(fp->args, Adr*);
- s = a->sym;
- if(s == S) {
- snprint(str, sizeof str, "%lld", a->offset);
- goto out;
- }
- switch(a->name) {
- default:
- snprint(str, sizeof str, "GOK-name(%d)", a->name);
- break;
-
- case D_NONE:
- snprint(str, sizeof str, "%lld", a->offset);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof str, "%s+%lld(SB)", s->name, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof str, "%s<>+%lld(SB)", s->name, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof str, "%s-%lld(SP)", s->name, -a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof str, "%s+%lld(FP)", s->name, a->offset);
- break;
- }
-out:
- return fmtstrcpy(fp, str);
-}
diff --git a/sys/src/cmd/7c/machcap.c b/sys/src/cmd/7c/machcap.c
deleted file mode 100644
index 79f4d67d7..000000000
--- a/sys/src/cmd/7c/machcap.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "gc.h"
-
-int
-machcap(Node *n)
-{
- if(n == Z) /* test */
- return 1;
- return 0;
-}
diff --git a/sys/src/cmd/7c/mkenam b/sys/src/cmd/7c/mkenam
deleted file mode 100644
index a1eca4316..000000000
--- a/sys/src/cmd/7c/mkenam
+++ /dev/null
@@ -1,15 +0,0 @@
-ed - ../7c/7.out.h <<'!'
-v/^ A/d
-,s/^ A/ "/
-g/ .*$/s///
-,s/,*$/",/
-1i
-char* anames[] =
-{
-.
-$a
-};
-.
-w enam.c
-Q
-!
diff --git a/sys/src/cmd/7c/mkfile b/sys/src/cmd/7c/mkfile
deleted file mode 100644
index f749eef90..000000000
--- a/sys/src/cmd/7c/mkfile
+++ /dev/null
@@ -1,39 +0,0 @@
-</$objtype/mkfile
-
-TARG=7c
-OFILES=\
- cgen.$O\
- enam.$O\
- list.$O\
- machcap.$O\
- peep.$O\
- pgen.$O\
- pswt.$O\
- reg.$O\
- sgen.$O\
- swt.$O\
- txt.$O\
- mul.$O\
-
-HFILES=\
- gc.h\
- 7.out.h\
- ../cc/cc.h\
-
-LIB=../cc/cc.a$O
-
-BIN=/$objtype/bin
-</sys/src/cmd/mkone
-
-$LIB:
- cd ../cc
- mk install
- mk clean
-
-%.$O: ../cc/%.c
- $CC $CFLAGS ../cc/$stem.c
-
-t:V: $O.out
- $O.out -S t
- $LD -o t.out t.$O
- t.out
diff --git a/sys/src/cmd/7c/mul.c b/sys/src/cmd/7c/mul.c
deleted file mode 100644
index 3ef56cd56..000000000
--- a/sys/src/cmd/7c/mul.c
+++ /dev/null
@@ -1,608 +0,0 @@
-#include "gc.h"
-
-/*
- * code sequences for multiply by constant.
- * [a-l][0-3]
- * lsl $(A-'a'),r0,r1
- * [+][0-7]
- * add r0,r1,r2
- * [-][0-7]
- * sub r0,r1,r2
- */
-
-static int multabp;
-static long mulval;
-static char* mulcp;
-static long valmax;
-static int shmax;
-
-static int docode(char *hp, char *cp, int r0, int r1);
-static int gen1(int len);
-static int gen2(int len, long r1);
-static int gen3(int len, long r0, long r1, int flag);
-enum
-{
- SR1 = 1<<0, /* r1 has been shifted */
- SR0 = 1<<1, /* r0 has been shifted */
- UR1 = 1<<2, /* r1 has not been used */
- UR0 = 1<<3, /* r0 has not been used */
-};
-
-Multab*
-mulcon0(long v)
-{
- int a1, a2, g;
- Multab *m, *m1;
- char hint[10];
-
- if(v < 0)
- v = -v;
-
- /*
- * look in cache
- */
- m = multab;
- for(g=0; g<nelem(multab); g++) {
- if(m->val == v) {
- if(m->code[0] == 0)
- return 0;
- return m;
- }
- m++;
- }
-
- /*
- * select a spot in cache to overwrite
- */
- multabp++;
- if(multabp < 0 || multabp >= nelem(multab))
- multabp = 0;
- m = multab+multabp;
- m->val = v;
- mulval = v;
-
- /*
- * look in execption hint table
- */
- a1 = 0;
- a2 = hintabsize;
- for(;;) {
- if(a1 >= a2)
- goto no;
- g = (a2 + a1)/2;
- if(v < hintab[g].val) {
- a2 = g;
- continue;
- }
- if(v > hintab[g].val) {
- a1 = g+1;
- continue;
- }
- break;
- }
-
- if(docode(hintab[g].hint, m->code, 1, 0))
- return m;
- print("multiply table failure %ld\n", v);
- m->code[0] = 0;
- return 0;
-
-no:
- /*
- * try to search
- */
- hint[0] = 0;
- for(g=1; g<=6; g++) {
- if(g >= 6 && v >= 65535)
- break;
- mulcp = hint+g;
- *mulcp = 0;
- if(gen1(g)) {
- if(docode(hint, m->code, 1, 0))
- return m;
- print("multiply table failure %ld\n", v);
- break;
- }
- }
-
- /*
- * try a recur followed by a shift
- */
- g = 0;
- while(!(v & 1)) {
- g++;
- v >>= 1;
- }
- if(g) {
- m1 = mulcon0(v);
- if(m1) {
- strcpy(m->code, m1->code);
- sprint(strchr(m->code, 0), "%c0", g+'a');
- return m;
- }
- }
- m->code[0] = 0;
- return 0;
-}
-
-static int
-docode(char *hp, char *cp, int r0, int r1)
-{
- int c, i;
-
- c = *hp++;
- *cp = c;
- cp += 2;
- switch(c) {
- default:
- c -= 'a';
- if(c < 1 || c >= 30)
- break;
- for(i=0; i<4; i++) {
- switch(i) {
- case 0:
- if(docode(hp, cp, r0<<c, r1))
- goto out;
- break;
- case 1:
- if(docode(hp, cp, r1<<c, r1))
- goto out;
- break;
- case 2:
- if(docode(hp, cp, r0, r0<<c))
- goto out;
- break;
- case 3:
- if(docode(hp, cp, r0, r1<<c))
- goto out;
- break;
- }
- }
- break;
-
- case '+':
- for(i=0; i<8; i++) {
- cp[-1] = i+'0';
- switch(i) {
- case 1:
- if(docode(hp, cp, r0+r1, r1))
- goto out;
- break;
- case 5:
- if(docode(hp, cp, r0, r0+r1))
- goto out;
- break;
- }
- }
- break;
-
- case '-':
- for(i=0; i<8; i++) {
- cp[-1] = i+'0';
- switch(i) {
- case 1:
- if(docode(hp, cp, r0-r1, r1))
- goto out;
- break;
- case 2:
- if(docode(hp, cp, r1-r0, r1))
- goto out;
- break;
- case 5:
- if(docode(hp, cp, r0, r0-r1))
- goto out;
- break;
- case 6:
- if(docode(hp, cp, r0, r1-r0))
- goto out;
- break;
- }
- }
- break;
-
- case 0:
- if(r0 == mulval)
- return 1;
- }
- return 0;
-
-out:
- cp[-1] = i+'0';
- return 1;
-}
-
-static int
-gen1(int len)
-{
- int i;
-
- for(shmax=1; shmax<30; shmax++) {
- valmax = 1<<shmax;
- if(valmax >= mulval)
- break;
- }
- if(mulval == 1)
- return 1;
-
- len--;
- for(i=1; i<=shmax; i++)
- if(gen2(len, 1<<i)) {
- *--mulcp = 'a'+i;
- return 1;
- }
- return 0;
-}
-
-static int
-gen2(int len, long r1)
-{
- int i;
-
- if(len <= 0) {
- if(r1 == mulval)
- return 1;
- return 0;
- }
-
- len--;
- if(len == 0)
- goto calcr0;
-
- if(gen3(len, r1, r1+1, UR1)) {
- i = '+';
- goto out;
- }
- if(gen3(len, r1-1, r1, UR0)) {
- i = '-';
- goto out;
- }
- if(gen3(len, 1, r1+1, UR1)) {
- i = '+';
- goto out;
- }
- if(gen3(len, 1, r1-1, UR1)) {
- i = '-';
- goto out;
- }
-
- return 0;
-
-calcr0:
- if(mulval == r1+1) {
- i = '+';
- goto out;
- }
- if(mulval == r1-1) {
- i = '-';
- goto out;
- }
- return 0;
-
-out:
- *--mulcp = i;
- return 1;
-}
-
-static int
-gen3(int len, long r0, long r1, int flag)
-{
- int i, f1, f2;
- long x;
-
- if(r0 <= 0 ||
- r0 >= r1 ||
- r1 > valmax)
- return 0;
-
- len--;
- if(len == 0)
- goto calcr0;
-
- if(!(flag & UR1)) {
- f1 = UR1|SR1;
- for(i=1; i<=shmax; i++) {
- x = r0<<i;
- if(x > valmax)
- break;
- if(gen3(len, r0, x, f1)) {
- i += 'a';
- goto out;
- }
- }
- }
-
- if(!(flag & UR0)) {
- f1 = UR1|SR1;
- for(i=1; i<=shmax; i++) {
- x = r1<<i;
- if(x > valmax)
- break;
- if(gen3(len, r1, x, f1)) {
- i += 'a';
- goto out;
- }
- }
- }
-
- if(!(flag & SR1)) {
- f1 = UR1|SR1|(flag&UR0);
- for(i=1; i<=shmax; i++) {
- x = r1<<i;
- if(x > valmax)
- break;
- if(gen3(len, r0, x, f1)) {
- i += 'a';
- goto out;
- }
- }
- }
-
- if(!(flag & SR0)) {
- f1 = UR0|SR0|(flag&(SR1|UR1));
-
- f2 = UR1|SR1;
- if(flag & UR1)
- f2 |= UR0;
- if(flag & SR1)
- f2 |= SR0;
-
- for(i=1; i<=shmax; i++) {
- x = r0<<i;
- if(x > valmax)
- break;
- if(x > r1) {
- if(gen3(len, r1, x, f2)) {
- i += 'a';
- goto out;
- }
- } else
- if(gen3(len, x, r1, f1)) {
- i += 'a';
- goto out;
- }
- }
- }
-
- x = r1+r0;
- if(gen3(len, r0, x, UR1)) {
- i = '+';
- goto out;
- }
-
- if(gen3(len, r1, x, UR1)) {
- i = '+';
- goto out;
- }
-
- x = r1-r0;
- if(gen3(len, x, r1, UR0)) {
- i = '-';
- goto out;
- }
-
- if(x > r0) {
- if(gen3(len, r0, x, UR1)) {
- i = '-';
- goto out;
- }
- } else
- if(gen3(len, x, r0, UR0)) {
- i = '-';
- goto out;
- }
-
- return 0;
-
-calcr0:
- f1 = flag & (UR0|UR1);
- if(f1 == UR1) {
- for(i=1; i<=shmax; i++) {
- x = r1<<i;
- if(x >= mulval) {
- if(x == mulval) {
- i += 'a';
- goto out;
- }
- break;
- }
- }
- }
-
- if(mulval == r1+r0) {
- i = '+';
- goto out;
- }
- if(mulval == r1-r0) {
- i = '-';
- goto out;
- }
-
- return 0;
-
-out:
- *--mulcp = i;
- return 1;
-}
-
-/*
- * hint table has numbers that
- * the search algorithm fails on.
- * <1000:
- * all numbers
- * <5000:
- * ÷ by 5
- * <10000:
- * ÷ by 50
- * <65536:
- * ÷ by 250
- */
-Hintab hintab[] =
-{
- 683, "b++d+e+",
- 687, "b+e++e-",
- 691, "b++d+e+",
- 731, "b++d+e+",
- 811, "b++d+i+",
- 821, "b++e+e+",
- 843, "b+d++e+",
- 851, "b+f-+e-",
- 853, "b++e+e+",
- 877, "c++++g-",
- 933, "b+c++g-",
- 981, "c-+e-d+",
- 1375, "b+c+b+h-",
- 1675, "d+b++h+",
- 2425, "c++f-e+",
- 2675, "c+d++f-",
- 2750, "b+d-b+h-",
- 2775, "c-+g-e-",
- 3125, "b++e+g+",
- 3275, "b+c+g+e+",
- 3350, "c++++i+",
- 3475, "c-+e-f-",
- 3525, "c-+d+g-",
- 3625, "c-+e-j+",
- 3675, "b+d+d+e+",
- 3725, "b+d-+h+",
- 3925, "b+d+f-d-",
- 4275, "b+g++e+",
- 4325, "b+h-+d+",
- 4425, "b+b+g-j-",
- 4525, "b+d-d+f+",
- 4675, "c++d-g+",
- 4775, "b+d+b+g-",
- 4825, "c+c-+i-",
- 4850, "c++++i-",
- 4925, "b++e-g-",
- 4975, "c+f++e-",
- 5500, "b+g-c+d+",
- 6700, "d+b++i+",
- 9700, "d++++j-",
- 11000, "b+f-c-h-",
- 11750, "b+d+g+j-",
- 12500, "b+c+e-k+",
- 13250, "b+d+e-f+",
- 13750, "b+h-c-d+",
- 14250, "b+g-c+e-",
- 14500, "c+f+j-d-",
- 14750, "d-g--f+",
- 16750, "b+e-d-n+",
- 17750, "c+h-b+e+",
- 18250, "d+b+h-d+",
- 18750, "b+g-++f+",
- 19250, "b+e+b+h+",
- 19750, "b++h--f-",
- 20250, "b+e-l-c+",
- 20750, "c++bi+e-",
- 21250, "b+i+l+c+",
- 22000, "b+e+d-g-",
- 22250, "b+d-h+k-",
- 22750, "b+d-e-g+",
- 23250, "b+c+h+e-",
- 23500, "b+g-c-g-",
- 23750, "b+g-b+h-",
- 24250, "c++g+m-",
- 24750, "b+e+e+j-",
- 25000, "b++dh+g+",
- 25250, "b+e+d-g-",
- 25750, "b+e+b+j+",
- 26250, "b+h+c+e+",
- 26500, "b+h+c+g+",
- 26750, "b+d+e+g-",
- 27250, "b+e+e+f+",
- 27500, "c-i-c-d+",
- 27750, "b+bd++j+",
- 28250, "d-d-++i-",
- 28500, "c+c-h-e-",
- 29000, "b+g-d-f+",
- 29500, "c+h+++e-",
- 29750, "b+g+f-c+",
- 30250, "b+f-g-c+",
- 33500, "c-f-d-n+",
- 33750, "b+d-b+j-",
- 34250, "c+e+++i+",
- 35250, "e+b+d+k+",
- 35500, "c+e+d-g-",
- 35750, "c+i-++e+",
- 36250, "b+bh-d+e+",
- 36500, "c+c-h-e-",
- 36750, "d+e--i+",
- 37250, "b+g+g+b+",
- 37500, "b+h-b+f+",
- 37750, "c+be++j-",
- 38500, "b+e+b+i+",
- 38750, "d+i-b+d+",
- 39250, "b+g-l-+d+",
- 39500, "b+g-c+g-",
- 39750, "b+bh-c+f-",
- 40250, "b+bf+d+g-",
- 40500, "b+g-c+g+",
- 40750, "c+b+i-e+",
- 41250, "d++bf+h+",
- 41500, "b+j+c+d-",
- 41750, "c+f+b+h-",
- 42500, "c+h++g+",
- 42750, "b+g+d-f-",
- 43250, "b+l-e+d-",
- 43750, "c+bd+h+f-",
- 44000, "b+f+g-d-",
- 44250, "b+d-g--f+",
- 44500, "c+e+c+h+",
- 44750, "b+e+d-h-",
- 45250, "b++g+j-g+",
- 45500, "c+d+e-g+",
- 45750, "b+d-h-e-",
- 46250, "c+bd++j+",
- 46500, "b+d-c-j-",
- 46750, "e-e-b+g-",
- 47000, "b+c+d-j-",
- 47250, "b+e+e-g-",
- 47500, "b+g-c-h-",
- 47750, "b+f-c+h-",
- 48250, "d--h+n-",
- 48500, "b+c-g+m-",
- 48750, "b+e+e-g+",
- 49500, "c-f+e+j-",
- 49750, "c+c+g++f-",
- 50000, "b+e+e+k+",
- 50250, "b++i++g+",
- 50500, "c+g+f-i+",
- 50750, "b+e+d+k-",
- 51500, "b+i+c-f+",
- 51750, "b+bd+g-e-",
- 52250, "b+d+g-j+",
- 52500, "c+c+f+g+",
- 52750, "b+c+e+i+",
- 53000, "b+i+c+g+",
- 53500, "c+g+g-n+",
- 53750, "b+j+d-c+",
- 54250, "b+d-g-j-",
- 54500, "c-f+e+f+",
- 54750, "b+f-+c+g+",
- 55000, "b+g-d-g-",
- 55250, "b+e+e+g+",
- 55500, "b+cd++j+",
- 55750, "b+bh-d-f-",
- 56250, "c+d-b+j-",
- 56500, "c+d+c+i+",
- 56750, "b+e+d++h-",
- 57000, "b+d+g-f+",
- 57250, "b+f-m+d-",
- 57750, "b+i+c+e-",
- 58000, "b+e+d+h+",
- 58250, "c+b+g+g+",
- 58750, "d-e-j--e+",
- 59000, "d-i-+e+",
- 59250, "e--h-m+",
- 59500, "c+c-h+f-",
- 59750, "b+bh-e+i-",
- 60250, "b+bh-e-e-",
- 60500, "c+c-g-g-",
- 60750, "b+e-l-e-",
- 61250, "b+g-g-c+",
- 61750, "b+g-c+g+",
- 62250, "f--+c-i-",
- 62750, "e+f--+g+",
- 64750, "b+f+d+p-",
-};
-int hintabsize = nelem(hintab);
diff --git a/sys/src/cmd/7c/peep.c b/sys/src/cmd/7c/peep.c
deleted file mode 100644
index e5d5f240b..000000000
--- a/sys/src/cmd/7c/peep.c
+++ /dev/null
@@ -1,759 +0,0 @@
-#include "gc.h"
-
-void
-peep(void)
-{
- Reg *r, *r1, *r2;
- Prog *p, *p1;
- int t;
-/*
- * 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:
- p = p->link;
- }
- }
-
-loop1:
- t = 0;
- for(r=firstr; r!=R; r=r->link) {
- p = r->prog;
- if(p->as == AMOVQ || /*p->as == AMOVL ||*/ p->as == AMOVS || p->as == AMOVT)
- if(regtyp(&p->to)) {
- if(regtyp(&p->from))
- if(p->from.type == p->to.type) {
- if(copyprop(r)) {
- excise(r);
- t++;
- } else
- if(subprop(r) && copyprop(r)) {
- excise(r);
- t++;
- }
- }
- if(regzer(&p->from))
- if(p->to.type == D_REG) {
- p->from.type = D_REG;
- p->from.reg = REGZERO;
- if(copyprop(r)) {
- excise(r);
- t++;
- } else
- if(subprop(r) && copyprop(r)) {
- excise(r);
- t++;
- }
- }
- }
-/* if(p->as == AMOVL)
- if(regtyp(&p->to)) {
- if(regzer(&p->from))
- if(p->to.type == D_REG) {
- p->from.type = D_REG;
- p->from.reg = REGZERO;
- if(copyprop(r)) {
- excise(r);
- t++;
- } else
- if(subprop(r) && copyprop(r)) {
- excise(r);
- t++;
- }
- }
- } */
- }
- if(t)
- goto loop1;
- /*
- * look for MOVB x,R; MOVB R,R
- */
- for(r=firstr; r!=R; r=r->link) {
- p = r->prog;
- switch(p->as) {
- default:
- continue;
- case AMOVW:
- case AMOVWU:
- case AMOVB:
- case AMOVBU:
- if(p->to.type != D_REG)
- continue;
- break;
- }
- r1 = r->link;
- if(r1 == R)
- continue;
- p1 = r1->prog;
- if(p1->as != p->as)
- continue;
- if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
- continue;
- if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
- continue;
- excise(r1);
- }
-}
-
-void
-excise(Reg *r)
-{
- Prog *p;
-
- p = r->prog;
- p->as = ANOP;
- p->from = zprog.from;
- p->to = zprog.to;
- p->reg = zprog.reg; /**/
-}
-
-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;
-}
-
-int
-regzer(Adr *a)
-{
-
- if(a->type == D_CONST)
- if(a->sym == S)
- if(a->offset == 0)
- return 1;
- if(a->type == D_REG)
- if(a->reg == REGZERO)
- return 1;
- return 0;
-}
-
-int
-regtyp(Adr *a)
-{
-
- if(a->type == D_REG) {
- if(a->reg != REGZERO)
- return 1;
- return 0;
- }
- if(a->type == D_FREG)
- 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 MOV
- * 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))
- return 0;
- v2 = &p->to;
- if(!regtyp(v2))
- return 0;
- for(r=uniqp(r0); r!=R; r=uniqp(r)) {
- if(uniqs(r) == R)
- break;
- p = r->prog;
- switch(p->as) {
- case AJSR:
- return 0;
-
- case AADDQ:
- case ASUBQ:
- case AADDL:
- case ASUBL:
- case ASLLQ:
- case ASRLQ:
- case ASRAQ:
- case ASLLL:
- case ASRLL:
- case ASRAL:
- case AOR:
- case AAND:
- case AXOR:
- case AMULQ:
- case ADIVQ:
- case ADIVQU:
- case AMODQ:
- case AMODQU:
- case ADIVL:
- case ADIVLU:
- case AMODL:
- case AMODLU:
- case ACMPEQ:
- case ACMPGT:
- case ACMPGE:
- case ACMPUGT:
- case ACMPUGE:
- case ACMPBLE:
- case AMULL:
- case AUMULH:
-
- case AADDT:
- case AADDS:
- case ASUBT:
- case ASUBS:
- case AMULT:
- case AMULS:
- case ADIVT:
- case ADIVS:
- case ACMPTEQ:
- case ACMPTGT:
- case ACMPTGE:
- if(p->to.type == v1->type)
- if(p->to.reg == v1->reg) {
- if(p->reg == NREG)
- p->reg = p->to.reg;
- goto gotit;
- }
- break;
-
- case AMOVS:
- case AMOVT:
- case AMOVQ:
- case ACVTQT:
- case ACVTTQ:
- if(p->to.type == v1->type)
- if(p->to.reg == v1->reg)
- goto gotit;
- break;
- }
- if(copyau(&p->from, v2) ||
- copyau1(p, v2) ||
- copyau(&p->to, v2))
- break;
- if(copysub(&p->from, v1, v2, 0) ||
- copysub1(p, v1, v2, 0) ||
- copysub(&p->to, v1, v2, 0))
- break;
- }
- return 0;
-
-gotit:
- copysub(&p->to, v1, v2, 1);
- if(debug['P']) {
- print("gotit: %D->%D\n%P", v1, v2, r->prog);
- if(p->from.type == v2->type)
- print(" excise");
- print("\n");
- }
- for(r=uniqs(r); r!=r0; r=uniqs(r)) {
- p = r->prog;
- copysub(&p->from, v1, v2, 1);
- copysub1(p, v1, v2, 1);
- copysub(&p->to, v1, v2, 1);
- if(debug['P'])
- print("%P\n", r->prog);
- }
- t = v1->reg;
- v1->reg = v2->reg;
- v2->reg = 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;
- Prog *p;
-
- if(r->active) {
- if(debug['P'])
- print("act set; return 1\n");
- return 1;
- }
- r->active = 1;
- if(debug['P'])
- print("copy %D->%D f=%d\n", v1, v2, f);
- for(; r != R; r = r->s1) {
- p = r->prog;
- if(debug['P'])
- print("%P", p);
- if(!f && uniqp(r) == R) {
- f = 1;
- if(debug['P'])
- print("; merge; f=%d", f);
- }
- t = copyu(p, v2, A);
- switch(t) {
- case 2: /* rar, cant split */
- if(debug['P'])
- print("; %Drar; return 0\n", v2);
- return 0;
-
- case 3: /* set */
- if(debug['P'])
- print("; %Dset; return 1\n", v2);
- return 1;
-
- case 1: /* used, substitute */
- case 4: /* use and set */
- if(f) {
- if(!debug['P'])
- return 0;
- if(t == 4)
- print("; %Dused+set and f=%d; return 0\n", v2, f);
- else
- print("; %Dused and f=%d; return 0\n", v2, f);
- return 0;
- }
- if(copyu(p, v2, v1)) {
- if(debug['P'])
- print("; sub fail; return 0\n");
- return 0;
- }
- if(debug['P'])
- print("; sub%D/%D", v2, v1);
- if(t == 4) {
- if(debug['P'])
- print("; %Dused+set; return 1\n", v2);
- return 1;
- }
- break;
- }
- if(!f) {
- t = copyu(p, v1, A);
- if(!f && (t == 2 || t == 3 || t == 4)) {
- f = 1;
- if(debug['P'])
- print("; %Dset and !f; f=%d", v1, f);
- }
- }
- 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)
- */
-copyu(Prog *p, Adr *v, Adr *s)
-{
-
- switch(p->as) {
-
- default:
- if(debug['P'])
- print(" (???)");
- diag(Z, "copyu: unknown op %P", p);
- return 2;
-
-
- case ANOP: /* read, write */
- case AMOVQ:
- case AMOVL:
- case AMOVLU:
- case AMOVW:
- case AMOVWU:
- case AMOVB:
- case AMOVBU:
-
- case AMOVS:
- case AMOVT:
- case ACVTTQ:
- case ACVTQT:
- case ACVTQS:
- case ACVTTS:
- if(s != A) {
- if(copysub(&p->from, v, s, 1))
- return 1;
- if(!copyas(&p->to, v))
- if(copysub(&p->to, v, s, 1))
- return 1;
- return 0;
- }
- if(copyas(&p->to, v)) {
- if(copyau(&p->from, v))
- return 4;
- return 3;
- }
- if(copyau(&p->from, v))
- return 1;
- if(copyau(&p->to, v))
- return 1;
- return 0;
-
- case AADDQ: /* read read write */
- case ASUBQ:
- case AADDL:
- case ASUBL:
- case ACMPEQ:
- case ACMPGT:
- case ACMPGE:
- case ACMPUGT:
- case ACMPUGE:
- case ACMPBLE:
- case ASLLQ:
- case ASRLQ:
- case ASRAQ:
- case ASLLL:
- case ASRLL:
- case ASRAL:
- case AOR:
- case AAND:
- case AXOR:
- case AMULQ:
- case AMULL:
- case AUMULH:
- case ADIVQ:
- case ADIVQU:
- case AMODQ:
- case AMODQU:
- case ADIVL:
- case ADIVLU:
- case AMODL:
- case AMODLU:
-
- case AADDS:
- case AADDT:
- case ASUBS:
- case ASUBT:
- case AMULS:
- case AMULT:
- case ADIVS:
- case ADIVT:
- case ACMPTEQ:
- case ACMPTGT:
- case ACMPTGE:
- if(s != A) {
- if(copysub(&p->from, v, s, 1))
- return 1;
- if(copysub1(p, v, s, 1))
- return 1;
- if(!copyas(&p->to, v))
- if(copysub(&p->to, v, s, 1))
- return 1;
- return 0;
- }
- if(copyas(&p->to, v)) {
- if(p->reg == NREG)
- p->reg = p->to.reg;
- if(copyau(&p->from, v))
- return 4;
- if(copyau1(p, v))
- return 4;
- return 3;
- }
- if(copyau(&p->from, v))
- return 1;
- if(copyau1(p, v))
- return 1;
- if(copyau(&p->to, v))
- return 1;
- return 0;
-
- case ABEQ: /* read */
- case ABNE:
- case ABLT:
- case ABGE:
- case ABLE:
- case ABGT:
- case ABLBC:
- case ABLBS:
-
- case AFBEQ:
- case AFBNE:
- case AFBLT:
- case AFBGE:
- case AFBLE:
- case AFBGT:
- if(s != A)
- return copysub(&p->from, v, s, 1);
- if(copyau(&p->from, v))
- return 1;
- return 0;
-
-#ifdef NOPE
- case ???: /* read read */
- if(s != A) {
- if(copysub(&p->from, v, s, 1))
- return 1;
- return copysub(&p->to, v, s, 1);
- }
- if(copyau(&p->from, v))
- return 1;
- if(copyau(&p->to, v))
- return 1;
- break;
-#endif
-
- case AJMP: /* funny */
- if(s != A) {
- if(copysub(&p->to, v, s, 1))
- return 1;
- return 0;
- }
- if(copyau(&p->to, v))
- return 1;
- return 0;
-
- case ARET: /* funny */
- if(v->type == D_REG)
- if(v->reg == REGRET)
- return 2;
- if(v->type == D_FREG)
- if(v->reg == FREGRET)
- return 2;
-
- case AJSR: /* funny */
- if(v->type == D_REG) {
- if(v->reg <= REGEXT && v->reg > exregoffset)
- return 2;
- if(REGARG != NREG && v->reg == REGARG)
- return 2;
- }
- if(v->type == D_FREG)
- if(v->reg <= FREGEXT && v->reg > exfregoffset)
- return 2;
-
- if(s != A) {
- if(copysub(&p->to, v, s, 1))
- return 1;
- return 0;
- }
- if(copyau(&p->to, v))
- return 4;
- return 3;
-
- case ATEXT: /* funny */
- if(v->type == D_REG)
- if(v->reg == REGARG)
- return 3;
- return 0;
- }
-}
-
-int
-a2type(Prog *p)
-{
-
- switch(p->as) {
- case AADDQ:
- case ASUBQ:
- case ASLLQ:
- case ASRLQ:
- case ASRAQ:
- case ASLLL:
- case ASRLL:
- case ASRAL:
- case AOR:
- case AAND:
- case AXOR:
- case AMULQ:
- case ADIVQ:
- case ADIVQU:
- case AMODQ:
- case AMODQU:
- case ADIVL:
- case ADIVLU:
- case AMODL:
- case AMODLU:
- case AADDL:
- case ASUBL:
- case AEXTLL:
- case ACMPEQ:
- case ACMPGT:
- case ACMPGE:
- case ACMPUGT:
- case ACMPUGE:
- case ACMPBLE:
- case AMULL:
- case AUMULH:
- return D_REG;
-
- case AADDS:
- case AADDT:
- case ASUBS:
- case ASUBT:
- case AMULS:
- case AMULT:
- case ADIVS:
- case ADIVT:
- case ACMPTEQ:
- case ACMPTGT:
- case ACMPTGE:
- case ACVTTQ:
- case ACVTQT:
- return D_FREG;
- }
- return D_NONE;
-}
-
-/*
- * direct reference,
- * could be set/use depending on
- * semantics
- */
-int
-copyas(Adr *a, Adr *v)
-{
-
- if(regtyp(v))
- if(a->type == v->type)
- if(a->reg == v->reg)
- return 1;
- return 0;
-}
-
-/*
- * either direct or indirect
- */
-int
-copyau(Adr *a, Adr *v)
-{
-
- if(copyas(a, v))
- return 1;
- if(v->type == D_REG)
- if(a->type == D_OREG)
- if(v->reg == a->reg)
- return 1;
- return 0;
-}
-
-int
-copyau1(Prog *p, Adr *v)
-{
-
- if(regtyp(v))
- if(p->from.type == v->type || p->to.type == v->type)
- if(p->reg == v->reg) {
- if(a2type(p) != v->type)
- print("botch a2type %P\n", p);
- return 1;
- }
- return 0;
-}
-
-/*
- * substitute s for v in a
- * return failure to substitute
- */
-int
-copysub(Adr *a, Adr *v, Adr *s, int f)
-{
-
- if(f)
- if(copyau(a, v))
- a->reg = s->reg;
- return 0;
-}
-
-int
-copysub1(Prog *p1, Adr *v, Adr *s, int f)
-{
-
- if(f)
- if(copyau1(p1, v))
- p1->reg = s->reg;
- return 0;
-}
diff --git a/sys/src/cmd/7c/reg.c b/sys/src/cmd/7c/reg.c
deleted file mode 100644
index 802bc75dc..000000000
--- a/sys/src/cmd/7c/reg.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-#include "gc.h"
-
-void addsplits(void);
-
-Reg*
-rega(void)
-{
- Reg *r;
-
- r = freer;
- if(r == R) {
- r = alloc(sizeof(*r));
- } else
- freer = r->link;
-
- *r = zreg;
- return r;
-}
-
-int
-rcmp(void *a1, void *a2)
-{
- Rgn *p1, *p2;
- int c1, c2;
-
- p1 = a1;
- p2 = a2;
- c1 = p2->cost;
- c2 = p1->cost;
- if(c1 -= c2)
- return c1;
- return p2->varno - p1->varno;
-}
-
-void
-regopt(Prog *p)
-{
- Reg *r, *r1, *r2;
- Prog *p1;
- int i, z;
- long initpc, val, npc;
- ulong vreg;
- Bits bit;
- struct
- {
- long m;
- long c;
- Reg* p;
- } log5[6], *lp;
-
- firstr = R;
- lastr = R;
- nvar = 0;
- regbits = 0;
- for(z=0; z<BITS; z++) {
- externs.b[z] = 0;
- params.b[z] = 0;
- consts.b[z] = 0;
- addrs.b[z] = 0;
- }
-
- /*
- * 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:
- 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 ARET:
- case AJMP:
- case AREI:
- r->p1 = R;
- r1->s1 = R;
- }
-
- /*
- * left side always read
- */
- bit = mkvar(&p->from, p->as==AMOVQ || p->as==AMOVL);
- for(z=0; z<BITS; z++)
- r->use1.b[z] |= bit.b[z];
-
- /*
- * right side depends on opcode
- */
- bit = mkvar(&p->to, 0);
- if(bany(&bit))
- switch(p->as) {
- default:
- diag(Z, "reg: unknown asop: %ud", p->as);
- break;
-
- /*
- * right side write
- */
- case ANOP:
- case AMOVB:
- case AMOVBU:
- case AMOVW:
- case AMOVWU:
- case AMOVL:
- case AMOVQ:
- case AMOVS:
- case AMOVT:
- for(z=0; z<BITS; z++)
- r->set.b[z] |= bit.b[z];
- break;
-
- /*
- * funny
- */
- case AJSR:
- for(z=0; z<BITS; z++)
- addrs.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) {
- nearln = p->lineno;
- diag(Z, "ref not found\n%P", p);
- continue;
- }
- if(r1 == r) {
- nearln = p->lineno;
- diag(Z, "ref to self\n%P", p);
- continue;
- }
- r->s2 = r1;
- r->p2link = r1->p2;
- r1->p2 = r;
- }
- }
- if(debug['R']) {
- p = firstr->prog;
- print("\n%L %D\n", p->lineno, &p->from);
- }
-
- /*
- * pass 2.5
- * find looping structure
- */
- for(r = firstr; r != R; r = r->link)
- r->active = 0;
- change = 0;
- loopit(firstr, npc);
-
- /*
- * pass 3
- * iterate propagating usage
- * back until flow graph is complete
- */
-loop1:
- change = 0;
- for(r = firstr; r != R; r = r->link)
- r->active = 0;
- for(r = firstr; r != R; r = r->link)
- if(r->prog->as == ARET)
- 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(change)
- goto loop1;
-
-
- /*
- * pass 4
- * iterate propagating register/variable synchrony
- * forward until graph is complete
- */
-loop2:
- change = 0;
- for(r = firstr; r != R; r = r->link)
- r->active = 0;
- synch(firstr, zbits);
- if(change)
- goto loop2;
-
- addsplits();
-
- if(debug['R'] && debug['v']) {
- print("\nprop 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->set.b[z] |
- r->refahead.b[z] | r->calahead.b[z] |
- r->refbehind.b[z] | r->calbehind.b[z] |
- r->use1.b[z] | r->use2.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);
- if(bany(&r->refahead))
- print(" ra=%B", r->refahead);
- if(bany(&r->calahead))
- print(" ca=%B", r->calahead);
- if(bany(&r->refbehind))
- print(" rb=%B", r->refbehind);
- if(bany(&r->calbehind))
- print(" cb=%B", r->calbehind);
- }
- print("\n");
- }
- }
-
- /*
- * 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] | consts.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);
- }
- }
-
- for(r = firstr; r != R; r = r->link)
- 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 and 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;
- change = 0;
- if(debug['R'] && debug['v'])
- print("\n");
- paint1(r, i);
- bit.b[i/32] &= ~(1L<<(i%32));
- if(change <= 0) {
- if(debug['R'])
- print("%L $%d: %B\n",
- r->prog->lineno, change, blsh(i));
- continue;
- }
- rgp->cost = change;
- 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']) {
- if(rgp->regno >= NREG)
- print("%L $%d F%d: %B\n",
- rgp->enter->prog->lineno,
- rgp->cost,
- rgp->regno-NREG,
- bit);
- else
- print("%L $%d R%d: %B\n",
- rgp->enter->prog->lineno,
- rgp->cost,
- rgp->regno,
- bit);
- }
- if(rgp->regno != 0)
- 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:
- 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;
- }
-}
-
-void
-addsplits(void)
-{
- Reg *r, *r1;
- int z, i;
- Bits bit;
-
- for(r = firstr; r != R; r = r->link) {
- if(r->loop > 1)
- continue;
- if(r->prog->as == AJSR)
- continue;
- for(r1 = r->p2; r1 != R; r1 = r1->p2link) {
- if(r1->loop <= 1)
- continue;
- for(z=0; z<BITS; z++)
- bit.b[z] = r1->calbehind.b[z] &
- (r->refahead.b[z] | r->use1.b[z] | r->use2.b[z]) &
- ~(r->calahead.b[z] & addrs.b[z]);
- while(bany(&bit)) {
- i = bnum(bit);
- bit.b[i/32] &= ~(1L << (i%32));
- }
- }
- }
-}
-
-/*
- * add mov b,rn
- * just after r
- */
-void
-addmove(Reg *r, int bn, int rn, int f)
-{
- Prog *p, *p1;
- Adr *a;
- Var *v;
-
- p1 = alloc(sizeof(*p1));
- *p1 = zprog;
- p = r->prog;
-
- p1->link = p->link;
- p->link = p1;
- p1->lineno = p->lineno;
-
- v = var + bn;
-
- a = &p1->to;
- a->sym = v->sym;
- a->name = v->name;
- a->offset = v->offset;
- a->etype = v->etype;
- a->type = D_OREG;
- if(a->etype == TARRAY || a->sym == S)
- a->type = D_CONST;
-
- p1->as = AMOVL;
- if(v->etype == TCHAR || v->etype == TUCHAR) /* TODO: optimise locals? */
- p1->as = AMOVB;
- if(v->etype == TSHORT || v->etype == TUSHORT)
- p1->as = AMOVW;
- if(v->etype == TVLONG || v->etype == TUVLONG)
- p1->as = AMOVQ;
- if(v->etype == TFLOAT)
- p1->as = AMOVS;
- if(v->etype == TDOUBLE)
- p1->as = AMOVT;
-
- p1->from.type = D_REG;
- p1->from.reg = rn;
- if(rn >= NREG) {
- p1->from.type = D_FREG;
- p1->from.reg = rn-NREG;
- }
- if(!f) {
- p1->from = *a;
- *a = zprog.from;
- a->type = D_REG;
- a->reg = rn;
- if(rn >= NREG) {
- a->type = D_FREG;
- a->reg = rn-NREG;
- }
- if(v->etype == TUCHAR)
- p1->as = AMOVBU;
- if(v->etype == TUSHORT)
- p1->as = AMOVWU;
- }
- if(debug['R'])
- print("%P\t.a%P\n", p, p1);
-}
-
-Bits
-mkvar(Adr *a, int docon)
-{
- Var *v;
- int i, t, n, et, z;
- vlong o;
- Bits bit;
- Sym *s;
-
- t = a->type;
- if(t == D_REG && a->reg != NREG)
- regbits |= RtoB(a->reg);
- if(t == D_FREG && a->reg != NREG)
- regbits |= FtoB(a->reg);
- s = a->sym;
- o = a->offset;
- et = a->etype;
- if(s == S) {
- if(t != D_CONST || !docon || a->reg != NREG)
- goto none;
- et = TLONG;
- if (o > 0x7FFFFFFFLL || o < -0x80000000LL)
- et = TVLONG;
- }
- if(t == D_CONST) {
- if(s == S && sval(o))
- goto none;
- }
-
- n = a->name;
- v = var;
- for(i=0; i<nvar; i++) {
- if(s == v->sym)
- if(n == v->name)
- 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 = et;
- v->name = n;
- if(debug['R'])
- print("bit=%2d et=%2d %D\n", i, et, a);
-out:
- bit = blsh(i);
- if(n == D_EXTERN || n == D_STATIC)
- for(z=0; z<BITS; z++)
- externs.b[z] |= bit.b[z];
- if(n == D_PARAM)
- for(z=0; z<BITS; z++)
- params.b[z] |= bit.b[z];
- if(v->etype != et || (!typechlpfd[et] && !typev[et])) /* funny punning? */
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
- if(t == D_CONST) {
- if(s == S) {
- for(z=0; z<BITS; z++)
- consts.b[z] |= bit.b[z];
- return bit;
- }
- if(et != TARRAY)
- for(z=0; z<BITS; z++)
- addrs.b[z] |= bit.b[z];
- for(z=0; z<BITS; z++)
- params.b[z] |= bit.b[z];
- return bit;
- }
- if(t == D_OREG)
- 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];
- change++;
- }
- cal.b[z] |= r1->calahead.b[z];
- if(cal.b[z] != r1->calahead.b[z]) {
- r1->calahead.b[z] = cal.b[z];
- change++;
- }
- }
- switch(r1->prog->as) {
- case AJSR:
- 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 ARET:
- 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];
- change++;
- }
- }
- 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;
-
- v = var + r->varno;
- r->regno = 0;
- switch(v->etype) {
-
- default:
- diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
- break;
-
- case TCHAR:
- case TUCHAR:
- case TSHORT:
- case TUSHORT:
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TVLONG:
- case TUVLONG:
- case TIND:
- case TARRAY:
- i = BtoR(~b);
- if(i && r->cost >= 0) {
- r->regno = i;
- return RtoB(i);
- }
- break;
-
- case TDOUBLE:
- case TFLOAT:
- i = BtoF(~b);
- if(i && r->cost >= 0) {
- r->regno = i+NREG;
- return FtoB(i);
- }
- break;
- }
- return 0;
-}
-
-void
-paint1(Reg *r, int bn)
-{
- 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) {
- change -= CLOAD * r->loop;
- if(debug['R'] && debug['v'])
- print("%ld%P\tld %B $%d\n", r->loop,
- r->prog, blsh(bn), change);
- }
- for(;;) {
- r->act.b[z] |= bb;
- p = r->prog;
-
- if(r->use1.b[z] & bb) {
- change += CREF * r->loop;
- if(debug['R'] && debug['v'])
- print("%ld%P\tu1 %B $%d\n", r->loop,
- p, blsh(bn), change);
- }
-
- if((r->use2.b[z]|r->set.b[z]) & bb) {
- change += CREF * r->loop;
- if(debug['R'] && debug['v'])
- print("%ld%P\tu2 %B $%d\n", r->loop,
- p, blsh(bn), change);
- }
-
- if(STORE(r) & r->regdiff.b[z] & bb) {
- change -= CLOAD * r->loop;
- if(debug['R'] && debug['v'])
- print("%ld%P\tst %B $%d\n", r->loop,
- p, blsh(bn), change);
- }
-
- 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, long 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(p->as == AMOVL && typechlp[var[bn].etype])
- p->as = AMOVQ;
- 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(p->as == AMOVL && typechlp[var[bn].etype])
- p->as = AMOVQ;
- 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;
- a->name = D_NONE;
- a->type = D_REG;
- a->reg = rn;
- if(rn >= NREG) {
- a->type = D_FREG;
- a->reg = rn-NREG;
- }
-}
-
-/*
- * bit reg
- * 0 R2
- * 1 R3
- * ... ...
- * 10 R12
- * 11 R16
- * ... ...
- * 19 R24
- * 20 R25
- */
-long
-RtoB(int r)
-{
-
- if(r >= 2 && r <= 12)
- return 1L << (r-2);
- if(r >= 16 && r <= 25)
- return 1L << (r-5);
- return 0;
-}
-
-BtoR(long b)
-{
- int r;
-
- b &= 0x001fffffL;
- if(b == 0)
- return 0;
- r = bitno(b) + 2;
- if (r >= 13)
- r += 3;
- return r;
-}
-
-/*
- * bit reg
- * 21 F1
- * 22 F2
- * ... ...
- * 31 F11
- */
-long
-FtoB(int f)
-{
-
- if(f < 1 || f > 11)
- return 0;
- return 1L << (f + 20);
-}
-
-int
-BtoF(long b)
-{
-
- b &= 0xffe00000L;
- if(b == 0)
- return 0;
- return bitno(b) - 20;
-}
diff --git a/sys/src/cmd/7c/sgen.c b/sys/src/cmd/7c/sgen.c
deleted file mode 100644
index 54aaacd4a..000000000
--- a/sys/src/cmd/7c/sgen.c
+++ /dev/null
@@ -1,235 +0,0 @@
-#include "gc.h"
-
-void
-noretval(int n)
-{
-
- if(n & 1) {
- gins(ANOP, Z, Z);
- p->to.type = D_REG;
- p->to.reg = REGRET;
- }
- if(n & 2) {
- gins(ANOP, Z, Z);
- p->to.type = D_FREG;
- p->to.reg = FREGRET;
- }
-}
-
-/*
- * calculate addressability as follows
- * CONST ==> 20 $value
- * NAME ==> 10 name
- * REGISTER ==> 11 register
- * INDREG ==> 12 *[(reg)+offset]
- * &10 ==> 2 $name
- * ADD(2, 20) ==> 2 $name+offset
- * ADD(3, 20) ==> 3 $(reg)+offset
- * &12 ==> 3 $(reg)+offset
- * *11 ==> 11 ??
- * *2 ==> 10 name
- * *3 ==> 12 *(reg)+offset
- * calculate complexity (number of registers)
- */
-void
-xcom(Node *n)
-{
- Node *l, *r;
- int t;
-
- if(n == Z)
- return;
- l = n->left;
- r = n->right;
- n->addable = 0;
- n->complex = 0;
- switch(n->op) {
- case OCONST:
- n->addable = 20;
- return;
-
- case OREGISTER:
- n->addable = 11;
- return;
-
- case OINDREG:
- n->addable = 12;
- return;
-
- case ONAME:
- n->addable = 10;
- return;
-
- case OADDR:
- xcom(l);
- if(l->addable == 10)
- n->addable = 2;
- if(l->addable == 12)
- n->addable = 3;
- break;
-
- case OIND:
- xcom(l);
- if(l->addable == 11)
- n->addable = 12;
- if(l->addable == 3)
- n->addable = 12;
- if(l->addable == 2)
- n->addable = 10;
- break;
-
- case OADD:
- xcom(l);
- xcom(r);
- if(l->addable == 20) {
- if(r->addable == 2)
- n->addable = 2;
- if(r->addable == 3)
- n->addable = 3;
- }
- if(r->addable == 20) {
- if(l->addable == 2)
- n->addable = 2;
- if(l->addable == 3)
- n->addable = 3;
- }
- break;
-
- case OASLMUL:
- case OASMUL:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASASHL;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
-
- case OMUL:
- case OLMUL:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASHL;
- r->vconst = t;
- r->type = types[TINT];
- }
- t = vlog(l);
- if(t >= 0) {
- n->op = OASHL;
- n->left = r;
- n->right = l;
- r = l;
- l = n->left;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
-
- case OASLDIV:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASLSHR;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
-
- case OLDIV:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OLSHR;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
-
- case OASLMOD:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASAND;
- r->vconst--;
- }
- break;
-
- case OLMOD:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OAND;
- r->vconst--;
- }
- break;
-
- default:
- if(l != Z)
- xcom(l);
- if(r != Z)
- xcom(r);
- break;
- }
- 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++;
-
- switch(n->op) {
- case OFUNC:
- n->complex = FNX;
- break;
-
- case OEQ:
- case ONE:
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OHI:
- case OHS:
- case OLO:
- case OLS:
- /*
- * immediate operators, make const on right
- */
- if(l->op == OCONST) {
- n->left = r;
- n->right = l;
- n->op = invrel[relindex(n->op)];
- }
- break;
-
- case OADD:
- case OXOR:
- case OAND:
- case OOR:
- /*
- * immediate operators, make const on right
- */
- if(l->op == OCONST) {
- n->left = r;
- n->right = l;
- }
- break;
- }
-}
-
diff --git a/sys/src/cmd/7c/swt.c b/sys/src/cmd/7c/swt.c
deleted file mode 100644
index 229558d86..000000000
--- a/sys/src/cmd/7c/swt.c
+++ /dev/null
@@ -1,578 +0,0 @@
-#include "gc.h"
-
-void
-swit1(C1 *q, int nc, long def, Node *n)
-{
- Node tn;
-
- regalloc(&tn, &regnode, Z);
- swit2(q, nc, def, n, &tn);
- regfree(&tn);
-}
-
-void
-swit2(C1 *q, int nc, long def, Node *n, Node *tn)
-{
- C1 *r;
- int i;
- Prog *sp;
-
- if(nc < 5) {
- for(i=0; i<nc; i++) {
- if(debug['W'])
- print("case = %.8llux\n", q->val);
- if(bval(q->val)) {
- gopcode(OEQ, n, Z, nodconst(q->val));
- } else {
- gopcode(OSUB, nodconst(q->val), n, tn);
- gopcode(OEQ, tn, Z, nodconst(0));
- }
- patch(p, q->label);
- q++;
- }
- gbranch(OGOTO);
- patch(p, def);
- return;
- }
- i = nc / 2;
- r = q+i;
- if(bval(r->val)) {
- gopcode(OGE, n, Z, nodconst(r->val));
- sp = p;
- swit2(q, i, def, n, tn);
-
- patch(sp, pc);
- swit2(r, nc-i, def, n, tn);
- } else {
- gopcode(OSUB, nodconst(r->val), n, tn);
- gopcode(OGE, tn, Z, nodconst(0));
- sp = p;
- swit2(q, i, def, n, tn);
-
- patch(sp, pc);
- swit2(r, nc-i, def, n, tn);
- }
-/* if(debug['W'])
- print("case > %.8llux\n", r->val);
- gmove(nodconst(r->val), tn);
- gopcode(OLT, tn, n, Z);
- sp = p;
- gopcode(OEQ, n, tn, Z);
- patch(p, r->label);
- swit2(q, i, def, n, tn);
-
- if(debug['W'])
- print("case < %.8llux\n", r->val);
- patch(sp, pc);
- swit2(r+1, nc-i-1, def, n, tn); */
-}
-
-void
-bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
-{
- int sh;
- long v;
- Node *l;
-
- /*
- * n1 gets adjusted/masked value
- * n2 gets address of cell
- * n3 gets contents of cell
- */
- l = b->left;
- if(n2 != Z) {
- regalloc(n1, l, nn);
- reglcgen(n2, l, Z);
- regalloc(n3, l, Z);
- gopcode(OAS, n2, Z, n3);
- gopcode(OAS, n3, Z, n1);
- } else {
- regalloc(n1, l, nn);
- cgen(l, n1);
- }
- if(b->type->shift == 0 && typeu[b->type->etype]) {
- v = ~0 + (1L << b->type->nbits);
- gopcode(OAND, nodconst(v), Z, n1);
- } else {
- sh = 32 - b->type->shift - b->type->nbits;
- if(sh > 0)
- gopcode(OASHL, nodconst(sh), Z, n1);
- sh += b->type->shift;
- if(sh > 0)
- if(typeu[b->type->etype])
- gopcode(OLSHR, nodconst(sh), Z, n1);
- else
- gopcode(OASHR, nodconst(sh), Z, n1);
- }
-}
-
-void
-bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
-{
- long v;
- Node nod, *l;
- int sh;
-
- /*
- * n1 has adjusted/masked value
- * n2 has address of cell
- * n3 has contents of cell
- */
- l = b->left;
- regalloc(&nod, l, Z);
- v = ~0 + (1L << b->type->nbits);
- gopcode(OAND, nodconst(v), Z, n1);
- gopcode(OAS, n1, Z, &nod);
- if(nn != Z)
- gopcode(OAS, n1, Z, nn);
- sh = b->type->shift;
- if(sh > 0)
- gopcode(OASHL, nodconst(sh), Z, &nod);
- v <<= sh;
- gopcode(OAND, nodconst(~v), Z, n3);
- gopcode(OOR, n3, Z, &nod);
- gopcode(OAS, &nod, Z, n2);
-
- regfree(&nod);
- regfree(n1);
- regfree(n2);
- regfree(n3);
-}
-
-long
-outstring(char *s, long n)
-{
- long r;
-
- if(suppress)
- return nstring;
- r = nstring;
- while(n) {
- string[mnstring] = *s++;
- mnstring++;
- nstring++;
- if(mnstring >= NSNAME) {
- gpseudo(ADATA, symstring, nodconst(0L));
- p->from.offset += nstring - NSNAME;
- p->reg = NSNAME;
- p->to.type = D_SCONST;
- memmove(p->to.sval, string, NSNAME);
- mnstring = 0;
- }
- n--;
- }
- return r;
-}
-
-int
-mulcon(Node *n, Node *nn)
-{
- Node *l, *r, nod1, nod2;
- Multab *m;
- long v;
- int o;
- char code[sizeof(m->code)+2], *p;
-
- if(typefd[n->type->etype])
- return 0;
- l = n->left;
- r = n->right;
- if(l->op == OCONST) {
- l = r;
- r = n->left;
- }
- if(r->op != OCONST)
- return 0;
- v = convvtox(r->vconst, n->type->etype);
- if(v != r->vconst) {
- if(debug['M'])
- print("%L multiply conv: %lld\n", n->lineno, r->vconst);
- return 0;
- }
- m = mulcon0(v);
- if(!m) {
- if(debug['M'])
- print("%L multiply table: %lld\n", n->lineno, r->vconst);
- return 0;
- }
- if(debug['M'] && debug['v'])
- print("%L multiply: %ld\n", n->lineno, v);
-
- memmove(code, m->code, sizeof(m->code));
- code[sizeof(m->code)] = 0;
-
- p = code;
- if(p[1] == 'i')
- p += 2;
- regalloc(&nod1, n, nn);
- cgen(l, &nod1);
- if(v < 0)
- gopcode(OSUB, &nod1, nodconst(0), &nod1);
- regalloc(&nod2, n, Z);
-
-loop:
- switch(*p) {
- case 0:
- regfree(&nod2);
- gopcode(OAS, &nod1, Z, nn);
- regfree(&nod1);
- return 1;
- case '+':
- o = OADD;
- goto addsub;
- case '-':
- o = OSUB;
- addsub: /* number is r,n,l */
- v = p[1] - '0';
- r = &nod1;
- if(v&4)
- r = &nod2;
- n = &nod1;
- if(v&2)
- n = &nod2;
- l = &nod1;
- if(v&1)
- l = &nod2;
- gopcode(o, l, n, r);
- break;
- default: /* op is shiftcount, number is r,l */
- v = p[1] - '0';
- r = &nod1;
- if(v&2)
- r = &nod2;
- l = &nod1;
- if(v&1)
- l = &nod2;
- v = *p - 'a';
- if(v < 0 || v >= 32) {
- diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
- break;
- }
- gopcode(OASHL, nodconst(v), l, r);
- break;
- }
- p += 2;
- goto loop;
-}
-
-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, nodconst(0));
- p->from.offset += o+e;
- p->reg = lw;
- p->to.type = D_SCONST;
- memmove(p->to.sval, a->cstring+e, lw);
- }
-}
-
-void
-gextern(Sym *s, Node *a, long o, long w)
-{
- gpseudo(ADATA, s, a);
- p->from.offset += o;
- p->reg = w;
- if(p->to.type == D_OREG)
- p->to.type = D_CONST;
-}
-
-void zname(Biobuf*, char*, int, int);
-char* zaddr(char*, Adr*, int);
-void zwrite(Biobuf*, Prog*, int, int);
-void outhist(Biobuf*);
-
-void
-zwrite(Biobuf *b, Prog *p, int sf, int st)
-{
- char bf[100], *bp;
-
- bf[0] = p->as;
- bf[1] = p->reg;
- bf[2] = p->lineno;
- bf[3] = p->lineno>>8;
- bf[4] = p->lineno>>16;
- bf[5] = p->lineno>>24;
- bp = zaddr(bf+6, &p->from, sf);
- bp = zaddr(bp, &p->to, st);
- Bwrite(b, bf, bp-bf);
-}
-
-void
-outcode(void)
-{
- struct { Sym *sym; short type; } h[NSYM];
- Prog *p;
- Sym *s;
- int sf, st, t, sym;
-
- 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++;
- }
- }
- outhist(&outbuf);
- 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.name;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- zname(&outbuf, s->name, t, sym);
- s->sym = sym;
- 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.name;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- zname(&outbuf, s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- zwrite(&outbuf, p, sf, st);
- }
- firstp = P;
- lastp = P;
-}
-
-void
-outhist(Biobuf *b)
-{
- Hist *h;
- char *p, *q, *op;
- Prog pg;
- int n;
-
- pg = zprog;
- pg.as = AHISTORY;
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- op = 0;
- if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
- op = p;
- p = pathname;
- }
- while(p) {
- q = utfrune(p, '/');
- if(q) {
- n = q-p;
- if(n == 0)
- n = 1; /* leading "/" */
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- Bputc(b, ANAME);
- 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
-zname(Biobuf *b, char *n, int t, int s)
-{
- char bf[3];
-
- bf[0] = ANAME;
- bf[1] = t; /* type */
- bf[2] = s; /* sym */
- Bwrite(b, bf, 3);
- Bwrite(b, n, strlen(n)+1);
-}
-
-char*
-zaddr(char *bp, Adr *a, int s)
-{
- long l;
- vlong v;
- Ieee e;
-
- bp[0] = a->type;
- bp[1] = a->reg;
- bp[2] = s;
- bp[3] = a->name;
- bp += 4;
- switch(a->type) {
- default:
- diag(Z, "unknown type %d in zaddr", a->type);
-
- case D_NONE:
- case D_REG:
- case D_FREG:
- case D_FCREG:
- break;
-
- case D_OREG:
- case D_CONST:
- case D_BRANCH:
- v = a->offset;
- bp[0] = v;
- bp[1] = v>>8;
- bp[2] = v>>16;
- bp[3] = v>>24;
- bp[4] = v>>32;
- bp[5] = v>>40;
- bp[6] = v>>48;
- bp[7] = v>>56;
- bp += 8;
- break;
-
- case D_SCONST:
- memmove(bp, a->sval, NSNAME);
- bp += NSNAME;
- break;
-
- case D_FCONST:
- ieeedtod(&e, a->dval);
- l = e.l;
- bp[0] = l;
- bp[1] = l>>8;
- bp[2] = l>>16;
- bp[3] = l>>24;
- bp += 4;
- l = e.h;
- bp[0] = l;
- bp[1] = l>>8;
- bp[2] = l>>16;
- bp[3] = l>>24;
- bp += 4;
- break;
- }
- return bp;
-}
-
-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_VLONG;
- 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_VLONG)
- w = SZ_VLONG;
- 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(typesu[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_VLONG) {
- w = SZ_VLONG;
- break;
- }
- w = 1; /* little endian no adjustment */
- 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_VLONG-1;
- if(v > max)
- max = round(v, SZ_VLONG);
- return max;
-}
diff --git a/sys/src/cmd/7c/txt.c b/sys/src/cmd/7c/txt.c
deleted file mode 100644
index ef6bd0fbd..000000000
--- a/sys/src/cmd/7c/txt.c
+++ /dev/null
@@ -1,1306 +0,0 @@
-#include "gc.h"
-
-void
-ginit(void)
-{
- Type *t;
-
- thechar = '7';
- thestring = "alpha";
- exregoffset = REGEXT;
- exfregoffset = FREGEXT;
- listinit();
- nstring = 0;
- mnstring = 0;
- nrathole = 0;
- pc = 0;
- breakpc = -1;
- continpc = -1;
- cases = C;
- firstp = P;
- lastp = P;
- tfield = types[TLONG];
-
- typeword = typechlvp;
- typecmplx = typesu;
-
- zprog.link = P;
- zprog.as = AGOK;
- zprog.reg = NREG;
- zprog.from.type = D_NONE;
- zprog.from.name = D_NONE;
- zprog.from.reg = NREG;
- zprog.to = zprog.from;
-
- regnode.op = OREGISTER;
- regnode.class = CEXREG;
- regnode.reg = REGTMP;
- regnode.complex = 0;
- regnode.addable = 11;
- regnode.type = types[TLONG];
-
- constnode.op = OCONST;
- constnode.class = CXXX;
- constnode.complex = 0;
- constnode.addable = 20;
- constnode.type = types[TLONG];
-
- fconstnode.op = OCONST;
- fconstnode.class = CXXX;
- fconstnode.complex = 0;
- fconstnode.addable = 20;
- fconstnode.type = types[TDOUBLE];
-
- nodsafe = new(ONAME, Z, Z);
- nodsafe->sym = slookup(".safe");
- nodsafe->type = types[TINT];
- nodsafe->etype = types[TINT]->etype;
- nodsafe->class = CAUTO;
- complex(nodsafe);
-
- t = typ(TARRAY, types[TCHAR]);
- symrathole = slookup(".rathole");
- symrathole->class = CGLOBL;
- symrathole->type = t;
-
- nodrat = new(ONAME, Z, Z);
- nodrat->sym = symrathole;
- nodrat->type = types[TIND];
- nodrat->etype = TVOID;
- nodrat->class = CGLOBL;
- complex(nodrat);
- nodrat->type = t;
-
- nodret = new(ONAME, Z, Z);
- nodret->sym = slookup(".ret");
- nodret->type = types[TIND];
- nodret->etype = TIND;
- nodret->class = CPARAM;
- nodret = new(OIND, nodret, Z);
- complex(nodret);
-
- memset(reg, 0, sizeof(reg));
- reg[REGZERO] = 1;
-}
-
-void
-gclean(void)
-{
- int i;
- Sym *s;
-
- for(i=0; i<NREG; i++)
- if(i != REGZERO)
- if(reg[i])
- diag(Z, "reg %d left allocated", i);
- for(i=NREG; i<NREG+NREG; i+=2)
- if(reg[i])
- diag(Z, "freg %d left allocated", i-NREG);
- while(mnstring)
- outstring("", 1L);
- symstring->type->width = nstring;
- 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, nodconst(s->type->width));
- }
- nextpc();
- p->as = AEND;
- outcode();
-}
-
-void
-nextpc(void)
-{
-
- p = alloc(sizeof(*p));
- *p = zprog;
- p->lineno = nearln;
- pc++;
- if(firstp == P) {
- firstp = p;
- lastp = p;
- return;
- }
- lastp->link = p;
- lastp = p;
-}
-
-void
-gargs(Node *n, Node *tn1, Node *tn2)
-{
- long regs;
- Node fnxargs[20], *fnxp;
-
- regs = cursafe;
-
- fnxp = fnxargs;
- garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
-
- curarg = 0;
- fnxp = fnxargs;
- garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
-
- cursafe = regs;
-}
-
-void
-garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
-{
- Node nod;
-
- if(n == Z)
- return;
- if(n->op == OLIST) {
- garg1(n->left, tn1, tn2, f, fnxp);
- garg1(n->right, tn1, tn2, f, fnxp);
- return;
- }
- if(f == 0) {
- if(n->complex >= FNX) {
- regsalloc(*fnxp, n);
- nod = znode;
- nod.op = OAS;
- nod.left = *fnxp;
- nod.right = n;
- nod.type = n->type;
- cgen(&nod, Z);
- (*fnxp)++;
- }
- return;
- }
- if(typesu[n->type->etype]) {
- regaalloc(tn2, n);
- if(n->complex >= FNX) {
- sugen(*fnxp, tn2, n->type->width);
- (*fnxp)++;
- } else
- sugen(n, tn2, n->type->width);
- return;
- }
- if(REGARG != NREG && curarg == 0 &&
- (typechlp[n->type->etype] || typev[n->type->etype])) {
- regaalloc1(tn1, n);
- if(n->complex >= FNX) {
- cgen(*fnxp, tn1);
- (*fnxp)++;
- } else
- cgen(n, tn1);
- return;
- }
- if(vconst(n) == 0) {
- regaalloc(tn2, n);
- gopcode(OAS, n, Z, tn2);
- return;
- }
- regalloc(tn1, n, Z);
- if(n->complex >= FNX) {
- cgen(*fnxp, tn1);
- (*fnxp)++;
- } else
- cgen(n, tn1);
- regaalloc(tn2, n);
- gopcode(OAS, tn1, Z, tn2);
- regfree(tn1);
-}
-
-Node*
-nodconst(long v)
-{
- constnode.vconst = v;
- return &constnode;
-}
-
-Node*
-nodfconst(double d)
-{
- fconstnode.fconst = d;
- return &fconstnode;
-}
-
-void
-nodreg(Node *n, Node *nn, int reg)
-{
- *n = regnode;
- n->reg = reg;
- n->type = nn->type;
- n->lineno = nn->lineno;
-}
-
-void
-regret(Node *n, Node *nn)
-{
- int r;
-
- r = REGRET;
- if(typefd[nn->type->etype])
- r = FREGRET+NREG;
- nodreg(n, nn, r);
- reg[r]++;
-}
-
-void
-regalloc(Node *n, Node *tn, Node *o)
-{
- int i, j;
- static int lasti;
-
- switch(tn->type->etype) {
- case TCHAR:
- case TUCHAR:
- case TSHORT:
- case TUSHORT:
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TIND:
- case TVLONG:
- case TUVLONG:
- if(o != Z && o->op == OREGISTER) {
- i = o->reg;
- if(i >= 0 && i < NREG - 1)
- goto out;
- }
- j = lasti + REGRET+1;
- for(i=REGRET+1; i<NREG; i++) {
- if(j >= NREG)
- j = REGRET+1;
- if(reg[j] == 0) {
- i = j;
- goto out;
- }
- j++;
- }
- diag(tn, "out of fixed registers");
- goto err;
-
- case TFLOAT:
- case TDOUBLE:
- if(o != Z && o->op == OREGISTER) {
- i = o->reg;
- if(i >= NREG && i < NREG+NREG)
- goto out;
- }
- j = NREG + 12 + lasti;
- for(i=NREG; i<NREG+NREG; i++) {
- if(j >= NREG+NREG)
- j = NREG;
- if(reg[j] == 0) {
- i = j;
- goto out;
- }
- j++;
- }
- diag(tn, "out of float registers");
- goto err;
- }
- diag(tn, "unknown type in regalloc: %T", tn->type);
-err:
- i = -1;
-out:
- if(i >= 0)
- reg[i]++;
- lasti++;
- if(lasti >= 5)
- lasti = 0;
- nodreg(n, tn, i);
-}
-
-void
-regialloc(Node *n, Node *tn, Node *o)
-{
- Node nod;
-
- nod = *tn;
- nod.type = types[TIND];
- regalloc(n, &nod, o);
-}
-
-void
-regfree(Node *n)
-{
- int i;
-
- i = 0;
- if(n->op != OREGISTER && n->op != OINDREG)
- goto err;
- i = n->reg;
- if(i < 0 || i >= sizeof(reg))
- goto err;
- if(reg[i] <= 0)
- goto err;
- reg[i]--;
- return;
-err:
- diag(n, "error in regfree: %d op %O", i, n->op);
-}
-
-void
-regsalloc(Node *n, Node *nn)
-{
- cursafe = align(cursafe, nn->type, Aaut3);
- maxargsafe = maxround(maxargsafe, cursafe+curarg);
- *n = *nodsafe;
- n->xoffset = -(stkoff + cursafe);
- n->type = nn->type;
- n->etype = nn->type->etype;
- n->lineno = nn->lineno;
-}
-
-void
-regaalloc1(Node *n, Node *nn)
-{
- nodreg(n, nn, REGARG);
- reg[REGARG]++;
- curarg = align(curarg, nn->type, Aarg1);
- curarg = align(curarg, nn->type, Aarg2);
- maxargsafe = maxround(maxargsafe, cursafe+curarg);
-}
-
-void
-regaalloc(Node *n, Node *nn)
-{
- curarg = align(curarg, nn->type, Aarg1);
- *n = *nn;
- n->op = OINDREG;
- n->reg = REGSP;
- n->xoffset = curarg + SZ_VLONG;
- n->complex = 0;
- n->addable = 20;
- curarg = align(curarg, nn->type, Aarg2);
- maxargsafe = maxround(maxargsafe, cursafe+curarg);
-}
-
-void
-regind(Node *n, Node *nn)
-{
-
- if(n->op != OREGISTER) {
- diag(n, "regind not OREGISTER");
- return;
- }
- n->op = OINDREG;
- n->type = nn->type;
-}
-
-void
-raddr(Node *n, Prog *p)
-{
- Adr a;
-
- naddr(n, &a);
- if(a.type == D_CONST && a.offset == 0) {
- a.type = D_REG;
- a.reg = 0;
- }
- if(a.type != D_REG && a.type != D_FREG) {
- if(n)
- diag(n, "bad in raddr: %O", n->op);
- else
- diag(n, "bad in raddr: <null>");
- p->reg = NREG;
- } else
- p->reg = a.reg;
-}
-
-void
-naddr(Node *n, Adr *a)
-{
- vlong v;
-
- a->type = D_NONE;
- if(n == Z)
- return;
- switch(n->op) {
- default:
- bad:
- diag(n, "bad in naddr: %O", n->op);
- break;
-
- case OREGISTER:
- a->type = D_REG;
- a->sym = S;
- a->reg = n->reg;
- if(a->reg >= NREG) {
- a->type = D_FREG;
- a->reg -= NREG;
- }
- break;
-
- case OIND:
- naddr(n->left, a);
- if(a->type == D_REG) {
- a->type = D_OREG;
- break;
- }
- if(a->type == D_CONST) {
- a->type = D_OREG;
- break;
- }
- goto bad;
-
- case OINDREG:
- a->type = D_OREG;
- a->sym = S;
- a->offset = n->xoffset;
- a->reg = n->reg;
- break;
-
- case ONAME:
- a->etype = n->etype;
- a->type = D_OREG;
- a->name = D_STATIC;
- a->sym = n->sym;
- a->offset = n->xoffset;
- if(n->class == CSTATIC)
- break;
- if(n->class == CEXTERN || n->class == CGLOBL) {
- a->name = D_EXTERN;
- break;
- }
- if(n->class == CAUTO) {
- a->name = D_AUTO;
- break;
- }
- if(n->class == CPARAM) {
- a->name = D_PARAM;
- break;
- }
- goto bad;
-
- case OCONST:
- a->sym = S;
- a->reg = NREG;
- if(typefd[n->type->etype]) {
- a->type = D_FCONST;
- a->dval = n->fconst;
- } else if(typev[n->type->etype]) {
- a->type = D_CONST;
- a->offset = n->vconst;
- } else {
- a->type = D_CONST;
- a->offset = convvtox(n->vconst, TLONG); /* alpha arithmetic */
- }
- break;
-
- case OADDR:
- naddr(n->left, a);
- if(a->type == D_OREG) {
- a->type = D_CONST;
- break;
- }
- goto bad;
-
- case OADD:
- if(n->left->op == OCONST) {
- naddr(n->left, a);
- v = a->offset;
- naddr(n->right, a);
- } else {
- naddr(n->right, a);
- v = a->offset;
- naddr(n->left, a);
- }
- a->offset += v;
- break;
-
- }
-}
-
-void
-fop(int as, int f1, int f2, Node *t)
-{
- Node nod1, nod2, nod3;
-
- nodreg(&nod1, t, NREG+f1);
- nodreg(&nod2, t, NREG+f2);
- regalloc(&nod3, t, t);
- gopcode(as, &nod1, &nod2, &nod3);
- gmove(&nod3, t);
- regfree(&nod3);
-}
-
-void
-gmove(Node *f, Node *t)
-{
- int ft, tt, a;
- Node nod;
- double d;
-
- ft = f->type->etype;
- tt = t->type->etype;
-
- if(ft == TDOUBLE && f->op == OCONST) {
- d = f->fconst;
- if(d == 0.0) {
- a = FREGZERO;
- goto ffreg;
- }
- if(d == 0.5) {
- a = FREGHALF;
- goto ffreg;
- }
- if(d == 1.0) {
- a = FREGONE;
- goto ffreg;
- }
- if(d == 2.0) {
- a = FREGTWO;
- goto ffreg;
- }
- if(d == -.5) {
- fop(OSUB, FREGHALF, FREGZERO, t);
- return;
- }
- if(d == -1.0) {
- fop(OSUB, FREGONE, FREGZERO, t);
- return;
- }
- if(d == -2.0) {
- fop(OSUB, FREGTWO, FREGZERO, t);
- return;
- }
- if(d == 1.5) {
- fop(OADD, FREGONE, FREGHALF, t);
- return;
- }
- if(d == 2.5) {
- fop(OADD, FREGTWO, FREGHALF, t);
- return;
- }
- if(d == 3.0) {
- fop(OADD, FREGTWO, FREGONE, t);
- return;
- }
- }
- if(ft == TFLOAT && f->op == OCONST) {
- d = f->fconst;
- if(d == 0) {
- a = FREGZERO;
- ffreg:
- nodreg(&nod, f, NREG+a);
- gmove(&nod, t);
- return;
- }
- }
- /*
- * a load --
- * put it into a register then
- * worry what to do with it.
- */
- if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
- switch(ft) {
- default:
- a = AMOVL;
- break;
- case TVLONG:
- case TUVLONG:
- /* todo: optimise freg case? */
- a = AMOVQ;
-#ifdef is_this_right
- if(typefd[tt]) {
- /* special case can load mem to Freg */
- regalloc(&nod, t, t);
- gins(AMOVL, f, &nod);
- a = ACVTQT;
- if(tt == TFLOAT)
- a = ACVTQS;
- gins(a, &nod, &nod);
- gmove(&nod, t);
- regfree(&nod);
- return;
- }
-#endif is_this_right
- break;
- case TFLOAT:
- a = AMOVS;
- break;
- case TDOUBLE:
- a = AMOVT;
- break;
- case TCHAR:
- a = AMOVB;
- break;
- case TUCHAR:
- a = AMOVBU;
- break;
- case TSHORT:
- a = AMOVW;
- break;
- case TUSHORT:
- a = AMOVWU;
- break;
- }
- if(typechlp[ft] && typeilp[tt])
- regalloc(&nod, t, t);
- else
- regalloc(&nod, f, t);
- gins(a, f, &nod);
- gmove(&nod, t);
- regfree(&nod);
- return;
- }
-
- /*
- * a store --
- * put it into a register then
- * store it.
- */
- if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
- switch(tt) {
- default:
- a = AMOVL;
- break;
- case TUCHAR:
- case TCHAR:
- a = AMOVB;
- break;
- case TUSHORT:
- case TSHORT:
- a = AMOVW;
- break;
- case TFLOAT:
- a = AMOVS;
- break;
- case TDOUBLE:
- a = AMOVT;
- break;
- case TVLONG:
- case TUVLONG:
- a = AMOVQ;
- break;
- }
- if(!typefd[ft] && vconst(f) == 0) {
- gins(a, f, t);
- return;
- }
- if(ft == tt)
- regalloc(&nod, t, f);
- else
- regalloc(&nod, t, Z);
- gmove(f, &nod);
- gins(a, &nod, t);
- regfree(&nod);
- return;
- }
-
- /*
- * type x type cross table
- */
- a = AGOK;
- switch(ft) {
- case TDOUBLE:
- case TFLOAT:
- switch(tt) {
- case TDOUBLE:
- a = AMOVT;
- break;
- case TFLOAT:
- a = ACVTTS;
- if(ft == TFLOAT)
- a = AMOVT;
- break;
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TUVLONG:
- case TVLONG:
- case TIND:
- case TSHORT:
- case TUSHORT:
- case TCHAR:
- case TUCHAR:
- /*warn(Z, "float to fix"); /**/
- regalloc(&nod, f, Z); /* should be type float */
- gins(ACVTTQ, f, &nod);
- gins(AMOVT, &nod, nodrat);
- regfree(&nod);
- gins(AMOVQ, nodrat, t);
- gmove(t, t);
- if(nrathole < SZ_VLONG)
- nrathole = SZ_VLONG;
- return;
- }
- break;
- case TVLONG:
- case TUVLONG:
- switch(tt) {
- case TDOUBLE:
- case TFLOAT:
- goto fxtofl;
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TIND:
- case TSHORT:
- case TUSHORT:
- case TCHAR:
- case TUCHAR:
- a = AMOVL;
- break;
- case TVLONG:
- case TUVLONG:
- a = AMOVQ;
- break;
- }
- break;
- case TINT:
- case TUINT:
- case TULONG:
- case TLONG:
- case TIND:
- switch(tt) {
- case TDOUBLE:
- case TFLOAT:
- goto fxtofl;
- case TVLONG:
- case TUVLONG:
- if (ft == TULONG || ft == TUINT) {
- a = AMOVLU;
- break;
- }
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TIND:
- case TSHORT:
- case TUSHORT:
- case TCHAR:
- case TUCHAR:
- a = AMOVQ;
- break;
- }
- break;
- case TSHORT:
- switch(tt) {
- case TDOUBLE:
- case TFLOAT:
- goto fxtofl;
- case TINT:
- case TUINT:
- case TULONG:
- case TLONG:
- case TVLONG:
- case TUVLONG:
- case TIND:
- a = AMOVW;
- break;
- case TSHORT:
- case TUSHORT:
- case TCHAR:
- case TUCHAR:
- a = AMOVQ;
- break;
- }
- break;
- case TUSHORT:
- switch(tt) {
- case TDOUBLE:
- case TFLOAT:
- goto fxtofl;
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TVLONG:
- case TUVLONG:
- case TIND:
- a = AMOVWU;
- break;
- case TSHORT:
- case TUSHORT:
- case TCHAR:
- case TUCHAR:
- a = AMOVQ;
- break;
- }
- break;
- case TCHAR:
- switch(tt) {
- case TDOUBLE:
- case TFLOAT:
- goto fxtofl;
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TVLONG:
- case TUVLONG:
- case TIND:
- case TSHORT:
- case TUSHORT:
- a = AMOVB;
- break;
- case TCHAR:
- case TUCHAR:
- a = AMOVQ;
- break;
- }
- break;
- case TUCHAR:
- switch(tt) {
- case TDOUBLE:
- case TFLOAT:
- fxtofl:
- /*warn(Z, "fix to float"); /**/
- regalloc(&nod, t, Z); /* should be type float */
- gins(AMOVQ, f, nodrat);
- gins(AMOVT, nodrat, &nod);
- a = ACVTQT;
- if(tt == TFLOAT)
- a = ACVTQS;
- gins(a, &nod, t);
- regfree(&nod);
- if(nrathole < SZ_VLONG)
- nrathole = SZ_VLONG;
- return;
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TVLONG:
- case TUVLONG:
- case TIND:
- case TSHORT:
- case TUSHORT:
- a = AMOVBU;
- break;
- case TCHAR:
- case TUCHAR:
- a = AMOVQ;
- break;
- }
- break;
- }
- if(a == AMOVQ || a == AMOVS || a == AMOVT)
- if(samaddr(f, t))
- return;
- gins(a, f, t);
-}
-
-void
-gins(int a, Node *f, Node *t)
-{
-
- nextpc();
- p->as = a;
- if(f != Z)
- naddr(f, &p->from);
- if(t != Z)
- naddr(t, &p->to);
- if(debug['g'])
- print("%P\n", p);
-}
-
-void
-gopcode(int o, Node *f1, Node *f2, Node *t)
-{
- int a, et;
- Adr ta;
- Node nod;
-
- et = TLONG;
- if(f1 != Z && f1->type != T) {
- if(f1->op == OCONST && t != Z && t->type != T)
- et = t->type->etype;
- else
- et = f1->type->etype;
- }
- a = AGOK;
- switch(o) {
- case OAS:
- gmove(f1, t);
- return;
-
- case OASADD:
- case OADD:
- a = AADDL;
- if(et == TFLOAT)
- a = AADDS;
- else
- if(et == TDOUBLE)
- a = AADDT;
- else
- if(et == TVLONG || et == TUVLONG)
- a = AADDQ;
- break;
-
- case OASSUB:
- case OSUB:
- a = ASUBL;
- if(et == TFLOAT)
- a = ASUBS;
- else
- if(et == TDOUBLE)
- a = ASUBT;
- else
- if(et == TVLONG || et == TUVLONG)
- a = ASUBQ;
- break;
-
- case OASOR:
- case OOR:
- a = AOR;
- break;
-
- case OASAND:
- case OAND:
- a = AAND;
- break;
-
- case OASXOR:
- case OXOR:
- a = AXOR;
- break;
-
- case OASLSHR:
- case OLSHR:
- a = ASRLL;
- if(et == TVLONG || et == TUVLONG)
- a = ASRLQ;
- break;
-
- case OASASHR:
- case OASHR:
- a = ASRAL;
- if(et == TVLONG || et == TUVLONG)
- a = ASRAQ;
- break;
-
- case OASASHL:
- case OASHL:
- a = ASLLL;
- if(et == TVLONG || et == TUVLONG)
- a = ASLLQ;
- break;
-
- case OFUNC:
- a = AJSR;
- break;
-
- case OASLMUL:
- case OLMUL:
- case OASMUL:
- case OMUL:
- a = AMULL;
- if(et == TFLOAT)
- a = AMULS;
- else
- if(et == TDOUBLE)
- a = AMULT;
- else
- if(et == TVLONG || et == TUVLONG)
- a = AMULQ;
- break;
-
- case OASDIV:
- case ODIV:
- a = ADIVL;
- if(et == TFLOAT)
- a = ADIVS;
- else
- if(et == TDOUBLE)
- a = ADIVT;
- else
- if(et == TVLONG || et == TUVLONG)
- a = ADIVQ;
- break;
-
- case OASMOD:
- case OMOD:
- a = AMODL;
- if(et == TVLONG || et == TUVLONG)
- a = AMODQ;
- break;
-
- case OASLMOD:
- case OLMOD:
- a = AMODLU;
- if(et == TVLONG || et == TUVLONG)
- a = AMODQU;
- break;
-
- case OASLDIV:
- case OLDIV:
- a = ADIVLU;
- if(et == TVLONG || et == TUVLONG)
- a = ADIVQU;
- break;
-
- case OEQ:
- case ONE:
- a = ACMPEQ;
- if(typefd[et])
- a = ACMPTEQ;
- else if (vconst(t) == 0) {
- a = (o == OEQ) ? ABEQ : ABNE;
- t = Z;
- break;
- }
- goto cmp;
-
- case OLT:
- case OGE:
- a = ACMPGT;
- if(typefd[et])
- a = ACMPTGT;
- else if (vconst(t) == 0) {
- a = (o == OLT) ? ABLT : ABGE;
- t = Z;
- break;
- }
- goto cmp;
-
- case OLE:
- case OGT:
- a = ACMPGE;
- if(typefd[et])
- a = ACMPTGE;
- else
- if(vconst(t) == 0) {
- a = (o == OLE)? ABLE: ABGT;
- t = Z;
- break;
- }
- goto cmp;
-
- case OLO:
- case OHS:
- a = ACMPUGT;
- goto cmp;
-
- case OLS:
- case OHI:
- a = ACMPUGE;
- goto cmp;
-
- cmp:
- nextpc();
- p->as = a;
- raddr(f1, p);
- naddr(t, &p->from);
- regalloc(&nod, t, Z);
- naddr(&nod, &p->to);
- if(debug['g'])
- print("%P\n", p);
- if(o == OEQ || o == OLT || o == OLE || o == OLO || o == OLS)
- a = typefd[et]? AFBNE: ABNE;
- else
- a = typefd[et]? AFBEQ: ABEQ;
- nextpc();
- p->as = a;
- naddr(&nod, &p->from);
- regfree(&nod);
- if(debug['g'])
- print("%P\n", p);
- return;
- }
- if(a == AGOK)
- diag(Z, "bad in gopcode %O", o);
- nextpc();
- p->as = a;
- if(f1 != Z)
- naddr(f1, &p->from);
- if(f2 != Z) {
- naddr(f2, &ta);
- p->reg = ta.reg;
- if(ta.type == D_CONST && ta.offset == 0)
- p->reg = REGZERO;
- }
- if(t != Z)
- naddr(t, &p->to);
- if(debug['g'])
- print("%P\n", p);
-}
-
-samaddr(Node *f, Node *t)
-{
-
- if(f->op != t->op)
- return 0;
- switch(f->op) {
-
- case OREGISTER:
- if(f->reg != t->reg)
- break;
- return 1;
- }
- return 0;
-}
-
-void
-gbranch(int o)
-{
- int a;
-
- a = AGOK;
- switch(o) {
- case ORETURN:
- a = ARET;
- break;
- case OGOTO:
- a = AJMP;
- break;
- }
- nextpc();
- if(a == AGOK) {
- diag(Z, "bad in gbranch %O", o);
- nextpc();
- }
- p->as = a;
-}
-
-void
-patch(Prog *op, long pc)
-{
-
- op->to.offset = pc;
- op->to.type = D_BRANCH;
-}
-
-void
-gpseudo(int a, Sym *s, Node *n)
-{
-
- nextpc();
- p->as = a;
- p->from.type = D_OREG;
- p->from.sym = s;
- if(a == ATEXT)
- p->reg = (profileflg ? 0 : NOPROF);
- p->from.name = D_EXTERN;
- if(s->class == CSTATIC)
- p->from.name = D_STATIC;
- naddr(n, &p->to);
- if(a == ADATA || a == AGLOBL)
- pc--;
-}
-
-int
-sconst(Node *n)
-{
- vlong vv;
-
- if(n->op == OCONST) {
- if(!typefd[n->type->etype]) {
- vv = n->vconst;
- if(vv >= -32766LL && vv < 32766LL)
- return 1;
- }
- }
- return 0;
-}
-
-int
-sval(long v)
-{
- if(v >= -32766L && v < 32766L)
- return 1;
- return 0;
-}
-
-int
-bval(vlong v)
-{
-
- if(v >= 0LL && v < 256LL)
- return 1;
- return 0;
-}
-
-int
-bconst(Node *n)
-{
- vlong vv;
-
- if(n->op == OCONST) {
- if(!typefd[n->type->etype]) {
- vv = n->vconst;
- if(vv >= 0LL && vv < 256LL)
- return 1;
- }
- }
- return 0;
-}
-
-long
-exreg(Type *t)
-{
- long o;
-
- if(typechlp[t->etype]) {
- if(exregoffset <= 12)
- return 0;
- o = exregoffset;
- exregoffset--;
- return o;
- }
- if(typefd[t->etype]) {
- if(exfregoffset <= 19)
- return 0;
- o = exfregoffset + NREG;
- 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] */
-};