12 Bprint(&bso, "%5.2f dodata\n", cputime());
14 for(p = datap; p != P; p = p->link) {
16 if(p->as == ADYNT || p->as == AINIT)
21 diag("initialize non-data (%d): %s\n%P",
23 t = p->from.offset + p->width;
25 diag("initialize bounds (%lld): %s\n%P",
26 s->value, s->name, p);
28 /* allocate small guys */
30 for(i=0; i<NHASH; i++)
31 for(s = hash[i]; s != S; s = s->link) {
37 diag("%s: no size", s->name);
45 datsize = rnd(datsize, 8);
51 /* allocate the rest of the data */
52 for(i=0; i<NHASH; i++)
53 for(s = hash[i]; s != S; s = s->link) {
54 if(s->type != SDATA) {
61 datsize = rnd(datsize, 8);
66 datsize = rnd(datsize, 8);
70 * pad data with bss that fits up to next
71 * 8k boundary, then push data to 8k
73 u = rnd(datsize, 8192);
75 for(i=0; i<NHASH; i++)
76 for(s = hash[i]; s != S; s = s->link) {
92 for(i=0; i<NHASH; i++)
93 for(s = hash[i]; s != S; s = s->link) {
98 bsssize = rnd(bsssize, 8);
99 s->value = bsssize + datsize;
102 xdefine("edata", SBSS, datsize);
103 xdefine("end", SBSS, bsssize + datsize);
111 for(i=0; i<20; i++) {
112 if(p == P || p->as != AJMP)
124 Bprint(&bso, "%5.2f follow\n", cputime());
130 firstp = firstp->link;
146 if((q = p->pcond) != P) {
153 /* copy up to 4 instructions to avoid branch */
154 for(i=0,q=p; i<4; i++,q=q->link) {
188 if(q->pcond == P || q->pcond->mark)
190 if(a == ACALL || a == ALOOP)
202 if(q->as != a || q->pcond == P || q->pcond->mark)
205 q->as = relinv(q->as);
220 q->to.type = D_BRANCH;
221 q->to.offset = p->pc;
229 if(a == AJMP || a == ARET || a == AIRETL || a == AIRETQ || a == AIRETW ||
230 a == ARETFL || a == ARETFQ || a == ARETFW)
234 q = brchain(p->link);
235 if(q != P && q->mark)
236 if(a != ALOOP && a != ATEXT) {
242 q = brchain(p->pcond);
259 case AJEQ: return AJNE;
260 case AJNE: return AJEQ;
261 case AJLE: return AJGT;
262 case AJLS: return AJHI;
263 case AJLT: return AJGE;
264 case AJMI: return AJPL;
265 case AJGE: return AJLT;
266 case AJPL: return AJMI;
267 case AJGT: return AJLE;
268 case AJHI: return AJLS;
269 case AJCS: return AJCC;
270 case AJCC: return AJCS;
271 case AJPS: return AJPC;
272 case AJPC: return AJPS;
273 case AJOS: return AJOC;
274 case AJOC: return AJOS;
276 diag("unknown relation: %s in %s", anames[a], TNAME);
287 for(p = datap; p != P; p = p->link) {
289 if(x != D_EXTERN && x != D_STATIC)
292 if(s->type == 0 || s->type == SXREF)
293 diag("undefined %s initializer of %s",
294 s->name, p->from.sym->name);
295 p->to.offset += s->value;
296 p->to.type = D_CONST;
297 if(s->type == SDATA || s->type == SBSS)
298 p->to.offset += INITDAT;
311 Bprint(&bso, "%5.2f mkfwd\n", cputime());
315 Bprint(&bso, "%5.2f patch\n", cputime());
317 s = lookup("exit", 0);
319 for(p = firstp; p != P; p = p->link) {
322 if(p->as == ACALL || p->as == ARET) {
326 Bprint(&bso, "%s calls %s\n", TNAME, s->name);
329 diag("undefined: %s in %s", s->name, TNAME);
332 break; /* or fall through to set offset? */
334 p->to.offset = s->value;
341 p->to.type = D_BRANCH;
344 if(p->to.type != D_BRANCH || p->pcond == UP)
347 for(q = firstp; q != P;) {
349 if(c >= q->forwd->pc) {
358 diag("branch out of range in %s\n%P", TNAME, p);
364 for(p = firstp; p != P; p = p->link) {
367 p->mark = 0; /* initialization for follow */
368 if(p->pcond != P && p->pcond != UP) {
369 p->pcond = brloop(p->pcond);
371 if(p->to.type == D_BRANCH)
372 p->to.offset = p->pcond->pc;
383 long dwn[LOG], cnt[LOG];
386 for(i=0; i<LOG; i++) {
389 cnt[i] = LOG * cnt[i-1];
394 for(p = firstp; p != P; p = p->link) {
418 for(q = p; q != P; q = q->pcond) {
432 long autoffset, deltasp;
433 int a, f, curframe, curbecome, maxbecome, pcsize;
439 for(p = firstp; p != P; p = p->link) {
441 /* find out how much arg space is used in this TEXT */
442 if(p->to.type == (D_INDIR+D_SP))
443 if(p->to.offset > curframe)
444 curframe = p->to.offset;
448 if(curtext && curtext->from.sym) {
449 curtext->from.sym->frame = curframe;
450 curtext->from.sym->become = curbecome;
451 if(curbecome > maxbecome)
452 maxbecome = curbecome;
461 /* special form of RET is BECOME */
462 if(p->from.type == D_CONST)
463 if(p->from.offset > curbecome)
464 curbecome = p->from.offset;
468 if(curtext && curtext->from.sym) {
469 curtext->from.sym->frame = curframe;
470 curtext->from.sym->become = curbecome;
471 if(curbecome > maxbecome)
472 maxbecome = curbecome;
476 print("max become = %d\n", maxbecome);
477 xdefine("ALEFbecome", STEXT, maxbecome);
480 for(p = firstp; p != P; p = p->link) {
486 if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
487 f = maxbecome - curtext->from.sym->frame;
490 /* calling a become or calling a variable */
491 if(p->to.sym == S || p->to.sym->become) {
492 curtext->to.offset += f;
495 print("%D calling %D increase %d\n",
496 &curtext->from, &p->to, f);
506 for(p = firstp; p != P; p = p->link) {
509 autoffset = p->to.offset;
517 p->from.type = D_CONST;
518 p->from.offset = autoffset;
525 p->from.offset += deltasp;
527 p->from.offset += deltasp + pcsize;
530 p->to.offset += deltasp;
532 p->to.offset += deltasp + pcsize;
565 if(autoffset != deltasp)
566 diag("unbalanced PUSH/POP");
567 if(p->from.type == D_CONST)
576 q->from.type = D_CONST;
577 q->from.offset = -autoffset;
590 q->from.type = D_CONST;
591 q->from.offset = -autoffset;
605 while(*s == ' ' || *s == '\t')
607 if(*s == '-' || *s == '+') {
610 while(*s == ' ' || *s == '\t')
613 if(s[0]=='0' && s[1]){
614 if(s[1]=='x' || s[1]=='X'){
617 if(*s >= '0' && *s <= '9')
618 n = n*16 + *s++ - '0';
619 else if(*s >= 'a' && *s <= 'f')
620 n = n*16 + *s++ - 'a' + 10;
621 else if(*s >= 'A' && *s <= 'F')
622 n = n*16 + *s++ - 'A' + 10;
627 while(*s >= '0' && *s <= '7')
628 n = n*8 + *s++ - '0';
630 while(*s >= '0' && *s <= '9')
631 n = n*10 + *s++ - '0';
643 for(i=0; i<NHASH; i++)
644 for(s = hash[i]; s != S; s = s->link)
646 diag("%s: not defined", s->name);
655 for(i = 0; i < NHASH; i++)
656 for(s = hash[i]; s != S; s = s->link)
657 if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
659 diag("value != 0 on SXREF");
661 Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value);
668 ckoff(Sym *s, long v)
670 if(v < 0 || v >= 1<<Roffset)
671 diag("relocation offset %ld for %s out of range", v, s->name);
675 newdata(Sym *s, int o, int w, int t)
691 p->to.type = D_CONST;
698 int i, j, n, off, nb, sv, ne;
699 Sym *s, *et, *str, **esyms;
701 char buf[NSNAME], *t;
704 for(i = 0; i < NHASH; i++)
705 for(s = hash[i]; s != S; s = s->link)
706 if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
708 esyms = malloc(n*sizeof(Sym*));
711 for(i = 0; i < NHASH; i++)
712 for(s = hash[i]; s != S; s = s->link)
713 if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
715 for(i = 0; i < ne-1; i++)
716 for(j = i+1; j < ne; j++)
717 if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
725 et = lookup(EXPTAB, 0);
726 if(et->type != 0 && et->type != SXREF)
727 diag("%s already defined", EXPTAB);
729 str = lookup(".string", 0);
733 for(i = 0; i < ne; i++){
737 /* Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type); */
740 p = newdata(et, off, sizeof(long), D_EXTERN);
742 p->to.offset = s->sig;
745 p = newdata(et, off, sizeof(long), D_EXTERN);
748 p->to.index = D_EXTERN;
758 p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
759 p->to.type = D_SCONST;
760 memmove(p->to.scon, buf, NSNAME);
768 p = newdata(et, off, sizeof(long), D_EXTERN);
771 p->to.index = D_STATIC;
777 p = newdata(str, sv-nb, nb, D_STATIC);
778 p->to.type = D_SCONST;
779 memmove(p->to.scon, buf, nb);
782 for(i = 0; i < 3; i++){
783 newdata(et, off, sizeof(long), D_EXTERN);