1*ce95e1b3SDavid du Colombier #include "l.h"
2*ce95e1b3SDavid du Colombier
3*ce95e1b3SDavid du Colombier void
span(void)4*ce95e1b3SDavid du Colombier span(void)
5*ce95e1b3SDavid du Colombier {
6*ce95e1b3SDavid du Colombier Prog *p, *q;
7*ce95e1b3SDavid du Colombier Sym *setext, *s;
8*ce95e1b3SDavid du Colombier Optab *o;
9*ce95e1b3SDavid du Colombier int m, bflag, i, spass;
10*ce95e1b3SDavid du Colombier long c, otxt, v;
11*ce95e1b3SDavid du Colombier
12*ce95e1b3SDavid du Colombier if(debug['v'])
13*ce95e1b3SDavid du Colombier Bprint(&bso, "%5.2f span\n", cputime());
14*ce95e1b3SDavid du Colombier Bflush(&bso);
15*ce95e1b3SDavid du Colombier
16*ce95e1b3SDavid du Colombier bflag = 0;
17*ce95e1b3SDavid du Colombier c = 0;
18*ce95e1b3SDavid du Colombier otxt = c;
19*ce95e1b3SDavid du Colombier for(p = firstp; p != P; p = p->link) {
20*ce95e1b3SDavid du Colombier if(p->as == ATEXT)
21*ce95e1b3SDavid du Colombier c = (c + 3) & ~3;
22*ce95e1b3SDavid du Colombier p->pc = c;
23*ce95e1b3SDavid du Colombier o = oplook(p);
24*ce95e1b3SDavid du Colombier m = o->size;
25*ce95e1b3SDavid du Colombier if(!debug['c']){
26*ce95e1b3SDavid du Colombier if(o->ctype && asmout(p, o, 2) == 2){
27*ce95e1b3SDavid du Colombier bflag = 1;
28*ce95e1b3SDavid du Colombier p->mark |= COMPR;
29*ce95e1b3SDavid du Colombier m = 2;
30*ce95e1b3SDavid du Colombier }
31*ce95e1b3SDavid du Colombier }
32*ce95e1b3SDavid du Colombier if(m == 0) {
33*ce95e1b3SDavid du Colombier if(p->as == ATEXT) {
34*ce95e1b3SDavid du Colombier curtext = p;
35*ce95e1b3SDavid du Colombier autosize = p->to.offset + ptrsize;
36*ce95e1b3SDavid du Colombier if(p->from.sym != S)
37*ce95e1b3SDavid du Colombier p->from.sym->value = c;
38*ce95e1b3SDavid du Colombier /* need passes to resolve branches */
39*ce95e1b3SDavid du Colombier if(c-otxt >= 0x1000)
40*ce95e1b3SDavid du Colombier bflag = 1;
41*ce95e1b3SDavid du Colombier otxt = c;
42*ce95e1b3SDavid du Colombier continue;
43*ce95e1b3SDavid du Colombier }
44*ce95e1b3SDavid du Colombier diag("zero-width instruction\n%P", p);
45*ce95e1b3SDavid du Colombier continue;
46*ce95e1b3SDavid du Colombier }
47*ce95e1b3SDavid du Colombier c += m;
48*ce95e1b3SDavid du Colombier }
49*ce95e1b3SDavid du Colombier
50*ce95e1b3SDavid du Colombier /*
51*ce95e1b3SDavid du Colombier * Multi-pass expansion of span dependent instructions
52*ce95e1b3SDavid du Colombier * Bcond JAL C.Bcond C.JAL C.JMP
53*ce95e1b3SDavid du Colombier */
54*ce95e1b3SDavid du Colombier spass = 0;
55*ce95e1b3SDavid du Colombier while(bflag) {
56*ce95e1b3SDavid du Colombier if(debug['v'])
57*ce95e1b3SDavid du Colombier Bprint(&bso, "%5.2f span1\n", cputime());
58*ce95e1b3SDavid du Colombier bflag = 0;
59*ce95e1b3SDavid du Colombier spass ^= SPASS;
60*ce95e1b3SDavid du Colombier c = 0;
61*ce95e1b3SDavid du Colombier for(p = firstp; p != P; p = p->link) {
62*ce95e1b3SDavid du Colombier o = oplook(p);
63*ce95e1b3SDavid du Colombier m = o->size;
64*ce95e1b3SDavid du Colombier if(p->mark&COMPR)
65*ce95e1b3SDavid du Colombier m = 2;
66*ce95e1b3SDavid du Colombier if((o->type == 3 || o->type == 4) && p->cond) {
67*ce95e1b3SDavid du Colombier if((p->cond->mark&SPASS) == spass)
68*ce95e1b3SDavid du Colombier p->pc = c;
69*ce95e1b3SDavid du Colombier if(m == 2){
70*ce95e1b3SDavid du Colombier /*
71*ce95e1b3SDavid du Colombier * If instruction was compressed, check again in case
72*ce95e1b3SDavid du Colombier * branch range is now too large.
73*ce95e1b3SDavid du Colombier */
74*ce95e1b3SDavid du Colombier m = asmout(p, o, 3);
75*ce95e1b3SDavid du Colombier if(m != 2){
76*ce95e1b3SDavid du Colombier p->mark &= ~COMPR;
77*ce95e1b3SDavid du Colombier bflag = 1;
78*ce95e1b3SDavid du Colombier }
79*ce95e1b3SDavid du Colombier }
80*ce95e1b3SDavid du Colombier otxt = p->cond->pc - p->pc;
81*ce95e1b3SDavid du Colombier if(otxt < 0)
82*ce95e1b3SDavid du Colombier otxt = -otxt;
83*ce95e1b3SDavid du Colombier if(o->type == 3){
84*ce95e1b3SDavid du Colombier /*
85*ce95e1b3SDavid du Colombier * If Bcond branch range exceeds 4K, replace it by the
86*ce95e1b3SDavid du Colombier * logically negated branch around a JMP.
87*ce95e1b3SDavid du Colombier */
88*ce95e1b3SDavid du Colombier if(otxt >= 0x1000) {
89*ce95e1b3SDavid du Colombier q = prg();
90*ce95e1b3SDavid du Colombier q->link = p->link;
91*ce95e1b3SDavid du Colombier q->line = p->line;
92*ce95e1b3SDavid du Colombier q->as = AJMP;
93*ce95e1b3SDavid du Colombier q->to.type = D_BRANCH;
94*ce95e1b3SDavid du Colombier q->cond = p->cond;
95*ce95e1b3SDavid du Colombier p->link = q;
96*ce95e1b3SDavid du Colombier p->as = relinv(p->as);
97*ce95e1b3SDavid du Colombier p->cond = q->link;
98*ce95e1b3SDavid du Colombier p->optab = 0;
99*ce95e1b3SDavid du Colombier o = oplook(p);
100*ce95e1b3SDavid du Colombier q->mark = spass ^ SPASS;
101*ce95e1b3SDavid du Colombier m = asmout(p, o, 2);
102*ce95e1b3SDavid du Colombier if(m == 2)
103*ce95e1b3SDavid du Colombier p->mark |= COMPR;
104*ce95e1b3SDavid du Colombier q->pc = p->pc + m;
105*ce95e1b3SDavid du Colombier bflag = 1;
106*ce95e1b3SDavid du Colombier }
107*ce95e1b3SDavid du Colombier }else{
108*ce95e1b3SDavid du Colombier /*
109*ce95e1b3SDavid du Colombier * If JAL branch range exceeds 1M, change address class
110*ce95e1b3SDavid du Colombier * and recalculate instruction length.
111*ce95e1b3SDavid du Colombier */
112*ce95e1b3SDavid du Colombier if(otxt >= 0x100000) {
113*ce95e1b3SDavid du Colombier p->to.class = C_LBRA + 1;
114*ce95e1b3SDavid du Colombier p->optab = 0;
115*ce95e1b3SDavid du Colombier o = oplook(p);
116*ce95e1b3SDavid du Colombier m = asmout(p, o, 3);
117*ce95e1b3SDavid du Colombier p->mark &= ~COMPR;
118*ce95e1b3SDavid du Colombier }
119*ce95e1b3SDavid du Colombier }
120*ce95e1b3SDavid du Colombier }
121*ce95e1b3SDavid du Colombier if(p->as == ATEXT)
122*ce95e1b3SDavid du Colombier c = (c + 3) & ~3;
123*ce95e1b3SDavid du Colombier p->pc = c;
124*ce95e1b3SDavid du Colombier p->mark ^= SPASS;
125*ce95e1b3SDavid du Colombier if(m == 0) {
126*ce95e1b3SDavid du Colombier if(p->as == ATEXT) {
127*ce95e1b3SDavid du Colombier curtext = p;
128*ce95e1b3SDavid du Colombier autosize = p->to.offset + ptrsize;
129*ce95e1b3SDavid du Colombier if(p->from.sym != S)
130*ce95e1b3SDavid du Colombier p->from.sym->value = c;
131*ce95e1b3SDavid du Colombier continue;
132*ce95e1b3SDavid du Colombier }
133*ce95e1b3SDavid du Colombier diag("zero-width instruction\n%P", p);
134*ce95e1b3SDavid du Colombier continue;
135*ce95e1b3SDavid du Colombier }
136*ce95e1b3SDavid du Colombier c += m;
137*ce95e1b3SDavid du Colombier }
138*ce95e1b3SDavid du Colombier }
139*ce95e1b3SDavid du Colombier
140*ce95e1b3SDavid du Colombier if(debug['t']) {
141*ce95e1b3SDavid du Colombier /*
142*ce95e1b3SDavid du Colombier * add strings to text segment
143*ce95e1b3SDavid du Colombier */
144*ce95e1b3SDavid du Colombier c = rnd(c, 8);
145*ce95e1b3SDavid du Colombier for(i=0; i<NHASH; i++)
146*ce95e1b3SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
147*ce95e1b3SDavid du Colombier if(s->type != SSTRING)
148*ce95e1b3SDavid du Colombier continue;
149*ce95e1b3SDavid du Colombier v = s->value;
150*ce95e1b3SDavid du Colombier while(v & 3)
151*ce95e1b3SDavid du Colombier v++;
152*ce95e1b3SDavid du Colombier s->value = c;
153*ce95e1b3SDavid du Colombier c += v;
154*ce95e1b3SDavid du Colombier }
155*ce95e1b3SDavid du Colombier }
156*ce95e1b3SDavid du Colombier
157*ce95e1b3SDavid du Colombier c = rnd(c, 8);
158*ce95e1b3SDavid du Colombier
159*ce95e1b3SDavid du Colombier setext = lookup("etext", 0);
160*ce95e1b3SDavid du Colombier if(setext != S) {
161*ce95e1b3SDavid du Colombier setext->value = c;
162*ce95e1b3SDavid du Colombier textsize = c;
163*ce95e1b3SDavid du Colombier }
164*ce95e1b3SDavid du Colombier if(INITRND)
165*ce95e1b3SDavid du Colombier INITDAT = rnd(INITTEXT + c, INITRND);
166*ce95e1b3SDavid du Colombier if(debug['v'])
167*ce95e1b3SDavid du Colombier Bprint(&bso, "tsize = %lux\n", textsize);
168*ce95e1b3SDavid du Colombier Bflush(&bso);
169*ce95e1b3SDavid du Colombier }
170*ce95e1b3SDavid du Colombier
171*ce95e1b3SDavid du Colombier void
xdefine(char * p,int t,long v)172*ce95e1b3SDavid du Colombier xdefine(char *p, int t, long v)
173*ce95e1b3SDavid du Colombier {
174*ce95e1b3SDavid du Colombier Sym *s;
175*ce95e1b3SDavid du Colombier
176*ce95e1b3SDavid du Colombier s = lookup(p, 0);
177*ce95e1b3SDavid du Colombier if(s->type == 0 || s->type == SXREF) {
178*ce95e1b3SDavid du Colombier s->type = t;
179*ce95e1b3SDavid du Colombier s->value = v;
180*ce95e1b3SDavid du Colombier }
181*ce95e1b3SDavid du Colombier }
182*ce95e1b3SDavid du Colombier
183*ce95e1b3SDavid du Colombier long
regoff(Adr * a)184*ce95e1b3SDavid du Colombier regoff(Adr *a)
185*ce95e1b3SDavid du Colombier {
186*ce95e1b3SDavid du Colombier
187*ce95e1b3SDavid du Colombier instoffset = 0;
188*ce95e1b3SDavid du Colombier a->class = aclass(a) + 1;
189*ce95e1b3SDavid du Colombier return instoffset;
190*ce95e1b3SDavid du Colombier }
191*ce95e1b3SDavid du Colombier
192*ce95e1b3SDavid du Colombier int
classreg(Adr * a)193*ce95e1b3SDavid du Colombier classreg(Adr *a)
194*ce95e1b3SDavid du Colombier {
195*ce95e1b3SDavid du Colombier if(a->reg == NREG) {
196*ce95e1b3SDavid du Colombier switch(a->class - 1) {
197*ce95e1b3SDavid du Colombier case C_SEXT:
198*ce95e1b3SDavid du Colombier case C_SECON:
199*ce95e1b3SDavid du Colombier case C_LECON:
200*ce95e1b3SDavid du Colombier return REGSB;
201*ce95e1b3SDavid du Colombier case C_SAUTO:
202*ce95e1b3SDavid du Colombier case C_LAUTO:
203*ce95e1b3SDavid du Colombier case C_SACON:
204*ce95e1b3SDavid du Colombier case C_LACON:
205*ce95e1b3SDavid du Colombier return REGSP;
206*ce95e1b3SDavid du Colombier }
207*ce95e1b3SDavid du Colombier }
208*ce95e1b3SDavid du Colombier return a->reg;
209*ce95e1b3SDavid du Colombier }
210*ce95e1b3SDavid du Colombier
211*ce95e1b3SDavid du Colombier int
aclass(Adr * a)212*ce95e1b3SDavid du Colombier aclass(Adr *a)
213*ce95e1b3SDavid du Colombier {
214*ce95e1b3SDavid du Colombier Sym *s;
215*ce95e1b3SDavid du Colombier int t;
216*ce95e1b3SDavid du Colombier
217*ce95e1b3SDavid du Colombier switch(a->type) {
218*ce95e1b3SDavid du Colombier case D_NONE:
219*ce95e1b3SDavid du Colombier return C_NONE;
220*ce95e1b3SDavid du Colombier
221*ce95e1b3SDavid du Colombier case D_REG:
222*ce95e1b3SDavid du Colombier return C_REG;
223*ce95e1b3SDavid du Colombier
224*ce95e1b3SDavid du Colombier case D_CTLREG:
225*ce95e1b3SDavid du Colombier return C_CTLREG;
226*ce95e1b3SDavid du Colombier
227*ce95e1b3SDavid du Colombier case D_FREG:
228*ce95e1b3SDavid du Colombier return C_FREG;
229*ce95e1b3SDavid du Colombier
230*ce95e1b3SDavid du Colombier case D_OREG:
231*ce95e1b3SDavid du Colombier switch(a->name) {
232*ce95e1b3SDavid du Colombier case D_EXTERN:
233*ce95e1b3SDavid du Colombier case D_STATIC:
234*ce95e1b3SDavid du Colombier if(a->sym == 0 || a->sym->name == 0) {
235*ce95e1b3SDavid du Colombier print("null sym external\n");
236*ce95e1b3SDavid du Colombier print("%D\n", a);
237*ce95e1b3SDavid du Colombier return C_GOK;
238*ce95e1b3SDavid du Colombier }
239*ce95e1b3SDavid du Colombier t = a->sym->type;
240*ce95e1b3SDavid du Colombier if(t == 0 || t == SXREF) {
241*ce95e1b3SDavid du Colombier diag("undefined external: %s in %s",
242*ce95e1b3SDavid du Colombier a->sym->name, TNAME);
243*ce95e1b3SDavid du Colombier a->sym->type = SDATA;
244*ce95e1b3SDavid du Colombier }
245*ce95e1b3SDavid du Colombier instoffset = a->sym->value + a->offset - BIG;
246*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
247*ce95e1b3SDavid du Colombier return C_SEXT;
248*ce95e1b3SDavid du Colombier return C_LEXT;
249*ce95e1b3SDavid du Colombier case D_AUTO:
250*ce95e1b3SDavid du Colombier instoffset = autosize + a->offset;
251*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
252*ce95e1b3SDavid du Colombier return C_SAUTO;
253*ce95e1b3SDavid du Colombier return C_LAUTO;
254*ce95e1b3SDavid du Colombier
255*ce95e1b3SDavid du Colombier case D_PARAM:
256*ce95e1b3SDavid du Colombier instoffset = autosize + a->offset + ptrsize;
257*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
258*ce95e1b3SDavid du Colombier return C_SAUTO;
259*ce95e1b3SDavid du Colombier return C_LAUTO;
260*ce95e1b3SDavid du Colombier case D_NONE:
261*ce95e1b3SDavid du Colombier instoffset = a->offset;
262*ce95e1b3SDavid du Colombier if(instoffset == 0)
263*ce95e1b3SDavid du Colombier return C_ZOREG;
264*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
265*ce95e1b3SDavid du Colombier return C_SOREG;
266*ce95e1b3SDavid du Colombier return C_LOREG;
267*ce95e1b3SDavid du Colombier }
268*ce95e1b3SDavid du Colombier return C_GOK;
269*ce95e1b3SDavid du Colombier
270*ce95e1b3SDavid du Colombier case D_FCONST:
271*ce95e1b3SDavid du Colombier return C_FCON;
272*ce95e1b3SDavid du Colombier
273*ce95e1b3SDavid du Colombier case D_VCONST:
274*ce95e1b3SDavid du Colombier return C_VCON;
275*ce95e1b3SDavid du Colombier
276*ce95e1b3SDavid du Colombier case D_CONST:
277*ce95e1b3SDavid du Colombier switch(a->name) {
278*ce95e1b3SDavid du Colombier
279*ce95e1b3SDavid du Colombier case D_NONE:
280*ce95e1b3SDavid du Colombier instoffset = a->offset;
281*ce95e1b3SDavid du Colombier if(a->reg != NREG && a->reg != REGZERO){
282*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
283*ce95e1b3SDavid du Colombier return C_SRCON;
284*ce95e1b3SDavid du Colombier return C_LRCON;
285*ce95e1b3SDavid du Colombier }
286*ce95e1b3SDavid du Colombier consize:
287*ce95e1b3SDavid du Colombier if(instoffset == 0)
288*ce95e1b3SDavid du Colombier return C_ZCON;
289*ce95e1b3SDavid du Colombier if(instoffset >= -0x800 && instoffset <= 0x7ff)
290*ce95e1b3SDavid du Colombier return C_SCON;
291*ce95e1b3SDavid du Colombier if((instoffset & 0xfff) == 0)
292*ce95e1b3SDavid du Colombier return C_UCON;
293*ce95e1b3SDavid du Colombier return C_LCON;
294*ce95e1b3SDavid du Colombier
295*ce95e1b3SDavid du Colombier case D_EXTERN:
296*ce95e1b3SDavid du Colombier case D_STATIC:
297*ce95e1b3SDavid du Colombier instoffx = 0;
298*ce95e1b3SDavid du Colombier s = a->sym;
299*ce95e1b3SDavid du Colombier if(s == S)
300*ce95e1b3SDavid du Colombier break;
301*ce95e1b3SDavid du Colombier t = s->type;
302*ce95e1b3SDavid du Colombier switch(t) {
303*ce95e1b3SDavid du Colombier case 0:
304*ce95e1b3SDavid du Colombier case SXREF:
305*ce95e1b3SDavid du Colombier diag("undefined external: %s in %s",
306*ce95e1b3SDavid du Colombier s->name, TNAME);
307*ce95e1b3SDavid du Colombier s->type = SDATA;
308*ce95e1b3SDavid du Colombier break;
309*ce95e1b3SDavid du Colombier case SCONST:
310*ce95e1b3SDavid du Colombier instoffset = s->value + a->offset;
311*ce95e1b3SDavid du Colombier goto consize;
312*ce95e1b3SDavid du Colombier case STEXT:
313*ce95e1b3SDavid du Colombier case SLEAF:
314*ce95e1b3SDavid du Colombier case SSTRING:
315*ce95e1b3SDavid du Colombier instoffset = s->value + a->offset;
316*ce95e1b3SDavid du Colombier instoffx = INITTEXT;
317*ce95e1b3SDavid du Colombier return C_LECON;
318*ce95e1b3SDavid du Colombier }
319*ce95e1b3SDavid du Colombier instoffset = s->value + a->offset - BIG;
320*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG && instoffset != 0L)
321*ce95e1b3SDavid du Colombier return C_SECON;
322*ce95e1b3SDavid du Colombier instoffset = s->value + a->offset;
323*ce95e1b3SDavid du Colombier instoffx = INITDAT;
324*ce95e1b3SDavid du Colombier return C_LECON;
325*ce95e1b3SDavid du Colombier
326*ce95e1b3SDavid du Colombier case D_AUTO:
327*ce95e1b3SDavid du Colombier instoffset = autosize + a->offset;
328*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
329*ce95e1b3SDavid du Colombier return C_SACON;
330*ce95e1b3SDavid du Colombier return C_LACON;
331*ce95e1b3SDavid du Colombier
332*ce95e1b3SDavid du Colombier case D_PARAM:
333*ce95e1b3SDavid du Colombier instoffset = autosize + a->offset + ptrsize;
334*ce95e1b3SDavid du Colombier if(instoffset >= -BIG && instoffset < BIG)
335*ce95e1b3SDavid du Colombier return C_SACON;
336*ce95e1b3SDavid du Colombier return C_LACON;
337*ce95e1b3SDavid du Colombier }
338*ce95e1b3SDavid du Colombier return C_GOK;
339*ce95e1b3SDavid du Colombier
340*ce95e1b3SDavid du Colombier case D_BRANCH:
341*ce95e1b3SDavid du Colombier return C_SBRA;
342*ce95e1b3SDavid du Colombier }
343*ce95e1b3SDavid du Colombier return C_GOK;
344*ce95e1b3SDavid du Colombier }
345*ce95e1b3SDavid du Colombier
346*ce95e1b3SDavid du Colombier Optab*
oplook(Prog * p)347*ce95e1b3SDavid du Colombier oplook(Prog *p)
348*ce95e1b3SDavid du Colombier {
349*ce95e1b3SDavid du Colombier int a1, a2, a3, r;
350*ce95e1b3SDavid du Colombier char *c1, *c3;
351*ce95e1b3SDavid du Colombier Optab *o, *e;
352*ce95e1b3SDavid du Colombier
353*ce95e1b3SDavid du Colombier a1 = p->optab;
354*ce95e1b3SDavid du Colombier if(a1)
355*ce95e1b3SDavid du Colombier return optab+(a1-1);
356*ce95e1b3SDavid du Colombier a1 = p->from.class;
357*ce95e1b3SDavid du Colombier if(a1 == 0) {
358*ce95e1b3SDavid du Colombier a1 = aclass(&p->from) + 1;
359*ce95e1b3SDavid du Colombier p->from.class = a1;
360*ce95e1b3SDavid du Colombier }
361*ce95e1b3SDavid du Colombier a1--;
362*ce95e1b3SDavid du Colombier a3 = p->to.class;
363*ce95e1b3SDavid du Colombier if(a3 == 0) {
364*ce95e1b3SDavid du Colombier a3 = aclass(&p->to) + 1;
365*ce95e1b3SDavid du Colombier p->to.class = a3;
366*ce95e1b3SDavid du Colombier }
367*ce95e1b3SDavid du Colombier a3--;
368*ce95e1b3SDavid du Colombier a2 = C_NONE;
369*ce95e1b3SDavid du Colombier if(p->reg != NREG)
370*ce95e1b3SDavid du Colombier a2 = C_REG;
371*ce95e1b3SDavid du Colombier r = p->as;
372*ce95e1b3SDavid du Colombier o = oprange[r].start;
373*ce95e1b3SDavid du Colombier if(o == 0) {
374*ce95e1b3SDavid du Colombier a1 = opcross[repop[r]][a1][a3];
375*ce95e1b3SDavid du Colombier if(a1) {
376*ce95e1b3SDavid du Colombier p->optab = a1+1;
377*ce95e1b3SDavid du Colombier return optab+a1;
378*ce95e1b3SDavid du Colombier }
379*ce95e1b3SDavid du Colombier o = oprange[r].stop; /* just generate an error */
380*ce95e1b3SDavid du Colombier a1 = p->from.class - 1;
381*ce95e1b3SDavid du Colombier }
382*ce95e1b3SDavid du Colombier e = oprange[r].stop;
383*ce95e1b3SDavid du Colombier
384*ce95e1b3SDavid du Colombier c1 = xcmp[a1];
385*ce95e1b3SDavid du Colombier c3 = xcmp[a3];
386*ce95e1b3SDavid du Colombier for(; o<e; o++)
387*ce95e1b3SDavid du Colombier if(c1[o->a1])
388*ce95e1b3SDavid du Colombier if(c3[o->a3]) {
389*ce95e1b3SDavid du Colombier p->optab = (o-optab)+1;
390*ce95e1b3SDavid du Colombier return o;
391*ce95e1b3SDavid du Colombier }
392*ce95e1b3SDavid du Colombier diag("illegal combination %A %d %d %d",
393*ce95e1b3SDavid du Colombier p->as, a1, a2, a3);
394*ce95e1b3SDavid du Colombier if(!debug['a'])
395*ce95e1b3SDavid du Colombier prasm(p);
396*ce95e1b3SDavid du Colombier o = optab;
397*ce95e1b3SDavid du Colombier p->optab = (o-optab)+1;
398*ce95e1b3SDavid du Colombier return o;
399*ce95e1b3SDavid du Colombier }
400*ce95e1b3SDavid du Colombier
401*ce95e1b3SDavid du Colombier int
cmp(int a,int b)402*ce95e1b3SDavid du Colombier cmp(int a, int b)
403*ce95e1b3SDavid du Colombier {
404*ce95e1b3SDavid du Colombier
405*ce95e1b3SDavid du Colombier if(a == b)
406*ce95e1b3SDavid du Colombier return 1;
407*ce95e1b3SDavid du Colombier switch(a) {
408*ce95e1b3SDavid du Colombier case C_LCON:
409*ce95e1b3SDavid du Colombier if(b == C_ZCON || b == C_SCON || b == C_UCON)
410*ce95e1b3SDavid du Colombier return 1;
411*ce95e1b3SDavid du Colombier break;
412*ce95e1b3SDavid du Colombier case C_UCON:
413*ce95e1b3SDavid du Colombier if(b == C_ZCON)
414*ce95e1b3SDavid du Colombier return 1;
415*ce95e1b3SDavid du Colombier break;
416*ce95e1b3SDavid du Colombier case C_SCON:
417*ce95e1b3SDavid du Colombier if(b == C_ZCON)
418*ce95e1b3SDavid du Colombier return 1;
419*ce95e1b3SDavid du Colombier break;
420*ce95e1b3SDavid du Colombier case C_LACON:
421*ce95e1b3SDavid du Colombier if(b == C_SACON)
422*ce95e1b3SDavid du Colombier return 1;
423*ce95e1b3SDavid du Colombier break;
424*ce95e1b3SDavid du Colombier case C_LRCON:
425*ce95e1b3SDavid du Colombier if(b == C_SRCON)
426*ce95e1b3SDavid du Colombier return 1;
427*ce95e1b3SDavid du Colombier break;
428*ce95e1b3SDavid du Colombier case C_LBRA:
429*ce95e1b3SDavid du Colombier if(b == C_SBRA)
430*ce95e1b3SDavid du Colombier return 1;
431*ce95e1b3SDavid du Colombier break;
432*ce95e1b3SDavid du Colombier case C_LEXT:
433*ce95e1b3SDavid du Colombier if(b == C_SEXT)
434*ce95e1b3SDavid du Colombier return 1;
435*ce95e1b3SDavid du Colombier break;
436*ce95e1b3SDavid du Colombier case C_LAUTO:
437*ce95e1b3SDavid du Colombier if(b == C_SAUTO)
438*ce95e1b3SDavid du Colombier return 1;
439*ce95e1b3SDavid du Colombier break;
440*ce95e1b3SDavid du Colombier case C_ZREG:
441*ce95e1b3SDavid du Colombier if(b == C_REG || b == C_ZCON)
442*ce95e1b3SDavid du Colombier return 1;
443*ce95e1b3SDavid du Colombier break;
444*ce95e1b3SDavid du Colombier case C_LOREG:
445*ce95e1b3SDavid du Colombier if(b == C_ZOREG || b == C_SOREG || b == C_SAUTO || b == C_LAUTO)
446*ce95e1b3SDavid du Colombier return 1;
447*ce95e1b3SDavid du Colombier break;
448*ce95e1b3SDavid du Colombier case C_SOREG:
449*ce95e1b3SDavid du Colombier if(b == C_ZOREG || b == C_SAUTO || b == C_SEXT)
450*ce95e1b3SDavid du Colombier return 1;
451*ce95e1b3SDavid du Colombier break;
452*ce95e1b3SDavid du Colombier }
453*ce95e1b3SDavid du Colombier return 0;
454*ce95e1b3SDavid du Colombier }
455*ce95e1b3SDavid du Colombier
456*ce95e1b3SDavid du Colombier int
ocmp(void * a1,void * a2)457*ce95e1b3SDavid du Colombier ocmp(void *a1, void *a2)
458*ce95e1b3SDavid du Colombier {
459*ce95e1b3SDavid du Colombier Optab *p1, *p2;
460*ce95e1b3SDavid du Colombier int n;
461*ce95e1b3SDavid du Colombier
462*ce95e1b3SDavid du Colombier p1 = (Optab*)a1;
463*ce95e1b3SDavid du Colombier p2 = (Optab*)a2;
464*ce95e1b3SDavid du Colombier n = p1->as - p2->as;
465*ce95e1b3SDavid du Colombier if(n)
466*ce95e1b3SDavid du Colombier return n;
467*ce95e1b3SDavid du Colombier n = p1->a1 - p2->a1;
468*ce95e1b3SDavid du Colombier if(n)
469*ce95e1b3SDavid du Colombier return n;
470*ce95e1b3SDavid du Colombier n = p1->a3 - p2->a3;
471*ce95e1b3SDavid du Colombier if(n)
472*ce95e1b3SDavid du Colombier return n;
473*ce95e1b3SDavid du Colombier return 0;
474*ce95e1b3SDavid du Colombier }
475*ce95e1b3SDavid du Colombier
476*ce95e1b3SDavid du Colombier void
buildop(void)477*ce95e1b3SDavid du Colombier buildop(void)
478*ce95e1b3SDavid du Colombier {
479*ce95e1b3SDavid du Colombier int i, n, r;
480*ce95e1b3SDavid du Colombier
481*ce95e1b3SDavid du Colombier for(i=0; i<32; i++)
482*ce95e1b3SDavid du Colombier for(n=0; n<32; n++)
483*ce95e1b3SDavid du Colombier xcmp[i][n] = cmp(n, i);
484*ce95e1b3SDavid du Colombier for(n=0; optab[n].as != AXXX; n++)
485*ce95e1b3SDavid du Colombier ;
486*ce95e1b3SDavid du Colombier qsort(optab, n, sizeof(optab[0]), ocmp);
487*ce95e1b3SDavid du Colombier for(i=0; i<n; i++) {
488*ce95e1b3SDavid du Colombier r = optab[i].as;
489*ce95e1b3SDavid du Colombier oprange[r].start = optab+i;
490*ce95e1b3SDavid du Colombier while(optab[i].as == r)
491*ce95e1b3SDavid du Colombier i++;
492*ce95e1b3SDavid du Colombier oprange[r].stop = optab+i;
493*ce95e1b3SDavid du Colombier i--;
494*ce95e1b3SDavid du Colombier }
495*ce95e1b3SDavid du Colombier
496*ce95e1b3SDavid du Colombier buildrep(1, AMOVW);
497*ce95e1b3SDavid du Colombier }
498*ce95e1b3SDavid du Colombier
499*ce95e1b3SDavid du Colombier void
buildrep(int x,int as)500*ce95e1b3SDavid du Colombier buildrep(int x, int as)
501*ce95e1b3SDavid du Colombier {
502*ce95e1b3SDavid du Colombier Opcross *p;
503*ce95e1b3SDavid du Colombier Optab *e, *s, *o;
504*ce95e1b3SDavid du Colombier int a1, a3, n;
505*ce95e1b3SDavid du Colombier
506*ce95e1b3SDavid du Colombier if(C_GOK >= 32 || x >= nelem(opcross)) {
507*ce95e1b3SDavid du Colombier diag("assumptions fail in buildrep");
508*ce95e1b3SDavid du Colombier errorexit();
509*ce95e1b3SDavid du Colombier }
510*ce95e1b3SDavid du Colombier repop[as] = x;
511*ce95e1b3SDavid du Colombier p = (opcross + x);
512*ce95e1b3SDavid du Colombier s = oprange[as].start;
513*ce95e1b3SDavid du Colombier e = oprange[as].stop;
514*ce95e1b3SDavid du Colombier for(o=e-1; o>=s; o--) {
515*ce95e1b3SDavid du Colombier n = o-optab;
516*ce95e1b3SDavid du Colombier for(a1=0; a1<32; a1++) {
517*ce95e1b3SDavid du Colombier if(!xcmp[a1][o->a1])
518*ce95e1b3SDavid du Colombier continue;
519*ce95e1b3SDavid du Colombier for(a3=0; a3<32; a3++)
520*ce95e1b3SDavid du Colombier if(xcmp[a3][o->a3])
521*ce95e1b3SDavid du Colombier (*p)[a1][a3] = n;
522*ce95e1b3SDavid du Colombier }
523*ce95e1b3SDavid du Colombier }
524*ce95e1b3SDavid du Colombier oprange[as].start = 0;
525*ce95e1b3SDavid du Colombier }
526