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