13e12c5d1SDavid du Colombier #include "l.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier void
dodata(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
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 REGSB)
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) {
436b6b9ac8SDavid du Colombier diag("%s: no size", 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 if(v >= 8)
523e12c5d1SDavid du Colombier while(orig & 7)
533e12c5d1SDavid du Colombier orig++;
543e12c5d1SDavid du Colombier s->value = orig;
553e12c5d1SDavid du Colombier orig += v;
563e12c5d1SDavid du Colombier s->type = SDATA1;
573e12c5d1SDavid du Colombier }
583e12c5d1SDavid du Colombier orig1 = orig;
593e12c5d1SDavid du Colombier
603e12c5d1SDavid du Colombier /*
613e12c5d1SDavid du Colombier * pass 2
623e12c5d1SDavid du Colombier * assign 'data' variables to data segment
633e12c5d1SDavid du Colombier */
643e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++)
653e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
663e12c5d1SDavid du Colombier t = s->type;
673e12c5d1SDavid du Colombier if(t != SDATA) {
683e12c5d1SDavid du Colombier if(t == SDATA1)
693e12c5d1SDavid du Colombier s->type = SDATA;
703e12c5d1SDavid du Colombier continue;
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier v = s->value;
733e12c5d1SDavid du Colombier if(v >= 8)
743e12c5d1SDavid du Colombier while(orig & 7)
753e12c5d1SDavid du Colombier orig++;
763e12c5d1SDavid du Colombier s->value = orig;
773e12c5d1SDavid du Colombier orig += v;
783e12c5d1SDavid du Colombier s->type = SDATA1;
793e12c5d1SDavid du Colombier }
803e12c5d1SDavid du Colombier
813e12c5d1SDavid du Colombier while(orig & 7)
823e12c5d1SDavid du Colombier orig++;
833e12c5d1SDavid du Colombier datsize = orig;
843e12c5d1SDavid du Colombier
853e12c5d1SDavid du Colombier /*
863e12c5d1SDavid du Colombier * pass 3
873e12c5d1SDavid du Colombier * everything else to bss segment
883e12c5d1SDavid du Colombier */
893e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++)
903e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
913e12c5d1SDavid du Colombier if(s->type != SBSS)
923e12c5d1SDavid du Colombier continue;
933e12c5d1SDavid du Colombier v = s->value;
943e12c5d1SDavid du Colombier if(v >= 8)
953e12c5d1SDavid du Colombier while(orig & 7)
963e12c5d1SDavid du Colombier orig++;
973e12c5d1SDavid du Colombier s->value = orig;
983e12c5d1SDavid du Colombier orig += v;
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier while(orig & 7)
1013e12c5d1SDavid du Colombier orig++;
1023e12c5d1SDavid du Colombier bsssize = orig-datsize;
1033e12c5d1SDavid du Colombier
1043e12c5d1SDavid du Colombier /*
1053e12c5d1SDavid du Colombier * pass 4
1063e12c5d1SDavid du Colombier * add literals to all large values.
1073e12c5d1SDavid du Colombier * at this time:
1083e12c5d1SDavid du Colombier * small data is allocated DATA
1093e12c5d1SDavid du Colombier * large data is allocated DATA1
1103e12c5d1SDavid du Colombier * large bss is allocated BSS
1113e12c5d1SDavid du Colombier * the new literals are loaded between
1123e12c5d1SDavid du Colombier * small data and large data.
1133e12c5d1SDavid du Colombier */
1143e12c5d1SDavid du Colombier orig = 0;
1153e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
1163e12c5d1SDavid du Colombier if(p->as != AMOVW)
1173e12c5d1SDavid du Colombier continue;
1183e12c5d1SDavid du Colombier if(p->from.type != D_CONST)
1193e12c5d1SDavid du Colombier continue;
1203e12c5d1SDavid du Colombier if(s = p->from.sym) {
1213e12c5d1SDavid du Colombier t = s->type;
1223e12c5d1SDavid du Colombier if(t != SDATA && t != SDATA1 && t != SBSS)
1233e12c5d1SDavid du Colombier continue;
1243e12c5d1SDavid du Colombier t = p->from.name;
1253e12c5d1SDavid du Colombier if(t != D_EXTERN && t != D_STATIC)
1263e12c5d1SDavid du Colombier continue;
1273e12c5d1SDavid du Colombier v = s->value + p->from.offset;
1283e12c5d1SDavid du Colombier if(v >= 0 && v <= 0xffff)
1293e12c5d1SDavid du Colombier continue;
1303e12c5d1SDavid du Colombier if(!strcmp(s->name, "setSB"))
1313e12c5d1SDavid du Colombier continue;
1323e12c5d1SDavid du Colombier /* size should be 19 max */
133bd389b36SDavid du Colombier if(strlen(s->name) >= 10) /* has loader address */
134*73e742d7SDavid du Colombier sprint(literal, "$%p.%lux", s, p->from.offset);
135bd389b36SDavid du Colombier else
136bd389b36SDavid du Colombier sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
1373e12c5d1SDavid du Colombier } else {
1383e12c5d1SDavid du Colombier if(p->from.name != D_NONE)
1393e12c5d1SDavid du Colombier continue;
1403e12c5d1SDavid du Colombier if(p->from.reg != NREG)
1413e12c5d1SDavid du Colombier continue;
1423e12c5d1SDavid du Colombier v = p->from.offset;
1433e12c5d1SDavid du Colombier if(v >= -0x7fff && v <= 0xffff)
1443e12c5d1SDavid du Colombier continue;
1453e12c5d1SDavid du Colombier if(!(v & 0xffff))
1463e12c5d1SDavid du Colombier continue;
1473e12c5d1SDavid du Colombier /* size should be 9 max */
1483e12c5d1SDavid du Colombier sprint(literal, "$%lux", v);
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier s = lookup(literal, 0);
1513e12c5d1SDavid du Colombier if(s->type == 0) {
1523e12c5d1SDavid du Colombier s->type = SDATA;
1533e12c5d1SDavid du Colombier s->value = orig1+orig;
1543e12c5d1SDavid du Colombier orig += 4;
1553e12c5d1SDavid du Colombier p1 = prg();
1563e12c5d1SDavid du Colombier p1->as = ADATA;
1573e12c5d1SDavid du Colombier p1->line = p->line;
1583e12c5d1SDavid du Colombier p1->from.type = D_OREG;
1593e12c5d1SDavid du Colombier p1->from.sym = s;
1603e12c5d1SDavid du Colombier p1->from.name = D_EXTERN;
1613e12c5d1SDavid du Colombier p1->reg = 4;
1623e12c5d1SDavid du Colombier p1->to = p->from;
1633e12c5d1SDavid du Colombier p1->link = datap;
1643e12c5d1SDavid du Colombier datap = p1;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier if(s->type != SDATA)
1673e12c5d1SDavid du Colombier diag("literal not data: %s", s->name);
1683e12c5d1SDavid du Colombier p->from.type = D_OREG;
1693e12c5d1SDavid du Colombier p->from.sym = s;
1703e12c5d1SDavid du Colombier p->from.name = D_EXTERN;
1713e12c5d1SDavid du Colombier p->from.offset = 0;
1723e12c5d1SDavid du Colombier continue;
1733e12c5d1SDavid du Colombier }
1743e12c5d1SDavid du Colombier while(orig & 7)
1753e12c5d1SDavid du Colombier orig++;
1763e12c5d1SDavid du Colombier /*
1773e12c5d1SDavid du Colombier * pass 5
1783e12c5d1SDavid du Colombier * re-adjust offsets
1793e12c5d1SDavid du Colombier */
1803e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++)
1813e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
1823e12c5d1SDavid du Colombier t = s->type;
1833e12c5d1SDavid du Colombier if(t == SBSS) {
1843e12c5d1SDavid du Colombier s->value += orig;
1853e12c5d1SDavid du Colombier continue;
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier if(t == SDATA1) {
1883e12c5d1SDavid du Colombier s->type = SDATA;
1893e12c5d1SDavid du Colombier s->value += orig;
1903e12c5d1SDavid du Colombier continue;
1913e12c5d1SDavid du Colombier }
1923e12c5d1SDavid du Colombier }
1933e12c5d1SDavid du Colombier datsize += orig;
1943e12c5d1SDavid du Colombier xdefine("setSB", SDATA, 0L+BIG);
1953e12c5d1SDavid du Colombier xdefine("bdata", SDATA, 0L);
1963e12c5d1SDavid du Colombier xdefine("edata", SDATA, datsize);
1973e12c5d1SDavid du Colombier xdefine("end", SBSS, datsize+bsssize);
1983e12c5d1SDavid du Colombier xdefine("etext", STEXT, 0L);
1993e12c5d1SDavid du Colombier }
2003e12c5d1SDavid du Colombier
2013e12c5d1SDavid du Colombier void
undef(void)2023e12c5d1SDavid du Colombier undef(void)
2033e12c5d1SDavid du Colombier {
2043e12c5d1SDavid du Colombier int i;
2053e12c5d1SDavid du Colombier Sym *s;
2063e12c5d1SDavid du Colombier
2073e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++)
2083e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
2093e12c5d1SDavid du Colombier if(s->type == SXREF)
2106b6b9ac8SDavid du Colombier diag("%s: not defined", s->name);
2113e12c5d1SDavid du Colombier }
2123e12c5d1SDavid du Colombier
2133e12c5d1SDavid du Colombier int
relinv(int a)2143e12c5d1SDavid du Colombier relinv(int a)
2153e12c5d1SDavid du Colombier {
2163e12c5d1SDavid du Colombier
2173e12c5d1SDavid du Colombier switch(a) {
2183e12c5d1SDavid du Colombier case ABA: return ABN;
2193e12c5d1SDavid du Colombier case ABN: return ABA;
2203e12c5d1SDavid du Colombier
2213e12c5d1SDavid du Colombier case ABE: return ABNE;
2223e12c5d1SDavid du Colombier case ABNE: return ABE;
2233e12c5d1SDavid du Colombier
2243e12c5d1SDavid du Colombier case ABLE: return ABG;
2253e12c5d1SDavid du Colombier case ABG: return ABLE;
2263e12c5d1SDavid du Colombier
2273e12c5d1SDavid du Colombier case ABL: return ABGE;
2283e12c5d1SDavid du Colombier case ABGE: return ABL;
2293e12c5d1SDavid du Colombier
2303e12c5d1SDavid du Colombier case ABLEU: return ABGU;
2313e12c5d1SDavid du Colombier case ABGU: return ABLEU;
2323e12c5d1SDavid du Colombier
2333e12c5d1SDavid du Colombier case ABCS: return ABCC;
2343e12c5d1SDavid du Colombier case ABCC: return ABCS;
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier case ABNEG: return ABPOS;
2373e12c5d1SDavid du Colombier case ABPOS: return ABNEG;
2383e12c5d1SDavid du Colombier
2393e12c5d1SDavid du Colombier case ABVC: return ABVS;
2403e12c5d1SDavid du Colombier case ABVS: return ABVC;
2413e12c5d1SDavid du Colombier
2423e12c5d1SDavid du Colombier case AFBN: return AFBA;
2433e12c5d1SDavid du Colombier case AFBA: return AFBN;
2443e12c5d1SDavid du Colombier
2453e12c5d1SDavid du Colombier case AFBE: return AFBLG;
2463e12c5d1SDavid du Colombier case AFBLG: return AFBE;
2473e12c5d1SDavid du Colombier
2483e12c5d1SDavid du Colombier case AFBG: return AFBLE;
2493e12c5d1SDavid du Colombier case AFBLE: return AFBG;
2503e12c5d1SDavid du Colombier
2513e12c5d1SDavid du Colombier case AFBGE: return AFBL;
2523e12c5d1SDavid du Colombier case AFBL: return AFBGE;
2533e12c5d1SDavid du Colombier
2543e12c5d1SDavid du Colombier /* unordered fp compares have no inverse
2553e12c5d1SDavid du Colombier that traps in the same way */
2563e12c5d1SDavid du Colombier }
2573e12c5d1SDavid du Colombier return 0;
2583e12c5d1SDavid du Colombier }
2593e12c5d1SDavid du Colombier
2603e12c5d1SDavid du Colombier void
follow(void)2613e12c5d1SDavid du Colombier follow(void)
2623e12c5d1SDavid du Colombier {
2633e12c5d1SDavid du Colombier
2643e12c5d1SDavid du Colombier if(debug['v'])
2653e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f follow\n", cputime());
2663e12c5d1SDavid du Colombier Bflush(&bso);
2673e12c5d1SDavid du Colombier
2683e12c5d1SDavid du Colombier firstp = prg();
2693e12c5d1SDavid du Colombier lastp = firstp;
2703e12c5d1SDavid du Colombier
2713e12c5d1SDavid du Colombier xfol(textp);
2723e12c5d1SDavid du Colombier
2733e12c5d1SDavid du Colombier firstp = firstp->link;
2743e12c5d1SDavid du Colombier lastp->link = P;
2753e12c5d1SDavid du Colombier }
2763e12c5d1SDavid du Colombier
2773e12c5d1SDavid du Colombier void
xfol(Prog * p)2783e12c5d1SDavid du Colombier xfol(Prog *p)
2793e12c5d1SDavid du Colombier {
2803e12c5d1SDavid du Colombier Prog *q, *r;
2813e12c5d1SDavid du Colombier int a, b, i;
2823e12c5d1SDavid du Colombier
2833e12c5d1SDavid du Colombier loop:
2843e12c5d1SDavid du Colombier if(p == P)
2853e12c5d1SDavid du Colombier return;
2863e12c5d1SDavid du Colombier a = p->as;
2873e12c5d1SDavid du Colombier if(a == ATEXT)
2883e12c5d1SDavid du Colombier curtext = p;
2893e12c5d1SDavid du Colombier if(a == AJMP) {
2903e12c5d1SDavid du Colombier q = p->cond;
291219b2ee8SDavid du Colombier if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){
292219b2ee8SDavid du Colombier p->mark |= FOLL;
293219b2ee8SDavid du Colombier lastp->link = p;
294219b2ee8SDavid du Colombier lastp = p;
295219b2ee8SDavid du Colombier p = p->link;
296219b2ee8SDavid du Colombier xfol(p);
297219b2ee8SDavid du Colombier p = q;
298219b2ee8SDavid du Colombier if(p && !(p->mark & FOLL))
299219b2ee8SDavid du Colombier goto loop;
300219b2ee8SDavid du Colombier return;
301219b2ee8SDavid du Colombier }
3023e12c5d1SDavid du Colombier if(q != P) {
303219b2ee8SDavid du Colombier p->mark |= FOLL;
3043e12c5d1SDavid du Colombier p = q;
3053e12c5d1SDavid du Colombier if(!(p->mark & FOLL))
3063e12c5d1SDavid du Colombier goto loop;
3073e12c5d1SDavid du Colombier }
3083e12c5d1SDavid du Colombier }
3093e12c5d1SDavid du Colombier if(p->mark & FOLL) {
3103e12c5d1SDavid du Colombier for(i=0,q=p; i<4; i++,q=q->link) {
311219b2ee8SDavid du Colombier if(q == lastp || (q->mark&NOSCHED))
3123e12c5d1SDavid du Colombier break;
3133e12c5d1SDavid du Colombier b = 0; /* set */
3143e12c5d1SDavid du Colombier a = q->as;
3153e12c5d1SDavid du Colombier if(a == ANOP) {
3163e12c5d1SDavid du Colombier i--;
3173e12c5d1SDavid du Colombier continue;
3183e12c5d1SDavid du Colombier }
3193e12c5d1SDavid du Colombier if(a == AJMP || a == ARETURN || a == ARETT)
3203e12c5d1SDavid du Colombier goto copy;
3213e12c5d1SDavid du Colombier if(!q->cond || (q->cond->mark&FOLL))
3223e12c5d1SDavid du Colombier continue;
3233e12c5d1SDavid du Colombier b = relinv(a);
3243e12c5d1SDavid du Colombier if(!b)
3253e12c5d1SDavid du Colombier continue;
3263e12c5d1SDavid du Colombier copy:
3273e12c5d1SDavid du Colombier for(;;) {
3283e12c5d1SDavid du Colombier r = prg();
3293e12c5d1SDavid du Colombier *r = *p;
3303e12c5d1SDavid du Colombier if(!(r->mark&FOLL))
3313e12c5d1SDavid du Colombier print("cant happen 1\n");
332219b2ee8SDavid du Colombier r->mark |= FOLL;
3333e12c5d1SDavid du Colombier if(p != q) {
3343e12c5d1SDavid du Colombier p = p->link;
3353e12c5d1SDavid du Colombier lastp->link = r;
3363e12c5d1SDavid du Colombier lastp = r;
3373e12c5d1SDavid du Colombier continue;
3383e12c5d1SDavid du Colombier }
3393e12c5d1SDavid du Colombier lastp->link = r;
3403e12c5d1SDavid du Colombier lastp = r;
3413e12c5d1SDavid du Colombier if(a == AJMP || a == ARETURN || a == ARETT)
3423e12c5d1SDavid du Colombier return;
3433e12c5d1SDavid du Colombier r->as = b;
3443e12c5d1SDavid du Colombier r->cond = p->link;
3453e12c5d1SDavid du Colombier r->link = p->cond;
3463e12c5d1SDavid du Colombier if(!(r->link->mark&FOLL))
3473e12c5d1SDavid du Colombier xfol(r->link);
3483e12c5d1SDavid du Colombier if(!(r->cond->mark&FOLL))
3493e12c5d1SDavid du Colombier print("cant happen 2\n");
3503e12c5d1SDavid du Colombier return;
3513e12c5d1SDavid du Colombier }
3523e12c5d1SDavid du Colombier }
3533e12c5d1SDavid du Colombier
3543e12c5d1SDavid du Colombier a = AJMP;
3553e12c5d1SDavid du Colombier q = prg();
3563e12c5d1SDavid du Colombier q->as = a;
3573e12c5d1SDavid du Colombier q->line = p->line;
3583e12c5d1SDavid du Colombier q->to.type = D_BRANCH;
3593e12c5d1SDavid du Colombier q->to.offset = p->pc;
3603e12c5d1SDavid du Colombier q->cond = p;
3613e12c5d1SDavid du Colombier p = q;
3623e12c5d1SDavid du Colombier }
363219b2ee8SDavid du Colombier p->mark |= FOLL;
3643e12c5d1SDavid du Colombier lastp->link = p;
3653e12c5d1SDavid du Colombier lastp = p;
366219b2ee8SDavid du Colombier if(a == AJMP || a == ARETURN || a == ARETT){
367219b2ee8SDavid du Colombier if(p->mark & NOSCHED){
368219b2ee8SDavid du Colombier p = p->link;
369219b2ee8SDavid du Colombier goto loop;
370219b2ee8SDavid du Colombier }
3713e12c5d1SDavid du Colombier return;
372219b2ee8SDavid du Colombier }
3733e12c5d1SDavid du Colombier if(p->cond != P)
3743e12c5d1SDavid du Colombier if(a != AJMPL && p->link != P) {
3753e12c5d1SDavid du Colombier xfol(p->link);
3763e12c5d1SDavid du Colombier p = p->cond;
3773e12c5d1SDavid du Colombier if(p == P || (p->mark&FOLL))
3783e12c5d1SDavid du Colombier return;
3793e12c5d1SDavid du Colombier goto loop;
3803e12c5d1SDavid du Colombier }
3813e12c5d1SDavid du Colombier p = p->link;
3823e12c5d1SDavid du Colombier goto loop;
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier
3853e12c5d1SDavid du Colombier void
patch(void)3863e12c5d1SDavid du Colombier patch(void)
3873e12c5d1SDavid du Colombier {
3883e12c5d1SDavid du Colombier long c, vexit;
3893e12c5d1SDavid du Colombier Prog *p, *q;
3903e12c5d1SDavid du Colombier Sym *s;
3913e12c5d1SDavid du Colombier int a;
3923e12c5d1SDavid du Colombier
3933e12c5d1SDavid du Colombier if(debug['v'])
3943e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f patch\n", cputime());
3953e12c5d1SDavid du Colombier Bflush(&bso);
3963e12c5d1SDavid du Colombier mkfwd();
3973e12c5d1SDavid du Colombier s = lookup("exit", 0);
3983e12c5d1SDavid du Colombier vexit = s->value;
3993e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
4003e12c5d1SDavid du Colombier a = p->as;
4013e12c5d1SDavid du Colombier if(a == ATEXT)
4023e12c5d1SDavid du Colombier curtext = p;
403219b2ee8SDavid du Colombier if((a == AJMPL || a == ARETURN) && p->to.sym != S) {
4043e12c5d1SDavid du Colombier s = p->to.sym;
4053e12c5d1SDavid du Colombier if(s->type != STEXT) {
4066b6b9ac8SDavid du Colombier diag("undefined: %s\n%P", s->name, p);
4073e12c5d1SDavid du Colombier s->type = STEXT;
4083e12c5d1SDavid du Colombier s->value = vexit;
4093e12c5d1SDavid du Colombier }
4103e12c5d1SDavid du Colombier p->to.offset = s->value;
4113e12c5d1SDavid du Colombier p->to.type = D_BRANCH;
4123e12c5d1SDavid du Colombier }
4133e12c5d1SDavid du Colombier if(p->to.type != D_BRANCH)
4143e12c5d1SDavid du Colombier continue;
4153e12c5d1SDavid du Colombier c = p->to.offset;
4163e12c5d1SDavid du Colombier for(q = firstp; q != P;) {
4173e12c5d1SDavid du Colombier if(q->forwd != P)
4183e12c5d1SDavid du Colombier if(c >= q->forwd->pc) {
4193e12c5d1SDavid du Colombier q = q->forwd;
4203e12c5d1SDavid du Colombier continue;
4213e12c5d1SDavid du Colombier }
4223e12c5d1SDavid du Colombier if(c == q->pc)
4233e12c5d1SDavid du Colombier break;
4243e12c5d1SDavid du Colombier q = q->link;
4253e12c5d1SDavid du Colombier }
4263e12c5d1SDavid du Colombier if(q == P) {
4276b6b9ac8SDavid du Colombier diag("branch out of range %ld\n%P", c, p);
4283e12c5d1SDavid du Colombier p->to.type = D_NONE;
4293e12c5d1SDavid du Colombier }
4303e12c5d1SDavid du Colombier p->cond = q;
4313e12c5d1SDavid du Colombier }
4323e12c5d1SDavid du Colombier
4333e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
4343e12c5d1SDavid du Colombier if(p->as == ATEXT)
4353e12c5d1SDavid du Colombier curtext = p;
4363e12c5d1SDavid du Colombier if(p->cond != P) {
4373e12c5d1SDavid du Colombier p->cond = brloop(p->cond);
4383e12c5d1SDavid du Colombier if(p->cond != P)
4393e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH)
4403e12c5d1SDavid du Colombier p->to.offset = p->cond->pc;
4413e12c5d1SDavid du Colombier }
4423e12c5d1SDavid du Colombier }
4433e12c5d1SDavid du Colombier }
4443e12c5d1SDavid du Colombier
4453e12c5d1SDavid du Colombier #define LOG 5
4463e12c5d1SDavid du Colombier void
mkfwd(void)4473e12c5d1SDavid du Colombier mkfwd(void)
4483e12c5d1SDavid du Colombier {
4493e12c5d1SDavid du Colombier Prog *p;
4503e12c5d1SDavid du Colombier long dwn[LOG], cnt[LOG], i;
4513e12c5d1SDavid du Colombier Prog *lst[LOG];
4523e12c5d1SDavid du Colombier
4533e12c5d1SDavid du Colombier for(i=0; i<LOG; i++) {
4543e12c5d1SDavid du Colombier if(i == 0)
4553e12c5d1SDavid du Colombier cnt[i] = 1; else
4563e12c5d1SDavid du Colombier cnt[i] = LOG * cnt[i-1];
4573e12c5d1SDavid du Colombier dwn[i] = 1;
4583e12c5d1SDavid du Colombier lst[i] = P;
4593e12c5d1SDavid du Colombier }
4603e12c5d1SDavid du Colombier i = 0;
4613e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
4623e12c5d1SDavid du Colombier if(p->as == ATEXT)
4633e12c5d1SDavid du Colombier curtext = p;
4643e12c5d1SDavid du Colombier i--;
4653e12c5d1SDavid du Colombier if(i < 0)
4663e12c5d1SDavid du Colombier i = LOG-1;
4673e12c5d1SDavid du Colombier p->forwd = P;
4683e12c5d1SDavid du Colombier dwn[i]--;
4693e12c5d1SDavid du Colombier if(dwn[i] <= 0) {
4703e12c5d1SDavid du Colombier dwn[i] = cnt[i];
4713e12c5d1SDavid du Colombier if(lst[i] != P)
4723e12c5d1SDavid du Colombier lst[i]->forwd = p;
4733e12c5d1SDavid du Colombier lst[i] = p;
4743e12c5d1SDavid du Colombier }
4753e12c5d1SDavid du Colombier }
4763e12c5d1SDavid du Colombier }
4773e12c5d1SDavid du Colombier
4783e12c5d1SDavid du Colombier Prog*
brloop(Prog * p)4793e12c5d1SDavid du Colombier brloop(Prog *p)
4803e12c5d1SDavid du Colombier {
4813e12c5d1SDavid du Colombier Prog *q;
4823e12c5d1SDavid du Colombier int c;
4833e12c5d1SDavid du Colombier
4843e12c5d1SDavid du Colombier for(c=0; p!=P;) {
485219b2ee8SDavid du Colombier if(p->as != AJMP || (p->mark&NOSCHED))
4863e12c5d1SDavid du Colombier return p;
4873e12c5d1SDavid du Colombier q = p->cond;
4883e12c5d1SDavid du Colombier if(q <= p) {
4893e12c5d1SDavid du Colombier c++;
4907dd7cddfSDavid du Colombier if(q == p || c > 5000)
4913e12c5d1SDavid du Colombier break;
4923e12c5d1SDavid du Colombier }
4933e12c5d1SDavid du Colombier p = q;
4943e12c5d1SDavid du Colombier }
4953e12c5d1SDavid du Colombier return P;
4963e12c5d1SDavid du Colombier }
4973e12c5d1SDavid du Colombier
4983e12c5d1SDavid du Colombier long
atolwhex(char * s)4993e12c5d1SDavid du Colombier atolwhex(char *s)
5003e12c5d1SDavid du Colombier {
5013e12c5d1SDavid du Colombier long n;
5023e12c5d1SDavid du Colombier int f;
5033e12c5d1SDavid du Colombier
5043e12c5d1SDavid du Colombier n = 0;
5053e12c5d1SDavid du Colombier f = 0;
5063e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t')
5073e12c5d1SDavid du Colombier s++;
5083e12c5d1SDavid du Colombier if(*s == '-' || *s == '+') {
5093e12c5d1SDavid du Colombier if(*s++ == '-')
5103e12c5d1SDavid du Colombier f = 1;
5113e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t')
5123e12c5d1SDavid du Colombier s++;
5133e12c5d1SDavid du Colombier }
5143e12c5d1SDavid du Colombier if(s[0]=='0' && s[1]){
5153e12c5d1SDavid du Colombier if(s[1]=='x' || s[1]=='X'){
5163e12c5d1SDavid du Colombier s += 2;
5173e12c5d1SDavid du Colombier for(;;){
5183e12c5d1SDavid du Colombier if(*s >= '0' && *s <= '9')
5193e12c5d1SDavid du Colombier n = n*16 + *s++ - '0';
5203e12c5d1SDavid du Colombier else if(*s >= 'a' && *s <= 'f')
5213e12c5d1SDavid du Colombier n = n*16 + *s++ - 'a' + 10;
5223e12c5d1SDavid du Colombier else if(*s >= 'A' && *s <= 'F')
5233e12c5d1SDavid du Colombier n = n*16 + *s++ - 'A' + 10;
5243e12c5d1SDavid du Colombier else
5253e12c5d1SDavid du Colombier break;
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier } else
5283e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '7')
5293e12c5d1SDavid du Colombier n = n*8 + *s++ - '0';
5303e12c5d1SDavid du Colombier } else
5313e12c5d1SDavid du Colombier while(*s >= '0' && *s <= '9')
5323e12c5d1SDavid du Colombier n = n*10 + *s++ - '0';
5333e12c5d1SDavid du Colombier if(f)
5343e12c5d1SDavid du Colombier n = -n;
5353e12c5d1SDavid du Colombier return n;
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier
5383e12c5d1SDavid du Colombier long
rnd(long v,long r)5393e12c5d1SDavid du Colombier rnd(long v, long r)
5403e12c5d1SDavid du Colombier {
5413e12c5d1SDavid du Colombier long c;
5423e12c5d1SDavid du Colombier
5433e12c5d1SDavid du Colombier if(r <= 0)
5443e12c5d1SDavid du Colombier return v;
5453e12c5d1SDavid du Colombier v += r - 1;
5463e12c5d1SDavid du Colombier c = v % r;
5473e12c5d1SDavid du Colombier if(c < 0)
5483e12c5d1SDavid du Colombier c += r;
5493e12c5d1SDavid du Colombier v -= c;
5503e12c5d1SDavid du Colombier return v;
5513e12c5d1SDavid du Colombier }
552