1*fbadb1c4SDavid du Colombier #include "l.h"
2*fbadb1c4SDavid du Colombier
3*fbadb1c4SDavid du Colombier void
dodata(void)4*fbadb1c4SDavid du Colombier dodata(void)
5*fbadb1c4SDavid du Colombier {
6*fbadb1c4SDavid du Colombier int i, t;
7*fbadb1c4SDavid du Colombier Sym *s;
8*fbadb1c4SDavid du Colombier Prog *p, *p1;
9*fbadb1c4SDavid du Colombier vlong orig, orig1, v;
10*fbadb1c4SDavid du Colombier
11*fbadb1c4SDavid du Colombier if(debug['v'])
12*fbadb1c4SDavid du Colombier Bprint(&bso, "%5.2f dodata\n", cputime());
13*fbadb1c4SDavid du Colombier Bflush(&bso);
14*fbadb1c4SDavid du Colombier for(p = datap; p != P; p = p->link) {
15*fbadb1c4SDavid du Colombier s = p->from.sym;
16*fbadb1c4SDavid du Colombier if(p->as == ADYNT || p->as == AINIT)
17*fbadb1c4SDavid du Colombier s->value = dtype;
18*fbadb1c4SDavid du Colombier if(s->type == SBSS)
19*fbadb1c4SDavid du Colombier s->type = SDATA;
20*fbadb1c4SDavid du Colombier if(s->type != SDATA)
21*fbadb1c4SDavid du Colombier diag("initialize non-data (%d): %s\n%P",
22*fbadb1c4SDavid du Colombier s->type, s->name, p);
23*fbadb1c4SDavid du Colombier v = p->from.offset + p->reg;
24*fbadb1c4SDavid du Colombier if(v > s->value)
25*fbadb1c4SDavid du Colombier diag("initialize bounds (%lld): %s\n%P",
26*fbadb1c4SDavid du Colombier s->value, s->name, p);
27*fbadb1c4SDavid du Colombier }
28*fbadb1c4SDavid du Colombier
29*fbadb1c4SDavid du Colombier /*
30*fbadb1c4SDavid du Colombier * pass 1
31*fbadb1c4SDavid du Colombier * assign 'small' variables to data segment
32*fbadb1c4SDavid du Colombier * (rational is that data segment is more easily
33*fbadb1c4SDavid du Colombier * addressed through offset on REGSB)
34*fbadb1c4SDavid du Colombier */
35*fbadb1c4SDavid du Colombier orig = 0;
36*fbadb1c4SDavid du Colombier for(i=0; i<NHASH; i++)
37*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
38*fbadb1c4SDavid du Colombier t = s->type;
39*fbadb1c4SDavid du Colombier if(t != SDATA && t != SBSS)
40*fbadb1c4SDavid du Colombier continue;
41*fbadb1c4SDavid du Colombier v = s->value;
42*fbadb1c4SDavid du Colombier if(v == 0) {
43*fbadb1c4SDavid du Colombier diag("%s: no size", s->name);
44*fbadb1c4SDavid du Colombier v = 1;
45*fbadb1c4SDavid du Colombier }
46*fbadb1c4SDavid du Colombier v = rnd(v, 4);
47*fbadb1c4SDavid du Colombier s->value = v;
48*fbadb1c4SDavid du Colombier if(v > MINSIZ)
49*fbadb1c4SDavid du Colombier continue;
50*fbadb1c4SDavid du Colombier if(v >= 8)
51*fbadb1c4SDavid du Colombier orig = rnd(orig, 8);
52*fbadb1c4SDavid du Colombier s->value = orig;
53*fbadb1c4SDavid du Colombier orig += v;
54*fbadb1c4SDavid du Colombier s->type = SDATA1;
55*fbadb1c4SDavid du Colombier }
56*fbadb1c4SDavid du Colombier orig1 = orig;
57*fbadb1c4SDavid du Colombier
58*fbadb1c4SDavid du Colombier /*
59*fbadb1c4SDavid du Colombier * pass 2
60*fbadb1c4SDavid du Colombier * assign 'data' variables to data segment
61*fbadb1c4SDavid du Colombier */
62*fbadb1c4SDavid du Colombier for(i=0; i<NHASH; i++)
63*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
64*fbadb1c4SDavid du Colombier t = s->type;
65*fbadb1c4SDavid du Colombier if(t != SDATA) {
66*fbadb1c4SDavid du Colombier if(t == SDATA1)
67*fbadb1c4SDavid du Colombier s->type = SDATA;
68*fbadb1c4SDavid du Colombier continue;
69*fbadb1c4SDavid du Colombier }
70*fbadb1c4SDavid du Colombier v = s->value;
71*fbadb1c4SDavid du Colombier if(v >= 8)
72*fbadb1c4SDavid du Colombier orig = rnd(orig, 8);
73*fbadb1c4SDavid du Colombier s->value = orig;
74*fbadb1c4SDavid du Colombier orig += v;
75*fbadb1c4SDavid du Colombier s->type = SDATA1;
76*fbadb1c4SDavid du Colombier }
77*fbadb1c4SDavid du Colombier
78*fbadb1c4SDavid du Colombier if(orig)
79*fbadb1c4SDavid du Colombier orig = rnd(orig, 8);
80*fbadb1c4SDavid du Colombier datsize = orig;
81*fbadb1c4SDavid du Colombier
82*fbadb1c4SDavid du Colombier /*
83*fbadb1c4SDavid du Colombier * pass 3
84*fbadb1c4SDavid du Colombier * everything else to bss segment
85*fbadb1c4SDavid du Colombier */
86*fbadb1c4SDavid du Colombier for(i=0; i<NHASH; i++)
87*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
88*fbadb1c4SDavid du Colombier if(s->type != SBSS)
89*fbadb1c4SDavid du Colombier continue;
90*fbadb1c4SDavid du Colombier v = s->value;
91*fbadb1c4SDavid du Colombier if(v >= 8)
92*fbadb1c4SDavid du Colombier orig = rnd(orig, 8);
93*fbadb1c4SDavid du Colombier s->value = orig;
94*fbadb1c4SDavid du Colombier orig += v;
95*fbadb1c4SDavid du Colombier }
96*fbadb1c4SDavid du Colombier if(orig)
97*fbadb1c4SDavid du Colombier orig = rnd(orig, 8);
98*fbadb1c4SDavid du Colombier bsssize = orig-datsize;
99*fbadb1c4SDavid du Colombier
100*fbadb1c4SDavid du Colombier /*
101*fbadb1c4SDavid du Colombier * pass 4
102*fbadb1c4SDavid du Colombier * add literals to all large values.
103*fbadb1c4SDavid du Colombier * at this time:
104*fbadb1c4SDavid du Colombier * small data is allocated DATA
105*fbadb1c4SDavid du Colombier * large data is allocated DATA1
106*fbadb1c4SDavid du Colombier * large bss is allocated BSS
107*fbadb1c4SDavid du Colombier * the new literals are loaded between
108*fbadb1c4SDavid du Colombier * small data and large data.
109*fbadb1c4SDavid du Colombier */
110*fbadb1c4SDavid du Colombier orig = 0;
111*fbadb1c4SDavid du Colombier for(p = firstp; p != P; p = p->link) {
112*fbadb1c4SDavid du Colombier if(p->as != AMOVW)
113*fbadb1c4SDavid du Colombier continue;
114*fbadb1c4SDavid du Colombier if(p->from.type != D_CONST)
115*fbadb1c4SDavid du Colombier continue;
116*fbadb1c4SDavid du Colombier if(s = p->from.sym) {
117*fbadb1c4SDavid du Colombier t = s->type;
118*fbadb1c4SDavid du Colombier if(t != SDATA && t != SDATA1 && t != SBSS)
119*fbadb1c4SDavid du Colombier continue;
120*fbadb1c4SDavid du Colombier t = p->from.name;
121*fbadb1c4SDavid du Colombier if(t != D_EXTERN && t != D_STATIC)
122*fbadb1c4SDavid du Colombier continue;
123*fbadb1c4SDavid du Colombier v = s->value + p->from.offset;
124*fbadb1c4SDavid du Colombier if(v >= 0 && v <= 0xffff)
125*fbadb1c4SDavid du Colombier continue;
126*fbadb1c4SDavid du Colombier if(!strcmp(s->name, "setSB"))
127*fbadb1c4SDavid du Colombier continue;
128*fbadb1c4SDavid du Colombier /* size should be 19 max */
129*fbadb1c4SDavid du Colombier if(strlen(s->name) >= 10) /* has loader address */
130*fbadb1c4SDavid du Colombier sprint(literal, "$%p.%llux", s, p->from.offset);
131*fbadb1c4SDavid du Colombier else
132*fbadb1c4SDavid du Colombier sprint(literal, "$%s.%d.%llux", s->name, s->version, p->from.offset);
133*fbadb1c4SDavid du Colombier } else {
134*fbadb1c4SDavid du Colombier if(p->from.name != D_NONE)
135*fbadb1c4SDavid du Colombier continue;
136*fbadb1c4SDavid du Colombier if(p->from.reg != NREG)
137*fbadb1c4SDavid du Colombier continue;
138*fbadb1c4SDavid du Colombier v = p->from.offset;
139*fbadb1c4SDavid du Colombier if(v >= -0x7fff-1 && v <= 0x7fff)
140*fbadb1c4SDavid du Colombier continue;
141*fbadb1c4SDavid du Colombier if(!(v & 0xffff))
142*fbadb1c4SDavid du Colombier continue;
143*fbadb1c4SDavid du Colombier if(v)
144*fbadb1c4SDavid du Colombier continue; /* quicker to build it than load it */
145*fbadb1c4SDavid du Colombier /* size should be 9 max */
146*fbadb1c4SDavid du Colombier sprint(literal, "$%llux", v);
147*fbadb1c4SDavid du Colombier }
148*fbadb1c4SDavid du Colombier s = lookup(literal, 0);
149*fbadb1c4SDavid du Colombier if(s->type == 0) {
150*fbadb1c4SDavid du Colombier s->type = SDATA;
151*fbadb1c4SDavid du Colombier s->value = orig1+orig;
152*fbadb1c4SDavid du Colombier orig += 4;
153*fbadb1c4SDavid du Colombier p1 = prg();
154*fbadb1c4SDavid du Colombier p1->as = ADATA;
155*fbadb1c4SDavid du Colombier p1->line = p->line;
156*fbadb1c4SDavid du Colombier p1->from.type = D_OREG;
157*fbadb1c4SDavid du Colombier p1->from.sym = s;
158*fbadb1c4SDavid du Colombier p1->from.name = D_EXTERN;
159*fbadb1c4SDavid du Colombier p1->reg = 4;
160*fbadb1c4SDavid du Colombier p1->to = p->from;
161*fbadb1c4SDavid du Colombier p1->link = datap;
162*fbadb1c4SDavid du Colombier datap = p1;
163*fbadb1c4SDavid du Colombier }
164*fbadb1c4SDavid du Colombier if(s->type != SDATA)
165*fbadb1c4SDavid du Colombier diag("literal not data: %s", s->name);
166*fbadb1c4SDavid du Colombier p->from.type = D_OREG;
167*fbadb1c4SDavid du Colombier p->from.sym = s;
168*fbadb1c4SDavid du Colombier p->from.name = D_EXTERN;
169*fbadb1c4SDavid du Colombier p->from.offset = 0;
170*fbadb1c4SDavid du Colombier continue;
171*fbadb1c4SDavid du Colombier }
172*fbadb1c4SDavid du Colombier while(orig & 7)
173*fbadb1c4SDavid du Colombier orig++;
174*fbadb1c4SDavid du Colombier /*
175*fbadb1c4SDavid du Colombier * pass 5
176*fbadb1c4SDavid du Colombier * re-adjust offsets
177*fbadb1c4SDavid du Colombier */
178*fbadb1c4SDavid du Colombier for(i=0; i<NHASH; i++)
179*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
180*fbadb1c4SDavid du Colombier t = s->type;
181*fbadb1c4SDavid du Colombier if(t == SBSS) {
182*fbadb1c4SDavid du Colombier s->value += orig;
183*fbadb1c4SDavid du Colombier continue;
184*fbadb1c4SDavid du Colombier }
185*fbadb1c4SDavid du Colombier if(t == SDATA1) {
186*fbadb1c4SDavid du Colombier s->type = SDATA;
187*fbadb1c4SDavid du Colombier s->value += orig;
188*fbadb1c4SDavid du Colombier continue;
189*fbadb1c4SDavid du Colombier }
190*fbadb1c4SDavid du Colombier }
191*fbadb1c4SDavid du Colombier datsize += orig;
192*fbadb1c4SDavid du Colombier xdefine("setSB", SDATA, 0+BIG);
193*fbadb1c4SDavid du Colombier xdefine("bdata", SDATA, 0);
194*fbadb1c4SDavid du Colombier xdefine("edata", SDATA, datsize);
195*fbadb1c4SDavid du Colombier xdefine("end", SBSS, datsize+bsssize);
196*fbadb1c4SDavid du Colombier xdefine("etext", STEXT, 0);
197*fbadb1c4SDavid du Colombier }
198*fbadb1c4SDavid du Colombier
199*fbadb1c4SDavid du Colombier void
undef(void)200*fbadb1c4SDavid du Colombier undef(void)
201*fbadb1c4SDavid du Colombier {
202*fbadb1c4SDavid du Colombier int i;
203*fbadb1c4SDavid du Colombier Sym *s;
204*fbadb1c4SDavid du Colombier
205*fbadb1c4SDavid du Colombier for(i=0; i<NHASH; i++)
206*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
207*fbadb1c4SDavid du Colombier if(s->type == SXREF)
208*fbadb1c4SDavid du Colombier diag("%s: not defined", s->name);
209*fbadb1c4SDavid du Colombier }
210*fbadb1c4SDavid du Colombier
211*fbadb1c4SDavid du Colombier int
relinv(int a)212*fbadb1c4SDavid du Colombier relinv(int a)
213*fbadb1c4SDavid du Colombier {
214*fbadb1c4SDavid du Colombier
215*fbadb1c4SDavid du Colombier switch(a) {
216*fbadb1c4SDavid du Colombier case ABEQ: return ABNE;
217*fbadb1c4SDavid du Colombier case ABNE: return ABEQ;
218*fbadb1c4SDavid du Colombier
219*fbadb1c4SDavid du Colombier case ABGE: return ABLT;
220*fbadb1c4SDavid du Colombier case ABLT: return ABGE;
221*fbadb1c4SDavid du Colombier
222*fbadb1c4SDavid du Colombier case ABGT: return ABLE;
223*fbadb1c4SDavid du Colombier case ABLE: return ABGT;
224*fbadb1c4SDavid du Colombier
225*fbadb1c4SDavid du Colombier case ABVC: return ABVS;
226*fbadb1c4SDavid du Colombier case ABVS: return ABVC;
227*fbadb1c4SDavid du Colombier }
228*fbadb1c4SDavid du Colombier return 0;
229*fbadb1c4SDavid du Colombier }
230*fbadb1c4SDavid du Colombier
231*fbadb1c4SDavid du Colombier void
follow(void)232*fbadb1c4SDavid du Colombier follow(void)
233*fbadb1c4SDavid du Colombier {
234*fbadb1c4SDavid du Colombier
235*fbadb1c4SDavid du Colombier if(debug['v'])
236*fbadb1c4SDavid du Colombier Bprint(&bso, "%5.2f follow\n", cputime());
237*fbadb1c4SDavid du Colombier Bflush(&bso);
238*fbadb1c4SDavid du Colombier
239*fbadb1c4SDavid du Colombier firstp = prg();
240*fbadb1c4SDavid du Colombier lastp = firstp;
241*fbadb1c4SDavid du Colombier
242*fbadb1c4SDavid du Colombier xfol(textp);
243*fbadb1c4SDavid du Colombier
244*fbadb1c4SDavid du Colombier firstp = firstp->link;
245*fbadb1c4SDavid du Colombier lastp->link = P;
246*fbadb1c4SDavid du Colombier }
247*fbadb1c4SDavid du Colombier
248*fbadb1c4SDavid du Colombier void
xfol(Prog * p)249*fbadb1c4SDavid du Colombier xfol(Prog *p)
250*fbadb1c4SDavid du Colombier {
251*fbadb1c4SDavid du Colombier Prog *q, *r;
252*fbadb1c4SDavid du Colombier int a, b, i;
253*fbadb1c4SDavid du Colombier
254*fbadb1c4SDavid du Colombier loop:
255*fbadb1c4SDavid du Colombier if(p == P)
256*fbadb1c4SDavid du Colombier return;
257*fbadb1c4SDavid du Colombier a = p->as;
258*fbadb1c4SDavid du Colombier if(a == ATEXT)
259*fbadb1c4SDavid du Colombier curtext = p;
260*fbadb1c4SDavid du Colombier if(a == ABR) {
261*fbadb1c4SDavid du Colombier q = p->cond;
262*fbadb1c4SDavid du Colombier if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){
263*fbadb1c4SDavid du Colombier p->mark |= FOLL;
264*fbadb1c4SDavid du Colombier lastp->link = p;
265*fbadb1c4SDavid du Colombier lastp = p;
266*fbadb1c4SDavid du Colombier p = p->link;
267*fbadb1c4SDavid du Colombier xfol(p);
268*fbadb1c4SDavid du Colombier p = q;
269*fbadb1c4SDavid du Colombier if(p && !(p->mark & FOLL))
270*fbadb1c4SDavid du Colombier goto loop;
271*fbadb1c4SDavid du Colombier return;
272*fbadb1c4SDavid du Colombier }
273*fbadb1c4SDavid du Colombier if(q != P) {
274*fbadb1c4SDavid du Colombier p->mark |= FOLL;
275*fbadb1c4SDavid du Colombier p = q;
276*fbadb1c4SDavid du Colombier if(!(p->mark & FOLL))
277*fbadb1c4SDavid du Colombier goto loop;
278*fbadb1c4SDavid du Colombier }
279*fbadb1c4SDavid du Colombier }
280*fbadb1c4SDavid du Colombier if(p->mark & FOLL) {
281*fbadb1c4SDavid du Colombier for(i=0,q=p; i<4; i++,q=q->link) {
282*fbadb1c4SDavid du Colombier if(q == lastp || (q->mark&NOSCHED))
283*fbadb1c4SDavid du Colombier break;
284*fbadb1c4SDavid du Colombier b = 0; /* set */
285*fbadb1c4SDavid du Colombier a = q->as;
286*fbadb1c4SDavid du Colombier if(a == ANOP) {
287*fbadb1c4SDavid du Colombier i--;
288*fbadb1c4SDavid du Colombier continue;
289*fbadb1c4SDavid du Colombier }
290*fbadb1c4SDavid du Colombier if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
291*fbadb1c4SDavid du Colombier goto copy;
292*fbadb1c4SDavid du Colombier if(!q->cond || (q->cond->mark&FOLL))
293*fbadb1c4SDavid du Colombier continue;
294*fbadb1c4SDavid du Colombier b = relinv(a);
295*fbadb1c4SDavid du Colombier if(!b)
296*fbadb1c4SDavid du Colombier continue;
297*fbadb1c4SDavid du Colombier copy:
298*fbadb1c4SDavid du Colombier for(;;) {
299*fbadb1c4SDavid du Colombier r = prg();
300*fbadb1c4SDavid du Colombier *r = *p;
301*fbadb1c4SDavid du Colombier if(!(r->mark&FOLL))
302*fbadb1c4SDavid du Colombier print("cant happen 1\n");
303*fbadb1c4SDavid du Colombier r->mark |= FOLL;
304*fbadb1c4SDavid du Colombier if(p != q) {
305*fbadb1c4SDavid du Colombier p = p->link;
306*fbadb1c4SDavid du Colombier lastp->link = r;
307*fbadb1c4SDavid du Colombier lastp = r;
308*fbadb1c4SDavid du Colombier continue;
309*fbadb1c4SDavid du Colombier }
310*fbadb1c4SDavid du Colombier lastp->link = r;
311*fbadb1c4SDavid du Colombier lastp = r;
312*fbadb1c4SDavid du Colombier if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
313*fbadb1c4SDavid du Colombier return;
314*fbadb1c4SDavid du Colombier r->as = b;
315*fbadb1c4SDavid du Colombier r->cond = p->link;
316*fbadb1c4SDavid du Colombier r->link = p->cond;
317*fbadb1c4SDavid du Colombier if(!(r->link->mark&FOLL))
318*fbadb1c4SDavid du Colombier xfol(r->link);
319*fbadb1c4SDavid du Colombier if(!(r->cond->mark&FOLL))
320*fbadb1c4SDavid du Colombier print("cant happen 2\n");
321*fbadb1c4SDavid du Colombier return;
322*fbadb1c4SDavid du Colombier }
323*fbadb1c4SDavid du Colombier }
324*fbadb1c4SDavid du Colombier
325*fbadb1c4SDavid du Colombier a = ABR;
326*fbadb1c4SDavid du Colombier q = prg();
327*fbadb1c4SDavid du Colombier q->as = a;
328*fbadb1c4SDavid du Colombier q->line = p->line;
329*fbadb1c4SDavid du Colombier q->to.type = D_BRANCH;
330*fbadb1c4SDavid du Colombier q->to.offset = p->pc;
331*fbadb1c4SDavid du Colombier q->cond = p;
332*fbadb1c4SDavid du Colombier p = q;
333*fbadb1c4SDavid du Colombier }
334*fbadb1c4SDavid du Colombier p->mark |= FOLL;
335*fbadb1c4SDavid du Colombier lastp->link = p;
336*fbadb1c4SDavid du Colombier lastp = p;
337*fbadb1c4SDavid du Colombier if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID){
338*fbadb1c4SDavid du Colombier if(p->mark & NOSCHED){
339*fbadb1c4SDavid du Colombier p = p->link;
340*fbadb1c4SDavid du Colombier goto loop;
341*fbadb1c4SDavid du Colombier }
342*fbadb1c4SDavid du Colombier return;
343*fbadb1c4SDavid du Colombier }
344*fbadb1c4SDavid du Colombier if(p->cond != P)
345*fbadb1c4SDavid du Colombier if(a != ABL && p->link != P) {
346*fbadb1c4SDavid du Colombier xfol(p->link);
347*fbadb1c4SDavid du Colombier p = p->cond;
348*fbadb1c4SDavid du Colombier if(p == P || (p->mark&FOLL))
349*fbadb1c4SDavid du Colombier return;
350*fbadb1c4SDavid du Colombier goto loop;
351*fbadb1c4SDavid du Colombier }
352*fbadb1c4SDavid du Colombier p = p->link;
353*fbadb1c4SDavid du Colombier goto loop;
354*fbadb1c4SDavid du Colombier }
355*fbadb1c4SDavid du Colombier
356*fbadb1c4SDavid du Colombier void
patch(void)357*fbadb1c4SDavid du Colombier patch(void)
358*fbadb1c4SDavid du Colombier {
359*fbadb1c4SDavid du Colombier long c;
360*fbadb1c4SDavid du Colombier Prog *p, *q;
361*fbadb1c4SDavid du Colombier Sym *s;
362*fbadb1c4SDavid du Colombier int a;
363*fbadb1c4SDavid du Colombier vlong vexit;
364*fbadb1c4SDavid du Colombier
365*fbadb1c4SDavid du Colombier if(debug['v'])
366*fbadb1c4SDavid du Colombier Bprint(&bso, "%5.2f patch\n", cputime());
367*fbadb1c4SDavid du Colombier Bflush(&bso);
368*fbadb1c4SDavid du Colombier mkfwd();
369*fbadb1c4SDavid du Colombier s = lookup("exit", 0);
370*fbadb1c4SDavid du Colombier vexit = s->value;
371*fbadb1c4SDavid du Colombier for(p = firstp; p != P; p = p->link) {
372*fbadb1c4SDavid du Colombier a = p->as;
373*fbadb1c4SDavid du Colombier if(a == ATEXT)
374*fbadb1c4SDavid du Colombier curtext = p;
375*fbadb1c4SDavid du Colombier if((a == ABL || a == ARETURN) && p->to.sym != S) {
376*fbadb1c4SDavid du Colombier s = p->to.sym;
377*fbadb1c4SDavid du Colombier if(s->type != STEXT && s->type != SUNDEF) {
378*fbadb1c4SDavid du Colombier diag("undefined: %s\n%P", s->name, p);
379*fbadb1c4SDavid du Colombier s->type = STEXT;
380*fbadb1c4SDavid du Colombier s->value = vexit;
381*fbadb1c4SDavid du Colombier }
382*fbadb1c4SDavid du Colombier if(s->type == SUNDEF){
383*fbadb1c4SDavid du Colombier p->to.offset = 0;
384*fbadb1c4SDavid du Colombier p->cond = UP;
385*fbadb1c4SDavid du Colombier }
386*fbadb1c4SDavid du Colombier else
387*fbadb1c4SDavid du Colombier p->to.offset = s->value;
388*fbadb1c4SDavid du Colombier p->to.type = D_BRANCH;
389*fbadb1c4SDavid du Colombier }
390*fbadb1c4SDavid du Colombier if(p->to.type != D_BRANCH || p->cond == UP)
391*fbadb1c4SDavid du Colombier continue;
392*fbadb1c4SDavid du Colombier c = p->to.offset;
393*fbadb1c4SDavid du Colombier for(q = firstp; q != P;) {
394*fbadb1c4SDavid du Colombier if(q->forwd != P)
395*fbadb1c4SDavid du Colombier if(c >= q->forwd->pc) {
396*fbadb1c4SDavid du Colombier q = q->forwd;
397*fbadb1c4SDavid du Colombier continue;
398*fbadb1c4SDavid du Colombier }
399*fbadb1c4SDavid du Colombier if(c == q->pc)
400*fbadb1c4SDavid du Colombier break;
401*fbadb1c4SDavid du Colombier q = q->link;
402*fbadb1c4SDavid du Colombier }
403*fbadb1c4SDavid du Colombier if(q == P) {
404*fbadb1c4SDavid du Colombier diag("branch out of range %ld\n%P", c, p);
405*fbadb1c4SDavid du Colombier p->to.type = D_NONE;
406*fbadb1c4SDavid du Colombier }
407*fbadb1c4SDavid du Colombier p->cond = q;
408*fbadb1c4SDavid du Colombier }
409*fbadb1c4SDavid du Colombier
410*fbadb1c4SDavid du Colombier for(p = firstp; p != P; p = p->link) {
411*fbadb1c4SDavid du Colombier if(p->as == ATEXT)
412*fbadb1c4SDavid du Colombier curtext = p;
413*fbadb1c4SDavid du Colombier p->mark = 0; /* initialization for follow */
414*fbadb1c4SDavid du Colombier if(p->cond != P && p->cond != UP) {
415*fbadb1c4SDavid du Colombier p->cond = brloop(p->cond);
416*fbadb1c4SDavid du Colombier if(p->cond != P)
417*fbadb1c4SDavid du Colombier if(p->to.type == D_BRANCH)
418*fbadb1c4SDavid du Colombier p->to.offset = p->cond->pc;
419*fbadb1c4SDavid du Colombier }
420*fbadb1c4SDavid du Colombier }
421*fbadb1c4SDavid du Colombier }
422*fbadb1c4SDavid du Colombier
423*fbadb1c4SDavid du Colombier #define LOG 5
424*fbadb1c4SDavid du Colombier void
mkfwd(void)425*fbadb1c4SDavid du Colombier mkfwd(void)
426*fbadb1c4SDavid du Colombier {
427*fbadb1c4SDavid du Colombier Prog *p;
428*fbadb1c4SDavid du Colombier long dwn[LOG], cnt[LOG], i;
429*fbadb1c4SDavid du Colombier Prog *lst[LOG];
430*fbadb1c4SDavid du Colombier
431*fbadb1c4SDavid du Colombier for(i=0; i<LOG; i++) {
432*fbadb1c4SDavid du Colombier if(i == 0)
433*fbadb1c4SDavid du Colombier cnt[i] = 1; else
434*fbadb1c4SDavid du Colombier cnt[i] = LOG * cnt[i-1];
435*fbadb1c4SDavid du Colombier dwn[i] = 1;
436*fbadb1c4SDavid du Colombier lst[i] = P;
437*fbadb1c4SDavid du Colombier }
438*fbadb1c4SDavid du Colombier i = 0;
439*fbadb1c4SDavid du Colombier for(p = firstp; p != P; p = p->link) {
440*fbadb1c4SDavid du Colombier if(p->as == ATEXT)
441*fbadb1c4SDavid du Colombier curtext = p;
442*fbadb1c4SDavid du Colombier i--;
443*fbadb1c4SDavid du Colombier if(i < 0)
444*fbadb1c4SDavid du Colombier i = LOG-1;
445*fbadb1c4SDavid du Colombier p->forwd = P;
446*fbadb1c4SDavid du Colombier dwn[i]--;
447*fbadb1c4SDavid du Colombier if(dwn[i] <= 0) {
448*fbadb1c4SDavid du Colombier dwn[i] = cnt[i];
449*fbadb1c4SDavid du Colombier if(lst[i] != P)
450*fbadb1c4SDavid du Colombier lst[i]->forwd = p;
451*fbadb1c4SDavid du Colombier lst[i] = p;
452*fbadb1c4SDavid du Colombier }
453*fbadb1c4SDavid du Colombier }
454*fbadb1c4SDavid du Colombier }
455*fbadb1c4SDavid du Colombier
456*fbadb1c4SDavid du Colombier Prog*
brloop(Prog * p)457*fbadb1c4SDavid du Colombier brloop(Prog *p)
458*fbadb1c4SDavid du Colombier {
459*fbadb1c4SDavid du Colombier Prog *q;
460*fbadb1c4SDavid du Colombier int c;
461*fbadb1c4SDavid du Colombier
462*fbadb1c4SDavid du Colombier for(c=0; p!=P;) {
463*fbadb1c4SDavid du Colombier if(p->as != ABR || (p->mark&NOSCHED))
464*fbadb1c4SDavid du Colombier return p;
465*fbadb1c4SDavid du Colombier q = p->cond;
466*fbadb1c4SDavid du Colombier if(q <= p) {
467*fbadb1c4SDavid du Colombier c++;
468*fbadb1c4SDavid du Colombier if(q == p || c > 5000)
469*fbadb1c4SDavid du Colombier break;
470*fbadb1c4SDavid du Colombier }
471*fbadb1c4SDavid du Colombier p = q;
472*fbadb1c4SDavid du Colombier }
473*fbadb1c4SDavid du Colombier return P;
474*fbadb1c4SDavid du Colombier }
475*fbadb1c4SDavid du Colombier
476*fbadb1c4SDavid du Colombier vlong
atolwhex(char * s)477*fbadb1c4SDavid du Colombier atolwhex(char *s)
478*fbadb1c4SDavid du Colombier {
479*fbadb1c4SDavid du Colombier vlong n;
480*fbadb1c4SDavid du Colombier int f;
481*fbadb1c4SDavid du Colombier
482*fbadb1c4SDavid du Colombier n = 0;
483*fbadb1c4SDavid du Colombier f = 0;
484*fbadb1c4SDavid du Colombier while(*s == ' ' || *s == '\t')
485*fbadb1c4SDavid du Colombier s++;
486*fbadb1c4SDavid du Colombier if(*s == '-' || *s == '+') {
487*fbadb1c4SDavid du Colombier if(*s++ == '-')
488*fbadb1c4SDavid du Colombier f = 1;
489*fbadb1c4SDavid du Colombier while(*s == ' ' || *s == '\t')
490*fbadb1c4SDavid du Colombier s++;
491*fbadb1c4SDavid du Colombier }
492*fbadb1c4SDavid du Colombier if(s[0]=='0' && s[1]){
493*fbadb1c4SDavid du Colombier if(s[1]=='x' || s[1]=='X'){
494*fbadb1c4SDavid du Colombier s += 2;
495*fbadb1c4SDavid du Colombier for(;;){
496*fbadb1c4SDavid du Colombier if(*s >= '0' && *s <= '9')
497*fbadb1c4SDavid du Colombier n = n*16 + *s++ - '0';
498*fbadb1c4SDavid du Colombier else if(*s >= 'a' && *s <= 'f')
499*fbadb1c4SDavid du Colombier n = n*16 + *s++ - 'a' + 10;
500*fbadb1c4SDavid du Colombier else if(*s >= 'A' && *s <= 'F')
501*fbadb1c4SDavid du Colombier n = n*16 + *s++ - 'A' + 10;
502*fbadb1c4SDavid du Colombier else
503*fbadb1c4SDavid du Colombier break;
504*fbadb1c4SDavid du Colombier }
505*fbadb1c4SDavid du Colombier } else
506*fbadb1c4SDavid du Colombier while(*s >= '0' && *s <= '7')
507*fbadb1c4SDavid du Colombier n = n*8 + *s++ - '0';
508*fbadb1c4SDavid du Colombier } else
509*fbadb1c4SDavid du Colombier while(*s >= '0' && *s <= '9')
510*fbadb1c4SDavid du Colombier n = n*10 + *s++ - '0';
511*fbadb1c4SDavid du Colombier if(f)
512*fbadb1c4SDavid du Colombier n = -n;
513*fbadb1c4SDavid du Colombier return n;
514*fbadb1c4SDavid du Colombier }
515*fbadb1c4SDavid du Colombier
516*fbadb1c4SDavid du Colombier vlong
rnd(vlong v,long r)517*fbadb1c4SDavid du Colombier rnd(vlong v, long r)
518*fbadb1c4SDavid du Colombier {
519*fbadb1c4SDavid du Colombier vlong c;
520*fbadb1c4SDavid du Colombier
521*fbadb1c4SDavid du Colombier if(r <= 0)
522*fbadb1c4SDavid du Colombier return v;
523*fbadb1c4SDavid du Colombier v += r - 1;
524*fbadb1c4SDavid du Colombier c = v % r;
525*fbadb1c4SDavid du Colombier if(c < 0)
526*fbadb1c4SDavid du Colombier c += r;
527*fbadb1c4SDavid du Colombier v -= c;
528*fbadb1c4SDavid du Colombier return v;
529*fbadb1c4SDavid du Colombier }
530*fbadb1c4SDavid du Colombier
531*fbadb1c4SDavid du Colombier void
import(void)532*fbadb1c4SDavid du Colombier import(void)
533*fbadb1c4SDavid du Colombier {
534*fbadb1c4SDavid du Colombier int i;
535*fbadb1c4SDavid du Colombier Sym *s;
536*fbadb1c4SDavid du Colombier
537*fbadb1c4SDavid du Colombier for(i = 0; i < NHASH; i++)
538*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
539*fbadb1c4SDavid du Colombier if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
540*fbadb1c4SDavid du Colombier undefsym(s);
541*fbadb1c4SDavid du Colombier Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value);
542*fbadb1c4SDavid du Colombier if(debug['S'])
543*fbadb1c4SDavid du Colombier s->sig = 0;
544*fbadb1c4SDavid du Colombier }
545*fbadb1c4SDavid du Colombier }
546*fbadb1c4SDavid du Colombier
547*fbadb1c4SDavid du Colombier void
ckoff(Sym * s,vlong v)548*fbadb1c4SDavid du Colombier ckoff(Sym *s, vlong v)
549*fbadb1c4SDavid du Colombier {
550*fbadb1c4SDavid du Colombier if(v < 0 || v >= 1<<Roffset)
551*fbadb1c4SDavid du Colombier diag("relocation offset %lld for %s out of range", v, s->name);
552*fbadb1c4SDavid du Colombier }
553*fbadb1c4SDavid du Colombier
554*fbadb1c4SDavid du Colombier static Prog*
newdata(Sym * s,int o,int w,int t)555*fbadb1c4SDavid du Colombier newdata(Sym *s, int o, int w, int t)
556*fbadb1c4SDavid du Colombier {
557*fbadb1c4SDavid du Colombier Prog *p;
558*fbadb1c4SDavid du Colombier
559*fbadb1c4SDavid du Colombier p = prg();
560*fbadb1c4SDavid du Colombier p->link = datap;
561*fbadb1c4SDavid du Colombier datap = p;
562*fbadb1c4SDavid du Colombier p->as = ADATA;
563*fbadb1c4SDavid du Colombier p->reg = w;
564*fbadb1c4SDavid du Colombier p->from.type = D_OREG;
565*fbadb1c4SDavid du Colombier p->from.name = t;
566*fbadb1c4SDavid du Colombier p->from.sym = s;
567*fbadb1c4SDavid du Colombier p->from.offset = o;
568*fbadb1c4SDavid du Colombier p->to.type = D_CONST;
569*fbadb1c4SDavid du Colombier p->to.name = D_NONE;
570*fbadb1c4SDavid du Colombier return p;
571*fbadb1c4SDavid du Colombier }
572*fbadb1c4SDavid du Colombier
573*fbadb1c4SDavid du Colombier void
export(void)574*fbadb1c4SDavid du Colombier export(void)
575*fbadb1c4SDavid du Colombier {
576*fbadb1c4SDavid du Colombier int i, j, n, off, nb, sv, ne;
577*fbadb1c4SDavid du Colombier Sym *s, *et, *str, **esyms;
578*fbadb1c4SDavid du Colombier Prog *p;
579*fbadb1c4SDavid du Colombier char buf[NSNAME], *t;
580*fbadb1c4SDavid du Colombier
581*fbadb1c4SDavid du Colombier n = 0;
582*fbadb1c4SDavid du Colombier for(i = 0; i < NHASH; i++)
583*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
584*fbadb1c4SDavid du Colombier if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport))
585*fbadb1c4SDavid du Colombier n++;
586*fbadb1c4SDavid du Colombier esyms = malloc(n*sizeof(Sym*));
587*fbadb1c4SDavid du Colombier ne = n;
588*fbadb1c4SDavid du Colombier n = 0;
589*fbadb1c4SDavid du Colombier for(i = 0; i < NHASH; i++)
590*fbadb1c4SDavid du Colombier for(s = hash[i]; s != S; s = s->link)
591*fbadb1c4SDavid du Colombier if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport))
592*fbadb1c4SDavid du Colombier esyms[n++] = s;
593*fbadb1c4SDavid du Colombier for(i = 0; i < ne-1; i++)
594*fbadb1c4SDavid du Colombier for(j = i+1; j < ne; j++)
595*fbadb1c4SDavid du Colombier if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
596*fbadb1c4SDavid du Colombier s = esyms[i];
597*fbadb1c4SDavid du Colombier esyms[i] = esyms[j];
598*fbadb1c4SDavid du Colombier esyms[j] = s;
599*fbadb1c4SDavid du Colombier }
600*fbadb1c4SDavid du Colombier
601*fbadb1c4SDavid du Colombier nb = 0;
602*fbadb1c4SDavid du Colombier off = 0;
603*fbadb1c4SDavid du Colombier et = lookup(EXPTAB, 0);
604*fbadb1c4SDavid du Colombier if(et->type != 0 && et->type != SXREF)
605*fbadb1c4SDavid du Colombier diag("%s already defined", EXPTAB);
606*fbadb1c4SDavid du Colombier et->type = SDATA;
607*fbadb1c4SDavid du Colombier str = lookup(".string", 0);
608*fbadb1c4SDavid du Colombier if(str->type == 0)
609*fbadb1c4SDavid du Colombier str->type = SDATA;
610*fbadb1c4SDavid du Colombier sv = str->value;
611*fbadb1c4SDavid du Colombier for(i = 0; i < ne; i++){
612*fbadb1c4SDavid du Colombier s = esyms[i];
613*fbadb1c4SDavid du Colombier Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
614*fbadb1c4SDavid du Colombier
615*fbadb1c4SDavid du Colombier /* signature */
616*fbadb1c4SDavid du Colombier p = newdata(et, off, sizeof(long), D_EXTERN);
617*fbadb1c4SDavid du Colombier off += sizeof(long);
618*fbadb1c4SDavid du Colombier p->to.offset = s->sig;
619*fbadb1c4SDavid du Colombier
620*fbadb1c4SDavid du Colombier /* address */
621*fbadb1c4SDavid du Colombier p = newdata(et, off, sizeof(long), D_EXTERN);
622*fbadb1c4SDavid du Colombier off += sizeof(long); /* TO DO: bug */
623*fbadb1c4SDavid du Colombier p->to.name = D_EXTERN;
624*fbadb1c4SDavid du Colombier p->to.sym = s;
625*fbadb1c4SDavid du Colombier
626*fbadb1c4SDavid du Colombier /* string */
627*fbadb1c4SDavid du Colombier t = s->name;
628*fbadb1c4SDavid du Colombier n = strlen(t)+1;
629*fbadb1c4SDavid du Colombier for(;;){
630*fbadb1c4SDavid du Colombier buf[nb++] = *t;
631*fbadb1c4SDavid du Colombier sv++;
632*fbadb1c4SDavid du Colombier if(nb >= NSNAME){
633*fbadb1c4SDavid du Colombier p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
634*fbadb1c4SDavid du Colombier p->to.type = D_SCONST;
635*fbadb1c4SDavid du Colombier memmove(p->to.sval, buf, NSNAME);
636*fbadb1c4SDavid du Colombier nb = 0;
637*fbadb1c4SDavid du Colombier }
638*fbadb1c4SDavid du Colombier if(*t++ == 0)
639*fbadb1c4SDavid du Colombier break;
640*fbadb1c4SDavid du Colombier }
641*fbadb1c4SDavid du Colombier
642*fbadb1c4SDavid du Colombier /* name */
643*fbadb1c4SDavid du Colombier p = newdata(et, off, sizeof(long), D_EXTERN);
644*fbadb1c4SDavid du Colombier off += sizeof(long);
645*fbadb1c4SDavid du Colombier p->to.name = D_STATIC;
646*fbadb1c4SDavid du Colombier p->to.sym = str;
647*fbadb1c4SDavid du Colombier p->to.offset = sv-n;
648*fbadb1c4SDavid du Colombier }
649*fbadb1c4SDavid du Colombier
650*fbadb1c4SDavid du Colombier if(nb > 0){
651*fbadb1c4SDavid du Colombier p = newdata(str, sv-nb, nb, D_STATIC);
652*fbadb1c4SDavid du Colombier p->to.type = D_SCONST;
653*fbadb1c4SDavid du Colombier memmove(p->to.sval, buf, nb);
654*fbadb1c4SDavid du Colombier }
655*fbadb1c4SDavid du Colombier
656*fbadb1c4SDavid du Colombier for(i = 0; i < 3; i++){
657*fbadb1c4SDavid du Colombier newdata(et, off, sizeof(long), D_EXTERN);
658*fbadb1c4SDavid du Colombier off += sizeof(long);
659*fbadb1c4SDavid du Colombier }
660*fbadb1c4SDavid du Colombier et->value = off;
661*fbadb1c4SDavid du Colombier if(sv == 0)
662*fbadb1c4SDavid du Colombier sv = 1;
663*fbadb1c4SDavid du Colombier str->value = sv;
664*fbadb1c4SDavid du Colombier exports = ne;
665*fbadb1c4SDavid du Colombier free(esyms);
666*fbadb1c4SDavid du Colombier }
667