28 p->from.reg = REGZERO;
43 Bprint(&bso, "%5.2f span\n", cputime());
49 for(p = firstp; p != P; p = p->link) {
50 /* bug in early 4000 chips delayslot on page boundary */
51 if((c&(0x1000-1)) == 0xffc)
59 autosize = p->to.offset + 4;
61 p->from.sym->value = c;
62 /* need passes to resolve branches */
68 diag("zero-width instruction\n%P", p);
75 * if any procedure is large enough to
76 * generate a large SBRA branch, then
77 * generate extra passes putting branches
78 * around jmps to fix. this is rare.
82 Bprint(&bso, "%5.2f span1\n", cputime());
85 for(p = firstp; p != P; p = p->link) {
86 /* bug in early 4000 chips delayslot on page boundary */
87 if((c&(0x1000-1)) == 0xffc)
91 if(o->type == 6 && p->cond) {
92 otxt = p->cond->pc - c;
95 if(otxt >= (1L<<17) - 10) {
100 q->to.type = D_BRANCH;
107 q->to.type = D_BRANCH;
108 q->cond = q->link->link;
118 autosize = p->to.offset + 4;
120 p->from.sym->value = c;
123 diag("zero-width instruction\n%P", p);
132 * add strings to text segment
135 for(i=0; i<NHASH; i++)
136 for(s = hash[i]; s != S; s = s->link) {
137 if(s->type != SSTRING)
149 setext = lookup("etext", 0);
152 textsize = c - INITTEXT;
155 INITDAT = rnd(c, INITRND);
157 Bprint(&bso, "tsize = %lux\n", textsize);
162 xdefine(char *p, int t, long v)
167 if(s->type == 0 || s->type == SXREF) {
207 if(a->sym == 0 || a->sym->name == 0) {
208 print("null sym external\n");
213 if(t == 0 || t == SXREF) {
214 diag("undefined external: %s in %s",
215 a->sym->name, TNAME);
216 a->sym->type = SDATA;
218 instoffset = a->sym->value + a->offset - BIG;
219 if(instoffset >= -BIG && instoffset < BIG)
223 instoffset = autosize + a->offset;
224 if(instoffset >= -BIG && instoffset < BIG)
229 instoffset = autosize + a->offset + 4L;
230 if(instoffset >= -BIG && instoffset < BIG)
234 instoffset = a->offset;
237 if(instoffset >= -BIG && instoffset < BIG)
254 if(t == 0 || t == SXREF) {
255 diag("undefined external: %s in %s",
259 instoffset = s->value + a->offset + INITDAT;
260 if(s->type == STEXT || s->type == SLEAF)
261 instoffset = s->value + a->offset;
270 instoffset = a->offset;
273 if(instoffset <= 0x7fff)
275 if(instoffset <= 0xffff)
277 if((instoffset & 0xffff) == 0)
283 if(instoffset >= -0x8000)
285 if((instoffset & 0xffff) == 0)
298 diag("undefined external: %s in %s",
303 instoffset = s->value + a->offset;
308 instoffset = s->value + a->offset;
311 instoffset = s->value + a->offset - BIG;
312 if(instoffset >= -BIG && instoffset < BIG && instoffset != 0L)
314 instoffset = s->value + a->offset + INITDAT;
318 instoffset = autosize + a->offset;
319 if(instoffset >= -BIG && instoffset < BIG)
324 instoffset = autosize + a->offset + 4L;
325 if(instoffset >= -BIG && instoffset < BIG)
349 a1 = aclass(&p->from) + 1;
355 a3 = aclass(&p->to) + 1;
363 o = oprange[r].start;
365 a1 = opcross[repop[r]][a1][a2][a3];
370 o = oprange[r].stop; /* just generate an error */
379 p->optab = (o-optab)+1;
382 diag("illegal combination %A %d %d %d",
387 p->optab = (o-optab)+1;
399 if(b == C_ZCON || b == C_SCON || b == C_UCON ||
400 b == C_ADDCON || b == C_ANDCON)
407 if(b == C_ZCON || b == C_SCON)
414 if(b == C_ZCON || b == C_SCON)
446 if(b == C_ZOREG || b == C_SOREG)
458 ocmp(const void *a1, const void *a2)
487 xcmp[i][n] = cmp(n, i);
488 for(n=0; optab[n].as != AXXX; n++)
490 qsort(optab, n, sizeof(optab[0]), ocmp);
493 oprange[r].start = optab+i;
494 while(optab[i].as == r)
496 oprange[r].stop = optab+i;
502 diag("unknown op in build: %A", r);
505 oprange[AMOVFD] = oprange[r];
506 oprange[AMOVDF] = oprange[r];
507 oprange[AMOVWF] = oprange[r];
508 oprange[AMOVFW] = oprange[r];
509 oprange[AMOVWD] = oprange[r];
510 oprange[AMOVDW] = oprange[r];
511 oprange[ANEGF] = oprange[r];
512 oprange[ANEGD] = oprange[r];
513 oprange[AABSD] = oprange[r];
517 oprange[ASGT] = oprange[r];
519 oprange[ASGTU] = oprange[r];
521 oprange[AADDU] = oprange[r];
523 oprange[AADDVU] = oprange[r];
527 oprange[ADIVF] = oprange[r];
528 oprange[ADIVD] = oprange[r];
529 oprange[AMULF] = oprange[r];
530 oprange[AMULD] = oprange[r];
531 oprange[ASUBF] = oprange[r];
532 oprange[ASUBD] = oprange[r];
533 oprange[AADDD] = oprange[r];
537 oprange[AXOR] = oprange[r];
539 oprange[AOR] = oprange[r];
543 oprange[ABNE] = oprange[r];
546 oprange[ABGEZ] = oprange[r];
547 oprange[ABGEZAL] = oprange[r];
548 oprange[ABLTZ] = oprange[r];
549 oprange[ABLTZAL] = oprange[r];
550 oprange[ABGTZ] = oprange[r];
554 oprange[AMOVH] = oprange[r];
559 oprange[AMOVHU] = oprange[r];
563 oprange[AREM] = oprange[r];
564 oprange[AREMU] = oprange[r];
565 oprange[ADIVU] = oprange[r];
566 oprange[AMULU] = oprange[r];
567 oprange[ADIV] = oprange[r];
568 oprange[ADIVVU] = oprange[r];
569 oprange[ADIVV] = oprange[r];
572 oprange[ASRL] = oprange[r];
573 oprange[ASRA] = oprange[r];
574 oprange[ASLLV] = oprange[r];
575 oprange[ASRAV] = oprange[r];
576 oprange[ASRLV] = oprange[r];
579 oprange[ASUBU] = oprange[r];
580 oprange[ANOR] = oprange[r];
583 oprange[ATLBP] = oprange[r];
584 oprange[ATLBR] = oprange[r];
585 oprange[ATLBWI] = oprange[r];
586 oprange[ATLBWR] = oprange[r];
589 oprange[ACMPGTF] = oprange[r];
590 oprange[ACMPGTD] = oprange[r];
591 oprange[ACMPGEF] = oprange[r];
592 oprange[ACMPGED] = oprange[r];
593 oprange[ACMPEQD] = oprange[r];
596 oprange[ABFPF] = oprange[r];
599 oprange[AMOVWR] = oprange[r];
600 oprange[AMOVVR] = oprange[r];
601 oprange[AMOVVL] = oprange[r];
629 buildrep(int x, int as)
635 if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
636 diag("assumptions fail in buildrep");
641 s = oprange[as].start;
642 e = oprange[as].stop;
643 for(o=e-1; o>=s; o--) {
645 for(a2=0; a2<2; a2++) {
652 for(a1=0; a1<32; a1++) {
655 for(a3=0; a3<32; a3++)
657 (*p)[a1][a2][a3] = n;
661 oprange[as].start = 0;