123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903 |
- #include "gc.h"
- void
- tindex(Type *tf, Type *tt)
- {
- int i, j;
- j = 0;
- if(tt != T) {
- j = tt->etype;
- if(j >= NTYPE)
- j = 0;
- }
- i = 0;
- if(tf != T) {
- i = tf->etype;
- if(i >= NTYPE)
- if(typesu[i])
- i = j;
- else
- i = 0;
- }
- txtp = &txt[i][j];
- }
- void
- ginit(void)
- {
- int i, j, si, sj;
- thestring = "68000";
- thechar = '1';
- exregoffset = 7;
- exaregoffset = 5;
- exfregoffset = 7;
- listinit();
- for(i=0; i<NREG; i++) {
- regused[i] = 0;
- fregused[i] = 0;
- aregused[i] = 0;
- }
- regaddr(D_A0+6);
- regaddr(D_A0+7);
- for(i=0; i<sizeof(regbase); i++)
- regbase[i] = D_NONE;
- for(i=0; i<NREG; i++) {
- regbase[D_R0+i] = D_R0+i;
- regbase[D_A0+i] = D_A0+i;
- regbase[D_F0+i] = D_F0+i;
- }
- regbase[D_TOS] = D_TOS;
- for(i=0; i<NTYPE; i++)
- for(j=0; j<NTYPE; j++) {
- txtp = &txt[i][j];
- txtp->movas = AGOK;
- txtp->preclr = 0;
- txtp->postext = AGOK;
- if(!(typechlp[i] && typechlp[j]))
- continue;
- si = types[i]->width;
- sj = types[j]->width;
- if(sj < si)
- txtp->preclr = -1;
- if(sj > si) {
- if(typeu[i]) {
- txtp->preclr = 1;
- } else {
- if(sj == 2)
- txtp->postext = AEXTBW;
- else
- if(sj == 4)
- if(si == 1)
- txtp->postext = AEXTBL;
- else
- txtp->postext = AEXTWL;
- }
- sj = si;
- }
- if(sj == 1)
- txtp->movas = AMOVB;
- if(sj == 2)
- txtp->movas = AMOVW;
- if(sj == 4)
- txtp->movas = AMOVL;
- }
- for(i=0; i<ALLOP; i++)
- for(j=0; j<NTYPE; j++)
- opxt[i][j] = AGOK;
- oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK);
- oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED);
- oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED);
- oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK);
- oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
- oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
- oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
- oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
- oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
- oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
- oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
- oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD);
- oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK);
- oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
- oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
- oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK);
- oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK);
- oinit(OOR, AORB, AORW, AORL, AGOK, AGOK);
- oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK);
- oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
- oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
- oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD);
- oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK);
- oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD);
- oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
- oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
- oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
- oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
- oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
- oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
- oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
- oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK);
- nstring = 0;
- mnstring = 0;
- nrathole = 0;
- nstatic = 0;
- pc = 0;
- breakpc = -1;
- continpc = -1;
- cases = C;
- firstp = P;
- lastp = P;
- tfield = types[TLONG];
- zprog.link = P;
- zprog.as = AGOK;
- zprog.from.type = D_NONE;
- zprog.to = zprog.from;
- nodret = new(ONAME, Z, Z);
- nodret->sym = slookup(".ret");
- nodret->type = types[TIND];
- nodret->etype = types[TIND]->etype;
- nodret->class = CPARAM;
- nodret = new(OIND, nodret, Z);
- complex(nodret);
- symrathole = slookup(".rathole");
- symrathole->class = CGLOBL;
- symrathole->type = typ(TARRAY, types[TCHAR]);
- nodrat = new(ONAME, Z, Z);
- nodrat->sym = symrathole;
- nodrat->type = types[TIND];
- nodrat->etype = TVOID;
- nodrat->class = CGLOBL;
- complex(nodrat);
- nodrat->type = symrathole->type;
- com64init();
- symstatic = slookup(".static");
- symstatic->class = CSTATIC;
- symstatic->type = typ(TARRAY, types[TLONG]);
- }
- void
- gclean(void)
- {
- int i;
- Sym *s;
- regfree(D_A0+6);
- regfree(D_A0+7);
- for(i=0; i<NREG; i++) {
- if(regused[i])
- diag(Z, "missing R%d", i);
- if(aregused[i])
- diag(Z, "missing A%d", i);
- if(fregused[i])
- diag(Z, "missing F%d", i);
- }
- while(mnstring)
- outstring("", 1L);
- symstring->type->width = nstring;
- symstatic->type->width = nstatic;
- symrathole->type->width = nrathole;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->link) {
- if(s->type == T)
- continue;
- if(s->type->width == 0)
- continue;
- if(s->class != CGLOBL && s->class != CSTATIC)
- continue;
- if(s->type == types[TENUM])
- continue;
- gpseudo(AGLOBL, s, D_CONST, s->type->width);
- pc--;
- }
- nextpc();
- p->as = AEND;
- outcode();
- }
- void
- oinit(int o, int ab, int aw, int al, int af, int ad)
- {
- int i;
- i = o;
- if(i >= ALLOP) {
- diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP);
- errorexit();
- }
- opxt[i][TCHAR] = ab;
- opxt[i][TUCHAR] = ab;
- opxt[i][TSHORT] = aw;
- opxt[i][TUSHORT] = aw;
- opxt[i][TINT] = al;
- opxt[i][TUINT] = al;
- opxt[i][TLONG] = al;
- opxt[i][TULONG] = al;
- opxt[i][TIND] = al;
- opxt[i][TFLOAT] = af;
- opxt[i][TDOUBLE] = ad;
- }
- Prog*
- prg(void)
- {
- Prog *p;
- p = alloc(sizeof(*p));
- *p = zprog;
- return p;
- }
- void
- nextpc(void)
- {
- p = prg();
- pc++;
- p->lineno = nearln;
- if(firstp == P) {
- firstp = p;
- lastp = p;
- return;
- }
- lastp->link = p;
- lastp = p;
- }
- void
- gargs(Node *n)
- {
- long s;
- loop:
- if(n == Z)
- return;
- if(n->op == OLIST) {
- gargs(n->right);
- n = n->left;
- goto loop;
- }
- s = argoff;
- cgen(n, D_TOS, n);
- argoff = s + n->type->width;
- }
- void
- naddr(Node *n, Adr *a, int x)
- {
- Node *l;
- long v;
- switch(n->op) {
- default:
- bad:
- diag(n, "bad in naddr: %O", n->op);
- break;
- case OADDR:
- case OIND:
- naddr(n->left, a, x);
- goto noadd;
- case OREGISTER:
- a->sym = S;
- a->type = n->reg;
- a->offset = n->xoffset;
- a->displace = 0;
- break;
- case ONAME:
- a->etype = n->etype;
- a->displace = 0;
- a->sym = n->sym;
- a->offset = n->xoffset;
- a->type = D_STATIC;
- if(n->class == CSTATIC)
- break;
- if(n->class == CEXTERN || n->class == CGLOBL) {
- a->type = D_EXTERN;
- break;
- }
- if(n->class == CAUTO) {
- a->type = D_AUTO;
- break;
- }
- if(n->class == CPARAM) {
- a->type = D_PARAM;
- break;
- }
- goto bad;
- case OCONST:
- a->displace = 0;
- if(typefd[n->type->etype]) {
- a->type = D_FCONST;
- a->dval = n->fconst;
- break;
- }
- a->type = D_CONST;
- a->offset = n->vconst;
- break;
- case OADD:
- l = n->left;
- if(l->addable == 20) {
- v = l->vconst;
- naddr(n->right, a, x);
- goto add;
- }
- l = n->right;
- if(l->addable == 20) {
- v = l->vconst;
- naddr(n->left, a, x);
- goto add;
- }
- goto bad;
- noadd:
- v = 0;
- add:
- switch(n->addable) {
- default:
- goto bad;
- case 2:
- a->displace += v;
- break;
- case 21:
- a->type &= D_MASK;
- a->type |= I_INDIR;
- break;
- case 1:
- case 12:
- a->offset += v;
- a->type &= D_MASK;
- a->type |= I_ADDR;
- break;
- case 10:
- case 11:
- case 20:
- a->type &= D_MASK;
- a->type |= I_DIR;
- break;
- }
- break;
- case OPREINC:
- case OPREDEC:
- case OPOSTINC:
- case OPOSTDEC:
- case OAS:
- case OASLMUL:
- case OASLDIV:
- case OASLMOD:
- case OASMUL:
- case OASDIV:
- case OASMOD:
- case OASXOR:
- case OASOR:
- case OASADD:
- case OASSUB:
- case OASLSHR:
- case OASASHR:
- case OASASHL:
- case OASAND:
- naddr(n->left, a, x);
- break;
- }
- }
- int
- regalloc(Type *t, int g)
- {
- if(t == T)
- return D_NONE;
- g &= D_MASK;
- if(typefd[t->etype]) {
- if(g >= D_F0 && g < D_F0+NREG) {
- fregused[g-D_F0]++;
- return g;
- }
- for(g=0; g<NREG; g++)
- if(fregused[g] == 0) {
- fregused[g]++;
- return g + D_F0;
- }
- } else {
- if(g >= D_R0 && g < D_R0+NREG) {
- regused[g-D_R0]++;
- return g;
- }
- for(g=0; g<NREG; g++)
- if(regused[g] == 0) {
- regused[g]++;
- return g + D_R0;
- }
- }
- diag(Z, "out of registers");
- return D_TOS;
- }
- int
- regaddr(int g)
- {
- if(g >= D_A0 && g < D_A0+NREG) {
- aregused[g-D_A0]++;
- return g;
- }
- for(g=0; g<NREG; g++)
- if(aregused[g] == 0) {
- aregused[g]++;
- return g + D_A0;
- }
- diag(Z, "out of addr registers");
- return D_TOS;
- }
- int
- regpair(int g)
- {
- if(g >= D_R0+1 && g < D_R0+NREG)
- if(!regused[g-D_R0-1]) {
- regused[g-D_R0-1]++;
- regused[g-D_R0]++;
- return g-1;
- }
- if(g >= D_R0 && g < D_R0+NREG-1)
- if(!regused[g-D_R0+1]) {
- regused[g-D_R0+1]++;
- regused[g-D_R0]++;
- return g;
- }
- for(g = 0; g < NREG-1; g++)
- if(!regused[g])
- if(!regused[g+1]) {
- regused[g]++;
- regused[g+1]++;
- return g + D_R0;
- }
- diag(Z, "out of register pairs");
- return D_TOS;
- }
- int
- regret(Type *t)
- {
- if(t == T)
- return D_NONE;
- if(typefd[t->etype])
- return D_F0;
- return D_R0;
- }
- void
- regfree(int g)
- {
- g &= D_MASK;
- if(g == D_TOS || g == D_TREE || g == D_NONE)
- return;
- if(g >= D_R0 && g < D_R0+NREG) {
- regused[g-D_R0]--;
- return;
- }
- if(g >= D_A0 && g < D_A0+NREG) {
- aregused[g-D_A0]--;
- return;
- }
- if(g >= D_F0 && g < D_F0+NREG) {
- fregused[g-D_F0]--;
- return;
- }
- diag(Z, "bad in regfree: %d", g);
- }
- void
- gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t)
- {
- int g, a, b;
- Prog *p1;
- tindex(tf, tt);
- if(txtp->preclr) {
- if(gf >= D_R0 && gf < D_R0+NREG)
- if(txtp->preclr < 0) {
- gmove(tt, tt, gf, f, gt, t);
- return;
- }
- g = regalloc(types[TLONG], gt);
- if(g == gf) {
- g = regalloc(types[TLONG], D_NONE);
- regfree(gf);
- }
- if(txtp->preclr > 0)
- gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z);
- gopcode(OAS, tf, gf, f, g, Z);
- if(g != gt)
- gopcode(OAS, tt, g, Z, gt, t);
- regfree(g);
- return;
- }
- a = txtp->postext;
- if(a != AGOK) {
- if(gf >= D_R0 && gf < D_R0+NREG)
- g = regalloc(types[TLONG], gf);
- else
- g = regalloc(types[TLONG], gt);
- if(g != gf)
- gopcode(OAS, tf, gf, f, g, Z);
- nextpc();
- p->as = a;
- p->to.type = g;
- if(debug['g'])
- print("%P\n", p);
- if(g != gt)
- gopcode(OAS, tt, g, Z, gt, t);
- regfree(g);
- return;
- }
- if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) ||
- (gf == D_TREE && gt == D_TREE && f == t))
- return;
- if(typefd[tf->etype] || typefd[tt->etype]) {
- if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */
- a = regalloc(types[TLONG], D_NONE);
- gmove(tf, types[TLONG], gf, f, a, t);
- if(tf->etype == TULONG) {
- b = regalloc(types[TDOUBLE], D_NONE);
- gmove(types[TLONG], tt, a, t, b, t);
- gopcode(OTST, types[TLONG], D_NONE, Z, a, t);
- gbranch(OGE);
- p1 = p;
- gopcode(OASADD, types[TDOUBLE],
- D_CONST, nodconst(100), b, t);
- p->from.dval = 4294967296.;
- patch(p1, pc);
- gmove(types[TDOUBLE], tt, b, t, gt, t);
- regfree(b);
- } else
- gmove(types[TLONG], tt, a, t, gt, t);
- regfree(a);
- return;
- }
- if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
- a = regalloc(types[TLONG], D_NONE);
- gopcode(OAS, types[TLONG], D_FPCR, t, a, t);
- gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t);
- }
- if(gf < D_F0 || gf >= D_F0+NREG) {
- g = regalloc(types[TDOUBLE], gt);
- gopcode(OFAS, tf, gf, f, g, t);
- if(g != gt)
- gopcode(OFAS, tt, g, t, gt, t);
- regfree(g);
- } else
- gopcode(OFAS, tt, gf, f, gt, t);
- if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
- gopcode(OAS, types[TLONG], a, t, D_FPCR, t);
- regfree(a);
- }
- return;
- }
- gopcode(OAS, tt, gf, f, gt, t);
- }
- void
- gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t)
- {
- int i, fidx, tidx;
- if(o == OAS)
- if(gf == gt)
- if(gf != D_TREE || f == t)
- return;
- fidx = D_NONE;
- tidx = D_NONE;
- i = 0;
- if(ty != T) {
- i = ty->etype;
- if(i >= NTYPE)
- i = 0;
- }
- nextpc();
- if(gf == D_TREE) {
- naddr(f, &p->from, fidx);
- } else {
- p->from.type = gf;
- if(gf == D_CONST) {
- p->from.offset = (long)(uintptr)f;
- if(typefd[i]) {
- p->from.type = D_FCONST;
- p->from.dval = (long)(uintptr)f;
- }
- }
- }
- p->as = opxt[o][i];
- if(gt == D_TREE) {
- naddr(t, &p->to, tidx);
- } else {
- p->to.type = gt;
- if(gt == D_CONST)
- p->to.offset = (long)(uintptr)t;
- }
- if(o == OBIT) {
- p->from.field = f->type->nbits;
- p->to.field = f->type->shift;
- if(p->from.field == 0)
- diag(Z, "BIT zero width bit field");
- }
- if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB)
- asopt();
- if(debug['g'])
- print("%P\n", p);
- if(p->as == AGOK)
- diag(Z, "GOK in gopcode: %s", onames[o]);
- if(fidx != D_NONE)
- regfree(fidx);
- if(tidx != D_NONE)
- regfree(tidx);
- }
- void
- asopt(void)
- {
- long v;
- int g;
- Prog *q;
- /*
- * mov $0, ...
- * ==>
- * clr , ...
- */
- v = 0;
- if(p->from.type == D_CONST) {
- v = p->from.offset;
- if(v == 0) {
- p->from.type = D_NONE;
- if(p->as == AMOVL)
- p->as = ACLRL;
- if(p->as == AMOVW)
- p->as = ACLRW;
- if(p->as == AMOVB)
- p->as = ACLRB;
- return;
- }
- }
- /*
- * mov ..., TOS
- * ==>
- * pea (...)
- */
- if(p->as == AMOVL && p->to.type == D_TOS)
- switch(p->from.type) {
- case D_CONST:
- p->from.type |= I_INDIR;
- p->to = p->from;
- p->from = zprog.from;
- p->as = APEA;
- return;
- case I_ADDR|D_EXTERN:
- case I_ADDR|D_STATIC:
- p->from.type &= ~I_ADDR;
- p->to = p->from;
- p->from = zprog.from;
- p->as = APEA;
- return;
- }
- /*
- * movL $Qx, ...
- * ==>
- * movL $Qx,R
- * movL R, ...
- */
- if(p->as == AMOVL && p->from.type == D_CONST)
- if(v >= -128 && v < 128)
- if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) {
- g = regalloc(types[TLONG], D_NONE);
- q = p;
- nextpc();
- p->as = AMOVL;
- p->from.type = g;
- p->to = q->to;
- q->to = p->from;
- regfree(g);
- if(debug['g'])
- print("%P\n", q);
- return;
- }
- }
- void
- gbranch(int o)
- {
- int a;
- a = ABNE;
- switch(o) {
- case ORETURN: a = ARTS; break;
- case OGOTO: a = ABRA; break;
- case OEQ: a = ABEQ; break;
- case ONE: a = ABNE; break;
- case OLE: a = ABLE; break;
- case OLS: a = ABLS; break;
- case OLT: a = ABLT; break;
- case OLO: a = ABCS; break;
- case OGE: a = ABGE; break;
- case OHS: a = ABCC; break;
- case OGT: a = ABGT; break;
- case OHI: a = ABHI; break;
- case OBIT: a = ABCS; break;
- case OCASE: a = ABCASE; break;
- }
- nextpc();
- p->from.type = D_NONE;
- p->to.type = D_NONE;
- p->as = a;
- }
- void
- fpbranch(void)
- {
- int a;
- a = p->as;
- switch(a) {
- case ABEQ: a = AFBEQ; break;
- case ABNE: a = AFBNE; break;
- case ABLE: a = AFBLE; break;
- case ABLT: a = AFBLT; break;
- case ABGE: a = AFBGE; break;
- case ABGT: a = AFBGT; break;
- }
- p->as = a;
- }
- void
- patch(Prog *op, long pc)
- {
- op->to.offset = pc;
- op->to.type = D_BRANCH;
- }
- void
- gpseudo(int a, Sym *s, int g, long v)
- {
- nextpc();
- if(a == ADATA)
- pc--;
- p->as = a;
- p->to.type = g;
- p->to.offset = v;
- p->from.sym = s;
- p->from.type = D_EXTERN;
- if(s->class == CSTATIC)
- p->from.type = D_STATIC;
- }
- void
- gpseudotree(int a, Sym *s, Node *n)
- {
- nextpc();
- if(a == ADATA)
- pc--;
- p->as = a;
- naddr(n, &p->to, D_NONE);
- p->from.sym = s;
- p->from.type = D_EXTERN;
- if(s->class == CSTATIC)
- p->from.type = D_STATIC;
- }
- long
- exreg(Type *t)
- {
- long o;
- if(typechl[t->etype]) {
- if(exregoffset <= 5)
- return 0;
- o = exregoffset + D_R0;
- exregoffset--;
- return o;
- }
- if(t->etype == TIND) {
- if(exaregoffset <= 3)
- return 0;
- o = exaregoffset + D_A0;
- exaregoffset--;
- return o;
- }
- if(typefd[t->etype]) {
- if(exfregoffset <= 5)
- return 0;
- o = exfregoffset + D_F0;
- exfregoffset--;
- return o;
- }
- return 0;
- }
- schar ewidth[NTYPE] =
- {
- -1, /* [TXXX] */
- SZ_CHAR, /* [TCHAR] */
- SZ_CHAR, /* [TUCHAR] */
- SZ_SHORT, /* [TSHORT] */
- SZ_SHORT, /* [TUSHORT] */
- SZ_INT, /* [TINT] */
- SZ_INT, /* [TUINT] */
- SZ_LONG, /* [TLONG] */
- SZ_LONG, /* [TULONG] */
- SZ_VLONG, /* [TVLONG] */
- SZ_VLONG, /* [TUVLONG] */
- SZ_FLOAT, /* [TFLOAT] */
- SZ_DOUBLE, /* [TDOUBLE] */
- SZ_IND, /* [TIND] */
- 0, /* [TFUNC] */
- -1, /* [TARRAY] */
- 0, /* [TVOID] */
- -1, /* [TSTRUCT] */
- -1, /* [TUNION] */
- SZ_INT, /* [TENUM] */
- };
- long ncast[NTYPE] =
- {
- 0, /* [TXXX] */
- BCHAR|BUCHAR, /* [TCHAR] */
- BCHAR|BUCHAR, /* [TUCHAR] */
- BSHORT|BUSHORT, /* [TSHORT] */
- BSHORT|BUSHORT, /* [TUSHORT] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
- BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
- BVLONG|BUVLONG, /* [TVLONG] */
- BVLONG|BUVLONG, /* [TUVLONG] */
- BFLOAT, /* [TFLOAT] */
- BDOUBLE, /* [TDOUBLE] */
- BLONG|BULONG|BIND, /* [TIND] */
- 0, /* [TFUNC] */
- 0, /* [TARRAY] */
- 0, /* [TVOID] */
- BSTRUCT, /* [TSTRUCT] */
- BUNION, /* [TUNION] */
- 0, /* [TENUM] */
- };
|