17edc7532SDavid du Colombier #include "l.h"
27edc7532SDavid du Colombier
37edc7532SDavid du Colombier void
pagebug(Prog * p)4*f8bc6aafSDavid du Colombier pagebug(Prog *p)
5*f8bc6aafSDavid du Colombier {
6*f8bc6aafSDavid du Colombier Prog *q;
7*f8bc6aafSDavid du Colombier
8*f8bc6aafSDavid du Colombier switch(p->as) {
9*f8bc6aafSDavid du Colombier case ABGEZAL:
10*f8bc6aafSDavid du Colombier case ABLTZAL:
11*f8bc6aafSDavid du Colombier case AJAL:
12*f8bc6aafSDavid du Colombier case ABEQ:
13*f8bc6aafSDavid du Colombier case ABGEZ:
14*f8bc6aafSDavid du Colombier case ABGTZ:
15*f8bc6aafSDavid du Colombier case ABLEZ:
16*f8bc6aafSDavid du Colombier case ABLTZ:
17*f8bc6aafSDavid du Colombier case ABNE:
18*f8bc6aafSDavid du Colombier case ABFPT:
19*f8bc6aafSDavid du Colombier case ABFPF:
20*f8bc6aafSDavid du Colombier case AJMP:
21*f8bc6aafSDavid du Colombier q = prg();
22*f8bc6aafSDavid du Colombier *q = *p;
23*f8bc6aafSDavid du Colombier p->link = q;
24*f8bc6aafSDavid du Colombier p->as = ANOR;
25*f8bc6aafSDavid du Colombier p->optab = 0;
26*f8bc6aafSDavid du Colombier p->from = zprg.from;
27*f8bc6aafSDavid du Colombier p->from.type = D_REG;
28*f8bc6aafSDavid du Colombier p->from.reg = REGZERO;
29*f8bc6aafSDavid du Colombier p->to = p->from;
30*f8bc6aafSDavid du Colombier }
31*f8bc6aafSDavid du Colombier }
32*f8bc6aafSDavid du Colombier
33*f8bc6aafSDavid du Colombier void
span(void)347edc7532SDavid du Colombier span(void)
357edc7532SDavid du Colombier {
367edc7532SDavid du Colombier Prog *p, *q;
37*f8bc6aafSDavid du Colombier Sym *setext, *s;
387edc7532SDavid du Colombier Optab *o;
39*f8bc6aafSDavid du Colombier int m, bflag, i;
40*f8bc6aafSDavid du Colombier vlong c, otxt, v;
417edc7532SDavid du Colombier
427edc7532SDavid du Colombier if(debug['v'])
437edc7532SDavid du Colombier Bprint(&bso, "%5.2f span\n", cputime());
447edc7532SDavid du Colombier Bflush(&bso);
457edc7532SDavid du Colombier
467edc7532SDavid du Colombier bflag = 0;
477edc7532SDavid du Colombier c = INITTEXT;
487edc7532SDavid du Colombier otxt = c;
497edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
50*f8bc6aafSDavid du Colombier /* bug in early 4000 chips delayslot on page boundary */
51*f8bc6aafSDavid du Colombier if((c&(0x1000-1)) == 0xffc)
52*f8bc6aafSDavid du Colombier pagebug(p);
537edc7532SDavid du Colombier p->pc = c;
547edc7532SDavid du Colombier o = oplook(p);
557edc7532SDavid du Colombier m = o->size;
567edc7532SDavid du Colombier if(m == 0) {
577edc7532SDavid du Colombier if(p->as == ATEXT) {
587edc7532SDavid du Colombier curtext = p;
597edc7532SDavid du Colombier autosize = p->to.offset + 8;
607edc7532SDavid du Colombier if(p->from.sym != S)
617edc7532SDavid du Colombier p->from.sym->value = c;
627edc7532SDavid du Colombier /* need passes to resolve branches */
637edc7532SDavid du Colombier if(c-otxt >= 1L<<17)
647edc7532SDavid du Colombier bflag = 1;
657edc7532SDavid du Colombier otxt = c;
667edc7532SDavid du Colombier continue;
677edc7532SDavid du Colombier }
687edc7532SDavid du Colombier diag("zero-width instruction\n%P", p);
697edc7532SDavid du Colombier continue;
707edc7532SDavid du Colombier }
717edc7532SDavid du Colombier c += m;
727edc7532SDavid du Colombier }
737edc7532SDavid du Colombier
747edc7532SDavid du Colombier /*
757edc7532SDavid du Colombier * if any procedure is large enough to
767edc7532SDavid du Colombier * generate a large SBRA branch, then
777edc7532SDavid du Colombier * generate extra passes putting branches
787edc7532SDavid du Colombier * around jmps to fix. this is rare.
797edc7532SDavid du Colombier */
807edc7532SDavid du Colombier while(bflag) {
817edc7532SDavid du Colombier if(debug['v'])
827edc7532SDavid du Colombier Bprint(&bso, "%5.2f span1\n", cputime());
837edc7532SDavid du Colombier bflag = 0;
847edc7532SDavid du Colombier c = INITTEXT;
857edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
86*f8bc6aafSDavid du Colombier /* bug in early 4000 chips delayslot on page boundary */
87*f8bc6aafSDavid du Colombier if((c&(0x1000-1)) == 0xffc)
88*f8bc6aafSDavid du Colombier pagebug(p);
897edc7532SDavid du Colombier p->pc = c;
907edc7532SDavid du Colombier o = oplook(p);
917edc7532SDavid du Colombier if(o->type == 6 && p->cond) {
927edc7532SDavid du Colombier otxt = p->cond->pc - c;
937edc7532SDavid du Colombier if(otxt < 0)
947edc7532SDavid du Colombier otxt = -otxt;
957edc7532SDavid du Colombier if(otxt >= (1L<<17) - 10) {
967edc7532SDavid du Colombier q = prg();
977edc7532SDavid du Colombier q->link = p->link;
987edc7532SDavid du Colombier p->link = q;
997edc7532SDavid du Colombier q->as = AJMP;
1007edc7532SDavid du Colombier q->to.type = D_BRANCH;
1017edc7532SDavid du Colombier q->cond = p->cond;
1027edc7532SDavid du Colombier p->cond = q;
1037edc7532SDavid du Colombier q = prg();
1047edc7532SDavid du Colombier q->link = p->link;
1057edc7532SDavid du Colombier p->link = q;
1067edc7532SDavid du Colombier q->as = AJMP;
1077edc7532SDavid du Colombier q->to.type = D_BRANCH;
1087edc7532SDavid du Colombier q->cond = q->link->link;
1097edc7532SDavid du Colombier addnop(p->link);
1107edc7532SDavid du Colombier addnop(p);
1117edc7532SDavid du Colombier bflag = 1;
1127edc7532SDavid du Colombier }
1137edc7532SDavid du Colombier }
1147edc7532SDavid du Colombier m = o->size;
1157edc7532SDavid du Colombier if(m == 0) {
1167edc7532SDavid du Colombier if(p->as == ATEXT) {
1177edc7532SDavid du Colombier curtext = p;
1187edc7532SDavid du Colombier autosize = p->to.offset + 8;
1197edc7532SDavid du Colombier if(p->from.sym != S)
1207edc7532SDavid du Colombier p->from.sym->value = c;
1217edc7532SDavid du Colombier continue;
1227edc7532SDavid du Colombier }
1237edc7532SDavid du Colombier diag("zero-width instruction\n%P", p);
1247edc7532SDavid du Colombier continue;
1257edc7532SDavid du Colombier }
1267edc7532SDavid du Colombier c += m;
1277edc7532SDavid du Colombier }
1287edc7532SDavid du Colombier }
129*f8bc6aafSDavid du Colombier
130*f8bc6aafSDavid du Colombier if(debug['t']) {
131*f8bc6aafSDavid du Colombier /*
132*f8bc6aafSDavid du Colombier * add strings to text segment
133*f8bc6aafSDavid du Colombier */
134*f8bc6aafSDavid du Colombier c = rnd(c, 8);
135*f8bc6aafSDavid du Colombier for(i=0; i<NHASH; i++)
136*f8bc6aafSDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
137*f8bc6aafSDavid du Colombier if(s->type != SSTRING)
138*f8bc6aafSDavid du Colombier continue;
139*f8bc6aafSDavid du Colombier v = s->value;
140*f8bc6aafSDavid du Colombier while(v & 3)
141*f8bc6aafSDavid du Colombier v++;
142*f8bc6aafSDavid du Colombier s->value = c;
143*f8bc6aafSDavid du Colombier c += v;
144*f8bc6aafSDavid du Colombier }
145*f8bc6aafSDavid du Colombier }
146*f8bc6aafSDavid du Colombier
1477edc7532SDavid du Colombier c = rnd(c, 8);
1487edc7532SDavid du Colombier
1497edc7532SDavid du Colombier setext = lookup("etext", 0);
1507edc7532SDavid du Colombier if(setext != S) {
1517edc7532SDavid du Colombier setext->value = c;
1527edc7532SDavid du Colombier textsize = c - INITTEXT;
1537edc7532SDavid du Colombier }
1547edc7532SDavid du Colombier if(INITRND)
1557edc7532SDavid du Colombier INITDAT = rnd(c, INITRND);
1567edc7532SDavid du Colombier if(debug['v'])
157*f8bc6aafSDavid du Colombier Bprint(&bso, "tsize = %llux\n", textsize);
1587edc7532SDavid du Colombier Bflush(&bso);
1597edc7532SDavid du Colombier }
1607edc7532SDavid du Colombier
1617edc7532SDavid du Colombier void
xdefine(char * p,int t,vlong v)162*f8bc6aafSDavid du Colombier xdefine(char *p, int t, vlong v)
1637edc7532SDavid du Colombier {
1647edc7532SDavid du Colombier Sym *s;
1657edc7532SDavid du Colombier
1667edc7532SDavid du Colombier s = lookup(p, 0);
1677edc7532SDavid du Colombier if(s->type == 0 || s->type == SXREF) {
1687edc7532SDavid du Colombier s->type = t;
1697edc7532SDavid du Colombier s->value = v;
1707edc7532SDavid du Colombier }
1717edc7532SDavid du Colombier }
1727edc7532SDavid du Colombier
1737edc7532SDavid du Colombier long
regoff(Adr * a)1747edc7532SDavid du Colombier regoff(Adr *a)
1757edc7532SDavid du Colombier {
1767edc7532SDavid du Colombier
1777edc7532SDavid du Colombier instoffset = 0;
1787edc7532SDavid du Colombier aclass(a);
1797edc7532SDavid du Colombier return instoffset;
1807edc7532SDavid du Colombier }
1817edc7532SDavid du Colombier
1827edc7532SDavid du Colombier int
isint32(vlong v)183*f8bc6aafSDavid du Colombier isint32(vlong v)
184*f8bc6aafSDavid du Colombier {
185*f8bc6aafSDavid du Colombier long l;
186*f8bc6aafSDavid du Colombier
187*f8bc6aafSDavid du Colombier l = v;
188*f8bc6aafSDavid du Colombier return (vlong)l == v;
189*f8bc6aafSDavid du Colombier }
190*f8bc6aafSDavid du Colombier
191*f8bc6aafSDavid du Colombier int
isuint32(uvlong v)192*f8bc6aafSDavid du Colombier isuint32(uvlong v)
193*f8bc6aafSDavid du Colombier {
194*f8bc6aafSDavid du Colombier ulong l;
195*f8bc6aafSDavid du Colombier
196*f8bc6aafSDavid du Colombier l = v;
197*f8bc6aafSDavid du Colombier return (uvlong)l == v;
198*f8bc6aafSDavid du Colombier }
199*f8bc6aafSDavid du Colombier
200*f8bc6aafSDavid du Colombier int
aclass(Adr * a)2017edc7532SDavid du Colombier aclass(Adr *a)
2027edc7532SDavid du Colombier {
2037edc7532SDavid du Colombier Sym *s;
2047edc7532SDavid du Colombier int t;
2057edc7532SDavid du Colombier
2067edc7532SDavid du Colombier switch(a->type) {
2077edc7532SDavid du Colombier case D_NONE:
2087edc7532SDavid du Colombier return C_NONE;
2097edc7532SDavid du Colombier
2107edc7532SDavid du Colombier case D_REG:
2117edc7532SDavid du Colombier return C_REG;
2127edc7532SDavid du Colombier
2137edc7532SDavid du Colombier case D_FREG:
2147edc7532SDavid du Colombier return C_FREG;
2157edc7532SDavid du Colombier
2167edc7532SDavid du Colombier case D_FCREG:
2177edc7532SDavid du Colombier return C_FCREG;
2187edc7532SDavid du Colombier
2197edc7532SDavid du Colombier case D_MREG:
2207edc7532SDavid du Colombier return C_MREG;
2217edc7532SDavid du Colombier
2227edc7532SDavid du Colombier case D_OREG:
2237edc7532SDavid du Colombier switch(a->name) {
2247edc7532SDavid du Colombier case D_EXTERN:
2257edc7532SDavid du Colombier case D_STATIC:
2267edc7532SDavid du Colombier if(a->sym == 0 || a->sym->name == 0) {
2277edc7532SDavid du Colombier print("null sym external\n");
2287edc7532SDavid du Colombier print("%D\n", a);
2297edc7532SDavid du Colombier return C_GOK;
2307edc7532SDavid du Colombier }
2317edc7532SDavid du Colombier t = a->sym->type;
2327edc7532SDavid du Colombier if(t == 0 || t == SXREF) {
2337edc7532SDavid du Colombier diag("undefined external: %s in %s",
2347edc7532SDavid du Colombier a->sym->name, TNAME);
2357edc7532SDavid du Colombier a->sym->type = SDATA;
2367edc7532SDavid du Colombier }
2377edc7532SDavid du Colombier instoffset = a->sym->value + a->offset - BIG;
2387edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
2397edc7532SDavid du Colombier return C_SEXT;
2407edc7532SDavid du Colombier return C_LEXT;
2417edc7532SDavid du Colombier case D_AUTO:
2427edc7532SDavid du Colombier instoffset = autosize + a->offset;
2437edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
2447edc7532SDavid du Colombier return C_SAUTO;
2457edc7532SDavid du Colombier return C_LAUTO;
2467edc7532SDavid du Colombier
2477edc7532SDavid du Colombier case D_PARAM:
2487edc7532SDavid du Colombier instoffset = autosize + a->offset + 8L;
2497edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
2507edc7532SDavid du Colombier return C_SAUTO;
2517edc7532SDavid du Colombier return C_LAUTO;
2527edc7532SDavid du Colombier case D_NONE:
2537edc7532SDavid du Colombier instoffset = a->offset;
2547edc7532SDavid du Colombier if(instoffset == 0)
2557edc7532SDavid du Colombier return C_ZOREG;
2567edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
2577edc7532SDavid du Colombier return C_SOREG;
2587edc7532SDavid du Colombier return C_LOREG;
2597edc7532SDavid du Colombier }
2607edc7532SDavid du Colombier return C_GOK;
2617edc7532SDavid du Colombier
2627edc7532SDavid du Colombier case D_HI:
2637edc7532SDavid du Colombier return C_LO;
2647edc7532SDavid du Colombier case D_LO:
2657edc7532SDavid du Colombier return C_HI;
2667edc7532SDavid du Colombier
2677edc7532SDavid du Colombier case D_OCONST:
2687edc7532SDavid du Colombier switch(a->name) {
2697edc7532SDavid du Colombier case D_EXTERN:
2707edc7532SDavid du Colombier case D_STATIC:
2717edc7532SDavid du Colombier s = a->sym;
2727edc7532SDavid du Colombier t = s->type;
2737edc7532SDavid du Colombier if(t == 0 || t == SXREF) {
2747edc7532SDavid du Colombier diag("undefined external: %s in %s",
2757edc7532SDavid du Colombier s->name, TNAME);
2767edc7532SDavid du Colombier s->type = SDATA;
2777edc7532SDavid du Colombier }
2787edc7532SDavid du Colombier instoffset = s->value + a->offset + INITDAT;
2797edc7532SDavid du Colombier if(s->type == STEXT || s->type == SLEAF)
2807edc7532SDavid du Colombier instoffset = s->value + a->offset;
2817edc7532SDavid du Colombier return C_LCON;
2827edc7532SDavid du Colombier }
2837edc7532SDavid du Colombier return C_GOK;
2847edc7532SDavid du Colombier
2857edc7532SDavid du Colombier case D_CONST:
2867edc7532SDavid du Colombier switch(a->name) {
2877edc7532SDavid du Colombier case D_NONE:
2887edc7532SDavid du Colombier instoffset = a->offset;
2897edc7532SDavid du Colombier consize:
2907edc7532SDavid du Colombier if(instoffset > 0) {
2917edc7532SDavid du Colombier if(instoffset <= 0x7fff)
2927edc7532SDavid du Colombier return C_SCON;
2937edc7532SDavid du Colombier if(instoffset <= 0xffff)
2947edc7532SDavid du Colombier return C_ANDCON;
295*f8bc6aafSDavid du Colombier if((instoffset & 0xffff) == 0 && isuint32(instoffset))
2967edc7532SDavid du Colombier return C_UCON;
2977edc7532SDavid du Colombier return C_LCON;
2987edc7532SDavid du Colombier }
2997edc7532SDavid du Colombier if(instoffset == 0)
3007edc7532SDavid du Colombier return C_ZCON;
3017edc7532SDavid du Colombier if(instoffset >= -0x8000)
3027edc7532SDavid du Colombier return C_ADDCON;
303*f8bc6aafSDavid du Colombier if((instoffset & 0xffff) == 0 && isint32(instoffset))
3047edc7532SDavid du Colombier return C_UCON;
3057edc7532SDavid du Colombier return C_LCON;
3067edc7532SDavid du Colombier
3077edc7532SDavid du Colombier case D_EXTERN:
3087edc7532SDavid du Colombier case D_STATIC:
3097edc7532SDavid du Colombier s = a->sym;
3107edc7532SDavid du Colombier if(s == S)
3117edc7532SDavid du Colombier break;
3127edc7532SDavid du Colombier t = s->type;
3137edc7532SDavid du Colombier switch(t) {
3147edc7532SDavid du Colombier case 0:
3157edc7532SDavid du Colombier case SXREF:
3167edc7532SDavid du Colombier diag("undefined external: %s in %s",
3177edc7532SDavid du Colombier s->name, TNAME);
3187edc7532SDavid du Colombier s->type = SDATA;
3197edc7532SDavid du Colombier break;
3207edc7532SDavid du Colombier case SCONST:
3217edc7532SDavid du Colombier instoffset = s->value + a->offset;
3227edc7532SDavid du Colombier goto consize;
3237edc7532SDavid du Colombier case STEXT:
3247edc7532SDavid du Colombier case SLEAF:
3257edc7532SDavid du Colombier instoffset = s->value + a->offset;
3267edc7532SDavid du Colombier return C_LCON;
3277edc7532SDavid du Colombier }
3287edc7532SDavid du Colombier instoffset = s->value + a->offset - BIG;
3297edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG && instoffset != 0L)
3307edc7532SDavid du Colombier return C_SECON;
3317edc7532SDavid du Colombier instoffset = s->value + a->offset + INITDAT;
3327edc7532SDavid du Colombier return C_LCON;
3337edc7532SDavid du Colombier
3347edc7532SDavid du Colombier case D_AUTO:
3357edc7532SDavid du Colombier instoffset = autosize + a->offset;
3367edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
3377edc7532SDavid du Colombier return C_SACON;
3387edc7532SDavid du Colombier return C_LACON;
3397edc7532SDavid du Colombier
3407edc7532SDavid du Colombier case D_PARAM:
3417edc7532SDavid du Colombier instoffset = autosize + a->offset + 8L;
3427edc7532SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
3437edc7532SDavid du Colombier return C_SACON;
3447edc7532SDavid du Colombier return C_LACON;
3457edc7532SDavid du Colombier }
3467edc7532SDavid du Colombier return C_GOK;
3477edc7532SDavid du Colombier
3487edc7532SDavid du Colombier case D_BRANCH:
3497edc7532SDavid du Colombier return C_SBRA;
3507edc7532SDavid du Colombier }
3517edc7532SDavid du Colombier return C_GOK;
3527edc7532SDavid du Colombier }
3537edc7532SDavid du Colombier
3547edc7532SDavid du Colombier Optab*
oplook(Prog * p)3557edc7532SDavid du Colombier oplook(Prog *p)
3567edc7532SDavid du Colombier {
357*f8bc6aafSDavid du Colombier int a1, a2, a3, r;
3587edc7532SDavid du Colombier char *c1, *c3;
3597edc7532SDavid du Colombier Optab *o, *e;
3607edc7532SDavid du Colombier
3617edc7532SDavid du Colombier a1 = p->optab;
3627edc7532SDavid du Colombier if(a1)
3637edc7532SDavid du Colombier return optab+(a1-1);
3647edc7532SDavid du Colombier a1 = p->from.class;
3657edc7532SDavid du Colombier if(a1 == 0) {
3667edc7532SDavid du Colombier a1 = aclass(&p->from) + 1;
3677edc7532SDavid du Colombier p->from.class = a1;
3687edc7532SDavid du Colombier }
3697edc7532SDavid du Colombier a1--;
3707edc7532SDavid du Colombier a3 = p->to.class;
3717edc7532SDavid du Colombier if(a3 == 0) {
3727edc7532SDavid du Colombier a3 = aclass(&p->to) + 1;
3737edc7532SDavid du Colombier p->to.class = a3;
3747edc7532SDavid du Colombier }
3757edc7532SDavid du Colombier a3--;
3767edc7532SDavid du Colombier a2 = C_NONE;
3777edc7532SDavid du Colombier if(p->reg != NREG)
3787edc7532SDavid du Colombier a2 = C_REG;
3797edc7532SDavid du Colombier r = p->as;
3807edc7532SDavid du Colombier o = oprange[r].start;
3817edc7532SDavid du Colombier if(o == 0) {
382*f8bc6aafSDavid du Colombier a1 = opcross[repop[r]][a1][a2][a3];
383*f8bc6aafSDavid du Colombier if(a1) {
384*f8bc6aafSDavid du Colombier p->optab = a1+1;
385*f8bc6aafSDavid du Colombier return optab+a1;
3867edc7532SDavid du Colombier }
3877edc7532SDavid du Colombier o = oprange[r].stop; /* just generate an error */
3887edc7532SDavid du Colombier }
3897edc7532SDavid du Colombier e = oprange[r].stop;
3907edc7532SDavid du Colombier c1 = xcmp[a1];
3917edc7532SDavid du Colombier c3 = xcmp[a3];
3927edc7532SDavid du Colombier for(; o<e; o++)
3937edc7532SDavid du Colombier if(o->a2 == a2)
3947edc7532SDavid du Colombier if(c1[o->a1])
3957edc7532SDavid du Colombier if(c3[o->a3]) {
3967edc7532SDavid du Colombier p->optab = (o-optab)+1;
3977edc7532SDavid du Colombier return o;
3987edc7532SDavid du Colombier }
3997edc7532SDavid du Colombier diag("illegal combination %A %d %d %d",
400*f8bc6aafSDavid du Colombier p->as, p->from.class-1, a2, a3);
4017edc7532SDavid du Colombier if(!debug['a'])
4027edc7532SDavid du Colombier prasm(p);
4037edc7532SDavid du Colombier o = optab;
4047edc7532SDavid du Colombier p->optab = (o-optab)+1;
4057edc7532SDavid du Colombier return o;
4067edc7532SDavid du Colombier }
4077edc7532SDavid du Colombier
4087edc7532SDavid du Colombier int
cmp(int a,int b)4097edc7532SDavid du Colombier cmp(int a, int b)
4107edc7532SDavid du Colombier {
4117edc7532SDavid du Colombier
4127edc7532SDavid du Colombier if(a == b)
4137edc7532SDavid du Colombier return 1;
4147edc7532SDavid du Colombier switch(a) {
4157edc7532SDavid du Colombier case C_LCON:
4167edc7532SDavid du Colombier if(b == C_ZCON || b == C_SCON || b == C_UCON ||
4177edc7532SDavid du Colombier b == C_ADDCON || b == C_ANDCON)
4187edc7532SDavid du Colombier return 1;
4197edc7532SDavid du Colombier break;
4207edc7532SDavid du Colombier case C_ADD0CON:
4217edc7532SDavid du Colombier if(b == C_ADDCON)
4227edc7532SDavid du Colombier return 1;
4237edc7532SDavid du Colombier case C_ADDCON:
4247edc7532SDavid du Colombier if(b == C_ZCON || b == C_SCON)
4257edc7532SDavid du Colombier return 1;
4267edc7532SDavid du Colombier break;
4277edc7532SDavid du Colombier case C_AND0CON:
4287edc7532SDavid du Colombier if(b == C_ANDCON)
4297edc7532SDavid du Colombier return 1;
4307edc7532SDavid du Colombier case C_ANDCON:
4317edc7532SDavid du Colombier if(b == C_ZCON || b == C_SCON)
4327edc7532SDavid du Colombier return 1;
4337edc7532SDavid du Colombier break;
4347edc7532SDavid du Colombier case C_UCON:
4357edc7532SDavid du Colombier if(b == C_ZCON)
4367edc7532SDavid du Colombier return 1;
4377edc7532SDavid du Colombier break;
4387edc7532SDavid du Colombier case C_SCON:
4397edc7532SDavid du Colombier if(b == C_ZCON)
4407edc7532SDavid du Colombier return 1;
4417edc7532SDavid du Colombier break;
4427edc7532SDavid du Colombier case C_LACON:
4437edc7532SDavid du Colombier if(b == C_SACON)
4447edc7532SDavid du Colombier return 1;
4457edc7532SDavid du Colombier break;
4467edc7532SDavid du Colombier case C_LBRA:
4477edc7532SDavid du Colombier if(b == C_SBRA)
4487edc7532SDavid du Colombier return 1;
4497edc7532SDavid du Colombier break;
4507edc7532SDavid du Colombier case C_LEXT:
4517edc7532SDavid du Colombier if(b == C_SEXT)
4527edc7532SDavid du Colombier return 1;
4537edc7532SDavid du Colombier break;
4547edc7532SDavid du Colombier case C_LAUTO:
4557edc7532SDavid du Colombier if(b == C_SAUTO)
4567edc7532SDavid du Colombier return 1;
4577edc7532SDavid du Colombier break;
4587edc7532SDavid du Colombier case C_REG:
4597edc7532SDavid du Colombier if(b == C_ZCON)
4607edc7532SDavid du Colombier return 1;
4617edc7532SDavid du Colombier break;
4627edc7532SDavid du Colombier case C_LOREG:
4637edc7532SDavid du Colombier if(b == C_ZOREG || b == C_SOREG)
4647edc7532SDavid du Colombier return 1;
4657edc7532SDavid du Colombier break;
4667edc7532SDavid du Colombier case C_SOREG:
4677edc7532SDavid du Colombier if(b == C_ZOREG)
4687edc7532SDavid du Colombier return 1;
4697edc7532SDavid du Colombier break;
4707edc7532SDavid du Colombier }
4717edc7532SDavid du Colombier return 0;
4727edc7532SDavid du Colombier }
4737edc7532SDavid du Colombier
4747edc7532SDavid du Colombier int
ocmp(const void * a1,const void * a2)4757edc7532SDavid du Colombier ocmp(const void *a1, const void *a2)
4767edc7532SDavid du Colombier {
4777edc7532SDavid du Colombier Optab *p1, *p2;
4787edc7532SDavid du Colombier int n;
4797edc7532SDavid du Colombier
4807edc7532SDavid du Colombier p1 = (Optab*)a1;
4817edc7532SDavid du Colombier p2 = (Optab*)a2;
4827edc7532SDavid du Colombier n = p1->as - p2->as;
4837edc7532SDavid du Colombier if(n)
4847edc7532SDavid du Colombier return n;
4857edc7532SDavid du Colombier n = p1->a1 - p2->a1;
4867edc7532SDavid du Colombier if(n)
4877edc7532SDavid du Colombier return n;
4887edc7532SDavid du Colombier n = p1->a2 - p2->a2;
4897edc7532SDavid du Colombier if(n)
4907edc7532SDavid du Colombier return n;
4917edc7532SDavid du Colombier n = p1->a3 - p2->a3;
4927edc7532SDavid du Colombier if(n)
4937edc7532SDavid du Colombier return n;
4947edc7532SDavid du Colombier return 0;
4957edc7532SDavid du Colombier }
4967edc7532SDavid du Colombier
4977edc7532SDavid du Colombier void
buildop(void)4987edc7532SDavid du Colombier buildop(void)
4997edc7532SDavid du Colombier {
5007edc7532SDavid du Colombier int i, n, r;
5017edc7532SDavid du Colombier
5027edc7532SDavid du Colombier for(i=0; i<32; i++)
5037edc7532SDavid du Colombier for(n=0; n<32; n++)
5047edc7532SDavid du Colombier xcmp[i][n] = cmp(n, i);
5057edc7532SDavid du Colombier for(n=0; optab[n].as != AXXX; n++)
5067edc7532SDavid du Colombier ;
5077edc7532SDavid du Colombier qsort(optab, n, sizeof(optab[0]), ocmp);
5087edc7532SDavid du Colombier for(i=0; i<n; i++) {
5097edc7532SDavid du Colombier r = optab[i].as;
5107edc7532SDavid du Colombier oprange[r].start = optab+i;
5117edc7532SDavid du Colombier while(optab[i].as == r)
5127edc7532SDavid du Colombier i++;
5137edc7532SDavid du Colombier oprange[r].stop = optab+i;
5147edc7532SDavid du Colombier i--;
5157edc7532SDavid du Colombier
5167edc7532SDavid du Colombier switch(r)
5177edc7532SDavid du Colombier {
5187edc7532SDavid du Colombier default:
5197edc7532SDavid du Colombier diag("unknown op in build: %A", r);
5207edc7532SDavid du Colombier errorexit();
5217edc7532SDavid du Colombier case AABSF:
5227edc7532SDavid du Colombier oprange[AMOVFD] = oprange[r];
5237edc7532SDavid du Colombier oprange[AMOVDF] = oprange[r];
5247edc7532SDavid du Colombier oprange[AMOVWF] = oprange[r];
5257edc7532SDavid du Colombier oprange[AMOVFW] = oprange[r];
5267edc7532SDavid du Colombier oprange[AMOVWD] = oprange[r];
5277edc7532SDavid du Colombier oprange[AMOVDW] = oprange[r];
5287edc7532SDavid du Colombier oprange[ANEGF] = oprange[r];
5297edc7532SDavid du Colombier oprange[ANEGD] = oprange[r];
5307edc7532SDavid du Colombier oprange[AABSD] = oprange[r];
5317edc7532SDavid du Colombier oprange[ATRUNCDW] = oprange[r];
5327edc7532SDavid du Colombier oprange[ATRUNCFW] = oprange[r];
5337edc7532SDavid du Colombier oprange[ATRUNCDV] = oprange[r];
5347edc7532SDavid du Colombier oprange[ATRUNCFV] = oprange[r];
5357edc7532SDavid du Colombier oprange[AMOVDV] = oprange[r];
5367edc7532SDavid du Colombier oprange[AMOVFV] = oprange[r];
5377edc7532SDavid du Colombier oprange[AMOVVD] = oprange[r];
5387edc7532SDavid du Colombier oprange[AMOVVF] = oprange[r];
5397edc7532SDavid du Colombier break;
5407edc7532SDavid du Colombier case AADD:
5417edc7532SDavid du Colombier buildrep(1, AADD);
5427edc7532SDavid du Colombier oprange[ASGT] = oprange[r];
5437edc7532SDavid du Colombier repop[ASGT] = 1;
5447edc7532SDavid du Colombier oprange[ASGTU] = oprange[r];
5457edc7532SDavid du Colombier repop[ASGTU] = 1;
5467edc7532SDavid du Colombier oprange[AADDU] = oprange[r];
5477edc7532SDavid du Colombier repop[AADDU] = 1;
5487edc7532SDavid du Colombier oprange[AADDVU] = oprange[r];
5497edc7532SDavid du Colombier repop[AADDVU] = 1;
5507edc7532SDavid du Colombier oprange[AADDV] = oprange[r];
5517edc7532SDavid du Colombier repop[AADDV] = 1;
5527edc7532SDavid du Colombier break;
5537edc7532SDavid du Colombier case AADDF:
5547edc7532SDavid du Colombier oprange[ADIVF] = oprange[r];
5557edc7532SDavid du Colombier oprange[ADIVD] = oprange[r];
5567edc7532SDavid du Colombier oprange[AMULF] = oprange[r];
5577edc7532SDavid du Colombier oprange[AMULD] = oprange[r];
5587edc7532SDavid du Colombier oprange[ASUBF] = oprange[r];
5597edc7532SDavid du Colombier oprange[ASUBD] = oprange[r];
5607edc7532SDavid du Colombier oprange[AADDD] = oprange[r];
5617edc7532SDavid du Colombier break;
5627edc7532SDavid du Colombier case AAND:
5637edc7532SDavid du Colombier buildrep(2, AAND);
5647edc7532SDavid du Colombier oprange[AXOR] = oprange[r];
5657edc7532SDavid du Colombier repop[AXOR] = 2;
5667edc7532SDavid du Colombier oprange[AOR] = oprange[r];
5677edc7532SDavid du Colombier repop[AOR] = 2;
5687edc7532SDavid du Colombier break;
5697edc7532SDavid du Colombier case ABEQ:
5707edc7532SDavid du Colombier oprange[ABNE] = oprange[r];
5717edc7532SDavid du Colombier break;
5727edc7532SDavid du Colombier case ABLEZ:
5737edc7532SDavid du Colombier oprange[ABGEZ] = oprange[r];
5747edc7532SDavid du Colombier oprange[ABGEZAL] = oprange[r];
5757edc7532SDavid du Colombier oprange[ABLTZ] = oprange[r];
5767edc7532SDavid du Colombier oprange[ABLTZAL] = oprange[r];
5777edc7532SDavid du Colombier oprange[ABGTZ] = oprange[r];
5787edc7532SDavid du Colombier break;
5797edc7532SDavid du Colombier case AMOVB:
5807edc7532SDavid du Colombier buildrep(3, AMOVB);
5817edc7532SDavid du Colombier oprange[AMOVH] = oprange[r];
5827edc7532SDavid du Colombier repop[AMOVH] = 3;
5837edc7532SDavid du Colombier break;
5847edc7532SDavid du Colombier case AMOVBU:
5857edc7532SDavid du Colombier buildrep(4, AMOVBU);
5867edc7532SDavid du Colombier oprange[AMOVHU] = oprange[r];
5877edc7532SDavid du Colombier repop[AMOVHU] = 4;
5887edc7532SDavid du Colombier break;
5897edc7532SDavid du Colombier case AMUL:
5907edc7532SDavid du Colombier oprange[AREM] = oprange[r];
5917edc7532SDavid du Colombier oprange[AREMU] = oprange[r];
5927edc7532SDavid du Colombier oprange[ADIVU] = oprange[r];
5937edc7532SDavid du Colombier oprange[AMULU] = oprange[r];
5947edc7532SDavid du Colombier oprange[ADIV] = oprange[r];
5957edc7532SDavid du Colombier oprange[ADIVV] = oprange[r];
5967edc7532SDavid du Colombier oprange[ADIVVU] = oprange[r];
5977edc7532SDavid du Colombier oprange[AMULV] = oprange[r];
5987edc7532SDavid du Colombier oprange[AMULVU] = oprange[r];
5997edc7532SDavid du Colombier oprange[AREMV] = oprange[r];
6007edc7532SDavid du Colombier oprange[AREMVU] = oprange[r];
6017edc7532SDavid du Colombier break;
6027edc7532SDavid du Colombier case ASLL:
6037edc7532SDavid du Colombier oprange[ASRL] = oprange[r];
6047edc7532SDavid du Colombier oprange[ASRA] = oprange[r];
6057edc7532SDavid du Colombier oprange[ASLLV] = oprange[r];
6067edc7532SDavid du Colombier oprange[ASRAV] = oprange[r];
6077edc7532SDavid du Colombier oprange[ASRLV] = oprange[r];
6087edc7532SDavid du Colombier break;
6097edc7532SDavid du Colombier case ASUB:
6107edc7532SDavid du Colombier oprange[ASUBU] = oprange[r];
6117edc7532SDavid du Colombier oprange[ASUBV] = oprange[r];
6127edc7532SDavid du Colombier oprange[ASUBVU] = oprange[r];
6137edc7532SDavid du Colombier oprange[ANOR] = oprange[r];
6147edc7532SDavid du Colombier break;
6157edc7532SDavid du Colombier case ASYSCALL:
6167edc7532SDavid du Colombier oprange[ATLBP] = oprange[r];
6177edc7532SDavid du Colombier oprange[ATLBR] = oprange[r];
6187edc7532SDavid du Colombier oprange[ATLBWI] = oprange[r];
6197edc7532SDavid du Colombier oprange[ATLBWR] = oprange[r];
6207edc7532SDavid du Colombier break;
6217edc7532SDavid du Colombier case ACMPEQF:
6227edc7532SDavid du Colombier oprange[ACMPGTF] = oprange[r];
6237edc7532SDavid du Colombier oprange[ACMPGTD] = oprange[r];
6247edc7532SDavid du Colombier oprange[ACMPGEF] = oprange[r];
6257edc7532SDavid du Colombier oprange[ACMPGED] = oprange[r];
6267edc7532SDavid du Colombier oprange[ACMPEQD] = oprange[r];
6277edc7532SDavid du Colombier break;
6287edc7532SDavid du Colombier case ABFPT:
6297edc7532SDavid du Colombier oprange[ABFPF] = oprange[r];
6307edc7532SDavid du Colombier break;
6317edc7532SDavid du Colombier case AMOVWL:
6327edc7532SDavid du Colombier oprange[AMOVWR] = oprange[r];
6337edc7532SDavid du Colombier oprange[AMOVVR] = oprange[r];
6347edc7532SDavid du Colombier oprange[AMOVVL] = oprange[r];
6357edc7532SDavid du Colombier break;
6367edc7532SDavid du Colombier case AMOVW:
6377edc7532SDavid du Colombier buildrep(5, AMOVW);
6387edc7532SDavid du Colombier break;
6397edc7532SDavid du Colombier case AMOVD:
6407edc7532SDavid du Colombier buildrep(6, AMOVD);
6417edc7532SDavid du Colombier break;
6427edc7532SDavid du Colombier case AMOVF:
6437edc7532SDavid du Colombier buildrep(7, AMOVF);
6447edc7532SDavid du Colombier break;
6457edc7532SDavid du Colombier case AMOVV:
6467edc7532SDavid du Colombier buildrep(8, AMOVV);
6477edc7532SDavid du Colombier break;
6487edc7532SDavid du Colombier case ABREAK:
6497edc7532SDavid du Colombier case AWORD:
6507edc7532SDavid du Colombier case ARFE:
6517edc7532SDavid du Colombier case AJAL:
6527edc7532SDavid du Colombier case AJMP:
6537edc7532SDavid du Colombier case ATEXT:
6547edc7532SDavid du Colombier case ACASE:
6557edc7532SDavid du Colombier case ABCASE:
6567edc7532SDavid du Colombier case AMOVWU:
6577edc7532SDavid du Colombier break;
6587edc7532SDavid du Colombier }
6597edc7532SDavid du Colombier }
6607edc7532SDavid du Colombier }
6617edc7532SDavid du Colombier
6627edc7532SDavid du Colombier void
buildrep(int x,int as)6637edc7532SDavid du Colombier buildrep(int x, int as)
6647edc7532SDavid du Colombier {
6657edc7532SDavid du Colombier Opcross *p;
6667edc7532SDavid du Colombier Optab *e, *s, *o;
6677edc7532SDavid du Colombier int a1, a2, a3, n;
6687edc7532SDavid du Colombier
669*f8bc6aafSDavid du Colombier if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
6707edc7532SDavid du Colombier diag("assumptions fail in buildrep");
6717edc7532SDavid du Colombier errorexit();
6727edc7532SDavid du Colombier }
6737edc7532SDavid du Colombier repop[as] = x;
6747edc7532SDavid du Colombier p = (opcross + x);
6757edc7532SDavid du Colombier s = oprange[as].start;
6767edc7532SDavid du Colombier e = oprange[as].stop;
6777edc7532SDavid du Colombier for(o=e-1; o>=s; o--) {
6787edc7532SDavid du Colombier n = o-optab;
6797edc7532SDavid du Colombier for(a2=0; a2<2; a2++) {
6807edc7532SDavid du Colombier if(a2) {
6817edc7532SDavid du Colombier if(o->a2 == C_NONE)
6827edc7532SDavid du Colombier continue;
6837edc7532SDavid du Colombier } else
6847edc7532SDavid du Colombier if(o->a2 != C_NONE)
6857edc7532SDavid du Colombier continue;
6867edc7532SDavid du Colombier for(a1=0; a1<32; a1++) {
6877edc7532SDavid du Colombier if(!xcmp[a1][o->a1])
6887edc7532SDavid du Colombier continue;
6897edc7532SDavid du Colombier for(a3=0; a3<32; a3++)
6907edc7532SDavid du Colombier if(xcmp[a3][o->a3])
6917edc7532SDavid du Colombier (*p)[a1][a2][a3] = n;
6927edc7532SDavid du Colombier }
6937edc7532SDavid du Colombier }
6947edc7532SDavid du Colombier }
6957edc7532SDavid du Colombier oprange[as].start = 0;
6967edc7532SDavid du Colombier }
697