1 #include "l.h"
2 #define r0iszero 1
3
4 void
span(void)5 span(void)
6 {
7 Prog *p, *q;
8 Sym *setext;
9 Optab *o;
10 int m, bflag;
11 long c, otxt;
12
13 if(debug['v'])
14 Bprint(&bso, "%5.2f span\n", cputime());
15 Bflush(&bso);
16
17 bflag = 0;
18 c = INITTEXT;
19 otxt = c;
20 for(p = firstp; p != P; p = p->link) {
21 p->pc = c;
22 o = oplook(p);
23 m = o->size;
24 if(m == 0) {
25 if(p->as == ATEXT) {
26 curtext = p;
27 autosize = p->to.offset + 4;
28 if(p->from3.type == D_CONST) {
29 if(p->from3.offset & 3)
30 diag("illegal origin\n%P", p);
31 if(c > p->from3.offset)
32 diag("passed origin (#%lux)\n%P", c, p);
33 else
34 c = p->from3.offset;
35 p->pc = c;
36 }
37 if(p->from.sym != S)
38 p->from.sym->value = c;
39 /* need passes to resolve branches? */
40 if(c-otxt >= (1L<<15))
41 bflag = c;
42 otxt = c;
43 continue;
44 }
45 if(p->as != ANOP)
46 diag("zero-width instruction\n%P", p);
47 continue;
48 }
49 c += m;
50 }
51
52 /*
53 * if any procedure is large enough to
54 * generate a large SBRA branch, then
55 * generate extra passes putting branches
56 * around jmps to fix. this is rare.
57 */
58 while(bflag) {
59 if(debug['v'])
60 Bprint(&bso, "%5.2f span1\n", cputime());
61 bflag = 0;
62 c = INITTEXT;
63 for(p = firstp; p != P; p = p->link) {
64 p->pc = c;
65 o = oplook(p);
66 if((o->type == 16 || o->type == 17) && p->cond) {
67 otxt = p->cond->pc - c;
68 if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
69 q = prg();
70 q->link = p->link;
71 p->link = q;
72 q->as = ABR;
73 q->to.type = D_BRANCH;
74 q->cond = p->cond;
75 p->cond = q;
76 q = prg();
77 q->link = p->link;
78 p->link = q;
79 q->as = ABR;
80 q->to.type = D_BRANCH;
81 q->cond = q->link->link;
82 addnop(p->link);
83 addnop(p);
84 bflag = 1;
85 }
86 }
87 m = o->size;
88 if(m == 0) {
89 if(p->as == ATEXT) {
90 curtext = p;
91 autosize = p->to.offset + 4;
92 if(p->from.sym != S)
93 p->from.sym->value = c;
94 continue;
95 }
96 if(p->as != ANOP)
97 diag("zero-width instruction\n%P", p);
98 continue;
99 }
100 c += m;
101 }
102 }
103
104 c = rnd(c, 8);
105
106 setext = lookup("etext", 0);
107 if(setext != S) {
108 setext->value = c;
109 textsize = c - INITTEXT;
110 }
111 if(INITRND)
112 INITDAT = rnd(c, INITRND);
113 if(debug['v'])
114 Bprint(&bso, "tsize = %lux\n", textsize);
115 Bflush(&bso);
116 }
117
118 void
xdefine(char * p,int t,long v)119 xdefine(char *p, int t, long v)
120 {
121 Sym *s;
122
123 s = lookup(p, 0);
124 if(s->type == 0 || s->type == SXREF) {
125 s->type = t;
126 s->value = v;
127 }
128 }
129
130 long
regoff(Adr * a)131 regoff(Adr *a)
132 {
133
134 instoffset = 0;
135 aclass(a);
136 return instoffset;
137 }
138
139 int
aclass(Adr * a)140 aclass(Adr *a)
141 {
142 Sym *s;
143 int t;
144
145 switch(a->type) {
146 case D_NONE:
147 return C_NONE;
148
149 case D_REG:
150 return C_REG;
151
152 case D_FREG:
153 return C_FREG;
154
155 case D_CREG:
156 return C_CREG;
157
158 case D_SPR:
159 if(a->offset == D_LR)
160 return C_LR;
161 if(a->offset == D_XER)
162 return C_XER;
163 if(a->offset == D_CTR)
164 return C_CTR;
165 return C_SPR;
166
167 case D_DCR:
168 return C_SPR;
169
170 case D_SREG:
171 return C_SREG;
172
173 case D_FPSCR:
174 return C_FPSCR;
175
176 case D_MSR:
177 return C_MSR;
178
179 case D_OREG:
180 switch(a->name) {
181 case D_EXTERN:
182 case D_STATIC:
183 if(a->sym == S)
184 break;
185 t = a->sym->type;
186 if(t == 0 || t == SXREF) {
187 diag("undefined external: %s in %s",
188 a->sym->name, TNAME);
189 a->sym->type = SDATA;
190 }
191 if(dlm){
192 instoffset = a->sym->value + a->offset;
193 switch(a->sym->type){
194 case STEXT:
195 case SLEAF:
196 case SCONST:
197 case SUNDEF:
198 break;
199 default:
200 instoffset += INITDAT;
201 }
202 return C_ADDR;
203 }
204 instoffset = a->sym->value + a->offset - BIG;
205 if(instoffset >= -BIG && instoffset < BIG)
206 return C_SEXT;
207 return C_LEXT;
208 case D_AUTO:
209 instoffset = autosize + a->offset;
210 if(instoffset >= -BIG && instoffset < BIG)
211 return C_SAUTO;
212 return C_LAUTO;
213
214 case D_PARAM:
215 instoffset = autosize + a->offset + 4L;
216 if(instoffset >= -BIG && instoffset < BIG)
217 return C_SAUTO;
218 return C_LAUTO;
219 case D_NONE:
220 instoffset = a->offset;
221 if(instoffset == 0)
222 return C_ZOREG;
223 if(instoffset >= -BIG && instoffset < BIG)
224 return C_SOREG;
225 return C_LOREG;
226 }
227 return C_GOK;
228
229 case D_OPT:
230 instoffset = a->offset & 31L;
231 if(a->name == D_NONE)
232 return C_SCON;
233 return C_GOK;
234
235 case D_CONST:
236 switch(a->name) {
237
238 case D_NONE:
239 instoffset = a->offset;
240 consize:
241 if(instoffset >= 0) {
242 if(r0iszero && instoffset == 0)
243 return C_ZCON;
244 if(instoffset <= 0x7fff)
245 return C_SCON;
246 if(instoffset <= 0xffff)
247 return C_ANDCON;
248 if((instoffset & 0xffff) == 0)
249 return C_UCON;
250 return C_LCON;
251 }
252 if(instoffset >= -0x8000)
253 return C_ADDCON;
254 if((instoffset & 0xffff) == 0)
255 return C_UCON;
256 return C_LCON;
257
258 case D_EXTERN:
259 case D_STATIC:
260 s = a->sym;
261 if(s == S)
262 break;
263 t = s->type;
264 if(t == 0 || t == SXREF) {
265 diag("undefined external: %s in %s",
266 s->name, TNAME);
267 s->type = SDATA;
268 }
269 if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
270 instoffset = s->value + a->offset;
271 return C_LCON;
272 }
273 if(s->type == SCONST) {
274 instoffset = s->value + a->offset;
275 if(dlm)
276 return C_LCON;
277 goto consize;
278 }
279 if(!dlm){
280 instoffset = s->value + a->offset - BIG;
281 if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
282 return C_SECON;
283 }
284 instoffset = s->value + a->offset + INITDAT;
285 if(dlm)
286 return C_LCON;
287 /* not sure why this barfs */
288 return C_LCON;
289 /*
290 if(instoffset == 0)
291 return C_ZCON;
292 if(instoffset >= -0x8000 && instoffset <= 0xffff)
293 return C_SCON;
294 if((instoffset & 0xffff) == 0)
295 return C_UCON;
296 return C_LCON;
297 */
298
299 case D_AUTO:
300 instoffset = autosize + a->offset;
301 if(instoffset >= -BIG && instoffset < BIG)
302 return C_SACON;
303 return C_LACON;
304
305 case D_PARAM:
306 instoffset = autosize + a->offset + 4L;
307 if(instoffset >= -BIG && instoffset < BIG)
308 return C_SACON;
309 return C_LACON;
310 }
311 return C_GOK;
312
313 case D_BRANCH:
314 return C_SBRA;
315 }
316 return C_GOK;
317 }
318
319 Optab*
oplook(Prog * p)320 oplook(Prog *p)
321 {
322 int a1, a2, a3, a4, r;
323 char *c1, *c3, *c4;
324 Optab *o, *e;
325
326 a1 = p->optab;
327 if(a1)
328 return optab+(a1-1);
329 a1 = p->from.class;
330 if(a1 == 0) {
331 a1 = aclass(&p->from) + 1;
332 p->from.class = a1;
333 }
334 a1--;
335 a3 = p->from3.class;
336 if(a3 == 0) {
337 a3 = aclass(&p->from3) + 1;
338 p->from3.class = a3;
339 }
340 a3--;
341 a4 = p->to.class;
342 if(a4 == 0) {
343 a4 = aclass(&p->to) + 1;
344 p->to.class = a4;
345 }
346 a4--;
347 a2 = C_NONE;
348 if(p->reg != NREG)
349 a2 = C_REG;
350 r = p->as;
351 o = oprange[r].start;
352 if(o == 0)
353 o = oprange[r].stop; /* just generate an error */
354 e = oprange[r].stop;
355 c1 = xcmp[a1];
356 c3 = xcmp[a3];
357 c4 = xcmp[a4];
358 for(; o<e; o++)
359 if(o->a2 == a2)
360 if(c1[o->a1])
361 if(c3[o->a3])
362 if(c4[o->a4]) {
363 p->optab = (o-optab)+1;
364 return o;
365 }
366 diag("illegal combination %A %R %R %R %R",
367 p->as, a1, a2, a3, a4);
368 if(1||!debug['a'])
369 prasm(p);
370 if(o == 0)
371 errorexit();
372 return o;
373 }
374
375 int
cmp(int a,int b)376 cmp(int a, int b)
377 {
378
379 if(a == b)
380 return 1;
381 switch(a) {
382 case C_LCON:
383 if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
384 return 1;
385 break;
386 case C_ADDCON:
387 if(b == C_ZCON || b == C_SCON)
388 return 1;
389 break;
390 case C_ANDCON:
391 if(b == C_ZCON || b == C_SCON)
392 return 1;
393 break;
394 case C_SPR:
395 if(b == C_LR || b == C_XER || b == C_CTR)
396 return 1;
397 break;
398 case C_UCON:
399 if(b == C_ZCON)
400 return 1;
401 break;
402 case C_SCON:
403 if(b == C_ZCON)
404 return 1;
405 break;
406 case C_LACON:
407 if(b == C_SACON)
408 return 1;
409 break;
410 case C_LBRA:
411 if(b == C_SBRA)
412 return 1;
413 break;
414 case C_LEXT:
415 if(b == C_SEXT)
416 return 1;
417 break;
418 case C_LAUTO:
419 if(b == C_SAUTO)
420 return 1;
421 break;
422 case C_REG:
423 if(r0iszero && b == C_ZCON)
424 return 1;
425 break;
426 case C_LOREG:
427 if(b == C_ZOREG || b == C_SOREG)
428 return 1;
429 break;
430 case C_SOREG:
431 if(b == C_ZOREG)
432 return 1;
433 break;
434
435 case C_ANY:
436 return 1;
437 }
438 return 0;
439 }
440
441 int
ocmp(void * a1,void * a2)442 ocmp(void *a1, void *a2)
443 {
444 Optab *p1, *p2;
445 int n;
446
447 p1 = a1;
448 p2 = a2;
449 n = p1->as - p2->as;
450 if(n)
451 return n;
452 n = p1->a1 - p2->a1;
453 if(n)
454 return n;
455 n = p1->a2 - p2->a2;
456 if(n)
457 return n;
458 n = p1->a3 - p2->a3;
459 if(n)
460 return n;
461 n = p1->a4 - p2->a4;
462 if(n)
463 return n;
464 return 0;
465 }
466
467 void
buildop(void)468 buildop(void)
469 {
470 int i, n, r;
471
472 for(i=0; i<C_NCLASS; i++)
473 for(n=0; n<C_NCLASS; n++)
474 xcmp[i][n] = cmp(n, i);
475 for(n=0; optab[n].as != AXXX; n++)
476 ;
477 qsort(optab, n, sizeof(optab[0]), ocmp);
478 for(i=0; i<n; i++) {
479 r = optab[i].as;
480 oprange[r].start = optab+i;
481 while(optab[i].as == r)
482 i++;
483 oprange[r].stop = optab+i;
484 i--;
485
486 switch(r)
487 {
488 default:
489 diag("unknown op in build: %A", r);
490 errorexit();
491 case ADCBF: /* unary indexed: op (b+a); op (b) */
492 oprange[ADCBI] = oprange[r];
493 oprange[ADCBST] = oprange[r];
494 oprange[ADCBT] = oprange[r];
495 oprange[ADCBTST] = oprange[r];
496 oprange[ADCBZ] = oprange[r];
497 oprange[AICBI] = oprange[r];
498 break;
499 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
500 oprange[ASTWCCC] = oprange[r];
501 break;
502 case AREM: /* macro */
503 oprange[AREMCC] = oprange[r];
504 oprange[AREMV] = oprange[r];
505 oprange[AREMVCC] = oprange[r];
506 oprange[AREMU] = oprange[r];
507 oprange[AREMUCC] = oprange[r];
508 oprange[AREMUV] = oprange[r];
509 oprange[AREMUVCC] = oprange[r];
510 break;
511 case ADIVW: /* op Rb[,Ra],Rd */
512 oprange[AMULHW] = oprange[r];
513 oprange[AMULHWCC] = oprange[r];
514 oprange[AMULHWU] = oprange[r];
515 oprange[AMULHWUCC] = oprange[r];
516 oprange[AMULLWCC] = oprange[r];
517 oprange[AMULLWVCC] = oprange[r];
518 oprange[AMULLWV] = oprange[r];
519 oprange[ADIVWCC] = oprange[r];
520 oprange[ADIVWV] = oprange[r];
521 oprange[ADIVWVCC] = oprange[r];
522 oprange[ADIVWU] = oprange[r];
523 oprange[ADIVWUCC] = oprange[r];
524 oprange[ADIVWUV] = oprange[r];
525 oprange[ADIVWUVCC] = oprange[r];
526 oprange[AADDCC] = oprange[r];
527 oprange[AADDCV] = oprange[r];
528 oprange[AADDCVCC] = oprange[r];
529 oprange[AADDV] = oprange[r];
530 oprange[AADDVCC] = oprange[r];
531 oprange[AADDE] = oprange[r];
532 oprange[AADDECC] = oprange[r];
533 oprange[AADDEV] = oprange[r];
534 oprange[AADDEVCC] = oprange[r];
535 oprange[ACRAND] = oprange[r];
536 oprange[ACRANDN] = oprange[r];
537 oprange[ACREQV] = oprange[r];
538 oprange[ACRNAND] = oprange[r];
539 oprange[ACRNOR] = oprange[r];
540 oprange[ACROR] = oprange[r];
541 oprange[ACRORN] = oprange[r];
542 oprange[ACRXOR] = oprange[r];
543 oprange[AMULCHW] = oprange[r];
544 oprange[AMULCHWCC] = oprange[r];
545 oprange[AMULCHWU] = oprange[r];
546 oprange[AMULCHWUCC] = oprange[r];
547 oprange[AMULHHW] = oprange[r];
548 oprange[AMULHHWCC] = oprange[r];
549 oprange[AMULHHWU] = oprange[r];
550 oprange[AMULHHWUCC] = oprange[r];
551 oprange[AMULLHW] = oprange[r];
552 oprange[AMULLHWCC] = oprange[r];
553 oprange[AMULLHWU] = oprange[r];
554 oprange[AMULLHWUCC] = oprange[r];
555 break;
556 case AMACCHW: /* strictly 3 registers */
557 oprange[AMACCHWCC] = oprange[r];
558 oprange[AMACCHWS] = oprange[r];
559 oprange[AMACCHWSCC] = oprange[r];
560 oprange[AMACCHWSU] = oprange[r];
561 oprange[AMACCHWSUCC] = oprange[r];
562 oprange[AMACCHWSUV] = oprange[r];
563 oprange[AMACCHWSUVCC] = oprange[r];
564 oprange[AMACCHWSV] = oprange[r];
565 oprange[AMACCHWSVCC] = oprange[r];
566 oprange[AMACCHWU] = oprange[r];
567 oprange[AMACCHWUCC] = oprange[r];
568 oprange[AMACCHWUV] = oprange[r];
569 oprange[AMACCHWUVCC] = oprange[r];
570 oprange[AMACCHWV] = oprange[r];
571 oprange[AMACCHWVCC] = oprange[r];
572 oprange[AMACHHW] = oprange[r];
573 oprange[AMACHHWCC] = oprange[r];
574 oprange[AMACHHWS] = oprange[r];
575 oprange[AMACHHWSCC] = oprange[r];
576 oprange[AMACHHWSU] = oprange[r];
577 oprange[AMACHHWSUCC] = oprange[r];
578 oprange[AMACHHWSUV] = oprange[r];
579 oprange[AMACHHWSUVCC] = oprange[r];
580 oprange[AMACHHWSV] = oprange[r];
581 oprange[AMACHHWSVCC] = oprange[r];
582 oprange[AMACHHWU] = oprange[r];
583 oprange[AMACHHWUCC] = oprange[r];
584 oprange[AMACHHWUV] = oprange[r];
585 oprange[AMACHHWUVCC] = oprange[r];
586 oprange[AMACHHWV] = oprange[r];
587 oprange[AMACHHWVCC] = oprange[r];
588 oprange[AMACLHW] = oprange[r];
589 oprange[AMACLHWCC] = oprange[r];
590 oprange[AMACLHWS] = oprange[r];
591 oprange[AMACLHWSCC] = oprange[r];
592 oprange[AMACLHWSU] = oprange[r];
593 oprange[AMACLHWSUCC] = oprange[r];
594 oprange[AMACLHWSUV] = oprange[r];
595 oprange[AMACLHWSUVCC] = oprange[r];
596 oprange[AMACLHWSV] = oprange[r];
597 oprange[AMACLHWSVCC] = oprange[r];
598 oprange[AMACLHWU] = oprange[r];
599 oprange[AMACLHWUCC] = oprange[r];
600 oprange[AMACLHWUV] = oprange[r];
601 oprange[AMACLHWUVCC] = oprange[r];
602 oprange[AMACLHWV] = oprange[r];
603 oprange[AMACLHWVCC] = oprange[r];
604 oprange[ANMACCHW] = oprange[r];
605 oprange[ANMACCHWCC] = oprange[r];
606 oprange[ANMACCHWS] = oprange[r];
607 oprange[ANMACCHWSCC] = oprange[r];
608 oprange[ANMACCHWSV] = oprange[r];
609 oprange[ANMACCHWSVCC] = oprange[r];
610 oprange[ANMACCHWV] = oprange[r];
611 oprange[ANMACCHWVCC] = oprange[r];
612 oprange[ANMACHHW] = oprange[r];
613 oprange[ANMACHHWCC] = oprange[r];
614 oprange[ANMACHHWS] = oprange[r];
615 oprange[ANMACHHWSCC] = oprange[r];
616 oprange[ANMACHHWSV] = oprange[r];
617 oprange[ANMACHHWSVCC] = oprange[r];
618 oprange[ANMACHHWV] = oprange[r];
619 oprange[ANMACHHWVCC] = oprange[r];
620 oprange[ANMACLHW] = oprange[r];
621 oprange[ANMACLHWCC] = oprange[r];
622 oprange[ANMACLHWS] = oprange[r];
623 oprange[ANMACLHWSCC] = oprange[r];
624 oprange[ANMACLHWSV] = oprange[r];
625 oprange[ANMACLHWSVCC] = oprange[r];
626 oprange[ANMACLHWV] = oprange[r];
627 oprange[ANMACLHWVCC] = oprange[r];
628 break;
629 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
630 oprange[AMOVH] = oprange[r];
631 oprange[AMOVHZ] = oprange[r];
632 break;
633 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */
634 oprange[AMOVHU] = oprange[r];
635 oprange[AMOVHZU] = oprange[r];
636 oprange[AMOVWU] = oprange[r];
637 oprange[AMOVMW] = oprange[r];
638 break;
639 case AAND: /* logical op Rb,Rs,Ra; no literal */
640 oprange[AANDN] = oprange[r];
641 oprange[AANDNCC] = oprange[r];
642 oprange[AEQV] = oprange[r];
643 oprange[AEQVCC] = oprange[r];
644 oprange[ANAND] = oprange[r];
645 oprange[ANANDCC] = oprange[r];
646 oprange[ANOR] = oprange[r];
647 oprange[ANORCC] = oprange[r];
648 oprange[AORCC] = oprange[r];
649 oprange[AORN] = oprange[r];
650 oprange[AORNCC] = oprange[r];
651 oprange[AXORCC] = oprange[r];
652 break;
653 case AADDME: /* op Ra, Rd */
654 oprange[AADDMECC] = oprange[r];
655 oprange[AADDMEV] = oprange[r];
656 oprange[AADDMEVCC] = oprange[r];
657 oprange[AADDZE] = oprange[r];
658 oprange[AADDZECC] = oprange[r];
659 oprange[AADDZEV] = oprange[r];
660 oprange[AADDZEVCC] = oprange[r];
661 oprange[ASUBME] = oprange[r];
662 oprange[ASUBMECC] = oprange[r];
663 oprange[ASUBMEV] = oprange[r];
664 oprange[ASUBMEVCC] = oprange[r];
665 oprange[ASUBZE] = oprange[r];
666 oprange[ASUBZECC] = oprange[r];
667 oprange[ASUBZEV] = oprange[r];
668 oprange[ASUBZEVCC] = oprange[r];
669 break;
670 case AADDC:
671 oprange[AADDCCC] = oprange[r];
672 break;
673 case ABEQ:
674 oprange[ABGE] = oprange[r];
675 oprange[ABGT] = oprange[r];
676 oprange[ABLE] = oprange[r];
677 oprange[ABLT] = oprange[r];
678 oprange[ABNE] = oprange[r];
679 oprange[ABVC] = oprange[r];
680 oprange[ABVS] = oprange[r];
681 break;
682 case ABR:
683 oprange[ABL] = oprange[r];
684 break;
685 case ABC:
686 oprange[ABCL] = oprange[r];
687 break;
688 case AEXTSB: /* op Rs, Ra */
689 oprange[AEXTSBCC] = oprange[r];
690 oprange[AEXTSH] = oprange[r];
691 oprange[AEXTSHCC] = oprange[r];
692 oprange[ACNTLZW] = oprange[r];
693 oprange[ACNTLZWCC] = oprange[r];
694 break;
695 case AFABS: /* fop [s,]d */
696 oprange[AFABSCC] = oprange[r];
697 oprange[AFNABS] = oprange[r];
698 oprange[AFNABSCC] = oprange[r];
699 oprange[AFNEG] = oprange[r];
700 oprange[AFNEGCC] = oprange[r];
701 oprange[AFRSP] = oprange[r];
702 oprange[AFRSPCC] = oprange[r];
703 oprange[AFCTIW] = oprange[r];
704 oprange[AFCTIWCC] = oprange[r];
705 oprange[AFCTIWZ] = oprange[r];
706 oprange[AFCTIWZCC] = oprange[r];
707 oprange[AFRES] = oprange[r];
708 oprange[AFRESCC] = oprange[r];
709 oprange[AFRSQRTE] = oprange[r];
710 oprange[AFRSQRTECC] = oprange[r];
711 oprange[AFSQRT] = oprange[r];
712 oprange[AFSQRTCC] = oprange[r];
713 oprange[AFSQRTS] = oprange[r];
714 oprange[AFSQRTSCC] = oprange[r];
715 oprange[AFPRE] = oprange[r];
716 oprange[AFPRSQRTE] = oprange[r];
717 oprange[AFPABS] = oprange[r];
718 oprange[AFPNEG] = oprange[r];
719 oprange[AFPRSP] = oprange[r];
720 oprange[AFPNABS] = oprange[r];
721 oprange[AFSABS] = oprange[r];
722 oprange[AFSNEG] = oprange[r];
723 oprange[AFSNABS] = oprange[r];
724 oprange[AFPCTIW] = oprange[r];
725 oprange[AFPCTIWZ] = oprange[r];
726 break;
727 case AFADD:
728 oprange[AFADDS] = oprange[r];
729 oprange[AFADDCC] = oprange[r];
730 oprange[AFADDSCC] = oprange[r];
731 oprange[AFDIV] = oprange[r];
732 oprange[AFDIVS] = oprange[r];
733 oprange[AFDIVCC] = oprange[r];
734 oprange[AFDIVSCC] = oprange[r];
735 oprange[AFSUB] = oprange[r];
736 oprange[AFSUBS] = oprange[r];
737 oprange[AFSUBCC] = oprange[r];
738 oprange[AFSUBSCC] = oprange[r];
739 oprange[AFPADD] = oprange[r];
740 oprange[AFPSUB] = oprange[r];
741 break;
742 case AFMADD:
743 oprange[AFMADDCC] = oprange[r];
744 oprange[AFMADDS] = oprange[r];
745 oprange[AFMADDSCC] = oprange[r];
746 oprange[AFMSUB] = oprange[r];
747 oprange[AFMSUBCC] = oprange[r];
748 oprange[AFMSUBS] = oprange[r];
749 oprange[AFMSUBSCC] = oprange[r];
750 oprange[AFNMADD] = oprange[r];
751 oprange[AFNMADDCC] = oprange[r];
752 oprange[AFNMADDS] = oprange[r];
753 oprange[AFNMADDSCC] = oprange[r];
754 oprange[AFNMSUB] = oprange[r];
755 oprange[AFNMSUBCC] = oprange[r];
756 oprange[AFNMSUBS] = oprange[r];
757 oprange[AFNMSUBSCC] = oprange[r];
758 oprange[AFSEL] = oprange[r];
759 oprange[AFSELCC] = oprange[r];
760 oprange[AFPSEL] = oprange[r];
761 oprange[AFPMADD] = oprange[r];
762 oprange[AFXMADD] = oprange[r];
763 oprange[AFXCPMADD] = oprange[r];
764 oprange[AFXCSMADD] = oprange[r];
765 oprange[AFPNMADD] = oprange[r];
766 oprange[AFXNMADD] = oprange[r];
767 oprange[AFXCPNMADD] = oprange[r];
768 oprange[AFXCSNMADD] = oprange[r];
769 oprange[AFPMSUB] = oprange[r];
770 oprange[AFXMSUB] = oprange[r];
771 oprange[AFXCPMSUB] = oprange[r];
772 oprange[AFXCSMSUB] = oprange[r];
773 oprange[AFPNMSUB] = oprange[r];
774 oprange[AFXNMSUB] = oprange[r];
775 oprange[AFXCPNMSUB] = oprange[r];
776 oprange[AFXCSNMSUB] = oprange[r];
777 oprange[AFXCPNPMA] = oprange[r];
778 oprange[AFXCSNPMA] = oprange[r];
779 oprange[AFXCPNSMA] = oprange[r];
780 oprange[AFXCSNSMA] = oprange[r];
781 oprange[AFXCXNPMA] = oprange[r];
782 oprange[AFXCXNSMA] = oprange[r];
783 oprange[AFXCXMA] = oprange[r];
784 oprange[AFXCXNMS] = oprange[r];
785 break;
786 case AFMUL:
787 oprange[AFMULS] = oprange[r];
788 oprange[AFMULCC] = oprange[r];
789 oprange[AFMULSCC] = oprange[r];
790 oprange[AFPMUL] = oprange[r];
791 oprange[AFXMUL] = oprange[r];
792 oprange[AFXPMUL] = oprange[r];
793 oprange[AFXSMUL] = oprange[r];
794 break;
795 case AFCMPO:
796 oprange[AFCMPU] = oprange[r];
797 break;
798 case AMTFSB0:
799 oprange[AMTFSB0CC] = oprange[r];
800 oprange[AMTFSB1] = oprange[r];
801 oprange[AMTFSB1CC] = oprange[r];
802 break;
803 case ANEG: /* op [Ra,] Rd */
804 oprange[ANEGCC] = oprange[r];
805 oprange[ANEGV] = oprange[r];
806 oprange[ANEGVCC] = oprange[r];
807 break;
808 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
809 oprange[AXOR] = oprange[r];
810 break;
811 case ASLW:
812 oprange[ASLWCC] = oprange[r];
813 oprange[ASRW] = oprange[r];
814 oprange[ASRWCC] = oprange[r];
815 break;
816 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
817 oprange[ASRAWCC] = oprange[r];
818 break;
819 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
820 oprange[ASUB] = oprange[r];
821 oprange[ASUBCC] = oprange[r];
822 oprange[ASUBV] = oprange[r];
823 oprange[ASUBVCC] = oprange[r];
824 oprange[ASUBCCC] = oprange[r];
825 oprange[ASUBCV] = oprange[r];
826 oprange[ASUBCVCC] = oprange[r];
827 oprange[ASUBE] = oprange[r];
828 oprange[ASUBECC] = oprange[r];
829 oprange[ASUBEV] = oprange[r];
830 oprange[ASUBEVCC] = oprange[r];
831 break;
832 case ASYNC:
833 oprange[AISYNC] = oprange[r];
834 break;
835 case ARLWMI:
836 oprange[ARLWMICC] = oprange[r];
837 oprange[ARLWNM] = oprange[r];
838 oprange[ARLWNMCC] = oprange[r];
839 break;
840 case AFMOVD:
841 oprange[AFMOVDCC] = oprange[r];
842 oprange[AFMOVDU] = oprange[r];
843 oprange[AFMOVS] = oprange[r];
844 oprange[AFMOVSU] = oprange[r];
845 break;
846 case AECIWX:
847 oprange[ALWAR] = oprange[r];
848 break;
849 case ASYSCALL: /* just the op; flow of control */
850 oprange[ARFI] = oprange[r];
851 oprange[ARFCI] = oprange[r];
852 break;
853 case AMOVHBR:
854 oprange[AMOVWBR] = oprange[r];
855 break;
856 case AFSMOVS: /* indexed floating loads and stores (fp2) */
857 oprange[AFSMOVSU] = oprange[r];
858 oprange[AFSMOVDU] = oprange[r];
859 oprange[AFXMOVS] = oprange[r];
860 oprange[AFXMOVSU] = oprange[r];
861 oprange[AFXMOVDU] = oprange[r];
862 oprange[AFPMOVS] = oprange[r];
863 oprange[AFPMOVSU] = oprange[r];
864 oprange[AFPMOVDU] = oprange[r];
865 oprange[AFPMOVIW] = oprange[r];
866 break;
867 case AFPMOVD: /* indexed load/store and moves (fp2) */
868 oprange[AFSMOVD] = oprange[r];
869 oprange[AFXMOVD] = oprange[r];
870 break;
871 case AFMOVSPD: /* move between fp reg sets (fp2) */
872 oprange[AFMOVPSD] = oprange[r];
873 break;
874 case AADD:
875 case AANDCC: /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
876 case ACMP:
877 case ACMPU:
878 case AEIEIO:
879 case ALSW:
880 case AMOVB: /* macro: move byte with sign extension */
881 case AMOVBU: /* macro: move byte with sign extension & update */
882 case AMOVW:
883 case AMOVFL:
884 case AMULLW: /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
885 case ASUBC: /* op r1,$s,r3; op r1[,r2],r3 */
886 case ASTSW:
887 case ATLBIE:
888 case ATW:
889 case AWORD:
890 case ANOP:
891 case ATEXT:
892 break;
893 }
894 }
895 }
896
897 enum{
898 ABSD = 0,
899 ABSU = 1,
900 RELD = 2,
901 RELU = 3,
902 };
903
904 int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
905
906 typedef struct Reloc Reloc;
907
908 struct Reloc
909 {
910 int n;
911 int t;
912 uchar *m;
913 ulong *a;
914 };
915
916 Reloc rels;
917
918 static void
grow(Reloc * r)919 grow(Reloc *r)
920 {
921 int t;
922 uchar *m, *nm;
923 ulong *a, *na;
924
925 t = r->t;
926 r->t += 64;
927 m = r->m;
928 a = r->a;
929 r->m = nm = malloc(r->t*sizeof(uchar));
930 r->a = na = malloc(r->t*sizeof(ulong));
931 memmove(nm, m, t*sizeof(uchar));
932 memmove(na, a, t*sizeof(ulong));
933 free(m);
934 free(a);
935 }
936
937 void
dynreloc(Sym * s,long v,int abs,int split,int sext)938 dynreloc(Sym *s, long v, int abs, int split, int sext)
939 {
940 int i, k, n;
941 uchar *m;
942 ulong *a;
943 Reloc *r;
944
945 if(v&3)
946 diag("bad relocation address");
947 v >>= 2;
948 if(s->type == SUNDEF)
949 k = abs ? ABSU : RELU;
950 else
951 k = abs ? ABSD : RELD;
952 if(split)
953 k += 4;
954 if(sext)
955 k += 2;
956 /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
957 k = modemap[k];
958 r = &rels;
959 n = r->n;
960 if(n >= r->t)
961 grow(r);
962 m = r->m;
963 a = r->a;
964 for(i = n; i > 0; i--){
965 if(v < a[i-1]){ /* happens occasionally for data */
966 m[i] = m[i-1];
967 a[i] = a[i-1];
968 }
969 else
970 break;
971 }
972 m[i] = k;
973 a[i] = v;
974 r->n++;
975 }
976
977 static int
sput(char * s)978 sput(char *s)
979 {
980 char *p;
981
982 p = s;
983 while(*s)
984 cput(*s++);
985 cput(0);
986 return s-p+1;
987 }
988
989 void
asmdyn()990 asmdyn()
991 {
992 int i, n, t, c;
993 Sym *s;
994 ulong la, ra, *a;
995 vlong off;
996 uchar *m;
997 Reloc *r;
998
999 cflush();
1000 off = seek(cout, 0, 1);
1001 lput(0);
1002 t = 0;
1003 lput(imports);
1004 t += 4;
1005 for(i = 0; i < NHASH; i++)
1006 for(s = hash[i]; s != S; s = s->link)
1007 if(s->type == SUNDEF){
1008 lput(s->sig);
1009 t += 4;
1010 t += sput(s->name);
1011 }
1012
1013 la = 0;
1014 r = &rels;
1015 n = r->n;
1016 m = r->m;
1017 a = r->a;
1018 lput(n);
1019 t += 4;
1020 for(i = 0; i < n; i++){
1021 ra = *a-la;
1022 if(*a < la)
1023 diag("bad relocation order");
1024 if(ra < 256)
1025 c = 0;
1026 else if(ra < 65536)
1027 c = 1;
1028 else
1029 c = 2;
1030 cput((c<<6)|*m++);
1031 t++;
1032 if(c == 0){
1033 cput(ra);
1034 t++;
1035 }
1036 else if(c == 1){
1037 wput(ra);
1038 t += 2;
1039 }
1040 else{
1041 lput(ra);
1042 t += 4;
1043 }
1044 la = *a++;
1045 }
1046
1047 cflush();
1048 seek(cout, off, 0);
1049 lput(t);
1050
1051 if(debug['v']){
1052 Bprint(&bso, "import table entries = %d\n", imports);
1053 Bprint(&bso, "export table entries = %d\n", exports);
1054 }
1055 }
1056