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, t; 73e12c5d1SDavid du Colombier Sym *s; 83e12c5d1SDavid du Colombier Prog *p, *p1; 93e12c5d1SDavid du Colombier long orig, orig1, v; 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 v = p->from.offset + p->reg; 243e12c5d1SDavid du Colombier if(v > 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 293e12c5d1SDavid du Colombier /* 303e12c5d1SDavid du Colombier * pass 1 313e12c5d1SDavid du Colombier * assign 'small' variables to data segment 323e12c5d1SDavid du Colombier * (rational is that data segment is more easily 333e12c5d1SDavid du Colombier * addressed through offset on R30) 343e12c5d1SDavid du Colombier */ 353e12c5d1SDavid du Colombier orig = 0; 363e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 373e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 383e12c5d1SDavid du Colombier t = s->type; 393e12c5d1SDavid du Colombier if(t != SDATA && t != SBSS) 403e12c5d1SDavid du Colombier continue; 413e12c5d1SDavid du Colombier v = s->value; 423e12c5d1SDavid du Colombier if(v == 0) { 433e12c5d1SDavid du Colombier diag("%s: no size\n", s->name); 443e12c5d1SDavid du Colombier v = 1; 453e12c5d1SDavid du Colombier } 463e12c5d1SDavid du Colombier while(v & 3) 473e12c5d1SDavid du Colombier v++; 483e12c5d1SDavid du Colombier s->value = v; 493e12c5d1SDavid du Colombier if(v > MINSIZ) 503e12c5d1SDavid du Colombier continue; 513e12c5d1SDavid du Colombier s->value = orig; 523e12c5d1SDavid du Colombier orig += v; 533e12c5d1SDavid du Colombier s->type = SDATA1; 543e12c5d1SDavid du Colombier } 553e12c5d1SDavid du Colombier orig1 = orig; 563e12c5d1SDavid du Colombier 573e12c5d1SDavid du Colombier /* 583e12c5d1SDavid du Colombier * pass 2 593e12c5d1SDavid du Colombier * assign 'data' variables to data segment 603e12c5d1SDavid du Colombier */ 613e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 623e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 633e12c5d1SDavid du Colombier t = s->type; 643e12c5d1SDavid du Colombier if(t != SDATA) { 653e12c5d1SDavid du Colombier if(t == SDATA1) 663e12c5d1SDavid du Colombier s->type = SDATA; 673e12c5d1SDavid du Colombier continue; 683e12c5d1SDavid du Colombier } 693e12c5d1SDavid du Colombier v = s->value; 703e12c5d1SDavid du Colombier s->value = orig; 713e12c5d1SDavid du Colombier orig += v; 723e12c5d1SDavid du Colombier s->type = SDATA1; 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier 753e12c5d1SDavid du Colombier while(orig & 7) 763e12c5d1SDavid du Colombier orig++; 773e12c5d1SDavid du Colombier datsize = orig; 783e12c5d1SDavid du Colombier 793e12c5d1SDavid du Colombier /* 803e12c5d1SDavid du Colombier * pass 3 813e12c5d1SDavid du Colombier * everything else to bss segment 823e12c5d1SDavid du Colombier */ 833e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 843e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 853e12c5d1SDavid du Colombier if(s->type != SBSS) 863e12c5d1SDavid du Colombier continue; 873e12c5d1SDavid du Colombier v = s->value; 883e12c5d1SDavid du Colombier s->value = orig; 893e12c5d1SDavid du Colombier orig += v; 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier while(orig & 7) 923e12c5d1SDavid du Colombier orig++; 933e12c5d1SDavid du Colombier bsssize = orig-datsize; 943e12c5d1SDavid du Colombier 953e12c5d1SDavid du Colombier /* 963e12c5d1SDavid du Colombier * pass 4 973e12c5d1SDavid du Colombier * add literals to all large values. 983e12c5d1SDavid du Colombier * at this time: 993e12c5d1SDavid du Colombier * small data is allocated DATA 1003e12c5d1SDavid du Colombier * large data is allocated DATA1 1013e12c5d1SDavid du Colombier * large bss is allocated BSS 1023e12c5d1SDavid du Colombier * the new literals are loaded between 1033e12c5d1SDavid du Colombier * small data and large data. 1043e12c5d1SDavid du Colombier */ 1053e12c5d1SDavid du Colombier orig = 0; 1063e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 1073e12c5d1SDavid du Colombier if(p->as != AMOVW) 1083e12c5d1SDavid du Colombier continue; 1093e12c5d1SDavid du Colombier if(p->from.type != D_CONST) 1103e12c5d1SDavid du Colombier continue; 1113e12c5d1SDavid du Colombier if(s = p->from.sym) { 1123e12c5d1SDavid du Colombier t = s->type; 1133e12c5d1SDavid du Colombier if(t != SDATA && t != SDATA1 && t != SBSS) 1143e12c5d1SDavid du Colombier continue; 1153e12c5d1SDavid du Colombier t = p->from.name; 1163e12c5d1SDavid du Colombier if(t != D_EXTERN && t != D_STATIC) 1173e12c5d1SDavid du Colombier continue; 1183e12c5d1SDavid du Colombier v = s->value + p->from.offset; 1193e12c5d1SDavid du Colombier if(v >= 0 && v <= 0xffff) 1203e12c5d1SDavid du Colombier continue; 1213e12c5d1SDavid du Colombier if(!strcmp(s->name, "setR30")) 1223e12c5d1SDavid du Colombier continue; 1233e12c5d1SDavid du Colombier /* size should be 19 max */ 124bd389b36SDavid du Colombier if(strlen(s->name) >= 10) /* has loader address */ 125bd389b36SDavid du Colombier sprint(literal, "$%lux.%lux", (long)s, p->from.offset); 126bd389b36SDavid du Colombier else 127bd389b36SDavid du Colombier sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset); 1283e12c5d1SDavid du Colombier } else { 1293e12c5d1SDavid du Colombier if(p->from.name != D_NONE) 1303e12c5d1SDavid du Colombier continue; 1313e12c5d1SDavid du Colombier if(p->from.reg != NREG) 1323e12c5d1SDavid du Colombier continue; 1333e12c5d1SDavid du Colombier v = p->from.offset; 1343e12c5d1SDavid du Colombier if(v >= -0x7fff && v <= 0xffff) 1353e12c5d1SDavid du Colombier continue; 1363e12c5d1SDavid du Colombier if(!(v & 0xffff)) 1373e12c5d1SDavid du Colombier continue; 1383e12c5d1SDavid du Colombier /* size should be 9 max */ 1393e12c5d1SDavid du Colombier sprint(literal, "$%lux", v); 1403e12c5d1SDavid du Colombier } 1413e12c5d1SDavid du Colombier s = lookup(literal, 0); 1423e12c5d1SDavid du Colombier if(s->type == 0) { 1433e12c5d1SDavid du Colombier s->type = SDATA; 1443e12c5d1SDavid du Colombier s->value = orig1+orig; 1453e12c5d1SDavid du Colombier orig += 4; 1463e12c5d1SDavid du Colombier p1 = prg(); 1473e12c5d1SDavid du Colombier p1->line = p->line; 1483e12c5d1SDavid du Colombier p1->as = ADATA; 1493e12c5d1SDavid du Colombier p1->from.type = D_OREG; 1503e12c5d1SDavid du Colombier p1->from.sym = s; 1513e12c5d1SDavid du Colombier p1->from.name = D_EXTERN; 1523e12c5d1SDavid du Colombier p1->reg = 4; 1533e12c5d1SDavid du Colombier p1->to = p->from; 1543e12c5d1SDavid du Colombier p1->link = datap; 1553e12c5d1SDavid du Colombier datap = p1; 1563e12c5d1SDavid du Colombier } 1573e12c5d1SDavid du Colombier if(s->type != SDATA) 1583e12c5d1SDavid du Colombier diag("literal not data: %s", s->name); 1593e12c5d1SDavid du Colombier p->from.type = D_OREG; 1603e12c5d1SDavid du Colombier p->from.sym = s; 1613e12c5d1SDavid du Colombier p->from.name = D_EXTERN; 1623e12c5d1SDavid du Colombier p->from.offset = 0; 163*219b2ee8SDavid du Colombier nocache(p); 1643e12c5d1SDavid du Colombier continue; 1653e12c5d1SDavid du Colombier } 1663e12c5d1SDavid du Colombier while(orig & 7) 1673e12c5d1SDavid du Colombier orig++; 1683e12c5d1SDavid du Colombier /* 1693e12c5d1SDavid du Colombier * pass 5 1703e12c5d1SDavid du Colombier * re-adjust offsets 1713e12c5d1SDavid du Colombier */ 1723e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 1733e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 1743e12c5d1SDavid du Colombier t = s->type; 1753e12c5d1SDavid du Colombier if(t == SBSS) { 1763e12c5d1SDavid du Colombier s->value += orig; 1773e12c5d1SDavid du Colombier continue; 1783e12c5d1SDavid du Colombier } 1793e12c5d1SDavid du Colombier if(t == SDATA1) { 1803e12c5d1SDavid du Colombier s->type = SDATA; 1813e12c5d1SDavid du Colombier s->value += orig; 1823e12c5d1SDavid du Colombier continue; 1833e12c5d1SDavid du Colombier } 1843e12c5d1SDavid du Colombier } 1853e12c5d1SDavid du Colombier datsize += orig; 1863e12c5d1SDavid du Colombier xdefine("setR30", SDATA, 0L+BIG); 1873e12c5d1SDavid du Colombier xdefine("bdata", SDATA, 0L); 1883e12c5d1SDavid du Colombier xdefine("edata", SDATA, datsize); 1893e12c5d1SDavid du Colombier xdefine("end", SBSS, datsize+bsssize); 1903e12c5d1SDavid du Colombier xdefine("etext", STEXT, 0L); 1913e12c5d1SDavid du Colombier } 1923e12c5d1SDavid du Colombier 1933e12c5d1SDavid du Colombier void 1943e12c5d1SDavid du Colombier undef(void) 1953e12c5d1SDavid du Colombier { 1963e12c5d1SDavid du Colombier int i; 1973e12c5d1SDavid du Colombier Sym *s; 1983e12c5d1SDavid du Colombier 1993e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 2003e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) 2013e12c5d1SDavid du Colombier if(s->type == SXREF) 2023e12c5d1SDavid du Colombier diag("%s: not defined\n", s->name); 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier 2053e12c5d1SDavid du Colombier void 2063e12c5d1SDavid du Colombier follow(void) 2073e12c5d1SDavid du Colombier { 2083e12c5d1SDavid du Colombier if(debug['v']) 2093e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f follow\n", cputime()); 2103e12c5d1SDavid du Colombier Bflush(&bso); 2113e12c5d1SDavid du Colombier 2123e12c5d1SDavid du Colombier firstp = prg(); 2133e12c5d1SDavid du Colombier lastp = firstp; 2143e12c5d1SDavid du Colombier xfol(textp); 2153e12c5d1SDavid du Colombier 2163e12c5d1SDavid du Colombier firstp = firstp->link; 2173e12c5d1SDavid du Colombier lastp->link = P; 2183e12c5d1SDavid du Colombier } 2193e12c5d1SDavid du Colombier 2203e12c5d1SDavid du Colombier void 2213e12c5d1SDavid du Colombier xfol(Prog *p) 2223e12c5d1SDavid du Colombier { 2233e12c5d1SDavid du Colombier Prog *q, *r; 2243e12c5d1SDavid du Colombier int a, i; 2253e12c5d1SDavid du Colombier 2263e12c5d1SDavid du Colombier loop: 2273e12c5d1SDavid du Colombier if(p == P) 2283e12c5d1SDavid du Colombier return; 2293e12c5d1SDavid du Colombier a = p->as; 2303e12c5d1SDavid du Colombier if(a == ATEXT) 2313e12c5d1SDavid du Colombier curtext = p; 2323e12c5d1SDavid du Colombier if(a == AJMP) { 2333e12c5d1SDavid du Colombier q = p->cond; 234*219b2ee8SDavid du Colombier if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){ 235*219b2ee8SDavid du Colombier p->mark |= FOLL; 236*219b2ee8SDavid du Colombier lastp->link = p; 237*219b2ee8SDavid du Colombier lastp = p; 238*219b2ee8SDavid du Colombier p = p->link; 239*219b2ee8SDavid du Colombier xfol(p); 240*219b2ee8SDavid du Colombier p = q; 241*219b2ee8SDavid du Colombier if(p && !(p->mark & FOLL)) 242*219b2ee8SDavid du Colombier goto loop; 243*219b2ee8SDavid du Colombier return; 244*219b2ee8SDavid du Colombier } 2453e12c5d1SDavid du Colombier if(q != P) { 246*219b2ee8SDavid du Colombier p->mark |= FOLL; 2473e12c5d1SDavid du Colombier p = q; 2483e12c5d1SDavid du Colombier if(!(p->mark & FOLL)) 2493e12c5d1SDavid du Colombier goto loop; 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier } 2523e12c5d1SDavid du Colombier if(p->mark & FOLL) { 2533e12c5d1SDavid du Colombier for(i=0,q=p; i<4; i++,q=q->link) { 254*219b2ee8SDavid du Colombier if(q == lastp || (q->mark&NOSCHED)) 2553e12c5d1SDavid du Colombier break; 2563e12c5d1SDavid du Colombier a = q->as; 2573e12c5d1SDavid du Colombier if(a == ANOP) { 2583e12c5d1SDavid du Colombier i--; 2593e12c5d1SDavid du Colombier continue; 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier if(a == AJMP || a == ARET || a == ARFE) 2623e12c5d1SDavid du Colombier goto copy; 2633e12c5d1SDavid du Colombier if(!q->cond || (q->cond->mark&FOLL)) 2643e12c5d1SDavid du Colombier continue; 2653e12c5d1SDavid du Colombier if(a != ABEQ && a != ABNE) 2663e12c5d1SDavid du Colombier continue; 2673e12c5d1SDavid du Colombier copy: 2683e12c5d1SDavid du Colombier for(;;) { 2693e12c5d1SDavid du Colombier r = prg(); 2703e12c5d1SDavid du Colombier *r = *p; 2713e12c5d1SDavid du Colombier if(!(r->mark&FOLL)) 2723e12c5d1SDavid du Colombier print("cant happen 1\n"); 273*219b2ee8SDavid du Colombier r->mark |= FOLL; 2743e12c5d1SDavid du Colombier if(p != q) { 2753e12c5d1SDavid du Colombier p = p->link; 2763e12c5d1SDavid du Colombier lastp->link = r; 2773e12c5d1SDavid du Colombier lastp = r; 2783e12c5d1SDavid du Colombier continue; 2793e12c5d1SDavid du Colombier } 2803e12c5d1SDavid du Colombier lastp->link = r; 2813e12c5d1SDavid du Colombier lastp = r; 2823e12c5d1SDavid du Colombier if(a == AJMP || a == ARET || a == ARFE) 2833e12c5d1SDavid du Colombier return; 2843e12c5d1SDavid du Colombier r->as = ABNE; 2853e12c5d1SDavid du Colombier if(a == ABNE) 2863e12c5d1SDavid du Colombier r->as = ABEQ; 2873e12c5d1SDavid du Colombier r->cond = p->link; 2883e12c5d1SDavid du Colombier r->link = p->cond; 2893e12c5d1SDavid du Colombier if(!(r->link->mark&FOLL)) 2903e12c5d1SDavid du Colombier xfol(r->link); 2913e12c5d1SDavid du Colombier if(!(r->cond->mark&FOLL)) 2923e12c5d1SDavid du Colombier print("cant happen 2\n"); 2933e12c5d1SDavid du Colombier return; 2943e12c5d1SDavid du Colombier } 2953e12c5d1SDavid du Colombier } 2963e12c5d1SDavid du Colombier a = AJMP; 2973e12c5d1SDavid du Colombier q = prg(); 2983e12c5d1SDavid du Colombier q->as = a; 2993e12c5d1SDavid du Colombier q->line = p->line; 3003e12c5d1SDavid du Colombier q->to.type = D_BRANCH; 3013e12c5d1SDavid du Colombier q->to.offset = p->pc; 3023e12c5d1SDavid du Colombier q->cond = p; 3033e12c5d1SDavid du Colombier p = q; 3043e12c5d1SDavid du Colombier } 305*219b2ee8SDavid du Colombier p->mark |= FOLL; 3063e12c5d1SDavid du Colombier lastp->link = p; 3073e12c5d1SDavid du Colombier lastp = p; 308*219b2ee8SDavid du Colombier if(a == AJMP || a == ARET || a == ARFE){ 309*219b2ee8SDavid du Colombier if(p->mark & NOSCHED){ 310*219b2ee8SDavid du Colombier p = p->link; 311*219b2ee8SDavid du Colombier goto loop; 312*219b2ee8SDavid du Colombier } 3133e12c5d1SDavid du Colombier return; 314*219b2ee8SDavid du Colombier } 3153e12c5d1SDavid du Colombier if(p->cond != P) 3163e12c5d1SDavid du Colombier if(a != AJAL && p->link != P) { 3173e12c5d1SDavid du Colombier xfol(p->link); 3183e12c5d1SDavid du Colombier p = p->cond; 3193e12c5d1SDavid du Colombier if(p == P || (p->mark&FOLL)) 3203e12c5d1SDavid du Colombier return; 3213e12c5d1SDavid du Colombier goto loop; 3223e12c5d1SDavid du Colombier } 3233e12c5d1SDavid du Colombier p = p->link; 3243e12c5d1SDavid du Colombier goto loop; 3253e12c5d1SDavid du Colombier } 3263e12c5d1SDavid du Colombier 3273e12c5d1SDavid du Colombier void 3283e12c5d1SDavid du Colombier patch(void) 3293e12c5d1SDavid du Colombier { 3303e12c5d1SDavid du Colombier long c, vexit; 3313e12c5d1SDavid du Colombier Prog *p, *q; 3323e12c5d1SDavid du Colombier Sym *s; 3333e12c5d1SDavid du Colombier int a; 3343e12c5d1SDavid du Colombier 3353e12c5d1SDavid du Colombier if(debug['v']) 3363e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f patch\n", cputime()); 3373e12c5d1SDavid du Colombier Bflush(&bso); 3383e12c5d1SDavid du Colombier mkfwd(); 3393e12c5d1SDavid du Colombier s = lookup("exit", 0); 3403e12c5d1SDavid du Colombier vexit = s->value; 3413e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3423e12c5d1SDavid du Colombier a = p->as; 3433e12c5d1SDavid du Colombier if(a == ATEXT) 3443e12c5d1SDavid du Colombier curtext = p; 345*219b2ee8SDavid du Colombier if((a == AJAL || a == AJMP || a == ARET) && 346*219b2ee8SDavid du Colombier p->to.type != D_BRANCH && p->to.sym != S) { 3473e12c5d1SDavid du Colombier s = p->to.sym; 3483e12c5d1SDavid du Colombier if(s->type != STEXT) { 3493e12c5d1SDavid du Colombier diag("undefined: %s\n%P\n", s->name, p); 3503e12c5d1SDavid du Colombier s->type = STEXT; 3513e12c5d1SDavid du Colombier s->value = vexit; 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier p->to.offset = s->value; 3543e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 3553e12c5d1SDavid du Colombier } 3563e12c5d1SDavid du Colombier if(p->to.type != D_BRANCH) 3573e12c5d1SDavid du Colombier continue; 3583e12c5d1SDavid du Colombier c = p->to.offset; 3593e12c5d1SDavid du Colombier for(q = firstp; q != P;) { 3603e12c5d1SDavid du Colombier if(q->forwd != P) 3613e12c5d1SDavid du Colombier if(c >= q->forwd->pc) { 3623e12c5d1SDavid du Colombier q = q->forwd; 3633e12c5d1SDavid du Colombier continue; 3643e12c5d1SDavid du Colombier } 3653e12c5d1SDavid du Colombier if(c == q->pc) 3663e12c5d1SDavid du Colombier break; 3673e12c5d1SDavid du Colombier q = q->link; 3683e12c5d1SDavid du Colombier } 3693e12c5d1SDavid du Colombier if(q == P) { 3703e12c5d1SDavid du Colombier diag("branch out of range %ld\n%P\n", c, p); 3713e12c5d1SDavid du Colombier p->to.type = D_NONE; 3723e12c5d1SDavid du Colombier } 3733e12c5d1SDavid du Colombier p->cond = q; 3743e12c5d1SDavid du Colombier } 3753e12c5d1SDavid du Colombier 3763e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3773e12c5d1SDavid du Colombier if(p->as == ATEXT) 3783e12c5d1SDavid du Colombier curtext = p; 3793e12c5d1SDavid du Colombier if(p->cond != P) { 3803e12c5d1SDavid du Colombier p->cond = brloop(p->cond); 3813e12c5d1SDavid du Colombier if(p->cond != P) 3823e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 3833e12c5d1SDavid du Colombier p->to.offset = p->cond->pc; 3843e12c5d1SDavid du Colombier } 3853e12c5d1SDavid du Colombier } 3863e12c5d1SDavid du Colombier } 3873e12c5d1SDavid du Colombier 3883e12c5d1SDavid du Colombier #define LOG 5 3893e12c5d1SDavid du Colombier void 3903e12c5d1SDavid du Colombier mkfwd(void) 3913e12c5d1SDavid du Colombier { 3923e12c5d1SDavid du Colombier Prog *p; 3933e12c5d1SDavid du Colombier long dwn[LOG], cnt[LOG], i; 3943e12c5d1SDavid du Colombier Prog *lst[LOG]; 3953e12c5d1SDavid du Colombier 3963e12c5d1SDavid du Colombier for(i=0; i<LOG; i++) { 3973e12c5d1SDavid du Colombier if(i == 0) 3983e12c5d1SDavid du Colombier cnt[i] = 1; else 3993e12c5d1SDavid du Colombier cnt[i] = LOG * cnt[i-1]; 4003e12c5d1SDavid du Colombier dwn[i] = 1; 4013e12c5d1SDavid du Colombier lst[i] = P; 4023e12c5d1SDavid du Colombier } 4033e12c5d1SDavid du Colombier i = 0; 4043e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4053e12c5d1SDavid du Colombier if(p->as == ATEXT) 4063e12c5d1SDavid du Colombier curtext = p; 4073e12c5d1SDavid du Colombier i--; 4083e12c5d1SDavid du Colombier if(i < 0) 4093e12c5d1SDavid du Colombier i = LOG-1; 4103e12c5d1SDavid du Colombier p->forwd = P; 4113e12c5d1SDavid du Colombier dwn[i]--; 4123e12c5d1SDavid du Colombier if(dwn[i] <= 0) { 4133e12c5d1SDavid du Colombier dwn[i] = cnt[i]; 4143e12c5d1SDavid du Colombier if(lst[i] != P) 4153e12c5d1SDavid du Colombier lst[i]->forwd = p; 4163e12c5d1SDavid du Colombier lst[i] = p; 4173e12c5d1SDavid du Colombier } 4183e12c5d1SDavid du Colombier } 4193e12c5d1SDavid du Colombier } 4203e12c5d1SDavid du Colombier 4213e12c5d1SDavid du Colombier Prog* 4223e12c5d1SDavid du Colombier brloop(Prog *p) 4233e12c5d1SDavid du Colombier { 4243e12c5d1SDavid du Colombier Prog *q; 4253e12c5d1SDavid du Colombier int c; 4263e12c5d1SDavid du Colombier 4273e12c5d1SDavid du Colombier for(c=0; p!=P;) { 428*219b2ee8SDavid du Colombier if(p->as != AJMP || (p->mark&NOSCHED)) 4293e12c5d1SDavid du Colombier return p; 4303e12c5d1SDavid du Colombier q = p->cond; 4313e12c5d1SDavid du Colombier if(q <= p) { 4323e12c5d1SDavid du Colombier c++; 4333e12c5d1SDavid du Colombier if(q == p || c > 50) 4343e12c5d1SDavid du Colombier break; 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier p = q; 4373e12c5d1SDavid du Colombier } 4383e12c5d1SDavid du Colombier return P; 4393e12c5d1SDavid du Colombier } 4403e12c5d1SDavid du Colombier 4413e12c5d1SDavid du Colombier long 4423e12c5d1SDavid du Colombier atolwhex(char *s) 4433e12c5d1SDavid du Colombier { 4443e12c5d1SDavid du Colombier long n; 4453e12c5d1SDavid du Colombier int f; 4463e12c5d1SDavid du Colombier 4473e12c5d1SDavid du Colombier n = 0; 4483e12c5d1SDavid du Colombier f = 0; 4493e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t') 4503e12c5d1SDavid du Colombier s++; 4513e12c5d1SDavid du Colombier if(*s == '-' || *s == '+') { 4523e12c5d1SDavid du Colombier if(*s++ == '-') 4533e12c5d1SDavid du Colombier f = 1; 4543e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t') 4553e12c5d1SDavid du Colombier s++; 4563e12c5d1SDavid du Colombier } 4573e12c5d1SDavid du Colombier if(s[0]=='0' && s[1]){ 4583e12c5d1SDavid du Colombier if(s[1]=='x' || s[1]=='X'){ 4593e12c5d1SDavid du Colombier s += 2; 4603e12c5d1SDavid du Colombier for(;;){ 4613e12c5d1SDavid du Colombier if(*s >= '0' && *s <= '9') 4623e12c5d1SDavid du Colombier n = n*16 + *s++ - '0'; 4633e12c5d1SDavid du Colombier else if(*s >= 'a' && *s <= 'f') 4643e12c5d1SDavid du Colombier n = n*16 + *s++ - 'a' + 10; 4653e12c5d1SDavid du Colombier else if(*s >= 'A' && *s <= 'F') 4663e12c5d1SDavid du Colombier n = n*16 + *s++ - 'A' + 10; 4673e12c5d1SDavid du Colombier else 4683e12c5d1SDavid du Colombier break; 4693e12c5d1SDavid du Colombier } 4703e12c5d1SDavid du Colombier } else 4713e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '7') 4723e12c5d1SDavid du Colombier n = n*8 + *s++ - '0'; 4733e12c5d1SDavid du Colombier } else 4743e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '9') 4753e12c5d1SDavid du Colombier n = n*10 + *s++ - '0'; 4763e12c5d1SDavid du Colombier if(f) 4773e12c5d1SDavid du Colombier n = -n; 4783e12c5d1SDavid du Colombier return n; 4793e12c5d1SDavid du Colombier } 4803e12c5d1SDavid du Colombier 4813e12c5d1SDavid du Colombier long 4823e12c5d1SDavid du Colombier rnd(long v, long r) 4833e12c5d1SDavid du Colombier { 4843e12c5d1SDavid du Colombier long c; 4853e12c5d1SDavid du Colombier 4863e12c5d1SDavid du Colombier if(r <= 0) 4873e12c5d1SDavid du Colombier return v; 4883e12c5d1SDavid du Colombier v += r - 1; 4893e12c5d1SDavid du Colombier c = v % r; 4903e12c5d1SDavid du Colombier if(c < 0) 4913e12c5d1SDavid du Colombier c += r; 4923e12c5d1SDavid du Colombier v -= c; 4933e12c5d1SDavid du Colombier return v; 4943e12c5d1SDavid du Colombier } 495