174a4d8c2SCharles.Forsyth #include "l.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth void
span(void)474a4d8c2SCharles.Forsyth span(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth Prog *p, *q;
774a4d8c2SCharles.Forsyth Sym *setext;
874a4d8c2SCharles.Forsyth Optab *o;
974a4d8c2SCharles.Forsyth int m, bflag;
1074a4d8c2SCharles.Forsyth long c, otxt;
1174a4d8c2SCharles.Forsyth
1274a4d8c2SCharles.Forsyth if(debug['v'])
1374a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f span\n", cputime());
1474a4d8c2SCharles.Forsyth Bflush(&bso);
1574a4d8c2SCharles.Forsyth
1674a4d8c2SCharles.Forsyth bflag = 0;
1774a4d8c2SCharles.Forsyth c = INITTEXT;
1874a4d8c2SCharles.Forsyth otxt = c;
1974a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
2074a4d8c2SCharles.Forsyth p->pc = c;
2174a4d8c2SCharles.Forsyth o = oplook(p);
2274a4d8c2SCharles.Forsyth m = o->size;
2374a4d8c2SCharles.Forsyth if(m == 0) {
2474a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
2574a4d8c2SCharles.Forsyth curtext = p;
2674a4d8c2SCharles.Forsyth autosize = p->to.offset + 8;
2774a4d8c2SCharles.Forsyth if(p->from.sym != S)
2874a4d8c2SCharles.Forsyth p->from.sym->value = c;
2974a4d8c2SCharles.Forsyth /* need passes to resolve branches */
3074a4d8c2SCharles.Forsyth if(c-otxt >= 1L<<17)
3174a4d8c2SCharles.Forsyth bflag = 1;
3274a4d8c2SCharles.Forsyth otxt = c;
3374a4d8c2SCharles.Forsyth continue;
3474a4d8c2SCharles.Forsyth }
3574a4d8c2SCharles.Forsyth diag("zero-width instruction\n%P\n", p);
3674a4d8c2SCharles.Forsyth continue;
3774a4d8c2SCharles.Forsyth }
3874a4d8c2SCharles.Forsyth c += m;
3974a4d8c2SCharles.Forsyth }
4074a4d8c2SCharles.Forsyth
4174a4d8c2SCharles.Forsyth /*
4274a4d8c2SCharles.Forsyth * if any procedure is large enough to
4374a4d8c2SCharles.Forsyth * generate a large SBRA branch, then
4474a4d8c2SCharles.Forsyth * generate extra passes putting branches
4574a4d8c2SCharles.Forsyth * around jmps to fix. this is rare.
4674a4d8c2SCharles.Forsyth */
4774a4d8c2SCharles.Forsyth while(bflag) {
4874a4d8c2SCharles.Forsyth if(debug['v'])
4974a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f span1\n", cputime());
5074a4d8c2SCharles.Forsyth bflag = 0;
5174a4d8c2SCharles.Forsyth c = INITTEXT;
5274a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
5374a4d8c2SCharles.Forsyth p->pc = c;
5474a4d8c2SCharles.Forsyth o = oplook(p);
5574a4d8c2SCharles.Forsyth if(o->type == 6 && p->cond) {
5674a4d8c2SCharles.Forsyth otxt = p->cond->pc - c;
5774a4d8c2SCharles.Forsyth if(otxt < 0)
5874a4d8c2SCharles.Forsyth otxt = -otxt;
5974a4d8c2SCharles.Forsyth if(otxt >= (1L<<17) - 10) {
6074a4d8c2SCharles.Forsyth q = prg();
6174a4d8c2SCharles.Forsyth q->link = p->link;
6274a4d8c2SCharles.Forsyth p->link = q;
6374a4d8c2SCharles.Forsyth q->as = AJMP;
6474a4d8c2SCharles.Forsyth q->to.type = D_BRANCH;
6574a4d8c2SCharles.Forsyth q->cond = p->cond;
6674a4d8c2SCharles.Forsyth p->cond = q;
6774a4d8c2SCharles.Forsyth q = prg();
6874a4d8c2SCharles.Forsyth q->link = p->link;
6974a4d8c2SCharles.Forsyth p->link = q;
7074a4d8c2SCharles.Forsyth q->as = AJMP;
7174a4d8c2SCharles.Forsyth q->to.type = D_BRANCH;
7274a4d8c2SCharles.Forsyth q->cond = q->link->link;
7374a4d8c2SCharles.Forsyth addnop(p->link);
7474a4d8c2SCharles.Forsyth addnop(p);
7574a4d8c2SCharles.Forsyth bflag = 1;
7674a4d8c2SCharles.Forsyth }
7774a4d8c2SCharles.Forsyth }
7874a4d8c2SCharles.Forsyth m = o->size;
7974a4d8c2SCharles.Forsyth if(m == 0) {
8074a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
8174a4d8c2SCharles.Forsyth curtext = p;
8274a4d8c2SCharles.Forsyth autosize = p->to.offset + 8;
8374a4d8c2SCharles.Forsyth if(p->from.sym != S)
8474a4d8c2SCharles.Forsyth p->from.sym->value = c;
8574a4d8c2SCharles.Forsyth continue;
8674a4d8c2SCharles.Forsyth }
8774a4d8c2SCharles.Forsyth diag("zero-width instruction\n%P\n", p);
8874a4d8c2SCharles.Forsyth continue;
8974a4d8c2SCharles.Forsyth }
9074a4d8c2SCharles.Forsyth c += m;
9174a4d8c2SCharles.Forsyth }
9274a4d8c2SCharles.Forsyth }
9374a4d8c2SCharles.Forsyth c = rnd(c, 8);
9474a4d8c2SCharles.Forsyth
9574a4d8c2SCharles.Forsyth setext = lookup("etext", 0);
9674a4d8c2SCharles.Forsyth if(setext != S) {
9774a4d8c2SCharles.Forsyth setext->value = c;
9874a4d8c2SCharles.Forsyth textsize = c - INITTEXT;
9974a4d8c2SCharles.Forsyth }
10074a4d8c2SCharles.Forsyth if(INITRND)
10174a4d8c2SCharles.Forsyth INITDAT = rnd(c, INITRND);
10274a4d8c2SCharles.Forsyth if(debug['v'])
10374a4d8c2SCharles.Forsyth Bprint(&bso, "tsize = %lux\n", textsize);
10474a4d8c2SCharles.Forsyth Bflush(&bso);
10574a4d8c2SCharles.Forsyth }
10674a4d8c2SCharles.Forsyth
10774a4d8c2SCharles.Forsyth void
xdefine(char * p,int t,long v)10874a4d8c2SCharles.Forsyth xdefine(char *p, int t, long v)
10974a4d8c2SCharles.Forsyth {
11074a4d8c2SCharles.Forsyth Sym *s;
11174a4d8c2SCharles.Forsyth
11274a4d8c2SCharles.Forsyth s = lookup(p, 0);
11374a4d8c2SCharles.Forsyth if(s->type == 0 || s->type == SXREF) {
11474a4d8c2SCharles.Forsyth s->type = t;
11574a4d8c2SCharles.Forsyth s->value = v;
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth }
11874a4d8c2SCharles.Forsyth
11974a4d8c2SCharles.Forsyth long
regoff(Adr * a)12074a4d8c2SCharles.Forsyth regoff(Adr *a)
12174a4d8c2SCharles.Forsyth {
12274a4d8c2SCharles.Forsyth
12374a4d8c2SCharles.Forsyth instoffset = 0;
12474a4d8c2SCharles.Forsyth aclass(a);
12574a4d8c2SCharles.Forsyth return instoffset;
12674a4d8c2SCharles.Forsyth }
12774a4d8c2SCharles.Forsyth
12874a4d8c2SCharles.Forsyth int
aclass(Adr * a)12974a4d8c2SCharles.Forsyth aclass(Adr *a)
13074a4d8c2SCharles.Forsyth {
13174a4d8c2SCharles.Forsyth Sym *s;
13274a4d8c2SCharles.Forsyth int t;
13374a4d8c2SCharles.Forsyth
13474a4d8c2SCharles.Forsyth switch(a->type) {
13574a4d8c2SCharles.Forsyth case D_NONE:
13674a4d8c2SCharles.Forsyth return C_NONE;
13774a4d8c2SCharles.Forsyth
13874a4d8c2SCharles.Forsyth case D_REG:
13974a4d8c2SCharles.Forsyth return C_REG;
14074a4d8c2SCharles.Forsyth
14174a4d8c2SCharles.Forsyth case D_FREG:
14274a4d8c2SCharles.Forsyth return C_FREG;
14374a4d8c2SCharles.Forsyth
14474a4d8c2SCharles.Forsyth case D_FCREG:
14574a4d8c2SCharles.Forsyth return C_FCREG;
14674a4d8c2SCharles.Forsyth
14774a4d8c2SCharles.Forsyth case D_MREG:
14874a4d8c2SCharles.Forsyth return C_MREG;
14974a4d8c2SCharles.Forsyth
15074a4d8c2SCharles.Forsyth case D_OREG:
15174a4d8c2SCharles.Forsyth switch(a->name) {
15274a4d8c2SCharles.Forsyth case D_EXTERN:
15374a4d8c2SCharles.Forsyth case D_STATIC:
15474a4d8c2SCharles.Forsyth if(a->sym == 0 || a->sym->name == 0) {
15574a4d8c2SCharles.Forsyth print("null sym external\n");
15674a4d8c2SCharles.Forsyth print("%D\n", a);
15774a4d8c2SCharles.Forsyth return C_GOK;
15874a4d8c2SCharles.Forsyth }
15974a4d8c2SCharles.Forsyth t = a->sym->type;
16074a4d8c2SCharles.Forsyth if(t == 0 || t == SXREF) {
16174a4d8c2SCharles.Forsyth diag("undefined external: %s in %s\n",
16274a4d8c2SCharles.Forsyth a->sym->name, TNAME);
16374a4d8c2SCharles.Forsyth a->sym->type = SDATA;
16474a4d8c2SCharles.Forsyth }
16574a4d8c2SCharles.Forsyth instoffset = a->sym->value + a->offset - BIG;
16674a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG)
16774a4d8c2SCharles.Forsyth return C_SEXT;
16874a4d8c2SCharles.Forsyth return C_LEXT;
16974a4d8c2SCharles.Forsyth case D_AUTO:
17074a4d8c2SCharles.Forsyth instoffset = autosize + a->offset;
17174a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG)
17274a4d8c2SCharles.Forsyth return C_SAUTO;
17374a4d8c2SCharles.Forsyth return C_LAUTO;
17474a4d8c2SCharles.Forsyth
17574a4d8c2SCharles.Forsyth case D_PARAM:
17674a4d8c2SCharles.Forsyth instoffset = autosize + a->offset + 8L;
17774a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG)
17874a4d8c2SCharles.Forsyth return C_SAUTO;
17974a4d8c2SCharles.Forsyth return C_LAUTO;
18074a4d8c2SCharles.Forsyth case D_NONE:
18174a4d8c2SCharles.Forsyth instoffset = a->offset;
18274a4d8c2SCharles.Forsyth if(instoffset == 0)
18374a4d8c2SCharles.Forsyth return C_ZOREG;
18474a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG)
18574a4d8c2SCharles.Forsyth return C_SOREG;
18674a4d8c2SCharles.Forsyth return C_LOREG;
18774a4d8c2SCharles.Forsyth }
18874a4d8c2SCharles.Forsyth return C_GOK;
18974a4d8c2SCharles.Forsyth
19074a4d8c2SCharles.Forsyth case D_HI:
19174a4d8c2SCharles.Forsyth return C_LO;
19274a4d8c2SCharles.Forsyth case D_LO:
19374a4d8c2SCharles.Forsyth return C_HI;
19474a4d8c2SCharles.Forsyth
19574a4d8c2SCharles.Forsyth case D_OCONST:
19674a4d8c2SCharles.Forsyth switch(a->name) {
19774a4d8c2SCharles.Forsyth case D_EXTERN:
19874a4d8c2SCharles.Forsyth case D_STATIC:
19974a4d8c2SCharles.Forsyth s = a->sym;
20074a4d8c2SCharles.Forsyth t = s->type;
20174a4d8c2SCharles.Forsyth if(t == 0 || t == SXREF) {
20274a4d8c2SCharles.Forsyth diag("undefined external: %s in %s\n",
20374a4d8c2SCharles.Forsyth s->name, TNAME);
20474a4d8c2SCharles.Forsyth s->type = SDATA;
20574a4d8c2SCharles.Forsyth }
20674a4d8c2SCharles.Forsyth instoffset = s->value + a->offset + INITDAT;
20774a4d8c2SCharles.Forsyth if(s->type == STEXT || s->type == SLEAF)
20874a4d8c2SCharles.Forsyth instoffset = s->value + a->offset;
20974a4d8c2SCharles.Forsyth return C_LCON;
21074a4d8c2SCharles.Forsyth }
21174a4d8c2SCharles.Forsyth return C_GOK;
21274a4d8c2SCharles.Forsyth
21374a4d8c2SCharles.Forsyth case D_CONST:
21474a4d8c2SCharles.Forsyth switch(a->name) {
21574a4d8c2SCharles.Forsyth
21674a4d8c2SCharles.Forsyth case D_NONE:
21774a4d8c2SCharles.Forsyth instoffset = a->offset;
21874a4d8c2SCharles.Forsyth consize:
21974a4d8c2SCharles.Forsyth if(instoffset > 0) {
22074a4d8c2SCharles.Forsyth if(instoffset <= 0x7fff)
22174a4d8c2SCharles.Forsyth return C_SCON;
22274a4d8c2SCharles.Forsyth if(instoffset <= 0xffff)
22374a4d8c2SCharles.Forsyth return C_ANDCON;
22474a4d8c2SCharles.Forsyth if((instoffset & 0xffff) == 0)
22574a4d8c2SCharles.Forsyth return C_UCON;
22674a4d8c2SCharles.Forsyth return C_LCON;
22774a4d8c2SCharles.Forsyth }
22874a4d8c2SCharles.Forsyth if(instoffset == 0)
22974a4d8c2SCharles.Forsyth return C_ZCON;
23074a4d8c2SCharles.Forsyth if(instoffset >= -0x8000)
23174a4d8c2SCharles.Forsyth return C_ADDCON;
23274a4d8c2SCharles.Forsyth if((instoffset & 0xffff) == 0)
23374a4d8c2SCharles.Forsyth return C_UCON;
23474a4d8c2SCharles.Forsyth return C_LCON;
23574a4d8c2SCharles.Forsyth
23674a4d8c2SCharles.Forsyth case D_EXTERN:
23774a4d8c2SCharles.Forsyth case D_STATIC:
23874a4d8c2SCharles.Forsyth s = a->sym;
23974a4d8c2SCharles.Forsyth if(s == S)
24074a4d8c2SCharles.Forsyth break;
24174a4d8c2SCharles.Forsyth t = s->type;
24274a4d8c2SCharles.Forsyth switch(t) {
24374a4d8c2SCharles.Forsyth case 0:
24474a4d8c2SCharles.Forsyth case SXREF:
24574a4d8c2SCharles.Forsyth diag("undefined external: %s in %s\n",
24674a4d8c2SCharles.Forsyth s->name, TNAME);
24774a4d8c2SCharles.Forsyth s->type = SDATA;
24874a4d8c2SCharles.Forsyth break;
24974a4d8c2SCharles.Forsyth case SCONST:
25074a4d8c2SCharles.Forsyth instoffset = s->value + a->offset;
25174a4d8c2SCharles.Forsyth goto consize;
25274a4d8c2SCharles.Forsyth case STEXT:
25374a4d8c2SCharles.Forsyth case SLEAF:
25474a4d8c2SCharles.Forsyth instoffset = s->value + a->offset;
25574a4d8c2SCharles.Forsyth return C_LCON;
25674a4d8c2SCharles.Forsyth }
25774a4d8c2SCharles.Forsyth instoffset = s->value + a->offset - BIG;
25874a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG && instoffset != 0L)
25974a4d8c2SCharles.Forsyth return C_SECON;
26074a4d8c2SCharles.Forsyth instoffset = s->value + a->offset + INITDAT;
26174a4d8c2SCharles.Forsyth return C_LCON;
26274a4d8c2SCharles.Forsyth
26374a4d8c2SCharles.Forsyth case D_AUTO:
26474a4d8c2SCharles.Forsyth instoffset = autosize + a->offset;
26574a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG)
26674a4d8c2SCharles.Forsyth return C_SACON;
26774a4d8c2SCharles.Forsyth return C_LACON;
26874a4d8c2SCharles.Forsyth
26974a4d8c2SCharles.Forsyth case D_PARAM:
27074a4d8c2SCharles.Forsyth instoffset = autosize + a->offset + 8L;
27174a4d8c2SCharles.Forsyth if(instoffset >= -BIG && instoffset < BIG)
27274a4d8c2SCharles.Forsyth return C_SACON;
27374a4d8c2SCharles.Forsyth return C_LACON;
27474a4d8c2SCharles.Forsyth }
27574a4d8c2SCharles.Forsyth return C_GOK;
27674a4d8c2SCharles.Forsyth
27774a4d8c2SCharles.Forsyth case D_BRANCH:
27874a4d8c2SCharles.Forsyth return C_SBRA;
27974a4d8c2SCharles.Forsyth }
28074a4d8c2SCharles.Forsyth return C_GOK;
28174a4d8c2SCharles.Forsyth }
28274a4d8c2SCharles.Forsyth
28374a4d8c2SCharles.Forsyth Optab*
oplook(Prog * p)28474a4d8c2SCharles.Forsyth oplook(Prog *p)
28574a4d8c2SCharles.Forsyth {
28674a4d8c2SCharles.Forsyth int a1, a2, a3, r, t;
28774a4d8c2SCharles.Forsyth char *c1, *c3;
28874a4d8c2SCharles.Forsyth Optab *o, *e;
28974a4d8c2SCharles.Forsyth
29074a4d8c2SCharles.Forsyth a1 = p->optab;
29174a4d8c2SCharles.Forsyth if(a1)
29274a4d8c2SCharles.Forsyth return optab+(a1-1);
29374a4d8c2SCharles.Forsyth a1 = p->from.class;
29474a4d8c2SCharles.Forsyth if(a1 == 0) {
29574a4d8c2SCharles.Forsyth a1 = aclass(&p->from) + 1;
29674a4d8c2SCharles.Forsyth p->from.class = a1;
29774a4d8c2SCharles.Forsyth }
29874a4d8c2SCharles.Forsyth a1--;
29974a4d8c2SCharles.Forsyth a3 = p->to.class;
30074a4d8c2SCharles.Forsyth if(a3 == 0) {
30174a4d8c2SCharles.Forsyth a3 = aclass(&p->to) + 1;
30274a4d8c2SCharles.Forsyth p->to.class = a3;
30374a4d8c2SCharles.Forsyth }
30474a4d8c2SCharles.Forsyth a3--;
30574a4d8c2SCharles.Forsyth a2 = C_NONE;
30674a4d8c2SCharles.Forsyth if(p->reg != NREG)
30774a4d8c2SCharles.Forsyth a2 = C_REG;
30874a4d8c2SCharles.Forsyth r = p->as;
30974a4d8c2SCharles.Forsyth o = oprange[r].start;
31074a4d8c2SCharles.Forsyth if(o == 0) {
31174a4d8c2SCharles.Forsyth t = opcross[repop[r]][a1][a2][a3];
31274a4d8c2SCharles.Forsyth if(t) {
31374a4d8c2SCharles.Forsyth p->optab = t+1;
31474a4d8c2SCharles.Forsyth return optab+t;
31574a4d8c2SCharles.Forsyth }
31674a4d8c2SCharles.Forsyth o = oprange[r].stop; /* just generate an error */
31774a4d8c2SCharles.Forsyth }
31874a4d8c2SCharles.Forsyth e = oprange[r].stop;
31974a4d8c2SCharles.Forsyth c1 = xcmp[a1];
32074a4d8c2SCharles.Forsyth c3 = xcmp[a3];
32174a4d8c2SCharles.Forsyth for(; o<e; o++)
32274a4d8c2SCharles.Forsyth if(o->a2 == a2)
32374a4d8c2SCharles.Forsyth if(c1[o->a1])
32474a4d8c2SCharles.Forsyth if(c3[o->a3]) {
32574a4d8c2SCharles.Forsyth p->optab = (o-optab)+1;
32674a4d8c2SCharles.Forsyth return o;
32774a4d8c2SCharles.Forsyth }
32874a4d8c2SCharles.Forsyth diag("illegal combination %A %d %d %d",
32974a4d8c2SCharles.Forsyth p->as, a1, a2, a3);
33074a4d8c2SCharles.Forsyth if(!debug['a'])
33174a4d8c2SCharles.Forsyth prasm(p);
33274a4d8c2SCharles.Forsyth o = optab;
33374a4d8c2SCharles.Forsyth p->optab = (o-optab)+1;
33474a4d8c2SCharles.Forsyth return o;
33574a4d8c2SCharles.Forsyth }
33674a4d8c2SCharles.Forsyth
33774a4d8c2SCharles.Forsyth int
cmp(int a,int b)33874a4d8c2SCharles.Forsyth cmp(int a, int b)
33974a4d8c2SCharles.Forsyth {
34074a4d8c2SCharles.Forsyth
34174a4d8c2SCharles.Forsyth if(a == b)
34274a4d8c2SCharles.Forsyth return 1;
34374a4d8c2SCharles.Forsyth switch(a) {
34474a4d8c2SCharles.Forsyth case C_LCON:
34574a4d8c2SCharles.Forsyth if(b == C_ZCON || b == C_SCON || b == C_UCON ||
34674a4d8c2SCharles.Forsyth b == C_ADDCON || b == C_ANDCON)
34774a4d8c2SCharles.Forsyth return 1;
34874a4d8c2SCharles.Forsyth break;
34974a4d8c2SCharles.Forsyth case C_ADD0CON:
35074a4d8c2SCharles.Forsyth if(b == C_ADDCON)
35174a4d8c2SCharles.Forsyth return 1;
35274a4d8c2SCharles.Forsyth case C_ADDCON:
35374a4d8c2SCharles.Forsyth if(b == C_ZCON || b == C_SCON)
35474a4d8c2SCharles.Forsyth return 1;
35574a4d8c2SCharles.Forsyth break;
35674a4d8c2SCharles.Forsyth case C_AND0CON:
35774a4d8c2SCharles.Forsyth if(b == C_ANDCON)
35874a4d8c2SCharles.Forsyth return 1;
35974a4d8c2SCharles.Forsyth case C_ANDCON:
36074a4d8c2SCharles.Forsyth if(b == C_ZCON || b == C_SCON)
36174a4d8c2SCharles.Forsyth return 1;
36274a4d8c2SCharles.Forsyth break;
36374a4d8c2SCharles.Forsyth case C_UCON:
36474a4d8c2SCharles.Forsyth if(b == C_ZCON)
36574a4d8c2SCharles.Forsyth return 1;
36674a4d8c2SCharles.Forsyth break;
36774a4d8c2SCharles.Forsyth case C_SCON:
36874a4d8c2SCharles.Forsyth if(b == C_ZCON)
36974a4d8c2SCharles.Forsyth return 1;
37074a4d8c2SCharles.Forsyth break;
37174a4d8c2SCharles.Forsyth case C_LACON:
37274a4d8c2SCharles.Forsyth if(b == C_SACON)
37374a4d8c2SCharles.Forsyth return 1;
37474a4d8c2SCharles.Forsyth break;
37574a4d8c2SCharles.Forsyth case C_LBRA:
37674a4d8c2SCharles.Forsyth if(b == C_SBRA)
37774a4d8c2SCharles.Forsyth return 1;
37874a4d8c2SCharles.Forsyth break;
37974a4d8c2SCharles.Forsyth case C_LEXT:
38074a4d8c2SCharles.Forsyth if(b == C_SEXT)
38174a4d8c2SCharles.Forsyth return 1;
38274a4d8c2SCharles.Forsyth break;
38374a4d8c2SCharles.Forsyth case C_LAUTO:
38474a4d8c2SCharles.Forsyth if(b == C_SAUTO)
38574a4d8c2SCharles.Forsyth return 1;
38674a4d8c2SCharles.Forsyth break;
38774a4d8c2SCharles.Forsyth case C_REG:
38874a4d8c2SCharles.Forsyth if(b == C_ZCON)
38974a4d8c2SCharles.Forsyth return 1;
39074a4d8c2SCharles.Forsyth break;
39174a4d8c2SCharles.Forsyth case C_LOREG:
39274a4d8c2SCharles.Forsyth if(b == C_ZOREG || b == C_SOREG)
39374a4d8c2SCharles.Forsyth return 1;
39474a4d8c2SCharles.Forsyth break;
39574a4d8c2SCharles.Forsyth case C_SOREG:
39674a4d8c2SCharles.Forsyth if(b == C_ZOREG)
39774a4d8c2SCharles.Forsyth return 1;
39874a4d8c2SCharles.Forsyth break;
39974a4d8c2SCharles.Forsyth }
40074a4d8c2SCharles.Forsyth return 0;
40174a4d8c2SCharles.Forsyth }
40274a4d8c2SCharles.Forsyth
40374a4d8c2SCharles.Forsyth int
ocmp(void * a1,void * a2)404*45a20ab7Sforsyth ocmp(void *a1, void *a2)
40574a4d8c2SCharles.Forsyth {
40674a4d8c2SCharles.Forsyth Optab *p1, *p2;
40774a4d8c2SCharles.Forsyth int n;
40874a4d8c2SCharles.Forsyth
40974a4d8c2SCharles.Forsyth p1 = (Optab*)a1;
41074a4d8c2SCharles.Forsyth p2 = (Optab*)a2;
41174a4d8c2SCharles.Forsyth n = p1->as - p2->as;
41274a4d8c2SCharles.Forsyth if(n)
41374a4d8c2SCharles.Forsyth return n;
41474a4d8c2SCharles.Forsyth n = p1->a1 - p2->a1;
41574a4d8c2SCharles.Forsyth if(n)
41674a4d8c2SCharles.Forsyth return n;
41774a4d8c2SCharles.Forsyth n = p1->a2 - p2->a2;
41874a4d8c2SCharles.Forsyth if(n)
41974a4d8c2SCharles.Forsyth return n;
42074a4d8c2SCharles.Forsyth n = p1->a3 - p2->a3;
42174a4d8c2SCharles.Forsyth if(n)
42274a4d8c2SCharles.Forsyth return n;
42374a4d8c2SCharles.Forsyth return 0;
42474a4d8c2SCharles.Forsyth }
42574a4d8c2SCharles.Forsyth
42674a4d8c2SCharles.Forsyth void
buildop(void)42774a4d8c2SCharles.Forsyth buildop(void)
42874a4d8c2SCharles.Forsyth {
42974a4d8c2SCharles.Forsyth int i, n, r;
43074a4d8c2SCharles.Forsyth
43174a4d8c2SCharles.Forsyth for(i=0; i<32; i++)
43274a4d8c2SCharles.Forsyth for(n=0; n<32; n++)
43374a4d8c2SCharles.Forsyth xcmp[i][n] = cmp(n, i);
43474a4d8c2SCharles.Forsyth for(n=0; optab[n].as != AXXX; n++)
43574a4d8c2SCharles.Forsyth ;
43674a4d8c2SCharles.Forsyth qsort(optab, n, sizeof(optab[0]), ocmp);
43774a4d8c2SCharles.Forsyth for(i=0; i<n; i++) {
43874a4d8c2SCharles.Forsyth r = optab[i].as;
43974a4d8c2SCharles.Forsyth oprange[r].start = optab+i;
44074a4d8c2SCharles.Forsyth while(optab[i].as == r)
44174a4d8c2SCharles.Forsyth i++;
44274a4d8c2SCharles.Forsyth oprange[r].stop = optab+i;
44374a4d8c2SCharles.Forsyth i--;
44474a4d8c2SCharles.Forsyth
44574a4d8c2SCharles.Forsyth switch(r)
44674a4d8c2SCharles.Forsyth {
44774a4d8c2SCharles.Forsyth default:
44874a4d8c2SCharles.Forsyth diag("unknown op in build: %A\n", r);
44974a4d8c2SCharles.Forsyth errorexit();
45074a4d8c2SCharles.Forsyth case AABSF:
45174a4d8c2SCharles.Forsyth oprange[AMOVFD] = oprange[r];
45274a4d8c2SCharles.Forsyth oprange[AMOVDF] = oprange[r];
45374a4d8c2SCharles.Forsyth oprange[AMOVWF] = oprange[r];
45474a4d8c2SCharles.Forsyth oprange[AMOVFW] = oprange[r];
45574a4d8c2SCharles.Forsyth oprange[AMOVWD] = oprange[r];
45674a4d8c2SCharles.Forsyth oprange[AMOVDW] = oprange[r];
45774a4d8c2SCharles.Forsyth oprange[ANEGF] = oprange[r];
45874a4d8c2SCharles.Forsyth oprange[ANEGD] = oprange[r];
45974a4d8c2SCharles.Forsyth oprange[AABSD] = oprange[r];
46074a4d8c2SCharles.Forsyth oprange[ATRUNCDW] = oprange[r];
46174a4d8c2SCharles.Forsyth oprange[ATRUNCFW] = oprange[r];
46274a4d8c2SCharles.Forsyth oprange[ATRUNCDV] = oprange[r];
46374a4d8c2SCharles.Forsyth oprange[ATRUNCFV] = oprange[r];
46474a4d8c2SCharles.Forsyth oprange[AMOVDV] = oprange[r];
46574a4d8c2SCharles.Forsyth oprange[AMOVFV] = oprange[r];
46674a4d8c2SCharles.Forsyth oprange[AMOVVD] = oprange[r];
46774a4d8c2SCharles.Forsyth oprange[AMOVVF] = oprange[r];
46874a4d8c2SCharles.Forsyth break;
46974a4d8c2SCharles.Forsyth case AADD:
47074a4d8c2SCharles.Forsyth buildrep(1, AADD);
47174a4d8c2SCharles.Forsyth oprange[ASGT] = oprange[r];
47274a4d8c2SCharles.Forsyth repop[ASGT] = 1;
47374a4d8c2SCharles.Forsyth oprange[ASGTU] = oprange[r];
47474a4d8c2SCharles.Forsyth repop[ASGTU] = 1;
47574a4d8c2SCharles.Forsyth oprange[AADDU] = oprange[r];
47674a4d8c2SCharles.Forsyth repop[AADDU] = 1;
47774a4d8c2SCharles.Forsyth oprange[AADDVU] = oprange[r];
47874a4d8c2SCharles.Forsyth repop[AADDVU] = 1;
47974a4d8c2SCharles.Forsyth oprange[AADDV] = oprange[r];
48074a4d8c2SCharles.Forsyth repop[AADDV] = 1;
48174a4d8c2SCharles.Forsyth break;
48274a4d8c2SCharles.Forsyth case AADDF:
48374a4d8c2SCharles.Forsyth oprange[ADIVF] = oprange[r];
48474a4d8c2SCharles.Forsyth oprange[ADIVD] = oprange[r];
48574a4d8c2SCharles.Forsyth oprange[AMULF] = oprange[r];
48674a4d8c2SCharles.Forsyth oprange[AMULD] = oprange[r];
48774a4d8c2SCharles.Forsyth oprange[ASUBF] = oprange[r];
48874a4d8c2SCharles.Forsyth oprange[ASUBD] = oprange[r];
48974a4d8c2SCharles.Forsyth oprange[AADDD] = oprange[r];
49074a4d8c2SCharles.Forsyth break;
49174a4d8c2SCharles.Forsyth case AAND:
49274a4d8c2SCharles.Forsyth buildrep(2, AAND);
49374a4d8c2SCharles.Forsyth oprange[AXOR] = oprange[r];
49474a4d8c2SCharles.Forsyth repop[AXOR] = 2;
49574a4d8c2SCharles.Forsyth oprange[AOR] = oprange[r];
49674a4d8c2SCharles.Forsyth repop[AOR] = 2;
49774a4d8c2SCharles.Forsyth break;
49874a4d8c2SCharles.Forsyth case ABEQ:
49974a4d8c2SCharles.Forsyth oprange[ABNE] = oprange[r];
50074a4d8c2SCharles.Forsyth break;
50174a4d8c2SCharles.Forsyth case ABLEZ:
50274a4d8c2SCharles.Forsyth oprange[ABGEZ] = oprange[r];
50374a4d8c2SCharles.Forsyth oprange[ABGEZAL] = oprange[r];
50474a4d8c2SCharles.Forsyth oprange[ABLTZ] = oprange[r];
50574a4d8c2SCharles.Forsyth oprange[ABLTZAL] = oprange[r];
50674a4d8c2SCharles.Forsyth oprange[ABGTZ] = oprange[r];
50774a4d8c2SCharles.Forsyth break;
50874a4d8c2SCharles.Forsyth case AMOVB:
50974a4d8c2SCharles.Forsyth buildrep(3, AMOVB);
51074a4d8c2SCharles.Forsyth oprange[AMOVH] = oprange[r];
51174a4d8c2SCharles.Forsyth repop[AMOVH] = 3;
51274a4d8c2SCharles.Forsyth break;
51374a4d8c2SCharles.Forsyth case AMOVBU:
51474a4d8c2SCharles.Forsyth buildrep(4, AMOVBU);
51574a4d8c2SCharles.Forsyth oprange[AMOVHU] = oprange[r];
51674a4d8c2SCharles.Forsyth repop[AMOVHU] = 4;
51774a4d8c2SCharles.Forsyth break;
51874a4d8c2SCharles.Forsyth case AMUL:
51974a4d8c2SCharles.Forsyth oprange[AREM] = oprange[r];
52074a4d8c2SCharles.Forsyth oprange[AREMU] = oprange[r];
52174a4d8c2SCharles.Forsyth oprange[ADIVU] = oprange[r];
52274a4d8c2SCharles.Forsyth oprange[AMULU] = oprange[r];
52374a4d8c2SCharles.Forsyth oprange[ADIV] = oprange[r];
52474a4d8c2SCharles.Forsyth oprange[ADIVV] = oprange[r];
52574a4d8c2SCharles.Forsyth oprange[ADIVVU] = oprange[r];
52674a4d8c2SCharles.Forsyth oprange[AMULV] = oprange[r];
52774a4d8c2SCharles.Forsyth oprange[AMULVU] = oprange[r];
52874a4d8c2SCharles.Forsyth oprange[AREMV] = oprange[r];
52974a4d8c2SCharles.Forsyth oprange[AREMVU] = oprange[r];
53074a4d8c2SCharles.Forsyth break;
53174a4d8c2SCharles.Forsyth case ASLL:
53274a4d8c2SCharles.Forsyth oprange[ASRL] = oprange[r];
53374a4d8c2SCharles.Forsyth oprange[ASRA] = oprange[r];
53474a4d8c2SCharles.Forsyth oprange[ASLLV] = oprange[r];
53574a4d8c2SCharles.Forsyth oprange[ASRAV] = oprange[r];
53674a4d8c2SCharles.Forsyth oprange[ASRLV] = oprange[r];
53774a4d8c2SCharles.Forsyth break;
53874a4d8c2SCharles.Forsyth case ASUB:
53974a4d8c2SCharles.Forsyth oprange[ASUBU] = oprange[r];
54074a4d8c2SCharles.Forsyth oprange[ASUBV] = oprange[r];
54174a4d8c2SCharles.Forsyth oprange[ASUBVU] = oprange[r];
54274a4d8c2SCharles.Forsyth oprange[ANOR] = oprange[r];
54374a4d8c2SCharles.Forsyth break;
54474a4d8c2SCharles.Forsyth case ASYSCALL:
54574a4d8c2SCharles.Forsyth oprange[ATLBP] = oprange[r];
54674a4d8c2SCharles.Forsyth oprange[ATLBR] = oprange[r];
54774a4d8c2SCharles.Forsyth oprange[ATLBWI] = oprange[r];
54874a4d8c2SCharles.Forsyth oprange[ATLBWR] = oprange[r];
54974a4d8c2SCharles.Forsyth break;
55074a4d8c2SCharles.Forsyth case ACMPEQF:
55174a4d8c2SCharles.Forsyth oprange[ACMPGTF] = oprange[r];
55274a4d8c2SCharles.Forsyth oprange[ACMPGTD] = oprange[r];
55374a4d8c2SCharles.Forsyth oprange[ACMPGEF] = oprange[r];
55474a4d8c2SCharles.Forsyth oprange[ACMPGED] = oprange[r];
55574a4d8c2SCharles.Forsyth oprange[ACMPEQD] = oprange[r];
55674a4d8c2SCharles.Forsyth break;
55774a4d8c2SCharles.Forsyth case ABFPT:
55874a4d8c2SCharles.Forsyth oprange[ABFPF] = oprange[r];
55974a4d8c2SCharles.Forsyth break;
56074a4d8c2SCharles.Forsyth case AMOVWL:
56174a4d8c2SCharles.Forsyth oprange[AMOVWR] = oprange[r];
56274a4d8c2SCharles.Forsyth oprange[AMOVVR] = oprange[r];
56374a4d8c2SCharles.Forsyth oprange[AMOVVL] = oprange[r];
56474a4d8c2SCharles.Forsyth break;
56574a4d8c2SCharles.Forsyth case AMOVW:
56674a4d8c2SCharles.Forsyth buildrep(5, AMOVW);
56774a4d8c2SCharles.Forsyth break;
56874a4d8c2SCharles.Forsyth case AMOVD:
56974a4d8c2SCharles.Forsyth buildrep(6, AMOVD);
57074a4d8c2SCharles.Forsyth break;
57174a4d8c2SCharles.Forsyth case AMOVF:
57274a4d8c2SCharles.Forsyth buildrep(7, AMOVF);
57374a4d8c2SCharles.Forsyth break;
57474a4d8c2SCharles.Forsyth case AMOVV:
57574a4d8c2SCharles.Forsyth buildrep(8, AMOVV);
57674a4d8c2SCharles.Forsyth break;
57774a4d8c2SCharles.Forsyth case ABREAK:
57874a4d8c2SCharles.Forsyth case AWORD:
57974a4d8c2SCharles.Forsyth case ARFE:
58074a4d8c2SCharles.Forsyth case AJAL:
58174a4d8c2SCharles.Forsyth case AJMP:
58274a4d8c2SCharles.Forsyth case ATEXT:
58374a4d8c2SCharles.Forsyth case ACASE:
58474a4d8c2SCharles.Forsyth case ABCASE:
58574a4d8c2SCharles.Forsyth case AMOVWU:
58674a4d8c2SCharles.Forsyth break;
58774a4d8c2SCharles.Forsyth }
58874a4d8c2SCharles.Forsyth }
58974a4d8c2SCharles.Forsyth }
59074a4d8c2SCharles.Forsyth
59174a4d8c2SCharles.Forsyth void
buildrep(int x,int as)59274a4d8c2SCharles.Forsyth buildrep(int x, int as)
59374a4d8c2SCharles.Forsyth {
59474a4d8c2SCharles.Forsyth Opcross *p;
59574a4d8c2SCharles.Forsyth Optab *e, *s, *o;
59674a4d8c2SCharles.Forsyth int a1, a2, a3, n;
59774a4d8c2SCharles.Forsyth
59874a4d8c2SCharles.Forsyth if(C_NONE != 0 ||
59974a4d8c2SCharles.Forsyth C_REG != 1 ||
60074a4d8c2SCharles.Forsyth C_GOK >= 32 ||
60174a4d8c2SCharles.Forsyth x >= nelem(opcross)) {
60274a4d8c2SCharles.Forsyth diag("assumptions fail in buildrep");
60374a4d8c2SCharles.Forsyth errorexit();
60474a4d8c2SCharles.Forsyth }
60574a4d8c2SCharles.Forsyth repop[as] = x;
60674a4d8c2SCharles.Forsyth p = (opcross + x);
60774a4d8c2SCharles.Forsyth s = oprange[as].start;
60874a4d8c2SCharles.Forsyth e = oprange[as].stop;
60974a4d8c2SCharles.Forsyth for(o=e-1; o>=s; o--) {
61074a4d8c2SCharles.Forsyth n = o-optab;
61174a4d8c2SCharles.Forsyth for(a2=0; a2<2; a2++) {
61274a4d8c2SCharles.Forsyth if(a2) {
61374a4d8c2SCharles.Forsyth if(o->a2 == C_NONE)
61474a4d8c2SCharles.Forsyth continue;
61574a4d8c2SCharles.Forsyth } else
61674a4d8c2SCharles.Forsyth if(o->a2 != C_NONE)
61774a4d8c2SCharles.Forsyth continue;
61874a4d8c2SCharles.Forsyth for(a1=0; a1<32; a1++) {
61974a4d8c2SCharles.Forsyth if(!xcmp[a1][o->a1])
62074a4d8c2SCharles.Forsyth continue;
62174a4d8c2SCharles.Forsyth for(a3=0; a3<32; a3++)
62274a4d8c2SCharles.Forsyth if(xcmp[a3][o->a3])
62374a4d8c2SCharles.Forsyth (*p)[a1][a2][a3] = n;
62474a4d8c2SCharles.Forsyth }
62574a4d8c2SCharles.Forsyth }
62674a4d8c2SCharles.Forsyth }
62774a4d8c2SCharles.Forsyth oprange[as].start = 0;
62874a4d8c2SCharles.Forsyth }
629