9 void flushpool(Prog*, int);
21 Bprint(&bso, "%5.2f span\n", cputime());
27 for(p = firstp; p != P; p = p->link) {
34 autosize = p->to.offset + 4;
36 p->from.sym->value = c;
37 /* need passes to resolve branches */
43 diag("zero-width instruction\n%P", p);
46 switch(o->flag & (LFROM|LTO|LPOOL)) {
54 if ((p->scond&C_SCOND) == 14)
58 if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14)
66 * if any procedure is large enough to
67 * generate a large SBRA branch, then
68 * generate extra passes putting branches
69 * around jmps to fix. this is rare.
73 Bprint(&bso, "%5.2f span1\n", cputime());
76 for(p = firstp; p != P; p = p->link) {
80 if(o->type == 6 && p->cond) {
81 otxt = p->cond->pc - c;
84 if(otxt >= (1L<<17) - 10) {
89 q->to.type = D_BRANCH;
96 q->to.type = D_BRANCH;
97 q->cond = q->link->link;
106 autosize = p->to.offset + 4;
108 p->from.sym->value = c;
111 diag("zero-width instruction\n%P", p);
120 * add strings to text segment
123 for(i=0; i<NHASH; i++)
124 for(s = hash[i]; s != S; s = s->link) {
125 if(s->type != SSTRING)
137 setext = lookup("etext", 0);
140 textsize = c - INITTEXT;
143 INITDAT = rnd(c, INITRND);
145 Bprint(&bso, "tsize = %lux\n", textsize);
150 * when the first reference to the literal pool threatens
151 * to go out of range of a 12-bit PC-relative offset,
152 * drop the pool now, and branch round it.
153 * this happens only in extended basic blocks that exceed 4k.
158 if(pool.size >= 0xffc || immaddr((p->pc+4)+4+pool.size - pool.start+8) == 0)
160 else if(p->link == P)
165 flushpool(Prog *p, int skip)
171 if(debug['v'] && skip == 1)
172 print("note: flush literal pool at %lux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start);
175 q->to.type = D_BRANCH;
180 else if(p->pc+pool.size-pool.start < 2048)
182 elitrl->link = p->link;
184 blitrl = 0; /* BUG: should refer back to values until out-of-range */
192 addpool(Prog *p, Adr *a)
217 t.to.offset = instoffset;
221 for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */
222 if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
243 xdefine(char *p, int t, long v)
248 if(s->type == 0 || s->type == SXREF) {
268 for(i=0; i<16; i++) {
270 return (i<<8) | v | (1<<25);
271 v = (v<<2) | (v>>30);
279 if(v >= 0 && v <= 0xfff)
281 (1<<24) | /* pre indexing */
282 (1<<23); /* pre indexing, up */
283 if(v >= -0xfff && v < 0)
284 return (-v & 0xfff) |
285 (1<<24); /* pre indexing */
292 return (v & 0xC03) == 0; /* offset will fit in floating-point load/store */
298 if(v >= 0 && v <= 0xff)
300 (1<<24)| /* pre indexing */
301 (1<<23); /* pre indexing, up */
302 if(v >= -0xff && v < 0)
304 (1<<24); /* pre indexing */
337 if(a->sym == 0 || a->sym->name == 0) {
338 print("null sym external\n");
344 if(t == 0 || t == SXREF) {
345 diag("undefined external: %s in %s",
352 instoffset = s->value + a->offset + INITDAT;
359 instoffset = s->value + a->offset;
364 instoffset = s->value + a->offset - BIG;
365 t = immaddr(instoffset);
367 if(immhalf(instoffset))
368 return immfloat(t) ? C_HFEXT : C_HEXT;
375 instoffset = autosize + a->offset;
376 t = immaddr(instoffset);
378 if(immhalf(instoffset))
379 return immfloat(t) ? C_HFAUTO : C_HAUTO;
387 instoffset = autosize + a->offset + 4L;
388 t = immaddr(instoffset);
390 if(immhalf(instoffset))
391 return immfloat(t) ? C_HFAUTO : C_HAUTO;
398 instoffset = a->offset;
399 t = immaddr(instoffset);
401 if(immhalf(instoffset)) /* n.b. that it will also satisfy immrot */
402 return immfloat(t) ? C_HFOREG : C_HOREG;
404 return C_FOREG; /* n.b. that it will also satisfy immrot */
405 t = immrot(instoffset);
408 if(immhalf(instoffset))
412 t = immrot(instoffset);
428 if(t == 0 || t == SXREF) {
429 diag("undefined external: %s in %s",
433 instoffset = s->value + a->offset + INITDAT;
434 if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF)
435 instoffset = s->value + a->offset;
447 instoffset = a->offset;
451 t = immrot(instoffset);
454 t = immrot(~instoffset);
468 diag("undefined external: %s in %s",
477 instoffset = s->value + a->offset;
481 instoffset = s->value + a->offset - BIG;
482 t = immrot(instoffset);
483 if(t && instoffset != 0)
486 instoffset = s->value + a->offset + INITDAT;
490 instoffset = autosize + a->offset;
494 instoffset = autosize + a->offset + 4L;
496 t = immrot(instoffset);
521 a1 = aclass(&p->from) + 1;
527 a3 = aclass(&p->to) + 1;
535 o = oprange[r].start;
537 a1 = opcross[repop[r]][a1][a2][a3];
542 o = oprange[r].stop; /* just generate an error */
545 print("oplook %A %d %d %d\n",
546 (int)p->as, a1, a2, a3);
547 print(" %d %d\n", p->from.type, p->to.type);
556 p->optab = (o-optab)+1;
559 diag("illegal combination %A %d %d %d",
575 if(b == C_RCON || b == C_NCON)
588 return b == C_HEXT || b == C_FEXT;
593 return cmp(C_HFEXT, b);
595 return cmp(C_SEXT, b);
598 return b == C_HAUTO || b == C_FAUTO;
601 return b == C_HFAUTO;
603 return cmp(C_HFAUTO, b);
605 return cmp(C_SAUTO, b);
608 return b == C_HOREG || b == C_FOREG;
611 return b == C_HFOREG;
613 return cmp(C_SOREG, b) || cmp(C_ROREG, b);
616 return b == C_SROREG || cmp(C_HFOREG, b);
618 return cmp(C_SROREG, b);
629 ocmp(const void *a1, const void *a2)
639 n = (p2->flag&V4) - (p1->flag&V4); /* architecture version */
642 n = (p2->flag&VFP) - (p1->flag&VFP); /* floating point arch */
664 for(i=0; i<C_GOK; i++)
665 for(n=0; n<C_GOK; n++)
666 xcmp[i][n] = cmp(n, i);
667 for(n=0; optab[n].as != AXXX; n++) {
668 if((optab[n].flag & VFP) && !vfp)
670 if((optab[n].flag & V4) && !armv4) {
675 qsort(optab, n, sizeof(optab[0]), ocmp);
678 oprange[r].start = optab+i;
679 while(optab[i].as == r)
681 oprange[r].stop = optab+i;
687 diag("unknown op in build: %A", r);
692 oprange[AAND] = oprange[r];
693 oprange[AEOR] = oprange[r];
694 oprange[ASUB] = oprange[r];
695 oprange[ARSB] = oprange[r];
696 oprange[AADC] = oprange[r];
697 oprange[ASBC] = oprange[r];
698 oprange[ARSC] = oprange[r];
699 oprange[AORR] = oprange[r];
700 oprange[ABIC] = oprange[r];
703 oprange[ATST] = oprange[r];
704 oprange[ATEQ] = oprange[r];
705 oprange[ACMN] = oprange[r];
710 oprange[ABNE] = oprange[r];
711 oprange[ABCS] = oprange[r];
712 oprange[ABHS] = oprange[r];
713 oprange[ABCC] = oprange[r];
714 oprange[ABLO] = oprange[r];
715 oprange[ABMI] = oprange[r];
716 oprange[ABPL] = oprange[r];
717 oprange[ABVS] = oprange[r];
718 oprange[ABVC] = oprange[r];
719 oprange[ABHI] = oprange[r];
720 oprange[ABLS] = oprange[r];
721 oprange[ABGE] = oprange[r];
722 oprange[ABLT] = oprange[r];
723 oprange[ABGT] = oprange[r];
724 oprange[ABLE] = oprange[r];
727 oprange[ASRL] = oprange[r];
728 oprange[ASRA] = oprange[r];
729 oprange[AROR] = oprange[r];
732 oprange[AMULU] = oprange[r];
735 oprange[AMOD] = oprange[r];
736 oprange[AMODU] = oprange[r];
737 oprange[ADIVU] = oprange[r];
746 oprange[ASWPBU] = oprange[r];
747 oprange[ALDREX] = oprange[r];
748 oprange[ASTREX] = oprange[r];
766 oprange[AADDD] = oprange[r];
767 oprange[ASUBF] = oprange[r];
768 oprange[ASUBD] = oprange[r];
769 oprange[AMULF] = oprange[r];
770 oprange[AMULD] = oprange[r];
771 oprange[ADIVF] = oprange[r];
772 oprange[ADIVD] = oprange[r];
773 oprange[AMOVFD] = oprange[r];
774 oprange[AMOVDF] = oprange[r];
778 oprange[ACMPD] = oprange[r];
782 oprange[AMOVD] = oprange[r];
786 oprange[AMOVWF] = oprange[r];
787 oprange[AMOVWD] = oprange[r];
788 oprange[AMOVDW] = oprange[r];
792 oprange[AMULA] = oprange[r];
793 oprange[AMULAL] = oprange[r];
794 oprange[AMULLU] = oprange[r];
795 oprange[AMULALU] = oprange[r];
803 buildrep(int x, int as)
809 if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
810 diag("assumptions fail in buildrep");
815 s = oprange[as].start;
816 e = oprange[as].stop;
817 for(o=e-1; o>=s; o--) {
819 for(a2=0; a2<2; a2++) {
826 for(a1=0; a1<32; a1++) {
829 for(a3=0; a3<32; a3++)
831 (*p)[a1][a2][a3] = n;
835 oprange[as].start = 0;
846 int modemap[4] = { 0, 1, -1, 2, };
848 typedef struct Reloc Reloc;
871 r->m = nm = malloc(r->t*sizeof(uchar));
872 r->a = na = malloc(r->t*sizeof(ulong));
873 memmove(nm, m, t*sizeof(uchar));
874 memmove(na, a, t*sizeof(ulong));
880 dynreloc(Sym *s, long v, int abs)
888 diag("bad relocation address");
890 if(s != S && s->type == SUNDEF)
891 k = abs ? ABSU : RELU;
893 k = abs ? ABSD : RELD;
894 /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
902 for(i = n; i > 0; i--){
903 if(v < a[i-1]){ /* happens occasionally for data */
938 off = seek(cout, 0, 1);
943 for(i = 0; i < NHASH; i++)
944 for(s = hash[i]; s != S; s = s->link)
945 if(s->type == SUNDEF){
958 for(i = 0; i < n; i++){
961 diag("bad relocation order");
990 Bprint(&bso, "import table entries = %d\n", imports);
991 Bprint(&bso, "export table entries = %d\n", exports);