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