123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- #include "l.h"
- void
- span(void)
- {
- Prog *p;
- Sym *setext;
- Optab *o;
- int m;
- long c;
- if(debug['v'])
- Bprint(&bso, "%5.2f span\n", cputime());
- Bflush(&bso);
- c = INITTEXT;
- for(p = firstp; p != P; p = p->link) {
- p->pc = c;
- o = oplook(p);
- m = o->size;
- if(m == 0) {
- if(p->as == ATEXT) {
- curtext = p;
- autosize = p->to.offset + 4;
- if(p->from.sym != S)
- p->from.sym->value = c;
- continue;
- }
- if(p->as != ANOP)
- diag("zero-width instruction\n%P\n", p);
- continue;
- }
- c += m;
- }
- c = rnd(c, 8);
- setext = lookup("etext", 0);
- if(setext != S) {
- setext->value = c;
- textsize = c - INITTEXT;
- }
- if(INITRND)
- INITDAT = rnd(c, INITRND);
- if(debug['v'])
- Bprint(&bso, "tsize = %lux\n", textsize);
- Bflush(&bso);
- }
-
- void
- xdefine(char *p, int t, long v)
- {
- Sym *s;
- s = lookup(p, 0);
- if(s->type == 0 || s->type == SXREF) {
- s->type = t;
- s->value = v;
- }
- }
- long
- regoff(Adr *a)
- {
- instoffset = 0;
- aclass(a);
- return instoffset;
- }
- int
- aclass(Adr *a)
- {
- Sym *s;
- int t;
- switch(a->type) {
- case D_NONE:
- return C_NONE;
- case D_REG:
- return C_REG;
- case D_FREG:
- return C_FREG;
- case D_CREG:
- return C_CREG;
- case D_PREG:
- if(a->reg == D_FSR)
- return C_FSR;
- if(a->reg == D_FPQ)
- return C_FQ;
- return C_PREG;
- case D_OREG:
- switch(a->name) {
- case D_EXTERN:
- case D_STATIC:
- if(a->sym == S)
- break;
- t = a->sym->type;
- if(t == 0 || t == SXREF) {
- diag("undefined external: %s in %s\n",
- a->sym->name, TNAME);
- a->sym->type = SDATA;
- }
- instoffset = a->sym->value + a->offset - BIG;
- if(instoffset >= -BIG && instoffset < BIG) {
- if(instoffset & 7)
- return C_OSEXT;
- return C_ESEXT;
- }
- if(instoffset & 7)
- return C_OLEXT;
- return C_ELEXT;
- case D_AUTO:
- instoffset = autosize + a->offset;
- goto dauto;
- case D_PARAM:
- instoffset = autosize + a->offset + 4L;
- dauto:
- if(instoffset >= -BIG && instoffset < BIG) {
- if(instoffset & 7)
- return C_OSAUTO;
- return C_ESAUTO;
- }
- if(instoffset & 7)
- return C_OLAUTO;
- return C_ELAUTO;
- case D_NONE:
- instoffset = a->offset;
- if(instoffset == 0)
- return C_ZOREG;
- if(instoffset >= -BIG && instoffset < BIG)
- return C_SOREG;
- return C_LOREG;
- }
- return C_GOK;
- case D_ASI:
- if(a->name == D_NONE)
- return C_ASI;
- return C_GOK;
- case D_CONST:
- switch(a->name) {
- case D_NONE:
- instoffset = a->offset;
- consize:
- if(instoffset == 0)
- return C_ZCON;
- if(instoffset >= -0x1000 && instoffset <= 0xfff)
- return C_SCON;
- if((instoffset & 0x3ff) == 0)
- return C_UCON;
- return C_LCON;
- case D_EXTERN:
- case D_STATIC:
- s = a->sym;
- if(s == S)
- break;
- t = s->type;
- if(t == 0 || t == SXREF) {
- diag("undefined external: %s in %s\n",
- s->name, TNAME);
- s->type = SDATA;
- }
- if(s->type == STEXT || s->type == SLEAF) {
- instoffset = s->value + a->offset;
- return C_LCON;
- }
- if(s->type == SCONST) {
- instoffset = s->value + a->offset;
- goto consize;
- }
- instoffset = s->value + a->offset - BIG;
- if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
- return C_SECON;
- instoffset = s->value + a->offset + INITDAT;
- /* not sure why this barfs */
- return C_LCON;
- if(instoffset == 0)
- return C_ZCON;
- if(instoffset >= -0x1000 && instoffset <= 0xfff)
- return C_SCON;
- if((instoffset & 0x3ff) == 0)
- return C_UCON;
- return C_LCON;
- case D_AUTO:
- instoffset = autosize + a->offset;
- if(instoffset >= -BIG && instoffset < BIG)
- return C_SACON;
- return C_LACON;
- case D_PARAM:
- instoffset = autosize + a->offset + 4L;
- if(instoffset >= -BIG && instoffset < BIG)
- return C_SACON;
- return C_LACON;
- }
- return C_GOK;
- case D_BRANCH:
- return C_SBRA;
- }
- return C_GOK;
- }
- Optab*
- oplook(Prog *p)
- {
- int a1, a2, a3, r;
- char *c1, *c3;
- Optab *o, *e;
- a1 = p->optab;
- if(a1)
- return optab+(a1-1);
- a1 = p->from.class;
- if(a1 == 0) {
- a1 = aclass(&p->from) + 1;
- p->from.class = a1;
- }
- a1--;
- a3 = p->to.class;
- if(a3 == 0) {
- a3 = aclass(&p->to) + 1;
- p->to.class = a3;
- }
- a3--;
- a2 = C_NONE;
- if(p->reg != NREG)
- a2 = C_REG;
- r = p->as;
- o = oprange[r].start;
- if(o == 0)
- o = oprange[r].stop; /* just generate an error */
- e = oprange[r].stop;
- c1 = xcmp[a1];
- c3 = xcmp[a3];
- for(; o<e; o++)
- if(o->a2 == a2)
- if(c1[o->a1])
- if(c3[o->a3]) {
- p->optab = (o-optab)+1;
- return o;
- }
- diag("illegal combination %A %d %d %d\n",
- p->as, a1, a2, a3);
- if(1||!debug['a'])
- prasm(p);
- if(o == 0)
- errorexit();
- return o;
- }
- int
- cmp(int a, int b)
- {
- if(a == b)
- return 1;
- switch(a) {
- case C_LCON:
- if(b == C_ZCON || b == C_SCON || b == C_UCON)
- return 1;
- break;
- case C_UCON:
- if(b == C_ZCON)
- return 1;
- break;
- case C_SCON:
- if(b == C_ZCON)
- return 1;
- break;
- case C_LACON:
- if(b == C_SACON)
- return 1;
- break;
- case C_LBRA:
- if(b == C_SBRA)
- return 1;
- break;
- case C_ELEXT:
- if(b == C_ESEXT)
- return 1;
- break;
- case C_LEXT:
- if(b == C_SEXT ||
- b == C_ESEXT || b == C_OSEXT ||
- b == C_ELEXT || b == C_OLEXT)
- return 1;
- break;
- case C_SEXT:
- if(b == C_ESEXT || b == C_OSEXT)
- return 1;
- break;
- case C_ELAUTO:
- if(b == C_ESAUTO)
- return 1;
- break;
- case C_LAUTO:
- if(b == C_SAUTO ||
- b == C_ESAUTO || b == C_OSAUTO ||
- b == C_ELAUTO || b == C_OLAUTO)
- return 1;
- break;
- case C_SAUTO:
- if(b == C_ESAUTO || b == C_OSAUTO)
- return 1;
- break;
- case C_REG:
- if(b == C_ZCON)
- return 1;
- break;
- case C_LOREG:
- if(b == C_ZOREG || b == C_SOREG)
- return 1;
- break;
- case C_SOREG:
- if(b == C_ZOREG)
- return 1;
- break;
- case C_ANY:
- return 1;
- }
- return 0;
- }
- int
- ocmp(const void *a1, const void *a2)
- {
- Optab *p1, *p2;
- int n;
- p1 = (Optab*)a1;
- p2 = (Optab*)a2;
- n = p1->as - p2->as;
- if(n)
- return n;
- n = p1->a1 - p2->a1;
- if(n)
- return n;
- n = p1->a2 - p2->a2;
- if(n)
- return n;
- n = p1->a3 - p2->a3;
- if(n)
- return n;
- return 0;
- }
- void
- buildop(void)
- {
- int i, n, r;
- for(i=0; i<C_NCLASS; i++)
- for(n=0; n<C_NCLASS; n++)
- xcmp[i][n] = cmp(n, i);
- for(n=0; optab[n].as != AXXX; n++)
- ;
- qsort(optab, n, sizeof(optab[0]), ocmp);
- for(i=0; i<n; i++) {
- r = optab[i].as;
- oprange[r].start = optab+i;
- while(optab[i].as == r)
- i++;
- oprange[r].stop = optab+i;
- i--;
-
- switch(r)
- {
- default:
- diag("unknown op in build: %A\n", r);
- errorexit();
- case AADD:
- oprange[AADDX] = oprange[r];
- oprange[ASUB] = oprange[r];
- oprange[ASUBX] = oprange[r];
- oprange[AMUL] = oprange[r];
- oprange[AXOR] = oprange[r];
- oprange[AXNOR] = oprange[r];
- oprange[AAND] = oprange[r];
- oprange[AANDN] = oprange[r];
- oprange[AOR] = oprange[r];
- oprange[AORN] = oprange[r];
- oprange[ASLL] = oprange[r];
- oprange[ASRL] = oprange[r];
- oprange[ASRA] = oprange[r];
- oprange[AADDCC] = oprange[r];
- oprange[AADDXCC] = oprange[r];
- oprange[ATADDCC] = oprange[r];
- oprange[ATADDCCTV] = oprange[r];
- oprange[ASUBCC] = oprange[r];
- oprange[ASUBXCC] = oprange[r];
- oprange[ATSUBCC] = oprange[r];
- oprange[ATSUBCCTV] = oprange[r];
- oprange[AXORCC] = oprange[r];
- oprange[AXNORCC] = oprange[r];
- oprange[AANDCC] = oprange[r];
- oprange[AANDNCC] = oprange[r];
- oprange[AORCC] = oprange[r];
- oprange[AORNCC] = oprange[r];
- oprange[AMULSCC] = oprange[r];
- oprange[ASAVE] = oprange[r];
- oprange[ARESTORE] = oprange[r];
- break;
- case AMOVB:
- oprange[AMOVH] = oprange[r];
- oprange[AMOVHU] = oprange[r];
- oprange[AMOVBU] = oprange[r];
- oprange[ASWAP] = oprange[r];
- oprange[ATAS] = oprange[r];
- break;
- case ABA:
- oprange[ABN] = oprange[r];
- oprange[AFBA] = oprange[r];
- oprange[AFBN] = oprange[r];
- break;
- case ABE:
- oprange[ABCC] = oprange[r];
- oprange[ABCS] = oprange[r];
- oprange[ABGE] = oprange[r];
- oprange[ABGU] = oprange[r];
- oprange[ABG] = oprange[r];
- oprange[ABLEU] = oprange[r];
- oprange[ABLE] = oprange[r];
- oprange[ABL] = oprange[r];
- oprange[ABNEG] = oprange[r];
- oprange[ABNE] = oprange[r];
- oprange[ABPOS] = oprange[r];
- oprange[ABVC] = oprange[r];
- oprange[ABVS] = oprange[r];
- oprange[AFBE] = oprange[r];
- oprange[AFBG] = oprange[r];
- oprange[AFBGE] = oprange[r];
- oprange[AFBL] = oprange[r];
- oprange[AFBLE] = oprange[r];
- oprange[AFBLG] = oprange[r];
- oprange[AFBNE] = oprange[r];
- oprange[AFBO] = oprange[r];
- oprange[AFBU] = oprange[r];
- oprange[AFBUE] = oprange[r];
- oprange[AFBUG] = oprange[r];
- oprange[AFBUGE] = oprange[r];
- oprange[AFBUL] = oprange[r];
- oprange[AFBULE] = oprange[r];
- break;
- case ATA:
- oprange[ATCC] = oprange[r];
- oprange[ATCS] = oprange[r];
- oprange[ATE] = oprange[r];
- oprange[ATGE] = oprange[r];
- oprange[ATGU] = oprange[r];
- oprange[ATG] = oprange[r];
- oprange[ATLEU] = oprange[r];
- oprange[ATLE] = oprange[r];
- oprange[ATL] = oprange[r];
- oprange[ATNEG] = oprange[r];
- oprange[ATNE] = oprange[r];
- oprange[ATN] = oprange[r];
- oprange[ATPOS] = oprange[r];
- oprange[ATVC] = oprange[r];
- oprange[ATVS] = oprange[r];
- break;
- case AFADDD:
- oprange[AFADDF] = oprange[r];
- oprange[AFADDX] = oprange[r];
- oprange[AFDIVD] = oprange[r];
- oprange[AFDIVF] = oprange[r];
- oprange[AFDIVX] = oprange[r];
- oprange[AFMULD] = oprange[r];
- oprange[AFMULF] = oprange[r];
- oprange[AFMULX] = oprange[r];
- oprange[AFSUBD] = oprange[r];
- oprange[AFSUBF] = oprange[r];
- oprange[AFSUBX] = oprange[r];
- break;
- case AFCMPD:
- oprange[AFCMPF] = oprange[r];
- oprange[AFCMPX] = oprange[r];
- oprange[AFCMPED] = oprange[r];
- oprange[AFCMPEF] = oprange[r];
- oprange[AFCMPEX] = oprange[r];
- break;
- case AFABSF:
- oprange[AFMOVDF] = oprange[r];
- oprange[AFMOVDW] = oprange[r];
- oprange[AFMOVFD] = oprange[r];
- oprange[AFMOVFW] = oprange[r];
- oprange[AFMOVWD] = oprange[r];
- oprange[AFMOVWF] = oprange[r];
- oprange[AFNEGF] = oprange[r];
- oprange[AFSQRTD] = oprange[r];
- oprange[AFSQRTF] = oprange[r];
- break;
- case AFMOVF:
- case AFMOVD:
- case AMOVW:
- case AMOVD:
- case AWORD:
- case ARETT:
- case AJMPL:
- case AJMP:
- case ACMP:
- case ANOP:
- case ATEXT:
- case ADIV:
- case ADIVL:
- case AMOD:
- case AMODL:
- break;
- }
- }
- }
|