Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

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