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