17dd7cddfSDavid du Colombier #include "l.h"
27dd7cddfSDavid du Colombier
37dd7cddfSDavid du Colombier void
dodata(void)47dd7cddfSDavid du Colombier dodata(void)
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier int i, t;
77dd7cddfSDavid du Colombier Sym *s;
87dd7cddfSDavid du Colombier Prog *p;
97dd7cddfSDavid du Colombier long orig, v;
107dd7cddfSDavid du Colombier
117dd7cddfSDavid du Colombier if(debug['v'])
127dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f dodata\n", cputime());
137dd7cddfSDavid du Colombier Bflush(&bso);
147dd7cddfSDavid du Colombier for(p = datap; p != P; p = p->link) {
157dd7cddfSDavid du Colombier s = p->from.sym;
167dd7cddfSDavid du Colombier if(p->as == ADYNT || p->as == AINIT)
177dd7cddfSDavid du Colombier s->value = dtype;
187dd7cddfSDavid du Colombier if(s->type == SBSS)
197dd7cddfSDavid du Colombier s->type = SDATA;
207dd7cddfSDavid du Colombier if(s->type != SDATA)
216b6b9ac8SDavid du Colombier diag("initialize non-data (%d): %s\n%P",
227dd7cddfSDavid du Colombier s->type, s->name, p);
237dd7cddfSDavid du Colombier v = p->from.offset + p->reg;
247dd7cddfSDavid du Colombier if(v > s->value)
256b6b9ac8SDavid du Colombier diag("initialize bounds (%ld): %s\n%P",
267dd7cddfSDavid du Colombier s->value, s->name, p);
277dd7cddfSDavid du Colombier }
287dd7cddfSDavid 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
407dd7cddfSDavid du Colombier /*
417dd7cddfSDavid du Colombier * pass 1
427dd7cddfSDavid du Colombier * assign 'small' variables to data segment
437dd7cddfSDavid du Colombier * (rational is that data segment is more easily
447dd7cddfSDavid du Colombier * addressed through offset on R12)
457dd7cddfSDavid du Colombier */
467dd7cddfSDavid du Colombier orig = 0;
477dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
487dd7cddfSDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
497dd7cddfSDavid du Colombier t = s->type;
507dd7cddfSDavid du Colombier if(t != SDATA && t != SBSS)
517dd7cddfSDavid du Colombier continue;
527dd7cddfSDavid du Colombier v = s->value;
537dd7cddfSDavid du Colombier if(v == 0) {
546b6b9ac8SDavid du Colombier diag("%s: no size", s->name);
557dd7cddfSDavid du Colombier v = 1;
567dd7cddfSDavid du Colombier }
577dd7cddfSDavid du Colombier while(v & 3)
587dd7cddfSDavid du Colombier v++;
597dd7cddfSDavid du Colombier s->value = v;
607dd7cddfSDavid du Colombier if(v > MINSIZ)
617dd7cddfSDavid du Colombier continue;
627dd7cddfSDavid du Colombier s->value = orig;
637dd7cddfSDavid du Colombier orig += v;
647dd7cddfSDavid du Colombier s->type = SDATA1;
657dd7cddfSDavid du Colombier }
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier /*
687dd7cddfSDavid du Colombier * pass 2
697dd7cddfSDavid du Colombier * assign large 'data' variables to data segment
707dd7cddfSDavid du Colombier */
717dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
727dd7cddfSDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
737dd7cddfSDavid du Colombier t = s->type;
747dd7cddfSDavid du Colombier if(t != SDATA) {
757dd7cddfSDavid du Colombier if(t == SDATA1)
767dd7cddfSDavid du Colombier s->type = SDATA;
777dd7cddfSDavid du Colombier continue;
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier v = s->value;
807dd7cddfSDavid du Colombier s->value = orig;
817dd7cddfSDavid du Colombier orig += v;
827dd7cddfSDavid du Colombier }
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier while(orig & 7)
857dd7cddfSDavid du Colombier orig++;
867dd7cddfSDavid du Colombier datsize = orig;
877dd7cddfSDavid du Colombier
887dd7cddfSDavid du Colombier /*
897dd7cddfSDavid du Colombier * pass 3
907dd7cddfSDavid du Colombier * everything else to bss segment
917dd7cddfSDavid du Colombier */
927dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
937dd7cddfSDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
947dd7cddfSDavid du Colombier if(s->type != SBSS)
957dd7cddfSDavid du Colombier continue;
967dd7cddfSDavid du Colombier v = s->value;
977dd7cddfSDavid du Colombier s->value = orig;
987dd7cddfSDavid du Colombier orig += v;
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier while(orig & 7)
1017dd7cddfSDavid du Colombier orig++;
1027dd7cddfSDavid du Colombier bsssize = orig-datsize;
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier xdefine("setR12", SDATA, 0L+BIG);
1057dd7cddfSDavid du Colombier xdefine("bdata", SDATA, 0L);
1067dd7cddfSDavid du Colombier xdefine("edata", SDATA, datsize);
1077dd7cddfSDavid du Colombier xdefine("end", SBSS, datsize+bsssize);
1087dd7cddfSDavid du Colombier xdefine("etext", STEXT, 0L);
1097dd7cddfSDavid du Colombier }
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier void
undef(void)1127dd7cddfSDavid du Colombier undef(void)
1137dd7cddfSDavid du Colombier {
1147dd7cddfSDavid du Colombier int i;
1157dd7cddfSDavid du Colombier Sym *s;
1167dd7cddfSDavid du Colombier
1177dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
1187dd7cddfSDavid du Colombier for(s = hash[i]; s != S; s = s->link)
1197dd7cddfSDavid du Colombier if(s->type == SXREF)
1206b6b9ac8SDavid du Colombier diag("%s: not defined", s->name);
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier
12359cc4ca5SDavid du Colombier Prog*
brchain(Prog * p)12459cc4ca5SDavid du Colombier brchain(Prog *p)
12559cc4ca5SDavid du Colombier {
12659cc4ca5SDavid du Colombier int i;
12759cc4ca5SDavid du Colombier
12859cc4ca5SDavid du Colombier for(i=0; i<20; i++) {
12959cc4ca5SDavid du Colombier if(p == P || p->as != AB)
13059cc4ca5SDavid du Colombier return p;
13159cc4ca5SDavid du Colombier p = p->cond;
13259cc4ca5SDavid du Colombier }
13359cc4ca5SDavid du Colombier return P;
13459cc4ca5SDavid du Colombier }
13559cc4ca5SDavid du Colombier
13659cc4ca5SDavid du Colombier int
relinv(int a)13759cc4ca5SDavid du Colombier relinv(int a)
13859cc4ca5SDavid du Colombier {
13959cc4ca5SDavid du Colombier switch(a) {
14059cc4ca5SDavid du Colombier case ABEQ: return ABNE;
14159cc4ca5SDavid du Colombier case ABNE: return ABEQ;
14259cc4ca5SDavid du Colombier case ABCS: return ABCC;
14359cc4ca5SDavid du Colombier case ABHS: return ABLO;
14459cc4ca5SDavid du Colombier case ABCC: return ABCS;
14559cc4ca5SDavid du Colombier case ABLO: return ABHS;
14659cc4ca5SDavid du Colombier case ABMI: return ABPL;
14759cc4ca5SDavid du Colombier case ABPL: return ABMI;
14859cc4ca5SDavid du Colombier case ABVS: return ABVC;
14959cc4ca5SDavid du Colombier case ABVC: return ABVS;
15059cc4ca5SDavid du Colombier case ABHI: return ABLS;
15159cc4ca5SDavid du Colombier case ABLS: return ABHI;
15259cc4ca5SDavid du Colombier case ABGE: return ABLT;
15359cc4ca5SDavid du Colombier case ABLT: return ABGE;
15459cc4ca5SDavid du Colombier case ABGT: return ABLE;
15559cc4ca5SDavid du Colombier case ABLE: return ABGT;
15659cc4ca5SDavid du Colombier }
1576b6b9ac8SDavid du Colombier diag("unknown relation: %s", anames[a]);
15859cc4ca5SDavid du Colombier return a;
15959cc4ca5SDavid du Colombier }
16059cc4ca5SDavid du Colombier
1617dd7cddfSDavid du Colombier void
follow(void)1627dd7cddfSDavid du Colombier follow(void)
1637dd7cddfSDavid du Colombier {
1647dd7cddfSDavid du Colombier if(debug['v'])
1657dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f follow\n", cputime());
1667dd7cddfSDavid du Colombier Bflush(&bso);
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier firstp = prg();
1697dd7cddfSDavid du Colombier lastp = firstp;
1707dd7cddfSDavid du Colombier xfol(textp);
1717dd7cddfSDavid du Colombier
1727dd7cddfSDavid du Colombier firstp = firstp->link;
1737dd7cddfSDavid du Colombier lastp->link = P;
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier void
xfol(Prog * p)1777dd7cddfSDavid du Colombier xfol(Prog *p)
1787dd7cddfSDavid du Colombier {
1797dd7cddfSDavid du Colombier Prog *q, *r;
1807dd7cddfSDavid du Colombier int a, i;
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier loop:
1837dd7cddfSDavid du Colombier if(p == P)
1847dd7cddfSDavid du Colombier return;
1857dd7cddfSDavid du Colombier a = p->as;
1867dd7cddfSDavid du Colombier if(a == ATEXT)
1877dd7cddfSDavid du Colombier curtext = p;
1887dd7cddfSDavid du Colombier if(a == AB) {
1897dd7cddfSDavid du Colombier q = p->cond;
1907dd7cddfSDavid du Colombier if(q != P) {
1917dd7cddfSDavid du Colombier p->mark |= FOLL;
1927dd7cddfSDavid du Colombier p = q;
1937dd7cddfSDavid du Colombier if(!(p->mark & FOLL))
1947dd7cddfSDavid du Colombier goto loop;
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier }
1977dd7cddfSDavid du Colombier if(p->mark & FOLL) {
1987dd7cddfSDavid du Colombier for(i=0,q=p; i<4; i++,q=q->link) {
1997dd7cddfSDavid du Colombier if(q == lastp)
2007dd7cddfSDavid du Colombier break;
2017dd7cddfSDavid du Colombier a = q->as;
2027dd7cddfSDavid du Colombier if(a == ANOP) {
2037dd7cddfSDavid du Colombier i--;
2047dd7cddfSDavid du Colombier continue;
2057dd7cddfSDavid du Colombier }
20659cc4ca5SDavid du Colombier if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
2077dd7cddfSDavid du Colombier goto copy;
2087dd7cddfSDavid du Colombier if(!q->cond || (q->cond->mark&FOLL))
2097dd7cddfSDavid du Colombier continue;
2107dd7cddfSDavid du Colombier if(a != ABEQ && a != ABNE)
2117dd7cddfSDavid du Colombier continue;
2127dd7cddfSDavid du Colombier copy:
2137dd7cddfSDavid du Colombier for(;;) {
2147dd7cddfSDavid du Colombier r = prg();
2157dd7cddfSDavid du Colombier *r = *p;
2167dd7cddfSDavid du Colombier if(!(r->mark&FOLL))
2177dd7cddfSDavid du Colombier print("cant happen 1\n");
2187dd7cddfSDavid du Colombier r->mark |= FOLL;
2197dd7cddfSDavid du Colombier if(p != q) {
2207dd7cddfSDavid du Colombier p = p->link;
2217dd7cddfSDavid du Colombier lastp->link = r;
2227dd7cddfSDavid du Colombier lastp = r;
2237dd7cddfSDavid du Colombier continue;
2247dd7cddfSDavid du Colombier }
2257dd7cddfSDavid du Colombier lastp->link = r;
2267dd7cddfSDavid du Colombier lastp = r;
22759cc4ca5SDavid du Colombier if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
2287dd7cddfSDavid du Colombier return;
2297dd7cddfSDavid du Colombier r->as = ABNE;
2307dd7cddfSDavid du Colombier if(a == ABNE)
2317dd7cddfSDavid du Colombier r->as = ABEQ;
2327dd7cddfSDavid du Colombier r->cond = p->link;
2337dd7cddfSDavid du Colombier r->link = p->cond;
2347dd7cddfSDavid du Colombier if(!(r->link->mark&FOLL))
2357dd7cddfSDavid du Colombier xfol(r->link);
2367dd7cddfSDavid du Colombier if(!(r->cond->mark&FOLL))
2377dd7cddfSDavid du Colombier print("cant happen 2\n");
2387dd7cddfSDavid du Colombier return;
2397dd7cddfSDavid du Colombier }
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier a = AB;
2427dd7cddfSDavid du Colombier q = prg();
2437dd7cddfSDavid du Colombier q->as = a;
2447dd7cddfSDavid du Colombier q->line = p->line;
2457dd7cddfSDavid du Colombier q->to.type = D_BRANCH;
2467dd7cddfSDavid du Colombier q->to.offset = p->pc;
2477dd7cddfSDavid du Colombier q->cond = p;
2487dd7cddfSDavid du Colombier p = q;
2497dd7cddfSDavid du Colombier }
2507dd7cddfSDavid du Colombier p->mark |= FOLL;
2517dd7cddfSDavid du Colombier lastp->link = p;
2527dd7cddfSDavid du Colombier lastp = p;
25359cc4ca5SDavid du Colombier if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){
2547dd7cddfSDavid du Colombier return;
2557dd7cddfSDavid du Colombier }
2567dd7cddfSDavid du Colombier if(p->cond != P)
2577dd7cddfSDavid du Colombier if(a != ABL && p->link != P) {
25859cc4ca5SDavid du Colombier q = brchain(p->link);
25959cc4ca5SDavid du Colombier if(a != ATEXT && a != ABCASE)
26059cc4ca5SDavid du Colombier if(q != P && (q->mark&FOLL)) {
26159cc4ca5SDavid du Colombier p->as = relinv(a);
26259cc4ca5SDavid du Colombier p->link = p->cond;
26359cc4ca5SDavid du Colombier p->cond = q;
26459cc4ca5SDavid du Colombier }
2657dd7cddfSDavid du Colombier xfol(p->link);
26659cc4ca5SDavid du Colombier q = brchain(p->cond);
26759cc4ca5SDavid du Colombier if(q == P)
26859cc4ca5SDavid du Colombier q = p->cond;
26959cc4ca5SDavid du Colombier if(q->mark&FOLL) {
27059cc4ca5SDavid du Colombier p->cond = q;
2717dd7cddfSDavid du Colombier return;
27259cc4ca5SDavid du Colombier }
27359cc4ca5SDavid du Colombier p = q;
2747dd7cddfSDavid du Colombier goto loop;
2757dd7cddfSDavid du Colombier }
2767dd7cddfSDavid du Colombier p = p->link;
2777dd7cddfSDavid du Colombier goto loop;
2787dd7cddfSDavid du Colombier }
2797dd7cddfSDavid du Colombier
2807dd7cddfSDavid du Colombier void
patch(void)2817dd7cddfSDavid du Colombier patch(void)
2827dd7cddfSDavid du Colombier {
2837dd7cddfSDavid du Colombier long c, vexit;
2847dd7cddfSDavid du Colombier Prog *p, *q;
2857dd7cddfSDavid du Colombier Sym *s;
2867dd7cddfSDavid du Colombier int a;
2877dd7cddfSDavid du Colombier
2887dd7cddfSDavid du Colombier if(debug['v'])
2897dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f patch\n", cputime());
2907dd7cddfSDavid du Colombier Bflush(&bso);
2917dd7cddfSDavid du Colombier mkfwd();
2927dd7cddfSDavid du Colombier s = lookup("exit", 0);
2937dd7cddfSDavid du Colombier vexit = s->value;
2947dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
2957dd7cddfSDavid du Colombier a = p->as;
2967dd7cddfSDavid du Colombier if(a == ATEXT)
2977dd7cddfSDavid du Colombier curtext = p;
2987dd7cddfSDavid du Colombier if((a == ABL || a == AB || a == ARET) &&
2997dd7cddfSDavid du Colombier p->to.type != D_BRANCH && p->to.sym != S) {
3007dd7cddfSDavid du Colombier s = p->to.sym;
301*375daca8SDavid du Colombier switch(s->type) {
302*375daca8SDavid du Colombier default:
3036b6b9ac8SDavid du Colombier diag("undefined: %s\n%P", s->name, p);
3047dd7cddfSDavid du Colombier s->type = STEXT;
3057dd7cddfSDavid du Colombier s->value = vexit;
306*375daca8SDavid du Colombier break;
307*375daca8SDavid du Colombier case STEXT:
3087dd7cddfSDavid du Colombier p->to.offset = s->value;
3097dd7cddfSDavid du Colombier p->to.type = D_BRANCH;
310*375daca8SDavid du Colombier break;
311*375daca8SDavid du Colombier case SUNDEF:
312*375daca8SDavid du Colombier if(p->as != ABL)
313*375daca8SDavid du Colombier diag("help: SUNDEF in AB || ARET");
314*375daca8SDavid du Colombier p->to.offset = 0;
315*375daca8SDavid du Colombier p->to.type = D_BRANCH;
316*375daca8SDavid du Colombier p->cond = UP;
317*375daca8SDavid du Colombier break;
3187dd7cddfSDavid du Colombier }
319*375daca8SDavid du Colombier }
320*375daca8SDavid du Colombier if(p->to.type != D_BRANCH || p->cond == UP)
3217dd7cddfSDavid du Colombier continue;
3227dd7cddfSDavid du Colombier c = p->to.offset;
3237dd7cddfSDavid du Colombier for(q = firstp; q != P;) {
3247dd7cddfSDavid du Colombier if(q->forwd != P)
3257dd7cddfSDavid du Colombier if(c >= q->forwd->pc) {
3267dd7cddfSDavid du Colombier q = q->forwd;
3277dd7cddfSDavid du Colombier continue;
3287dd7cddfSDavid du Colombier }
3297dd7cddfSDavid du Colombier if(c == q->pc)
3307dd7cddfSDavid du Colombier break;
3317dd7cddfSDavid du Colombier q = q->link;
3327dd7cddfSDavid du Colombier }
3337dd7cddfSDavid du Colombier if(q == P) {
3346b6b9ac8SDavid du Colombier diag("branch out of range %ld\n%P", c, p);
3357dd7cddfSDavid du Colombier p->to.type = D_NONE;
3367dd7cddfSDavid du Colombier }
3377dd7cddfSDavid du Colombier p->cond = q;
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier
3407dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
3417dd7cddfSDavid du Colombier if(p->as == ATEXT)
3427dd7cddfSDavid du Colombier curtext = p;
3439a747e4fSDavid du Colombier if(p->cond != P && p->cond != UP) {
3447dd7cddfSDavid du Colombier p->cond = brloop(p->cond);
3457dd7cddfSDavid du Colombier if(p->cond != P)
3467dd7cddfSDavid du Colombier if(p->to.type == D_BRANCH)
3477dd7cddfSDavid du Colombier p->to.offset = p->cond->pc;
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier }
3507dd7cddfSDavid du Colombier }
3517dd7cddfSDavid du Colombier
3527dd7cddfSDavid du Colombier #define LOG 5
3537dd7cddfSDavid du Colombier void
mkfwd(void)3547dd7cddfSDavid du Colombier mkfwd(void)
3557dd7cddfSDavid du Colombier {
3567dd7cddfSDavid du Colombier Prog *p;
3577dd7cddfSDavid du Colombier long dwn[LOG], cnt[LOG], i;
3587dd7cddfSDavid du Colombier Prog *lst[LOG];
3597dd7cddfSDavid du Colombier
3607dd7cddfSDavid du Colombier for(i=0; i<LOG; i++) {
3617dd7cddfSDavid du Colombier if(i == 0)
3627dd7cddfSDavid du Colombier cnt[i] = 1; else
3637dd7cddfSDavid du Colombier cnt[i] = LOG * cnt[i-1];
3647dd7cddfSDavid du Colombier dwn[i] = 1;
3657dd7cddfSDavid du Colombier lst[i] = P;
3667dd7cddfSDavid du Colombier }
3677dd7cddfSDavid du Colombier i = 0;
3687dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
3697dd7cddfSDavid du Colombier if(p->as == ATEXT)
3707dd7cddfSDavid du Colombier curtext = p;
3717dd7cddfSDavid du Colombier i--;
3727dd7cddfSDavid du Colombier if(i < 0)
3737dd7cddfSDavid du Colombier i = LOG-1;
3747dd7cddfSDavid du Colombier p->forwd = P;
3757dd7cddfSDavid du Colombier dwn[i]--;
3767dd7cddfSDavid du Colombier if(dwn[i] <= 0) {
3777dd7cddfSDavid du Colombier dwn[i] = cnt[i];
3787dd7cddfSDavid du Colombier if(lst[i] != P)
3797dd7cddfSDavid du Colombier lst[i]->forwd = p;
3807dd7cddfSDavid du Colombier lst[i] = p;
3817dd7cddfSDavid du Colombier }
3827dd7cddfSDavid du Colombier }
3837dd7cddfSDavid du Colombier }
3847dd7cddfSDavid du Colombier
3857dd7cddfSDavid du Colombier Prog*
brloop(Prog * p)3867dd7cddfSDavid du Colombier brloop(Prog *p)
3877dd7cddfSDavid du Colombier {
3887dd7cddfSDavid du Colombier Prog *q;
3897dd7cddfSDavid du Colombier int c;
3907dd7cddfSDavid du Colombier
3917dd7cddfSDavid du Colombier for(c=0; p!=P;) {
3927dd7cddfSDavid du Colombier if(p->as != AB)
3937dd7cddfSDavid du Colombier return p;
3947dd7cddfSDavid du Colombier q = p->cond;
3957dd7cddfSDavid du Colombier if(q <= p) {
3967dd7cddfSDavid du Colombier c++;
3977dd7cddfSDavid du Colombier if(q == p || c > 5000)
3987dd7cddfSDavid du Colombier break;
3997dd7cddfSDavid du Colombier }
4007dd7cddfSDavid du Colombier p = q;
4017dd7cddfSDavid du Colombier }
4027dd7cddfSDavid du Colombier return P;
4037dd7cddfSDavid du Colombier }
4047dd7cddfSDavid du Colombier
4057dd7cddfSDavid du Colombier long
atolwhex(char * s)4067dd7cddfSDavid du Colombier atolwhex(char *s)
4077dd7cddfSDavid du Colombier {
4087dd7cddfSDavid du Colombier long n;
4097dd7cddfSDavid du Colombier int f;
4107dd7cddfSDavid du Colombier
4117dd7cddfSDavid du Colombier n = 0;
4127dd7cddfSDavid du Colombier f = 0;
4137dd7cddfSDavid du Colombier while(*s == ' ' || *s == '\t')
4147dd7cddfSDavid du Colombier s++;
4157dd7cddfSDavid du Colombier if(*s == '-' || *s == '+') {
4167dd7cddfSDavid du Colombier if(*s++ == '-')
4177dd7cddfSDavid du Colombier f = 1;
4187dd7cddfSDavid du Colombier while(*s == ' ' || *s == '\t')
4197dd7cddfSDavid du Colombier s++;
4207dd7cddfSDavid du Colombier }
4217dd7cddfSDavid du Colombier if(s[0]=='0' && s[1]){
4227dd7cddfSDavid du Colombier if(s[1]=='x' || s[1]=='X'){
4237dd7cddfSDavid du Colombier s += 2;
4247dd7cddfSDavid du Colombier for(;;){
4257dd7cddfSDavid du Colombier if(*s >= '0' && *s <= '9')
4267dd7cddfSDavid du Colombier n = n*16 + *s++ - '0';
4277dd7cddfSDavid du Colombier else if(*s >= 'a' && *s <= 'f')
4287dd7cddfSDavid du Colombier n = n*16 + *s++ - 'a' + 10;
4297dd7cddfSDavid du Colombier else if(*s >= 'A' && *s <= 'F')
4307dd7cddfSDavid du Colombier n = n*16 + *s++ - 'A' + 10;
4317dd7cddfSDavid du Colombier else
4327dd7cddfSDavid du Colombier break;
4337dd7cddfSDavid du Colombier }
4347dd7cddfSDavid du Colombier } else
4357dd7cddfSDavid du Colombier while(*s >= '0' && *s <= '7')
4367dd7cddfSDavid du Colombier n = n*8 + *s++ - '0';
4377dd7cddfSDavid du Colombier } else
4387dd7cddfSDavid du Colombier while(*s >= '0' && *s <= '9')
4397dd7cddfSDavid du Colombier n = n*10 + *s++ - '0';
4407dd7cddfSDavid du Colombier if(f)
4417dd7cddfSDavid du Colombier n = -n;
4427dd7cddfSDavid du Colombier return n;
4437dd7cddfSDavid du Colombier }
4447dd7cddfSDavid du Colombier
4457dd7cddfSDavid du Colombier long
rnd(long v,long r)4467dd7cddfSDavid du Colombier rnd(long v, long r)
4477dd7cddfSDavid du Colombier {
4487dd7cddfSDavid du Colombier long c;
4497dd7cddfSDavid du Colombier
4507dd7cddfSDavid du Colombier if(r <= 0)
4517dd7cddfSDavid du Colombier return v;
4527dd7cddfSDavid du Colombier v += r - 1;
4537dd7cddfSDavid du Colombier c = v % r;
4547dd7cddfSDavid du Colombier if(c < 0)
4557dd7cddfSDavid du Colombier c += r;
4567dd7cddfSDavid du Colombier v -= c;
4577dd7cddfSDavid du Colombier return v;
4587dd7cddfSDavid du Colombier }
459*375daca8SDavid du Colombier
460*375daca8SDavid du Colombier void
import(void)461*375daca8SDavid du Colombier import(void)
462*375daca8SDavid du Colombier {
463*375daca8SDavid du Colombier int i;
464*375daca8SDavid du Colombier Sym *s;
465*375daca8SDavid du Colombier
466*375daca8SDavid du Colombier for(i = 0; i < NHASH; i++)
467*375daca8SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
468*375daca8SDavid du Colombier if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
469*375daca8SDavid du Colombier undefsym(s);
470*375daca8SDavid du Colombier Bprint(&bso, "IMPORT: %s sig=%lux v=%ld\n", s->name, s->sig, s->value);
471*375daca8SDavid du Colombier }
472*375daca8SDavid du Colombier }
473*375daca8SDavid du Colombier
474*375daca8SDavid du Colombier void
ckoff(Sym * s,long v)475*375daca8SDavid du Colombier ckoff(Sym *s, long v)
476*375daca8SDavid du Colombier {
477*375daca8SDavid du Colombier if(v < 0 || v >= 1<<Roffset)
478*375daca8SDavid du Colombier diag("relocation offset %ld for %s out of range", v, s->name);
479*375daca8SDavid du Colombier }
480*375daca8SDavid du Colombier
481*375daca8SDavid du Colombier static Prog*
newdata(Sym * s,int o,int w,int t)482*375daca8SDavid du Colombier newdata(Sym *s, int o, int w, int t)
483*375daca8SDavid du Colombier {
484*375daca8SDavid du Colombier Prog *p;
485*375daca8SDavid du Colombier
486*375daca8SDavid du Colombier p = prg();
487*375daca8SDavid du Colombier p->link = datap;
488*375daca8SDavid du Colombier datap = p;
489*375daca8SDavid du Colombier p->as = ADATA;
490*375daca8SDavid du Colombier p->reg = w;
491*375daca8SDavid du Colombier p->from.type = D_OREG;
492*375daca8SDavid du Colombier p->from.name = t;
493*375daca8SDavid du Colombier p->from.sym = s;
494*375daca8SDavid du Colombier p->from.offset = o;
495*375daca8SDavid du Colombier p->to.type = D_CONST;
496*375daca8SDavid du Colombier p->to.name = D_NONE;
497*375daca8SDavid du Colombier return p;
498*375daca8SDavid du Colombier }
499*375daca8SDavid du Colombier
500*375daca8SDavid du Colombier void
export(void)501*375daca8SDavid du Colombier export(void)
502*375daca8SDavid du Colombier {
503*375daca8SDavid du Colombier int i, j, n, off, nb, sv, ne;
504*375daca8SDavid du Colombier Sym *s, *et, *str, **esyms;
505*375daca8SDavid du Colombier Prog *p;
506*375daca8SDavid du Colombier char buf[NSNAME], *t;
507*375daca8SDavid du Colombier
508*375daca8SDavid du Colombier n = 0;
509*375daca8SDavid du Colombier for(i = 0; i < NHASH; i++)
510*375daca8SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
511*375daca8SDavid du Colombier if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
512*375daca8SDavid du Colombier n++;
513*375daca8SDavid du Colombier esyms = malloc(n*sizeof(Sym*));
514*375daca8SDavid du Colombier ne = n;
515*375daca8SDavid du Colombier n = 0;
516*375daca8SDavid du Colombier for(i = 0; i < NHASH; i++)
517*375daca8SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
518*375daca8SDavid du Colombier if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
519*375daca8SDavid du Colombier esyms[n++] = s;
520*375daca8SDavid du Colombier for(i = 0; i < ne-1; i++)
521*375daca8SDavid du Colombier for(j = i+1; j < ne; j++)
522*375daca8SDavid du Colombier if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
523*375daca8SDavid du Colombier s = esyms[i];
524*375daca8SDavid du Colombier esyms[i] = esyms[j];
525*375daca8SDavid du Colombier esyms[j] = s;
526*375daca8SDavid du Colombier }
527*375daca8SDavid du Colombier
528*375daca8SDavid du Colombier nb = 0;
529*375daca8SDavid du Colombier off = 0;
530*375daca8SDavid du Colombier et = lookup(EXPTAB, 0);
531*375daca8SDavid du Colombier if(et->type != 0 && et->type != SXREF)
532*375daca8SDavid du Colombier diag("%s already defined", EXPTAB);
533*375daca8SDavid du Colombier et->type = SDATA;
534*375daca8SDavid du Colombier str = lookup(".string", 0);
535*375daca8SDavid du Colombier if(str->type == 0)
536*375daca8SDavid du Colombier str->type = SDATA;
537*375daca8SDavid du Colombier sv = str->value;
538*375daca8SDavid du Colombier for(i = 0; i < ne; i++){
539*375daca8SDavid du Colombier s = esyms[i];
540*375daca8SDavid du Colombier Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
541*375daca8SDavid du Colombier
542*375daca8SDavid du Colombier /* signature */
543*375daca8SDavid du Colombier p = newdata(et, off, sizeof(long), D_EXTERN);
544*375daca8SDavid du Colombier off += sizeof(long);
545*375daca8SDavid du Colombier p->to.offset = s->sig;
546*375daca8SDavid du Colombier
547*375daca8SDavid du Colombier /* address */
548*375daca8SDavid du Colombier p = newdata(et, off, sizeof(long), D_EXTERN);
549*375daca8SDavid du Colombier off += sizeof(long);
550*375daca8SDavid du Colombier p->to.name = D_EXTERN;
551*375daca8SDavid du Colombier p->to.sym = s;
552*375daca8SDavid du Colombier
553*375daca8SDavid du Colombier /* string */
554*375daca8SDavid du Colombier t = s->name;
555*375daca8SDavid du Colombier n = strlen(t)+1;
556*375daca8SDavid du Colombier for(;;){
557*375daca8SDavid du Colombier buf[nb++] = *t;
558*375daca8SDavid du Colombier sv++;
559*375daca8SDavid du Colombier if(nb >= NSNAME){
560*375daca8SDavid du Colombier p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
561*375daca8SDavid du Colombier p->to.type = D_SCONST;
562*375daca8SDavid du Colombier p->to.sval = malloc(NSNAME);
563*375daca8SDavid du Colombier memmove(p->to.sval, buf, NSNAME);
564*375daca8SDavid du Colombier nb = 0;
565*375daca8SDavid du Colombier }
566*375daca8SDavid du Colombier if(*t++ == 0)
567*375daca8SDavid du Colombier break;
568*375daca8SDavid du Colombier }
569*375daca8SDavid du Colombier
570*375daca8SDavid du Colombier /* name */
571*375daca8SDavid du Colombier p = newdata(et, off, sizeof(long), D_EXTERN);
572*375daca8SDavid du Colombier off += sizeof(long);
573*375daca8SDavid du Colombier p->to.name = D_STATIC;
574*375daca8SDavid du Colombier p->to.sym = str;
575*375daca8SDavid du Colombier p->to.offset = sv-n;
576*375daca8SDavid du Colombier }
577*375daca8SDavid du Colombier
578*375daca8SDavid du Colombier if(nb > 0){
579*375daca8SDavid du Colombier p = newdata(str, sv-nb, nb, D_STATIC);
580*375daca8SDavid du Colombier p->to.type = D_SCONST;
581*375daca8SDavid du Colombier p->to.sval = malloc(NSNAME);
582*375daca8SDavid du Colombier memmove(p->to.sval, buf, nb);
583*375daca8SDavid du Colombier }
584*375daca8SDavid du Colombier
585*375daca8SDavid du Colombier for(i = 0; i < 3; i++){
586*375daca8SDavid du Colombier newdata(et, off, sizeof(long), D_EXTERN);
587*375daca8SDavid du Colombier off += sizeof(long);
588*375daca8SDavid du Colombier }
589*375daca8SDavid du Colombier et->value = off;
590*375daca8SDavid du Colombier if(sv == 0)
591*375daca8SDavid du Colombier sv = 1;
592*375daca8SDavid du Colombier str->value = sv;
593*375daca8SDavid du Colombier exports = ne;
594*375daca8SDavid du Colombier free(esyms);
595*375daca8SDavid du Colombier }
596