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