1 #include "l.h"
2
3 void
span(void)4 span(void)
5 {
6 Prog *p;
7 Sym *setext;
8 Optab *o;
9 int m;
10 long c;
11
12 if(debug['v'])
13 Bprint(&bso, "%5.2f span\n", cputime());
14 Bflush(&bso);
15 c = INITTEXT;
16 for(p = firstp; p != P; p = p->link) {
17 p->pc = c;
18 o = oplook(p);
19 m = o->size;
20 if(m == 0) {
21 if(p->as == ATEXT) {
22 curtext = p;
23 autosize = p->to.offset + 4;
24 if(p->from.sym != S)
25 p->from.sym->value = c;
26 continue;
27 }
28 if(p->as != ANOP)
29 diag("zero-width instruction\n%P", p);
30 continue;
31 }
32 c += m;
33 }
34 c = rnd(c, 8);
35
36 setext = lookup("etext", 0);
37 if(setext != S) {
38 setext->value = c;
39 textsize = c - INITTEXT;
40 }
41 if(INITRND)
42 INITDAT = rnd(c, INITRND);
43 if(debug['v'])
44 Bprint(&bso, "tsize = %lux\n", textsize);
45 Bflush(&bso);
46 }
47
48 void
xdefine(char * p,int t,long v)49 xdefine(char *p, int t, long v)
50 {
51 Sym *s;
52
53 s = lookup(p, 0);
54 if(s->type == 0 || s->type == SXREF) {
55 s->type = t;
56 s->value = v;
57 }
58 }
59
60 long
regoff(Adr * a)61 regoff(Adr *a)
62 {
63
64 instoffset = 0;
65 aclass(a);
66 return instoffset;
67 }
68
69 int
aclass(Adr * a)70 aclass(Adr *a)
71 {
72 Sym *s;
73 int t;
74
75 switch(a->type) {
76 case D_NONE:
77 return C_NONE;
78
79 case D_REG:
80 return C_REG;
81
82 case D_FREG:
83 return C_FREG;
84
85 case D_CREG:
86 return C_CREG;
87
88 case D_PREG:
89 if(a->reg == D_FSR)
90 return C_FSR;
91 if(a->reg == D_FPQ)
92 return C_FQ;
93 return C_PREG;
94
95 case D_OREG:
96 switch(a->name) {
97 case D_EXTERN:
98 case D_STATIC:
99 if(a->sym == S)
100 break;
101 t = a->sym->type;
102 if(t == 0 || t == SXREF) {
103 diag("undefined external: %s in %s",
104 a->sym->name, TNAME);
105 a->sym->type = SDATA;
106 }
107 instoffset = a->sym->value + a->offset - BIG;
108 if(instoffset >= -BIG && instoffset < BIG) {
109 if(instoffset & 7)
110 return C_OSEXT;
111 return C_ESEXT;
112 }
113 if(instoffset & 7)
114 return C_OLEXT;
115 return C_ELEXT;
116 case D_AUTO:
117 instoffset = autosize + a->offset;
118 goto dauto;
119
120 case D_PARAM:
121 instoffset = autosize + a->offset + 4L;
122 dauto:
123 if(instoffset >= -BIG && instoffset < BIG) {
124 if(instoffset & 7)
125 return C_OSAUTO;
126 return C_ESAUTO;
127 }
128 if(instoffset & 7)
129 return C_OLAUTO;
130 return C_ELAUTO;
131 case D_NONE:
132 instoffset = a->offset;
133 if(instoffset == 0)
134 return C_ZOREG;
135 if(instoffset >= -BIG && instoffset < BIG)
136 return C_SOREG;
137 return C_LOREG;
138 }
139 return C_GOK;
140
141 case D_ASI:
142 if(a->name == D_NONE)
143 return C_ASI;
144 return C_GOK;
145
146 case D_CONST:
147 switch(a->name) {
148
149 case D_NONE:
150 instoffset = a->offset;
151 consize:
152 if(instoffset == 0)
153 return C_ZCON;
154 if(instoffset >= -0x1000 && instoffset <= 0xfff)
155 return C_SCON;
156 if((instoffset & 0x3ff) == 0)
157 return C_UCON;
158 return C_LCON;
159
160 case D_EXTERN:
161 case D_STATIC:
162 s = a->sym;
163 if(s == S)
164 break;
165 t = s->type;
166 if(t == 0 || t == SXREF) {
167 diag("undefined external: %s in %s",
168 s->name, TNAME);
169 s->type = SDATA;
170 }
171 if(s->type == STEXT || s->type == SLEAF) {
172 instoffset = s->value + a->offset;
173 return C_LCON;
174 }
175 if(s->type == SCONST) {
176 instoffset = s->value + a->offset;
177 goto consize;
178 }
179 instoffset = s->value + a->offset - BIG;
180 if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
181 return C_SECON;
182 instoffset = s->value + a->offset + INITDAT;
183 /* not sure why this barfs */
184 return C_LCON;
185 /*
186 if(instoffset == 0)
187 return C_ZCON;
188 if(instoffset >= -0x1000 && instoffset <= 0xfff)
189 return C_SCON;
190 if((instoffset & 0x3ff) == 0)
191 return C_UCON;
192 return C_LCON;
193 */
194
195 case D_AUTO:
196 instoffset = autosize + a->offset;
197 if(instoffset >= -BIG && instoffset < BIG)
198 return C_SACON;
199 return C_LACON;
200
201 case D_PARAM:
202 instoffset = autosize + a->offset + 4L;
203 if(instoffset >= -BIG && instoffset < BIG)
204 return C_SACON;
205 return C_LACON;
206 }
207 return C_GOK;
208
209 case D_BRANCH:
210 return C_SBRA;
211 }
212 return C_GOK;
213 }
214
215 Optab*
oplook(Prog * p)216 oplook(Prog *p)
217 {
218 int a1, a2, a3, r;
219 char *c1, *c3;
220 Optab *o, *e;
221
222 a1 = p->optab;
223 if(a1)
224 return optab+(a1-1);
225 a1 = p->from.class;
226 if(a1 == 0) {
227 a1 = aclass(&p->from) + 1;
228 p->from.class = a1;
229 }
230 a1--;
231 a3 = p->to.class;
232 if(a3 == 0) {
233 a3 = aclass(&p->to) + 1;
234 p->to.class = a3;
235 }
236 a3--;
237 a2 = C_NONE;
238 if(p->reg != NREG)
239 a2 = C_REG;
240 r = p->as;
241 o = oprange[r].start;
242 if(o == 0)
243 o = oprange[r].stop; /* just generate an error */
244 e = oprange[r].stop;
245 c1 = xcmp[a1];
246 c3 = xcmp[a3];
247 for(; o<e; o++)
248 if(o->a2 == a2)
249 if(c1[o->a1])
250 if(c3[o->a3]) {
251 p->optab = (o-optab)+1;
252 return o;
253 }
254 diag("illegal combination %A %d %d %d",
255 p->as, a1, a2, a3);
256 if(1||!debug['a'])
257 prasm(p);
258 if(o == 0)
259 errorexit();
260 return o;
261 }
262
263 int
cmp(int a,int b)264 cmp(int a, int b)
265 {
266
267 if(a == b)
268 return 1;
269 switch(a) {
270 case C_LCON:
271 if(b == C_ZCON || b == C_SCON || b == C_UCON)
272 return 1;
273 break;
274 case C_UCON:
275 if(b == C_ZCON)
276 return 1;
277 break;
278 case C_SCON:
279 if(b == C_ZCON)
280 return 1;
281 break;
282 case C_LACON:
283 if(b == C_SACON)
284 return 1;
285 break;
286 case C_LBRA:
287 if(b == C_SBRA)
288 return 1;
289 break;
290 case C_ELEXT:
291 if(b == C_ESEXT)
292 return 1;
293 break;
294 case C_LEXT:
295 if(b == C_SEXT ||
296 b == C_ESEXT || b == C_OSEXT ||
297 b == C_ELEXT || b == C_OLEXT)
298 return 1;
299 break;
300 case C_SEXT:
301 if(b == C_ESEXT || b == C_OSEXT)
302 return 1;
303 break;
304 case C_ELAUTO:
305 if(b == C_ESAUTO)
306 return 1;
307 break;
308 case C_LAUTO:
309 if(b == C_SAUTO ||
310 b == C_ESAUTO || b == C_OSAUTO ||
311 b == C_ELAUTO || b == C_OLAUTO)
312 return 1;
313 break;
314 case C_SAUTO:
315 if(b == C_ESAUTO || b == C_OSAUTO)
316 return 1;
317 break;
318 case C_REG:
319 if(b == C_ZCON)
320 return 1;
321 break;
322 case C_LOREG:
323 if(b == C_ZOREG || b == C_SOREG)
324 return 1;
325 break;
326 case C_SOREG:
327 if(b == C_ZOREG)
328 return 1;
329 break;
330
331 case C_ANY:
332 return 1;
333 }
334 return 0;
335 }
336
337 int
ocmp(const void * a1,const void * a2)338 ocmp(const void *a1, const void *a2)
339 {
340 Optab *p1, *p2;
341 int n;
342
343 p1 = (Optab*)a1;
344 p2 = (Optab*)a2;
345 n = p1->as - p2->as;
346 if(n)
347 return n;
348 n = p1->a1 - p2->a1;
349 if(n)
350 return n;
351 n = p1->a2 - p2->a2;
352 if(n)
353 return n;
354 n = p1->a3 - p2->a3;
355 if(n)
356 return n;
357 return 0;
358 }
359
360 void
buildop(void)361 buildop(void)
362 {
363 int i, n, r;
364
365 for(i=0; i<C_NCLASS; i++)
366 for(n=0; n<C_NCLASS; n++)
367 xcmp[i][n] = cmp(n, i);
368 for(n=0; optab[n].as != AXXX; n++)
369 ;
370 qsort(optab, n, sizeof(optab[0]), ocmp);
371 for(i=0; i<n; i++) {
372 r = optab[i].as;
373 oprange[r].start = optab+i;
374 while(optab[i].as == r)
375 i++;
376 oprange[r].stop = optab+i;
377 i--;
378
379 switch(r)
380 {
381 default:
382 diag("unknown op in build: %A", r);
383 errorexit();
384 case AADD:
385 oprange[AADDX] = oprange[r];
386 oprange[ASUB] = oprange[r];
387 oprange[ASUBX] = oprange[r];
388 oprange[AMUL] = oprange[r];
389 oprange[AXOR] = oprange[r];
390 oprange[AXNOR] = oprange[r];
391 oprange[AAND] = oprange[r];
392 oprange[AANDN] = oprange[r];
393 oprange[AOR] = oprange[r];
394 oprange[AORN] = oprange[r];
395 oprange[ASLL] = oprange[r];
396 oprange[ASRL] = oprange[r];
397 oprange[ASRA] = oprange[r];
398 oprange[AADDCC] = oprange[r];
399 oprange[AADDXCC] = oprange[r];
400 oprange[ATADDCC] = oprange[r];
401 oprange[ATADDCCTV] = oprange[r];
402 oprange[ASUBCC] = oprange[r];
403 oprange[ASUBXCC] = oprange[r];
404 oprange[ATSUBCC] = oprange[r];
405 oprange[ATSUBCCTV] = oprange[r];
406 oprange[AXORCC] = oprange[r];
407 oprange[AXNORCC] = oprange[r];
408 oprange[AANDCC] = oprange[r];
409 oprange[AANDNCC] = oprange[r];
410 oprange[AORCC] = oprange[r];
411 oprange[AORNCC] = oprange[r];
412 oprange[AMULSCC] = oprange[r];
413 oprange[ASAVE] = oprange[r];
414 oprange[ARESTORE] = oprange[r];
415 break;
416 case AMOVB:
417 oprange[AMOVH] = oprange[r];
418 oprange[AMOVHU] = oprange[r];
419 oprange[AMOVBU] = oprange[r];
420 oprange[ASWAP] = oprange[r];
421 oprange[ATAS] = oprange[r];
422 break;
423 case ABA:
424 oprange[ABN] = oprange[r];
425 oprange[AFBA] = oprange[r];
426 oprange[AFBN] = oprange[r];
427 break;
428 case ABE:
429 oprange[ABCC] = oprange[r];
430 oprange[ABCS] = oprange[r];
431 oprange[ABGE] = oprange[r];
432 oprange[ABGU] = oprange[r];
433 oprange[ABG] = oprange[r];
434 oprange[ABLEU] = oprange[r];
435 oprange[ABLE] = oprange[r];
436 oprange[ABL] = oprange[r];
437 oprange[ABNEG] = oprange[r];
438 oprange[ABNE] = oprange[r];
439 oprange[ABPOS] = oprange[r];
440 oprange[ABVC] = oprange[r];
441 oprange[ABVS] = oprange[r];
442
443 oprange[AFBE] = oprange[r];
444 oprange[AFBG] = oprange[r];
445 oprange[AFBGE] = oprange[r];
446 oprange[AFBL] = oprange[r];
447 oprange[AFBLE] = oprange[r];
448 oprange[AFBLG] = oprange[r];
449 oprange[AFBNE] = oprange[r];
450 oprange[AFBO] = oprange[r];
451 oprange[AFBU] = oprange[r];
452 oprange[AFBUE] = oprange[r];
453 oprange[AFBUG] = oprange[r];
454 oprange[AFBUGE] = oprange[r];
455 oprange[AFBUL] = oprange[r];
456 oprange[AFBULE] = oprange[r];
457 break;
458 case ATA:
459 oprange[ATCC] = oprange[r];
460 oprange[ATCS] = oprange[r];
461 oprange[ATE] = oprange[r];
462 oprange[ATGE] = oprange[r];
463 oprange[ATGU] = oprange[r];
464 oprange[ATG] = oprange[r];
465 oprange[ATLEU] = oprange[r];
466 oprange[ATLE] = oprange[r];
467 oprange[ATL] = oprange[r];
468 oprange[ATNEG] = oprange[r];
469 oprange[ATNE] = oprange[r];
470 oprange[ATN] = oprange[r];
471 oprange[ATPOS] = oprange[r];
472 oprange[ATVC] = oprange[r];
473 oprange[ATVS] = oprange[r];
474 break;
475 case AFADDD:
476 oprange[AFADDF] = oprange[r];
477 oprange[AFADDX] = oprange[r];
478 oprange[AFDIVD] = oprange[r];
479 oprange[AFDIVF] = oprange[r];
480 oprange[AFDIVX] = oprange[r];
481 oprange[AFMULD] = oprange[r];
482 oprange[AFMULF] = oprange[r];
483 oprange[AFMULX] = oprange[r];
484 oprange[AFSUBD] = oprange[r];
485 oprange[AFSUBF] = oprange[r];
486 oprange[AFSUBX] = oprange[r];
487 break;
488 case AFCMPD:
489 oprange[AFCMPF] = oprange[r];
490 oprange[AFCMPX] = oprange[r];
491 oprange[AFCMPED] = oprange[r];
492 oprange[AFCMPEF] = oprange[r];
493 oprange[AFCMPEX] = oprange[r];
494 break;
495 case AFABSF:
496 oprange[AFMOVDF] = oprange[r];
497 oprange[AFMOVDW] = oprange[r];
498 oprange[AFMOVFD] = oprange[r];
499 oprange[AFMOVFW] = oprange[r];
500 oprange[AFMOVWD] = oprange[r];
501 oprange[AFMOVWF] = oprange[r];
502 oprange[AFNEGF] = oprange[r];
503 oprange[AFSQRTD] = oprange[r];
504 oprange[AFSQRTF] = oprange[r];
505 break;
506 case AFMOVF:
507 case AFMOVD:
508 case AMOVW:
509 case AMOVD:
510 case AWORD:
511 case ARETT:
512 case AJMPL:
513 case AJMP:
514 case ACMP:
515 case ANOP:
516 case ATEXT:
517 case ADIV:
518 case ADIVL:
519 case AMOD:
520 case AMODL:
521 break;
522 }
523 }
524 }
525