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; 16219b2ee8SDavid du Colombier if(p->as == ADYNT || p->as == AINIT) 17219b2ee8SDavid 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) 216b6b9ac8SDavid du Colombier diag("initialize non-data (%d): %s\n%P", 223e12c5d1SDavid du Colombier s->type, s->name, p); 233e12c5d1SDavid du Colombier v = p->from.offset + p->reg; 243e12c5d1SDavid du Colombier if(v > s->value) 256b6b9ac8SDavid du Colombier diag("initialize bounds (%ld): %s\n%P", 263e12c5d1SDavid du Colombier s->value, s->name, p); 273e12c5d1SDavid du Colombier } 283e12c5d1SDavid du Colombier 299a747e4fSDavid du Colombier if(debug['t']) { 309a747e4fSDavid du Colombier /* 319a747e4fSDavid du Colombier * pull out string constants 329a747e4fSDavid du Colombier */ 339a747e4fSDavid du Colombier for(p = datap; p != P; p = p->link) { 349a747e4fSDavid du Colombier s = p->from.sym; 359a747e4fSDavid du Colombier if(p->to.type == D_SCONST) 369a747e4fSDavid du Colombier s->type = SSTRING; 379a747e4fSDavid du Colombier } 389a747e4fSDavid du Colombier } 399a747e4fSDavid du Colombier 403e12c5d1SDavid du Colombier /* 413e12c5d1SDavid du Colombier * pass 1 423e12c5d1SDavid du Colombier * assign 'small' variables to data segment 433e12c5d1SDavid du Colombier * (rational is that data segment is more easily 443e12c5d1SDavid du Colombier * addressed through offset on R30) 453e12c5d1SDavid du Colombier */ 463e12c5d1SDavid du Colombier orig = 0; 473e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 483e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 493e12c5d1SDavid du Colombier t = s->type; 503e12c5d1SDavid du Colombier if(t != SDATA && t != SBSS) 513e12c5d1SDavid du Colombier continue; 523e12c5d1SDavid du Colombier v = s->value; 533e12c5d1SDavid du Colombier if(v == 0) { 546b6b9ac8SDavid du Colombier diag("%s: no size", s->name); 553e12c5d1SDavid du Colombier v = 1; 563e12c5d1SDavid du Colombier } 573e12c5d1SDavid du Colombier while(v & 3) 583e12c5d1SDavid du Colombier v++; 593e12c5d1SDavid du Colombier s->value = v; 603e12c5d1SDavid du Colombier if(v > MINSIZ) 613e12c5d1SDavid du Colombier continue; 623e12c5d1SDavid du Colombier s->value = orig; 633e12c5d1SDavid du Colombier orig += v; 643e12c5d1SDavid du Colombier s->type = SDATA1; 653e12c5d1SDavid du Colombier } 663e12c5d1SDavid du Colombier orig1 = orig; 673e12c5d1SDavid du Colombier 683e12c5d1SDavid du Colombier /* 693e12c5d1SDavid du Colombier * pass 2 703e12c5d1SDavid du Colombier * assign 'data' variables to data segment 713e12c5d1SDavid du Colombier */ 723e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 733e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 743e12c5d1SDavid du Colombier t = s->type; 753e12c5d1SDavid du Colombier if(t != SDATA) { 763e12c5d1SDavid du Colombier if(t == SDATA1) 773e12c5d1SDavid du Colombier s->type = SDATA; 783e12c5d1SDavid du Colombier continue; 793e12c5d1SDavid du Colombier } 803e12c5d1SDavid du Colombier v = s->value; 813e12c5d1SDavid du Colombier s->value = orig; 823e12c5d1SDavid du Colombier orig += v; 833e12c5d1SDavid du Colombier s->type = SDATA1; 843e12c5d1SDavid du Colombier } 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier while(orig & 7) 873e12c5d1SDavid du Colombier orig++; 883e12c5d1SDavid du Colombier datsize = orig; 893e12c5d1SDavid du Colombier 903e12c5d1SDavid du Colombier /* 913e12c5d1SDavid du Colombier * pass 3 923e12c5d1SDavid du Colombier * everything else to bss segment 933e12c5d1SDavid du Colombier */ 943e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 953e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 963e12c5d1SDavid du Colombier if(s->type != SBSS) 973e12c5d1SDavid du Colombier continue; 983e12c5d1SDavid du Colombier v = s->value; 993e12c5d1SDavid du Colombier s->value = orig; 1003e12c5d1SDavid du Colombier orig += v; 1013e12c5d1SDavid du Colombier } 1023e12c5d1SDavid du Colombier while(orig & 7) 1033e12c5d1SDavid du Colombier orig++; 1043e12c5d1SDavid du Colombier bsssize = orig-datsize; 1053e12c5d1SDavid du Colombier 1063e12c5d1SDavid du Colombier /* 1073e12c5d1SDavid du Colombier * pass 4 1083e12c5d1SDavid du Colombier * add literals to all large values. 1093e12c5d1SDavid du Colombier * at this time: 1103e12c5d1SDavid du Colombier * small data is allocated DATA 1113e12c5d1SDavid du Colombier * large data is allocated DATA1 1123e12c5d1SDavid du Colombier * large bss is allocated BSS 1133e12c5d1SDavid du Colombier * the new literals are loaded between 1143e12c5d1SDavid du Colombier * small data and large data. 1153e12c5d1SDavid du Colombier */ 1163e12c5d1SDavid du Colombier orig = 0; 1173e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 1183e12c5d1SDavid du Colombier if(p->as != AMOVW) 1193e12c5d1SDavid du Colombier continue; 1203e12c5d1SDavid du Colombier if(p->from.type != D_CONST) 1213e12c5d1SDavid du Colombier continue; 1223e12c5d1SDavid du Colombier if(s = p->from.sym) { 1233e12c5d1SDavid du Colombier t = s->type; 1243e12c5d1SDavid du Colombier if(t != SDATA && t != SDATA1 && t != SBSS) 1253e12c5d1SDavid du Colombier continue; 1263e12c5d1SDavid du Colombier t = p->from.name; 1273e12c5d1SDavid du Colombier if(t != D_EXTERN && t != D_STATIC) 1283e12c5d1SDavid du Colombier continue; 1293e12c5d1SDavid du Colombier v = s->value + p->from.offset; 1303e12c5d1SDavid du Colombier if(v >= 0 && v <= 0xffff) 1313e12c5d1SDavid du Colombier continue; 1323e12c5d1SDavid du Colombier if(!strcmp(s->name, "setR30")) 1333e12c5d1SDavid du Colombier continue; 1343e12c5d1SDavid du Colombier /* size should be 19 max */ 135bd389b36SDavid du Colombier if(strlen(s->name) >= 10) /* has loader address */ 136*73e742d7SDavid du Colombier sprint(literal, "$%p.%lux", s, p->from.offset); 137bd389b36SDavid du Colombier else 138bd389b36SDavid du Colombier sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset); 1393e12c5d1SDavid du Colombier } else { 1403e12c5d1SDavid du Colombier if(p->from.name != D_NONE) 1413e12c5d1SDavid du Colombier continue; 1423e12c5d1SDavid du Colombier if(p->from.reg != NREG) 1433e12c5d1SDavid du Colombier continue; 1443e12c5d1SDavid du Colombier v = p->from.offset; 1453e12c5d1SDavid du Colombier if(v >= -0x7fff && v <= 0xffff) 1463e12c5d1SDavid du Colombier continue; 1473e12c5d1SDavid du Colombier if(!(v & 0xffff)) 1483e12c5d1SDavid du Colombier continue; 1493e12c5d1SDavid du Colombier /* size should be 9 max */ 1503e12c5d1SDavid du Colombier sprint(literal, "$%lux", v); 1513e12c5d1SDavid du Colombier } 1523e12c5d1SDavid du Colombier s = lookup(literal, 0); 1533e12c5d1SDavid du Colombier if(s->type == 0) { 1543e12c5d1SDavid du Colombier s->type = SDATA; 1553e12c5d1SDavid du Colombier s->value = orig1+orig; 1563e12c5d1SDavid du Colombier orig += 4; 1573e12c5d1SDavid du Colombier p1 = prg(); 1583e12c5d1SDavid du Colombier p1->line = p->line; 1593e12c5d1SDavid du Colombier p1->as = ADATA; 1603e12c5d1SDavid du Colombier p1->from.type = D_OREG; 1613e12c5d1SDavid du Colombier p1->from.sym = s; 1623e12c5d1SDavid du Colombier p1->from.name = D_EXTERN; 1633e12c5d1SDavid du Colombier p1->reg = 4; 1643e12c5d1SDavid du Colombier p1->to = p->from; 1653e12c5d1SDavid du Colombier p1->link = datap; 1663e12c5d1SDavid du Colombier datap = p1; 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier if(s->type != SDATA) 1693e12c5d1SDavid du Colombier diag("literal not data: %s", s->name); 1703e12c5d1SDavid du Colombier p->from.type = D_OREG; 1713e12c5d1SDavid du Colombier p->from.sym = s; 1723e12c5d1SDavid du Colombier p->from.name = D_EXTERN; 1733e12c5d1SDavid du Colombier p->from.offset = 0; 174219b2ee8SDavid du Colombier nocache(p); 1753e12c5d1SDavid du Colombier continue; 1763e12c5d1SDavid du Colombier } 1773e12c5d1SDavid du Colombier while(orig & 7) 1783e12c5d1SDavid du Colombier orig++; 1793e12c5d1SDavid du Colombier /* 1803e12c5d1SDavid du Colombier * pass 5 1813e12c5d1SDavid du Colombier * re-adjust offsets 1823e12c5d1SDavid du Colombier */ 1833e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 1843e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 1853e12c5d1SDavid du Colombier t = s->type; 1863e12c5d1SDavid du Colombier if(t == SBSS) { 1873e12c5d1SDavid du Colombier s->value += orig; 1883e12c5d1SDavid du Colombier continue; 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier if(t == SDATA1) { 1913e12c5d1SDavid du Colombier s->type = SDATA; 1923e12c5d1SDavid du Colombier s->value += orig; 1933e12c5d1SDavid du Colombier continue; 1943e12c5d1SDavid du Colombier } 1953e12c5d1SDavid du Colombier } 1963e12c5d1SDavid du Colombier datsize += orig; 1973e12c5d1SDavid du Colombier xdefine("setR30", SDATA, 0L+BIG); 1983e12c5d1SDavid du Colombier xdefine("bdata", SDATA, 0L); 1993e12c5d1SDavid du Colombier xdefine("edata", SDATA, datsize); 2003e12c5d1SDavid du Colombier xdefine("end", SBSS, datsize+bsssize); 2013e12c5d1SDavid du Colombier xdefine("etext", STEXT, 0L); 2023e12c5d1SDavid du Colombier } 2033e12c5d1SDavid du Colombier 2043e12c5d1SDavid du Colombier void 2053e12c5d1SDavid du Colombier undef(void) 2063e12c5d1SDavid du Colombier { 2073e12c5d1SDavid du Colombier int i; 2083e12c5d1SDavid du Colombier Sym *s; 2093e12c5d1SDavid du Colombier 2103e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 2113e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) 2123e12c5d1SDavid du Colombier if(s->type == SXREF) 2136b6b9ac8SDavid du Colombier diag("%s: not defined", s->name); 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier 2163e12c5d1SDavid du Colombier void 2173e12c5d1SDavid du Colombier follow(void) 2183e12c5d1SDavid du Colombier { 2193e12c5d1SDavid du Colombier if(debug['v']) 2203e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f follow\n", cputime()); 2213e12c5d1SDavid du Colombier Bflush(&bso); 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier firstp = prg(); 2243e12c5d1SDavid du Colombier lastp = firstp; 2253e12c5d1SDavid du Colombier xfol(textp); 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier firstp = firstp->link; 2283e12c5d1SDavid du Colombier lastp->link = P; 2293e12c5d1SDavid du Colombier } 2303e12c5d1SDavid du Colombier 2313e12c5d1SDavid du Colombier void 2323e12c5d1SDavid du Colombier xfol(Prog *p) 2333e12c5d1SDavid du Colombier { 2343e12c5d1SDavid du Colombier Prog *q, *r; 2353e12c5d1SDavid du Colombier int a, i; 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier loop: 2383e12c5d1SDavid du Colombier if(p == P) 2393e12c5d1SDavid du Colombier return; 2403e12c5d1SDavid du Colombier a = p->as; 2413e12c5d1SDavid du Colombier if(a == ATEXT) 2423e12c5d1SDavid du Colombier curtext = p; 2433e12c5d1SDavid du Colombier if(a == AJMP) { 2443e12c5d1SDavid du Colombier q = p->cond; 245219b2ee8SDavid du Colombier if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){ 246219b2ee8SDavid du Colombier p->mark |= FOLL; 247219b2ee8SDavid du Colombier lastp->link = p; 248219b2ee8SDavid du Colombier lastp = p; 249219b2ee8SDavid du Colombier p = p->link; 250219b2ee8SDavid du Colombier xfol(p); 251219b2ee8SDavid du Colombier p = q; 252219b2ee8SDavid du Colombier if(p && !(p->mark & FOLL)) 253219b2ee8SDavid du Colombier goto loop; 254219b2ee8SDavid du Colombier return; 255219b2ee8SDavid du Colombier } 2563e12c5d1SDavid du Colombier if(q != P) { 257219b2ee8SDavid du Colombier p->mark |= FOLL; 2583e12c5d1SDavid du Colombier p = q; 2593e12c5d1SDavid du Colombier if(!(p->mark & FOLL)) 2603e12c5d1SDavid du Colombier goto loop; 2613e12c5d1SDavid du Colombier } 2623e12c5d1SDavid du Colombier } 2633e12c5d1SDavid du Colombier if(p->mark & FOLL) { 2643e12c5d1SDavid du Colombier for(i=0,q=p; i<4; i++,q=q->link) { 265219b2ee8SDavid du Colombier if(q == lastp || (q->mark&NOSCHED)) 2663e12c5d1SDavid du Colombier break; 2673e12c5d1SDavid du Colombier a = q->as; 2683e12c5d1SDavid du Colombier if(a == ANOP) { 2693e12c5d1SDavid du Colombier i--; 2703e12c5d1SDavid du Colombier continue; 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier if(a == AJMP || a == ARET || a == ARFE) 2733e12c5d1SDavid du Colombier goto copy; 2743e12c5d1SDavid du Colombier if(!q->cond || (q->cond->mark&FOLL)) 2753e12c5d1SDavid du Colombier continue; 2763e12c5d1SDavid du Colombier if(a != ABEQ && a != ABNE) 2773e12c5d1SDavid du Colombier continue; 2783e12c5d1SDavid du Colombier copy: 2793e12c5d1SDavid du Colombier for(;;) { 2803e12c5d1SDavid du Colombier r = prg(); 2813e12c5d1SDavid du Colombier *r = *p; 2823e12c5d1SDavid du Colombier if(!(r->mark&FOLL)) 2833e12c5d1SDavid du Colombier print("cant happen 1\n"); 284219b2ee8SDavid du Colombier r->mark |= FOLL; 2853e12c5d1SDavid du Colombier if(p != q) { 2863e12c5d1SDavid du Colombier p = p->link; 2873e12c5d1SDavid du Colombier lastp->link = r; 2883e12c5d1SDavid du Colombier lastp = r; 2893e12c5d1SDavid du Colombier continue; 2903e12c5d1SDavid du Colombier } 2913e12c5d1SDavid du Colombier lastp->link = r; 2923e12c5d1SDavid du Colombier lastp = r; 2933e12c5d1SDavid du Colombier if(a == AJMP || a == ARET || a == ARFE) 2943e12c5d1SDavid du Colombier return; 2953e12c5d1SDavid du Colombier r->as = ABNE; 2963e12c5d1SDavid du Colombier if(a == ABNE) 2973e12c5d1SDavid du Colombier r->as = ABEQ; 2983e12c5d1SDavid du Colombier r->cond = p->link; 2993e12c5d1SDavid du Colombier r->link = p->cond; 3003e12c5d1SDavid du Colombier if(!(r->link->mark&FOLL)) 3013e12c5d1SDavid du Colombier xfol(r->link); 3023e12c5d1SDavid du Colombier if(!(r->cond->mark&FOLL)) 3033e12c5d1SDavid du Colombier print("cant happen 2\n"); 3043e12c5d1SDavid du Colombier return; 3053e12c5d1SDavid du Colombier } 3063e12c5d1SDavid du Colombier } 3073e12c5d1SDavid du Colombier a = AJMP; 3083e12c5d1SDavid du Colombier q = prg(); 3093e12c5d1SDavid du Colombier q->as = a; 3103e12c5d1SDavid du Colombier q->line = p->line; 3113e12c5d1SDavid du Colombier q->to.type = D_BRANCH; 3123e12c5d1SDavid du Colombier q->to.offset = p->pc; 3133e12c5d1SDavid du Colombier q->cond = p; 3143e12c5d1SDavid du Colombier p = q; 3153e12c5d1SDavid du Colombier } 316219b2ee8SDavid du Colombier p->mark |= FOLL; 3173e12c5d1SDavid du Colombier lastp->link = p; 3183e12c5d1SDavid du Colombier lastp = p; 319219b2ee8SDavid du Colombier if(a == AJMP || a == ARET || a == ARFE){ 320219b2ee8SDavid du Colombier if(p->mark & NOSCHED){ 321219b2ee8SDavid du Colombier p = p->link; 322219b2ee8SDavid du Colombier goto loop; 323219b2ee8SDavid du Colombier } 3243e12c5d1SDavid du Colombier return; 325219b2ee8SDavid du Colombier } 3263e12c5d1SDavid du Colombier if(p->cond != P) 3273e12c5d1SDavid du Colombier if(a != AJAL && p->link != P) { 3283e12c5d1SDavid du Colombier xfol(p->link); 3293e12c5d1SDavid du Colombier p = p->cond; 3303e12c5d1SDavid du Colombier if(p == P || (p->mark&FOLL)) 3313e12c5d1SDavid du Colombier return; 3323e12c5d1SDavid du Colombier goto loop; 3333e12c5d1SDavid du Colombier } 3343e12c5d1SDavid du Colombier p = p->link; 3353e12c5d1SDavid du Colombier goto loop; 3363e12c5d1SDavid du Colombier } 3373e12c5d1SDavid du Colombier 3383e12c5d1SDavid du Colombier void 3393e12c5d1SDavid du Colombier patch(void) 3403e12c5d1SDavid du Colombier { 3413e12c5d1SDavid du Colombier long c, vexit; 3423e12c5d1SDavid du Colombier Prog *p, *q; 3433e12c5d1SDavid du Colombier Sym *s; 3443e12c5d1SDavid du Colombier int a; 3453e12c5d1SDavid du Colombier 3463e12c5d1SDavid du Colombier if(debug['v']) 3473e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f patch\n", cputime()); 3483e12c5d1SDavid du Colombier Bflush(&bso); 3493e12c5d1SDavid du Colombier mkfwd(); 3503e12c5d1SDavid du Colombier s = lookup("exit", 0); 3513e12c5d1SDavid du Colombier vexit = s->value; 3523e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3533e12c5d1SDavid du Colombier a = p->as; 3543e12c5d1SDavid du Colombier if(a == ATEXT) 3553e12c5d1SDavid du Colombier curtext = p; 356219b2ee8SDavid du Colombier if((a == AJAL || a == AJMP || a == ARET) && 357219b2ee8SDavid du Colombier p->to.type != D_BRANCH && p->to.sym != S) { 3583e12c5d1SDavid du Colombier s = p->to.sym; 3593e12c5d1SDavid du Colombier if(s->type != STEXT) { 3606b6b9ac8SDavid du Colombier diag("undefined: %s\n%P", s->name, p); 3613e12c5d1SDavid du Colombier s->type = STEXT; 3623e12c5d1SDavid du Colombier s->value = vexit; 3633e12c5d1SDavid du Colombier } 3643e12c5d1SDavid du Colombier p->to.offset = s->value; 3653e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 3663e12c5d1SDavid du Colombier } 3673e12c5d1SDavid du Colombier if(p->to.type != D_BRANCH) 3683e12c5d1SDavid du Colombier continue; 3693e12c5d1SDavid du Colombier c = p->to.offset; 3703e12c5d1SDavid du Colombier for(q = firstp; q != P;) { 3713e12c5d1SDavid du Colombier if(q->forwd != P) 3723e12c5d1SDavid du Colombier if(c >= q->forwd->pc) { 3733e12c5d1SDavid du Colombier q = q->forwd; 3743e12c5d1SDavid du Colombier continue; 3753e12c5d1SDavid du Colombier } 3763e12c5d1SDavid du Colombier if(c == q->pc) 3773e12c5d1SDavid du Colombier break; 3783e12c5d1SDavid du Colombier q = q->link; 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier if(q == P) { 3816b6b9ac8SDavid du Colombier diag("branch out of range %ld\n%P", c, p); 3823e12c5d1SDavid du Colombier p->to.type = D_NONE; 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier p->cond = q; 3853e12c5d1SDavid du Colombier } 3863e12c5d1SDavid du Colombier 3873e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 3883e12c5d1SDavid du Colombier if(p->as == ATEXT) 3893e12c5d1SDavid du Colombier curtext = p; 3903e12c5d1SDavid du Colombier if(p->cond != P) { 3913e12c5d1SDavid du Colombier p->cond = brloop(p->cond); 3923e12c5d1SDavid du Colombier if(p->cond != P) 3933e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 3943e12c5d1SDavid du Colombier p->to.offset = p->cond->pc; 3953e12c5d1SDavid du Colombier } 3963e12c5d1SDavid du Colombier } 3973e12c5d1SDavid du Colombier } 3983e12c5d1SDavid du Colombier 3993e12c5d1SDavid du Colombier #define LOG 5 4003e12c5d1SDavid du Colombier void 4013e12c5d1SDavid du Colombier mkfwd(void) 4023e12c5d1SDavid du Colombier { 4033e12c5d1SDavid du Colombier Prog *p; 4043e12c5d1SDavid du Colombier long dwn[LOG], cnt[LOG], i; 4053e12c5d1SDavid du Colombier Prog *lst[LOG]; 4063e12c5d1SDavid du Colombier 4073e12c5d1SDavid du Colombier for(i=0; i<LOG; i++) { 4083e12c5d1SDavid du Colombier if(i == 0) 4093e12c5d1SDavid du Colombier cnt[i] = 1; else 4103e12c5d1SDavid du Colombier cnt[i] = LOG * cnt[i-1]; 4113e12c5d1SDavid du Colombier dwn[i] = 1; 4123e12c5d1SDavid du Colombier lst[i] = P; 4133e12c5d1SDavid du Colombier } 4143e12c5d1SDavid du Colombier i = 0; 4153e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4163e12c5d1SDavid du Colombier if(p->as == ATEXT) 4173e12c5d1SDavid du Colombier curtext = p; 4183e12c5d1SDavid du Colombier i--; 4193e12c5d1SDavid du Colombier if(i < 0) 4203e12c5d1SDavid du Colombier i = LOG-1; 4213e12c5d1SDavid du Colombier p->forwd = P; 4223e12c5d1SDavid du Colombier dwn[i]--; 4233e12c5d1SDavid du Colombier if(dwn[i] <= 0) { 4243e12c5d1SDavid du Colombier dwn[i] = cnt[i]; 4253e12c5d1SDavid du Colombier if(lst[i] != P) 4263e12c5d1SDavid du Colombier lst[i]->forwd = p; 4273e12c5d1SDavid du Colombier lst[i] = p; 4283e12c5d1SDavid du Colombier } 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier } 4313e12c5d1SDavid du Colombier 4323e12c5d1SDavid du Colombier Prog* 4333e12c5d1SDavid du Colombier brloop(Prog *p) 4343e12c5d1SDavid du Colombier { 4353e12c5d1SDavid du Colombier Prog *q; 4363e12c5d1SDavid du Colombier int c; 4373e12c5d1SDavid du Colombier 4383e12c5d1SDavid du Colombier for(c=0; p!=P;) { 439219b2ee8SDavid du Colombier if(p->as != AJMP || (p->mark&NOSCHED)) 4403e12c5d1SDavid du Colombier return p; 4413e12c5d1SDavid du Colombier q = p->cond; 4423e12c5d1SDavid du Colombier if(q <= p) { 4433e12c5d1SDavid du Colombier c++; 4447dd7cddfSDavid du Colombier if(q == p || c > 5000) 4453e12c5d1SDavid du Colombier break; 4463e12c5d1SDavid du Colombier } 4473e12c5d1SDavid du Colombier p = q; 4483e12c5d1SDavid du Colombier } 4493e12c5d1SDavid du Colombier return P; 4503e12c5d1SDavid du Colombier } 4513e12c5d1SDavid du Colombier 4523e12c5d1SDavid du Colombier long 4533e12c5d1SDavid du Colombier atolwhex(char *s) 4543e12c5d1SDavid du Colombier { 4553e12c5d1SDavid du Colombier long n; 4563e12c5d1SDavid du Colombier int f; 4573e12c5d1SDavid du Colombier 4583e12c5d1SDavid du Colombier n = 0; 4593e12c5d1SDavid du Colombier f = 0; 4603e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t') 4613e12c5d1SDavid du Colombier s++; 4623e12c5d1SDavid du Colombier if(*s == '-' || *s == '+') { 4633e12c5d1SDavid du Colombier if(*s++ == '-') 4643e12c5d1SDavid du Colombier f = 1; 4653e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t') 4663e12c5d1SDavid du Colombier s++; 4673e12c5d1SDavid du Colombier } 4683e12c5d1SDavid du Colombier if(s[0]=='0' && s[1]){ 4693e12c5d1SDavid du Colombier if(s[1]=='x' || s[1]=='X'){ 4703e12c5d1SDavid du Colombier s += 2; 4713e12c5d1SDavid du Colombier for(;;){ 4723e12c5d1SDavid du Colombier if(*s >= '0' && *s <= '9') 4733e12c5d1SDavid du Colombier n = n*16 + *s++ - '0'; 4743e12c5d1SDavid du Colombier else if(*s >= 'a' && *s <= 'f') 4753e12c5d1SDavid du Colombier n = n*16 + *s++ - 'a' + 10; 4763e12c5d1SDavid du Colombier else if(*s >= 'A' && *s <= 'F') 4773e12c5d1SDavid du Colombier n = n*16 + *s++ - 'A' + 10; 4783e12c5d1SDavid du Colombier else 4793e12c5d1SDavid du Colombier break; 4803e12c5d1SDavid du Colombier } 4813e12c5d1SDavid du Colombier } else 4823e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '7') 4833e12c5d1SDavid du Colombier n = n*8 + *s++ - '0'; 4843e12c5d1SDavid du Colombier } else 4853e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '9') 4863e12c5d1SDavid du Colombier n = n*10 + *s++ - '0'; 4873e12c5d1SDavid du Colombier if(f) 4883e12c5d1SDavid du Colombier n = -n; 4893e12c5d1SDavid du Colombier return n; 4903e12c5d1SDavid du Colombier } 4913e12c5d1SDavid du Colombier 4923e12c5d1SDavid du Colombier long 4933e12c5d1SDavid du Colombier rnd(long v, long r) 4943e12c5d1SDavid du Colombier { 4953e12c5d1SDavid du Colombier long c; 4963e12c5d1SDavid du Colombier 4973e12c5d1SDavid du Colombier if(r <= 0) 4983e12c5d1SDavid du Colombier return v; 4993e12c5d1SDavid du Colombier v += r - 1; 5003e12c5d1SDavid du Colombier c = v % r; 5013e12c5d1SDavid du Colombier if(c < 0) 5023e12c5d1SDavid du Colombier c += r; 5033e12c5d1SDavid du Colombier v -= c; 5043e12c5d1SDavid du Colombier return v; 5053e12c5d1SDavid du Colombier } 506