13e12c5d1SDavid du Colombier #include "l.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier void 43e12c5d1SDavid du Colombier dodata(void) 53e12c5d1SDavid du Colombier { 63e12c5d1SDavid du Colombier int i; 73e12c5d1SDavid du Colombier Sym *s; 83e12c5d1SDavid du Colombier Prog *p; 93e12c5d1SDavid du Colombier long t, u; 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier if(debug['v']) 123e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f dodata\n", cputime()); 133e12c5d1SDavid du Colombier Bflush(&bso); 143e12c5d1SDavid du Colombier for(p = datap; p != P; p = p->link) { 153e12c5d1SDavid du Colombier s = p->from.sym; 16*219b2ee8SDavid du Colombier if(p->as == ADYNT || p->as == AINIT) 17*219b2ee8SDavid du Colombier s->value = dtype; 183e12c5d1SDavid du Colombier if(s->type == SBSS) 193e12c5d1SDavid du Colombier s->type = SDATA; 203e12c5d1SDavid du Colombier if(s->type != SDATA) 213e12c5d1SDavid du Colombier diag("initialize non-data (%d): %s\n%P\n", 223e12c5d1SDavid du Colombier s->type, s->name, p); 233e12c5d1SDavid du Colombier t = p->from.offset + p->width; 243e12c5d1SDavid du Colombier if(t > s->value) 253e12c5d1SDavid du Colombier diag("initialize bounds (%ld): %s\n%P\n", 263e12c5d1SDavid du Colombier s->value, s->name, p); 273e12c5d1SDavid du Colombier } 283e12c5d1SDavid du Colombier /* allocate small guys */ 293e12c5d1SDavid du Colombier datsize = 0; 303e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 313e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 323e12c5d1SDavid du Colombier if(s->type != SDATA) 333e12c5d1SDavid du Colombier if(s->type != SBSS) 343e12c5d1SDavid du Colombier continue; 353e12c5d1SDavid du Colombier t = s->value; 363e12c5d1SDavid du Colombier if(t == 0) { 373e12c5d1SDavid du Colombier diag("%s: no size\n", s->name); 383e12c5d1SDavid du Colombier t = 1; 393e12c5d1SDavid du Colombier } 403e12c5d1SDavid du Colombier t = rnd(t, 4);; 413e12c5d1SDavid du Colombier s->value = t; 423e12c5d1SDavid du Colombier if(t > MINSIZ) 433e12c5d1SDavid du Colombier continue; 443e12c5d1SDavid du Colombier s->value = datsize; 453e12c5d1SDavid du Colombier datsize += t; 463e12c5d1SDavid du Colombier s->type = SDATA1; 473e12c5d1SDavid du Colombier } 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier /* allocate the rest of the data */ 503e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 513e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 523e12c5d1SDavid du Colombier if(s->type != SDATA) { 533e12c5d1SDavid du Colombier if(s->type == SDATA1) 543e12c5d1SDavid du Colombier s->type = SDATA; 553e12c5d1SDavid du Colombier continue; 563e12c5d1SDavid du Colombier } 573e12c5d1SDavid du Colombier t = s->value; 583e12c5d1SDavid du Colombier s->value = datsize; 593e12c5d1SDavid du Colombier datsize += t; 603e12c5d1SDavid du Colombier } 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier if(debug['j']) { 633e12c5d1SDavid du Colombier /* 643e12c5d1SDavid du Colombier * pad data with bss that fits up to next 653e12c5d1SDavid du Colombier * 8k boundary, then push data to 8k 663e12c5d1SDavid du Colombier */ 673e12c5d1SDavid du Colombier u = rnd(datsize, 8192); 683e12c5d1SDavid du Colombier u -= datsize; 693e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 703e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 713e12c5d1SDavid du Colombier if(s->type != SBSS) 723e12c5d1SDavid du Colombier continue; 733e12c5d1SDavid du Colombier t = s->value; 743e12c5d1SDavid du Colombier if(t > u) 753e12c5d1SDavid du Colombier continue; 763e12c5d1SDavid du Colombier u -= t; 773e12c5d1SDavid du Colombier s->value = datsize; 783e12c5d1SDavid du Colombier s->type = SDATA; 793e12c5d1SDavid du Colombier datsize += t; 803e12c5d1SDavid du Colombier } 813e12c5d1SDavid du Colombier datsize += u; 823e12c5d1SDavid du Colombier } 833e12c5d1SDavid du Colombier 843e12c5d1SDavid du Colombier /* now the bss */ 853e12c5d1SDavid du Colombier bsssize = 0; 863e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 873e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 883e12c5d1SDavid du Colombier if(s->type != SBSS) 893e12c5d1SDavid du Colombier continue; 903e12c5d1SDavid du Colombier t = s->value; 913e12c5d1SDavid du Colombier s->value = bsssize + datsize; 923e12c5d1SDavid du Colombier bsssize += t; 933e12c5d1SDavid du Colombier } 943e12c5d1SDavid du Colombier xdefine("edata", SBSS, datsize); 953e12c5d1SDavid du Colombier xdefine("end", SBSS, bsssize + datsize); 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier 983e12c5d1SDavid du Colombier Prog* 993e12c5d1SDavid du Colombier brchain(Prog *p) 1003e12c5d1SDavid du Colombier { 1013e12c5d1SDavid du Colombier int i; 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier for(i=0; i<20; i++) { 1043e12c5d1SDavid du Colombier if(p == P || p->as != AJMP) 1053e12c5d1SDavid du Colombier return p; 1063e12c5d1SDavid du Colombier p = p->cond; 1073e12c5d1SDavid du Colombier } 1083e12c5d1SDavid du Colombier return P; 1093e12c5d1SDavid du Colombier } 1103e12c5d1SDavid du Colombier 1113e12c5d1SDavid du Colombier void 1123e12c5d1SDavid du Colombier follow(void) 1133e12c5d1SDavid du Colombier { 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier if(debug['v']) 1163e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f follow\n", cputime()); 1173e12c5d1SDavid du Colombier Bflush(&bso); 1183e12c5d1SDavid du Colombier firstp = prg(); 1193e12c5d1SDavid du Colombier lastp = firstp; 1203e12c5d1SDavid du Colombier xfol(textp); 1213e12c5d1SDavid du Colombier lastp->link = P; 1223e12c5d1SDavid du Colombier firstp = firstp->link; 1233e12c5d1SDavid du Colombier } 1243e12c5d1SDavid du Colombier 1253e12c5d1SDavid du Colombier void 1263e12c5d1SDavid du Colombier xfol(Prog *p) 1273e12c5d1SDavid du Colombier { 1283e12c5d1SDavid du Colombier Prog *q; 1293e12c5d1SDavid du Colombier int i; 1303e12c5d1SDavid du Colombier enum as a; 1313e12c5d1SDavid du Colombier 1323e12c5d1SDavid du Colombier loop: 1333e12c5d1SDavid du Colombier if(p == P) 1343e12c5d1SDavid du Colombier return; 1353e12c5d1SDavid du Colombier if(p->as == ATEXT) 1363e12c5d1SDavid du Colombier curtext = p; 1373e12c5d1SDavid du Colombier if(p->as == AJMP) 1383e12c5d1SDavid du Colombier if((q = p->cond) != P) { 1393e12c5d1SDavid du Colombier p->mark = 1; 1403e12c5d1SDavid du Colombier p = q; 1413e12c5d1SDavid du Colombier if(p->mark == 0) 1423e12c5d1SDavid du Colombier goto loop; 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier if(p->mark) { 1453e12c5d1SDavid du Colombier /* copy up to 4 instructions to avoid branch */ 1463e12c5d1SDavid du Colombier for(i=0,q=p; i<4; i++,q=q->link) { 1473e12c5d1SDavid du Colombier if(q == P) 1483e12c5d1SDavid du Colombier break; 1493e12c5d1SDavid du Colombier if(q == lastp) 1503e12c5d1SDavid du Colombier break; 1513e12c5d1SDavid du Colombier a = q->as; 1523e12c5d1SDavid du Colombier if(a == ANOP) { 1533e12c5d1SDavid du Colombier i--; 1543e12c5d1SDavid du Colombier continue; 1553e12c5d1SDavid du Colombier } 156*219b2ee8SDavid du Colombier switch(a) { 157*219b2ee8SDavid du Colombier case AJMP: 158*219b2ee8SDavid du Colombier case ARET: 159*219b2ee8SDavid du Colombier case AIRETL: 160*219b2ee8SDavid du Colombier 161*219b2ee8SDavid du Colombier case APUSHL: 162*219b2ee8SDavid du Colombier case APUSHFL: 163*219b2ee8SDavid du Colombier case APUSHW: 164*219b2ee8SDavid du Colombier case APUSHFW: 165*219b2ee8SDavid du Colombier case APOPL: 166*219b2ee8SDavid du Colombier case APOPFL: 167*219b2ee8SDavid du Colombier case APOPW: 168*219b2ee8SDavid du Colombier case APOPFW: 169*219b2ee8SDavid du Colombier goto brk; 170*219b2ee8SDavid du Colombier } 1713e12c5d1SDavid du Colombier if(q->cond == P || q->cond->mark) 1723e12c5d1SDavid du Colombier continue; 1733e12c5d1SDavid du Colombier if(a == ACALL || a == ALOOP) 1743e12c5d1SDavid du Colombier continue; 1753e12c5d1SDavid du Colombier for(;;) { 1763e12c5d1SDavid du Colombier if(p->as == ANOP) { 1773e12c5d1SDavid du Colombier p = p->link; 1783e12c5d1SDavid du Colombier continue; 1793e12c5d1SDavid du Colombier } 1803e12c5d1SDavid du Colombier q = copyp(p); 1813e12c5d1SDavid du Colombier p = p->link; 1823e12c5d1SDavid du Colombier q->mark = 1; 1833e12c5d1SDavid du Colombier lastp->link = q; 1843e12c5d1SDavid du Colombier lastp = q; 1853e12c5d1SDavid du Colombier if(q->as != a || q->cond == P || q->cond->mark) 1863e12c5d1SDavid du Colombier continue; 187*219b2ee8SDavid du Colombier 1883e12c5d1SDavid du Colombier q->as = relinv(q->as); 1893e12c5d1SDavid du Colombier p = q->cond; 1903e12c5d1SDavid du Colombier q->cond = q->link; 1913e12c5d1SDavid du Colombier q->link = p; 1923e12c5d1SDavid du Colombier xfol(q->link); 1933e12c5d1SDavid du Colombier p = q->link; 1943e12c5d1SDavid du Colombier if(p->mark) 1953e12c5d1SDavid du Colombier return; 1963e12c5d1SDavid du Colombier goto loop; 1973e12c5d1SDavid du Colombier } 1983e12c5d1SDavid du Colombier } /* */ 199*219b2ee8SDavid du Colombier brk:; 2003e12c5d1SDavid du Colombier q = prg(); 2013e12c5d1SDavid du Colombier q->as = AJMP; 2023e12c5d1SDavid du Colombier q->line = p->line; 2033e12c5d1SDavid du Colombier q->to.type = D_BRANCH; 2043e12c5d1SDavid du Colombier q->to.offset = p->pc; 2053e12c5d1SDavid du Colombier q->cond = p; 2063e12c5d1SDavid du Colombier p = q; 2073e12c5d1SDavid du Colombier } 2083e12c5d1SDavid du Colombier p->mark = 1; 2093e12c5d1SDavid du Colombier lastp->link = p; 2103e12c5d1SDavid du Colombier lastp = p; 2113e12c5d1SDavid du Colombier a = p->as; 2123e12c5d1SDavid du Colombier if(a == AJMP || a == ARET || a == AIRETL) 2133e12c5d1SDavid du Colombier return; 2143e12c5d1SDavid du Colombier if(p->cond != P) 2153e12c5d1SDavid du Colombier if(a != ACALL) { 2163e12c5d1SDavid du Colombier q = brchain(p->link); 2173e12c5d1SDavid du Colombier if(q != P && q->mark) 2183e12c5d1SDavid du Colombier if(a != ALOOP) { 2193e12c5d1SDavid du Colombier p->as = relinv(a); 2203e12c5d1SDavid du Colombier p->link = p->cond; 2213e12c5d1SDavid du Colombier p->cond = q; 2223e12c5d1SDavid du Colombier } 2233e12c5d1SDavid du Colombier xfol(p->link); 2243e12c5d1SDavid du Colombier q = brchain(p->cond); 2253e12c5d1SDavid du Colombier if(q->mark) { 2263e12c5d1SDavid du Colombier p->cond = q; 2273e12c5d1SDavid du Colombier return; 2283e12c5d1SDavid du Colombier } 2293e12c5d1SDavid du Colombier p = q; 2303e12c5d1SDavid du Colombier goto loop; 2313e12c5d1SDavid du Colombier } 2323e12c5d1SDavid du Colombier p = p->link; 2333e12c5d1SDavid du Colombier goto loop; 2343e12c5d1SDavid du Colombier } 2353e12c5d1SDavid du Colombier 2363e12c5d1SDavid du Colombier int 2373e12c5d1SDavid du Colombier relinv(int a) 2383e12c5d1SDavid du Colombier { 2393e12c5d1SDavid du Colombier 2403e12c5d1SDavid du Colombier switch(a) { 2413e12c5d1SDavid du Colombier case AJEQ: return AJNE; 2423e12c5d1SDavid du Colombier case AJNE: return AJEQ; 2433e12c5d1SDavid du Colombier case AJLE: return AJGT; 2443e12c5d1SDavid du Colombier case AJLS: return AJHI; 2453e12c5d1SDavid du Colombier case AJLT: return AJGE; 2463e12c5d1SDavid du Colombier case AJMI: return AJPL; 2473e12c5d1SDavid du Colombier case AJGE: return AJLT; 2483e12c5d1SDavid du Colombier case AJPL: return AJMI; 2493e12c5d1SDavid du Colombier case AJGT: return AJLE; 2503e12c5d1SDavid du Colombier case AJHI: return AJLS; 2513e12c5d1SDavid du Colombier case AJCS: return AJCC; 2523e12c5d1SDavid du Colombier case AJCC: return AJCS; 2533e12c5d1SDavid du Colombier case AJPS: return AJPC; 2543e12c5d1SDavid du Colombier case AJPC: return AJPS; 2553e12c5d1SDavid du Colombier case AJOS: return AJOC; 2563e12c5d1SDavid du Colombier case AJOC: return AJOS; 2573e12c5d1SDavid du Colombier } 2583e12c5d1SDavid du Colombier diag("unknown relation: %s in %s\n", anames[a], TNAME); 2593e12c5d1SDavid du Colombier return a; 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier 2623e12c5d1SDavid du Colombier void 2633e12c5d1SDavid du Colombier doinit(void) 2643e12c5d1SDavid du Colombier { 2653e12c5d1SDavid du Colombier Sym *s; 2663e12c5d1SDavid du Colombier Prog *p; 2673e12c5d1SDavid du Colombier int x; 2683e12c5d1SDavid du Colombier 2693e12c5d1SDavid du Colombier for(p = datap; p != P; p = p->link) { 2703e12c5d1SDavid du Colombier x = p->to.type; 2713e12c5d1SDavid du Colombier if(x != D_EXTERN && x != D_STATIC) 2723e12c5d1SDavid du Colombier continue; 2733e12c5d1SDavid du Colombier s = p->to.sym; 2743e12c5d1SDavid du Colombier if(s->type == 0 || s->type == SXREF) 2753e12c5d1SDavid du Colombier diag("undefined %s initializer of %s\n", 2763e12c5d1SDavid du Colombier s->name, p->from.sym->name); 2773e12c5d1SDavid du Colombier p->to.offset += s->value; 2783e12c5d1SDavid du Colombier p->to.type = D_CONST; 2793e12c5d1SDavid du Colombier if(s->type == SDATA || s->type == SBSS) 2803e12c5d1SDavid du Colombier p->to.offset += INITDAT; 2813e12c5d1SDavid du Colombier } 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier 2843e12c5d1SDavid du Colombier void 2853e12c5d1SDavid du Colombier patch(void) 2863e12c5d1SDavid du Colombier { 2873e12c5d1SDavid du Colombier long c; 2883e12c5d1SDavid du Colombier Prog *p, *q; 2893e12c5d1SDavid du Colombier Sym *s; 2903e12c5d1SDavid du Colombier long vexit; 2913e12c5d1SDavid du Colombier 2923e12c5d1SDavid du Colombier if(debug['v']) 2933e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f mkfwd\n", cputime()); 2943e12c5d1SDavid du Colombier Bflush(&bso); 2953e12c5d1SDavid du Colombier mkfwd(); 2963e12c5d1SDavid du Colombier if(debug['v']) 2973e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f patch\n", cputime()); 2983e12c5d1SDavid du Colombier Bflush(&bso); 2993e12c5d1SDavid du Colombier s = lookup("exit", 0); 3003e12c5d1SDavid du Colombier vexit = s->value; 3013e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3023e12c5d1SDavid du Colombier if(p->as == ATEXT) 3033e12c5d1SDavid du Colombier curtext = p; 304*219b2ee8SDavid du Colombier if(p->as == ACALL || p->as == ARET) { 3053e12c5d1SDavid du Colombier s = p->to.sym; 3063e12c5d1SDavid du Colombier if(s) { 3073e12c5d1SDavid du Colombier if(s->type != STEXT) { 3083e12c5d1SDavid du Colombier diag("undefined: %s in %s\n", s->name, TNAME); 3093e12c5d1SDavid du Colombier s->type = STEXT; 3103e12c5d1SDavid du Colombier s->value = vexit; 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier p->to.offset = s->value; 3133e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 3143e12c5d1SDavid du Colombier } 3153e12c5d1SDavid du Colombier } 3163e12c5d1SDavid du Colombier if(p->to.type != D_BRANCH) 3173e12c5d1SDavid du Colombier continue; 3183e12c5d1SDavid du Colombier c = p->to.offset; 3193e12c5d1SDavid du Colombier for(q = firstp; q != P;) { 3203e12c5d1SDavid du Colombier if(q->forwd != P) 3213e12c5d1SDavid du Colombier if(c >= q->forwd->pc) { 3223e12c5d1SDavid du Colombier q = q->forwd; 3233e12c5d1SDavid du Colombier continue; 3243e12c5d1SDavid du Colombier } 3253e12c5d1SDavid du Colombier if(c == q->pc) 3263e12c5d1SDavid du Colombier break; 3273e12c5d1SDavid du Colombier q = q->link; 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier if(q == P) { 3303e12c5d1SDavid du Colombier diag("branch out of range in %s\n%P\n", TNAME, p); 3313e12c5d1SDavid du Colombier p->to.type = D_NONE; 3323e12c5d1SDavid du Colombier } 3333e12c5d1SDavid du Colombier p->cond = q; 3343e12c5d1SDavid du Colombier } 3353e12c5d1SDavid du Colombier 3363e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3373e12c5d1SDavid du Colombier if(p->as == ATEXT) 3383e12c5d1SDavid du Colombier curtext = p; 3393e12c5d1SDavid du Colombier p->mark = 0; /* initialization for follow */ 3403e12c5d1SDavid du Colombier if(p->cond != P) { 3413e12c5d1SDavid du Colombier p->cond = brloop(p->cond); 3423e12c5d1SDavid du Colombier if(p->cond != P) 3433e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 3443e12c5d1SDavid du Colombier p->to.offset = p->cond->pc; 3453e12c5d1SDavid du Colombier } 3463e12c5d1SDavid du Colombier } 3473e12c5d1SDavid du Colombier } 3483e12c5d1SDavid du Colombier 3493e12c5d1SDavid du Colombier #define LOG 5 3503e12c5d1SDavid du Colombier void 3513e12c5d1SDavid du Colombier mkfwd(void) 3523e12c5d1SDavid du Colombier { 3533e12c5d1SDavid du Colombier Prog *p; 3543e12c5d1SDavid du Colombier int i; 3553e12c5d1SDavid du Colombier long dwn[LOG], cnt[LOG]; 3563e12c5d1SDavid du Colombier Prog *lst[LOG]; 3573e12c5d1SDavid du Colombier 3583e12c5d1SDavid du Colombier for(i=0; i<LOG; i++) { 3593e12c5d1SDavid du Colombier if(i == 0) 3603e12c5d1SDavid du Colombier cnt[i] = 1; else 3613e12c5d1SDavid du Colombier cnt[i] = LOG * cnt[i-1]; 3623e12c5d1SDavid du Colombier dwn[i] = 1; 3633e12c5d1SDavid du Colombier lst[i] = P; 3643e12c5d1SDavid du Colombier } 3653e12c5d1SDavid du Colombier i = 0; 3663e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3673e12c5d1SDavid du Colombier if(p->as == ATEXT) 3683e12c5d1SDavid du Colombier curtext = p; 3693e12c5d1SDavid du Colombier i--; 3703e12c5d1SDavid du Colombier if(i < 0) 3713e12c5d1SDavid du Colombier i = LOG-1; 3723e12c5d1SDavid du Colombier p->forwd = P; 3733e12c5d1SDavid du Colombier dwn[i]--; 3743e12c5d1SDavid du Colombier if(dwn[i] <= 0) { 3753e12c5d1SDavid du Colombier dwn[i] = cnt[i]; 3763e12c5d1SDavid du Colombier if(lst[i] != P) 3773e12c5d1SDavid du Colombier lst[i]->forwd = p; 3783e12c5d1SDavid du Colombier lst[i] = p; 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier } 3813e12c5d1SDavid du Colombier } 3823e12c5d1SDavid du Colombier 3833e12c5d1SDavid du Colombier Prog* 3843e12c5d1SDavid du Colombier brloop(Prog *p) 3853e12c5d1SDavid du Colombier { 3863e12c5d1SDavid du Colombier int c; 3873e12c5d1SDavid du Colombier Prog *q; 3883e12c5d1SDavid du Colombier 3893e12c5d1SDavid du Colombier c = 0; 3903e12c5d1SDavid du Colombier for(q = p; q != P; q = q->cond) { 3913e12c5d1SDavid du Colombier if(q->as != AJMP) 3923e12c5d1SDavid du Colombier break; 3933e12c5d1SDavid du Colombier c++; 3943e12c5d1SDavid du Colombier if(c >= 100) 3953e12c5d1SDavid du Colombier return P; 3963e12c5d1SDavid du Colombier } 3973e12c5d1SDavid du Colombier return q; 3983e12c5d1SDavid du Colombier } 3993e12c5d1SDavid du Colombier 4003e12c5d1SDavid du Colombier void 4013e12c5d1SDavid du Colombier dostkoff(void) 4023e12c5d1SDavid du Colombier { 4033e12c5d1SDavid du Colombier Prog *p, *q; 404*219b2ee8SDavid du Colombier long autoffset, deltasp; 405*219b2ee8SDavid du Colombier int a, f, curframe, curbecome, maxbecome; 4063e12c5d1SDavid du Colombier 407*219b2ee8SDavid du Colombier curframe = 0; 408*219b2ee8SDavid du Colombier curbecome = 0; 409*219b2ee8SDavid du Colombier maxbecome = 0; 410*219b2ee8SDavid du Colombier curtext = 0; 411*219b2ee8SDavid du Colombier for(p = firstp; p != P; p = p->link) { 412*219b2ee8SDavid du Colombier 413*219b2ee8SDavid du Colombier /* find out how much arg space is used in this TEXT */ 414*219b2ee8SDavid du Colombier if(p->to.type == (D_INDIR+D_SP)) 415*219b2ee8SDavid du Colombier if(p->to.offset > curframe) 416*219b2ee8SDavid du Colombier curframe = p->to.offset; 417*219b2ee8SDavid du Colombier 418*219b2ee8SDavid du Colombier switch(p->as) { 419*219b2ee8SDavid du Colombier case ATEXT: 420*219b2ee8SDavid du Colombier if(curtext && curtext->from.sym) { 421*219b2ee8SDavid du Colombier curtext->from.sym->frame = curframe; 422*219b2ee8SDavid du Colombier curtext->from.sym->become = curbecome; 423*219b2ee8SDavid du Colombier if(curbecome > maxbecome) 424*219b2ee8SDavid du Colombier maxbecome = curbecome; 425*219b2ee8SDavid du Colombier } 426*219b2ee8SDavid du Colombier curframe = 0; 427*219b2ee8SDavid du Colombier curbecome = 0; 428*219b2ee8SDavid du Colombier 429*219b2ee8SDavid du Colombier curtext = p; 430*219b2ee8SDavid du Colombier break; 431*219b2ee8SDavid du Colombier 432*219b2ee8SDavid du Colombier case ARET: 433*219b2ee8SDavid du Colombier /* special form of RET is BECOME */ 434*219b2ee8SDavid du Colombier if(p->from.type == D_CONST) 435*219b2ee8SDavid du Colombier if(p->from.offset > curbecome) 436*219b2ee8SDavid du Colombier curbecome = p->from.offset; 437*219b2ee8SDavid du Colombier break; 438*219b2ee8SDavid du Colombier } 439*219b2ee8SDavid du Colombier } 440*219b2ee8SDavid du Colombier if(curtext && curtext->from.sym) { 441*219b2ee8SDavid du Colombier curtext->from.sym->frame = curframe; 442*219b2ee8SDavid du Colombier curtext->from.sym->become = curbecome; 443*219b2ee8SDavid du Colombier if(curbecome > maxbecome) 444*219b2ee8SDavid du Colombier maxbecome = curbecome; 445*219b2ee8SDavid du Colombier } 446*219b2ee8SDavid du Colombier 447*219b2ee8SDavid du Colombier if(debug['b']) 448*219b2ee8SDavid du Colombier print("max become = %d\n", maxbecome); 449*219b2ee8SDavid du Colombier xdefine("ALEFbecome", STEXT, maxbecome); 450*219b2ee8SDavid du Colombier 451*219b2ee8SDavid du Colombier curtext = 0; 452*219b2ee8SDavid du Colombier for(p = firstp; p != P; p = p->link) { 453*219b2ee8SDavid du Colombier switch(p->as) { 454*219b2ee8SDavid du Colombier case ATEXT: 455*219b2ee8SDavid du Colombier curtext = p; 456*219b2ee8SDavid du Colombier break; 457*219b2ee8SDavid du Colombier case ACALL: 458*219b2ee8SDavid du Colombier if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) { 459*219b2ee8SDavid du Colombier f = maxbecome - curtext->from.sym->frame; 460*219b2ee8SDavid du Colombier if(f <= 0) 461*219b2ee8SDavid du Colombier break; 462*219b2ee8SDavid du Colombier /* calling a become or calling a variable */ 463*219b2ee8SDavid du Colombier if(p->to.sym == S || p->to.sym->become) { 464*219b2ee8SDavid du Colombier curtext->to.offset += f; 465*219b2ee8SDavid du Colombier if(debug['b']) { 466*219b2ee8SDavid du Colombier curp = p; 467*219b2ee8SDavid du Colombier print("%D calling %D increase %d\n", 468*219b2ee8SDavid du Colombier &curtext->from, &p->to, f); 469*219b2ee8SDavid du Colombier } 470*219b2ee8SDavid du Colombier } 471*219b2ee8SDavid du Colombier } 472*219b2ee8SDavid du Colombier break; 473*219b2ee8SDavid du Colombier } 474*219b2ee8SDavid du Colombier } 475*219b2ee8SDavid du Colombier 476*219b2ee8SDavid du Colombier autoffset = 0; 477*219b2ee8SDavid du Colombier deltasp = 0; 4783e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4793e12c5d1SDavid du Colombier if(p->as == ATEXT) { 4803e12c5d1SDavid du Colombier curtext = p; 481*219b2ee8SDavid du Colombier autoffset = p->to.offset; 482*219b2ee8SDavid du Colombier if(autoffset < 0) 483*219b2ee8SDavid du Colombier autoffset = 0; 484*219b2ee8SDavid du Colombier if(autoffset) { 4853e12c5d1SDavid du Colombier p = appendp(p); 4863e12c5d1SDavid du Colombier p->as = AADJSP; 4873e12c5d1SDavid du Colombier p->from.type = D_CONST; 488*219b2ee8SDavid du Colombier p->from.offset = autoffset; 4893e12c5d1SDavid du Colombier } 490*219b2ee8SDavid du Colombier deltasp = autoffset; 4913e12c5d1SDavid du Colombier } 4923e12c5d1SDavid du Colombier a = p->from.type; 4933e12c5d1SDavid du Colombier if(a == D_AUTO) 494*219b2ee8SDavid du Colombier p->from.offset += deltasp; 4953e12c5d1SDavid du Colombier if(a == D_PARAM) 496*219b2ee8SDavid du Colombier p->from.offset += deltasp + 4; 4973e12c5d1SDavid du Colombier a = p->to.type; 4983e12c5d1SDavid du Colombier if(a == D_AUTO) 499*219b2ee8SDavid du Colombier p->to.offset += deltasp; 5003e12c5d1SDavid du Colombier if(a == D_PARAM) 501*219b2ee8SDavid du Colombier p->to.offset += deltasp + 4; 502*219b2ee8SDavid du Colombier 503*219b2ee8SDavid du Colombier switch(p->as) { 504*219b2ee8SDavid du Colombier default: 5053e12c5d1SDavid du Colombier continue; 506*219b2ee8SDavid du Colombier case APUSHL: 507*219b2ee8SDavid du Colombier case APUSHFL: 508*219b2ee8SDavid du Colombier deltasp += 4; 5093e12c5d1SDavid du Colombier continue; 510*219b2ee8SDavid du Colombier case APUSHW: 511*219b2ee8SDavid du Colombier case APUSHFW: 512*219b2ee8SDavid du Colombier deltasp += 2; 513*219b2ee8SDavid du Colombier continue; 514*219b2ee8SDavid du Colombier case APOPL: 515*219b2ee8SDavid du Colombier case APOPFL: 516*219b2ee8SDavid du Colombier deltasp -= 4; 517*219b2ee8SDavid du Colombier continue; 518*219b2ee8SDavid du Colombier case APOPW: 519*219b2ee8SDavid du Colombier case APOPFW: 520*219b2ee8SDavid du Colombier deltasp -= 2; 521*219b2ee8SDavid du Colombier continue; 522*219b2ee8SDavid du Colombier case ARET: 523*219b2ee8SDavid du Colombier break; 524*219b2ee8SDavid du Colombier } 525*219b2ee8SDavid du Colombier 526*219b2ee8SDavid du Colombier if(autoffset != deltasp) 527*219b2ee8SDavid du Colombier diag("unbalanced PUSH/POP"); 528*219b2ee8SDavid du Colombier if(p->from.type == D_CONST) 529*219b2ee8SDavid du Colombier goto become; 530*219b2ee8SDavid du Colombier 531*219b2ee8SDavid du Colombier if(autoffset) { 5323e12c5d1SDavid du Colombier q = p; 5333e12c5d1SDavid du Colombier p = appendp(p); 5343e12c5d1SDavid du Colombier p->as = ARET; 5353e12c5d1SDavid du Colombier 5363e12c5d1SDavid du Colombier q->as = AADJSP; 5373e12c5d1SDavid du Colombier q->from.type = D_CONST; 538*219b2ee8SDavid du Colombier q->from.offset = -autoffset; 539*219b2ee8SDavid du Colombier } 540*219b2ee8SDavid du Colombier continue; 541*219b2ee8SDavid du Colombier 542*219b2ee8SDavid du Colombier become: 543*219b2ee8SDavid du Colombier q = p; 544*219b2ee8SDavid du Colombier p = appendp(p); 545*219b2ee8SDavid du Colombier p->as = AJMP; 546*219b2ee8SDavid du Colombier p->to = q->to; 547*219b2ee8SDavid du Colombier p->cond = q->cond; 548*219b2ee8SDavid du Colombier 549*219b2ee8SDavid du Colombier q->as = AADJSP; 550*219b2ee8SDavid du Colombier q->from = zprg.from; 551*219b2ee8SDavid du Colombier q->from.type = D_CONST; 552*219b2ee8SDavid du Colombier q->from.offset = -autoffset; 553*219b2ee8SDavid du Colombier q->to = zprg.to; 554*219b2ee8SDavid du Colombier continue; 5553e12c5d1SDavid du Colombier } 5563e12c5d1SDavid du Colombier } 5573e12c5d1SDavid du Colombier 5583e12c5d1SDavid du Colombier long 5593e12c5d1SDavid du Colombier atolwhex(char *s) 5603e12c5d1SDavid du Colombier { 5613e12c5d1SDavid du Colombier long n; 5623e12c5d1SDavid du Colombier int f; 5633e12c5d1SDavid du Colombier 5643e12c5d1SDavid du Colombier n = 0; 5653e12c5d1SDavid du Colombier f = 0; 5663e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t') 5673e12c5d1SDavid du Colombier s++; 5683e12c5d1SDavid du Colombier if(*s == '-' || *s == '+') { 5693e12c5d1SDavid du Colombier if(*s++ == '-') 5703e12c5d1SDavid du Colombier f = 1; 5713e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t') 5723e12c5d1SDavid du Colombier s++; 5733e12c5d1SDavid du Colombier } 5743e12c5d1SDavid du Colombier if(s[0]=='0' && s[1]){ 5753e12c5d1SDavid du Colombier if(s[1]=='x' || s[1]=='X'){ 5763e12c5d1SDavid du Colombier s += 2; 5773e12c5d1SDavid du Colombier for(;;){ 5783e12c5d1SDavid du Colombier if(*s >= '0' && *s <= '9') 5793e12c5d1SDavid du Colombier n = n*16 + *s++ - '0'; 5803e12c5d1SDavid du Colombier else if(*s >= 'a' && *s <= 'f') 5813e12c5d1SDavid du Colombier n = n*16 + *s++ - 'a' + 10; 5823e12c5d1SDavid du Colombier else if(*s >= 'A' && *s <= 'F') 5833e12c5d1SDavid du Colombier n = n*16 + *s++ - 'A' + 10; 5843e12c5d1SDavid du Colombier else 5853e12c5d1SDavid du Colombier break; 5863e12c5d1SDavid du Colombier } 5873e12c5d1SDavid du Colombier } else 5883e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '7') 5893e12c5d1SDavid du Colombier n = n*8 + *s++ - '0'; 5903e12c5d1SDavid du Colombier } else 5913e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '9') 5923e12c5d1SDavid du Colombier n = n*10 + *s++ - '0'; 5933e12c5d1SDavid du Colombier if(f) 5943e12c5d1SDavid du Colombier n = -n; 5953e12c5d1SDavid du Colombier return n; 5963e12c5d1SDavid du Colombier } 5973e12c5d1SDavid du Colombier 5983e12c5d1SDavid du Colombier void 5993e12c5d1SDavid du Colombier undef(void) 6003e12c5d1SDavid du Colombier { 6013e12c5d1SDavid du Colombier int i; 6023e12c5d1SDavid du Colombier Sym *s; 6033e12c5d1SDavid du Colombier 6043e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 6053e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) 6063e12c5d1SDavid du Colombier if(s->type == SXREF) 6073e12c5d1SDavid du Colombier diag("%s: not defined\n", s->name); 6083e12c5d1SDavid du Colombier } 609