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;
9
	long orig, 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
	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 R12)
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
 
67
	/*
68
	 * pass 2
69
	 *	assign large 'data' variables to data segment
70
	 */
71
	for(i=0; i<NHASH; i++)
72
	for(s = hash[i]; s != S; s = s->link) {
73
		t = s->type;
74
		if(t != SDATA) {
75
			if(t == SDATA1)
76
				s->type = SDATA;
77
			continue;
78
		}
79
		v = s->value;
80
		s->value = orig;
81
		orig += v;
82
	}
83
 
84
	while(orig & 7)
85
		orig++;
86
	datsize = orig;
87
 
88
	/*
89
	 * pass 3
90
	 *	everything else to bss segment
91
	 */
92
	for(i=0; i<NHASH; i++)
93
	for(s = hash[i]; s != S; s = s->link) {
94
		if(s->type != SBSS)
95
			continue;
96
		v = s->value;
97
		s->value = orig;
98
		orig += v;
99
	}
100
	while(orig & 7)
101
		orig++;
102
	bsssize = orig-datsize;
103
 
104
	xdefine("setR12", SDATA, 0L+BIG);
105
	xdefine("bdata", SDATA, 0L);
106
	xdefine("edata", SDATA, datsize);
107
	xdefine("end", SBSS, datsize+bsssize);
108
	xdefine("etext", STEXT, 0L);
109
}
110
 
111
void
112
undef(void)
113
{
114
	int i;
115
	Sym *s;
116
 
117
	for(i=0; i<NHASH; i++)
118
	for(s = hash[i]; s != S; s = s->link)
119
		if(s->type == SXREF)
120
			diag("%s: not defined", s->name);
121
}
122
 
123
Prog*
124
brchain(Prog *p)
125
{
126
	int i;
127
 
128
	for(i=0; i<20; i++) {
129
		if(p == P || p->as != AB)
130
			return p;
131
		p = p->cond;
132
	}
133
	return P;
134
}
135
 
136
int
137
relinv(int a)
138
{
139
	switch(a) {
140
	case ABEQ:	return ABNE;
141
	case ABNE:	return ABEQ;
142
	case ABCS:	return ABCC;
143
	case ABHS:	return ABLO;
144
	case ABCC:	return ABCS;
145
	case ABLO:	return ABHS;
146
	case ABMI:	return ABPL;
147
	case ABPL:	return ABMI;
148
	case ABVS:	return ABVC;
149
	case ABVC:	return ABVS;
150
	case ABHI:	return ABLS;
151
	case ABLS:	return ABHI;
152
	case ABGE:	return ABLT;
153
	case ABLT:	return ABGE;
154
	case ABGT:	return ABLE;
155
	case ABLE:	return ABGT;
156
	}
157
	diag("unknown relation: %s", anames[a]);
158
	return a;
159
}
160
 
161
void
162
follow(void)
163
{
164
	if(debug['v'])
165
		Bprint(&bso, "%5.2f follow\n", cputime());
166
	Bflush(&bso);
167
 
168
	firstp = prg();
169
	lastp = firstp;
170
	xfol(textp);
171
 
172
	firstp = firstp->link;
173
	lastp->link = P;
174
}
175
 
176
void
177
xfol(Prog *p)
178
{
179
	Prog *q, *r;
180
	int a, i;
181
 
182
loop:
183
	if(p == P)
184
		return;
185
	a = p->as;
186
	if(a == ATEXT)
187
		curtext = p;
188
	if(a == AB) {
189
		q = p->cond;
190
		if(q != P) {
191
			p->mark |= FOLL;
192
			p = q;
193
			if(!(p->mark & FOLL))
194
				goto loop;
195
		}
196
	}
197
	if(p->mark & FOLL) {
198
		for(i=0,q=p; i<4; i++,q=q->link) {
199
			if(q == lastp)
200
				break;
201
			a = q->as;
202
			if(a == ANOP) {
203
				i--;
204
				continue;
205
			}
206
			if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
207
				goto copy;
208
			if(!q->cond || (q->cond->mark&FOLL))
209
				continue;
210
			if(a != ABEQ && a != ABNE)
211
				continue;
212
		copy:
213
			for(;;) {
214
				r = prg();
215
				*r = *p;
216
				if(!(r->mark&FOLL))
217
					print("cant happen 1\n");
218
				r->mark |= FOLL;
219
				if(p != q) {
220
					p = p->link;
221
					lastp->link = r;
222
					lastp = r;
223
					continue;
224
				}
225
				lastp->link = r;
226
				lastp = r;
227
				if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
228
					return;
229
				r->as = ABNE;
230
				if(a == ABNE)
231
					r->as = ABEQ;
232
				r->cond = p->link;
233
				r->link = p->cond;
234
				if(!(r->link->mark&FOLL))
235
					xfol(r->link);
236
				if(!(r->cond->mark&FOLL))
237
					print("cant happen 2\n");
238
				return;
239
			}
240
		}
241
		a = AB;
242
		q = prg();
243
		q->as = a;
244
		q->line = p->line;
245
		q->to.type = D_BRANCH;
246
		q->to.offset = p->pc;
247
		q->cond = p;
248
		p = q;
249
	}
250
	p->mark |= FOLL;
251
	lastp->link = p;
252
	lastp = p;
253
	if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){
254
		return;
255
	}
256
	if(p->cond != P)
257
	if(a != ABL && p->link != P) {
258
		q = brchain(p->link);
259
		if(a != ATEXT && a != ABCASE)
260
		if(q != P && (q->mark&FOLL)) {
261
			p->as = relinv(a);
262
			p->link = p->cond;
263
			p->cond = q;
264
		}
265
		xfol(p->link);
266
		q = brchain(p->cond);
267
		if(q == P)
268
			q = p->cond;
269
		if(q->mark&FOLL) {
270
			p->cond = q;
271
			return;
272
		}
273
		p = q;
274
		goto loop;
275
	}
276
	p = p->link;
277
	goto loop;
278
}
279
 
280
void
281
patch(void)
282
{
283
	long c, vexit;
284
	Prog *p, *q;
285
	Sym *s;
286
	int a;
287
 
288
	if(debug['v'])
289
		Bprint(&bso, "%5.2f patch\n", cputime());
290
	Bflush(&bso);
291
	mkfwd();
292
	s = lookup("exit", 0);
293
	vexit = s->value;
294
	for(p = firstp; p != P; p = p->link) {
295
		a = p->as;
296
		if(a == ATEXT)
297
			curtext = p;
298
		if((a == ABL || a == AB || a == ARET) &&
299
		   p->to.type != D_BRANCH && p->to.sym != S) {
300
			s = p->to.sym;
301
			switch(s->type) {
302
			default:
303
				diag("undefined: %s\n%P", s->name, p);
304
				s->type = STEXT;
305
				s->value = vexit;
306
				break;
307
			case STEXT:
308
				p->to.offset = s->value;
309
				p->to.type = D_BRANCH;
310
				break;
311
			case SUNDEF:
312
				if(p->as != ABL)
313
					diag("help: SUNDEF in AB || ARET");
314
				p->to.offset = 0;
315
				p->to.type = D_BRANCH;
316
				p->cond = UP;
317
				break;
318
			}
319
		}
320
		if(p->to.type != D_BRANCH || p->cond == UP)
321
			continue;
322
		c = p->to.offset;
323
		for(q = firstp; q != P;) {
324
			if(q->forwd != P)
325
			if(c >= q->forwd->pc) {
326
				q = q->forwd;
327
				continue;
328
			}
329
			if(c == q->pc)
330
				break;
331
			q = q->link;
332
		}
333
		if(q == P) {
334
			diag("branch out of range %ld\n%P", c, p);
335
			p->to.type = D_NONE;
336
		}
337
		p->cond = q;
338
	}
339
 
340
	for(p = firstp; p != P; p = p->link) {
341
		if(p->as == ATEXT)
342
			curtext = p;
343
		if(p->cond != P && p->cond != UP) {
344
			p->cond = brloop(p->cond);
345
			if(p->cond != P)
346
			if(p->to.type == D_BRANCH)
347
				p->to.offset = p->cond->pc;
348
		}
349
	}
350
}
351
 
352
#define	LOG	5
353
void
354
mkfwd(void)
355
{
356
	Prog *p;
357
	long dwn[LOG], cnt[LOG], i;
358
	Prog *lst[LOG];
359
 
360
	for(i=0; i<LOG; i++) {
361
		if(i == 0)
362
			cnt[i] = 1; else
363
			cnt[i] = LOG * cnt[i-1];
364
		dwn[i] = 1;
365
		lst[i] = P;
366
	}
367
	i = 0;
368
	for(p = firstp; p != P; p = p->link) {
369
		if(p->as == ATEXT)
370
			curtext = p;
371
		i--;
372
		if(i < 0)
373
			i = LOG-1;
374
		p->forwd = P;
375
		dwn[i]--;
376
		if(dwn[i] <= 0) {
377
			dwn[i] = cnt[i];
378
			if(lst[i] != P)
379
				lst[i]->forwd = p;
380
			lst[i] = p;
381
		}
382
	}
383
}
384
 
385
Prog*
386
brloop(Prog *p)
387
{
388
	Prog *q;
389
	int c;
390
 
391
	for(c=0; p!=P;) {
392
		if(p->as != AB)
393
			return p;
394
		q = p->cond;
395
		if(q <= p) {
396
			c++;
397
			if(q == p || c > 5000)
398
				break;
399
		}
400
		p = q;
401
	}
402
	return P;
403
}
404
 
405
long
406
atolwhex(char *s)
407
{
408
	long n;
409
	int f;
410
 
411
	n = 0;
412
	f = 0;
413
	while(*s == ' ' || *s == '\t')
414
		s++;
415
	if(*s == '-' || *s == '+') {
416
		if(*s++ == '-')
417
			f = 1;
418
		while(*s == ' ' || *s == '\t')
419
			s++;
420
	}
421
	if(s[0]=='0' && s[1]){
422
		if(s[1]=='x' || s[1]=='X'){
423
			s += 2;
424
			for(;;){
425
				if(*s >= '0' && *s <= '9')
426
					n = n*16 + *s++ - '0';
427
				else if(*s >= 'a' && *s <= 'f')
428
					n = n*16 + *s++ - 'a' + 10;
429
				else if(*s >= 'A' && *s <= 'F')
430
					n = n*16 + *s++ - 'A' + 10;
431
				else
432
					break;
433
			}
434
		} else
435
			while(*s >= '0' && *s <= '7')
436
				n = n*8 + *s++ - '0';
437
	} else
438
		while(*s >= '0' && *s <= '9')
439
			n = n*10 + *s++ - '0';
440
	if(f)
441
		n = -n;
442
	return n;
443
}
444
 
445
long
446
rnd(long v, long r)
447
{
448
	long c;
449
 
450
	if(r <= 0)
451
		return v;
452
	v += r - 1;
453
	c = v % r;
454
	if(c < 0)
455
		c += r;
456
	v -= c;
457
	return v;
458
}
459
 
460
void
461
import(void)
462
{
463
	int i;
464
	Sym *s;
465
 
466
	for(i = 0; i < NHASH; i++)
467
		for(s = hash[i]; s != S; s = s->link)
468
			if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
469
				undefsym(s);
470
				Bprint(&bso, "IMPORT: %s sig=%lux v=%ld\n", s->name, s->sig, s->value);
471
			}
472
}
473
 
474
void
475
ckoff(Sym *s, long v)
476
{
477
	if(v < 0 || v >= 1<<Roffset)
478
		diag("relocation offset %ld for %s out of range", v, s->name);
479
}
480
 
481
static Prog*
482
newdata(Sym *s, int o, int w, int t)
483
{
484
	Prog *p;
485
 
486
	p = prg();
487
	p->link = datap;
488
	datap = p;
489
	p->as = ADATA;
490
	p->reg = w;
491
	p->from.type = D_OREG;
492
	p->from.name = t;
493
	p->from.sym = s;
494
	p->from.offset = o;
495
	p->to.type = D_CONST;
496
	p->to.name = D_NONE;
497
	return p;
498
}
499
 
500
void
501
export(void)
502
{
503
	int i, j, n, off, nb, sv, ne;
504
	Sym *s, *et, *str, **esyms;
505
	Prog *p;
506
	char buf[NSNAME], *t;
507
 
508
	n = 0;
509
	for(i = 0; i < NHASH; i++)
510
		for(s = hash[i]; s != S; s = s->link)
511
			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
512
				n++;
513
	esyms = malloc(n*sizeof(Sym*));
514
	ne = n;
515
	n = 0;
516
	for(i = 0; i < NHASH; i++)
517
		for(s = hash[i]; s != S; s = s->link)
518
			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
519
				esyms[n++] = s;
520
	for(i = 0; i < ne-1; i++)
521
		for(j = i+1; j < ne; j++)
522
			if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
523
				s = esyms[i];
524
				esyms[i] = esyms[j];
525
				esyms[j] = s;
526
			}
527
 
528
	nb = 0;
529
	off = 0;
530
	et = lookup(EXPTAB, 0);
531
	if(et->type != 0 && et->type != SXREF)
532
		diag("%s already defined", EXPTAB);
533
	et->type = SDATA;
534
	str = lookup(".string", 0);
535
	if(str->type == 0)
536
		str->type = SDATA;
537
	sv = str->value;
538
	for(i = 0; i < ne; i++){
539
		s = esyms[i];
540
		Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
541
 
542
		/* signature */
543
		p = newdata(et, off, sizeof(long), D_EXTERN);
544
		off += sizeof(long);
545
		p->to.offset = s->sig;
546
 
547
		/* address */
548
		p = newdata(et, off, sizeof(long), D_EXTERN);
549
		off += sizeof(long);
550
		p->to.name = D_EXTERN;
551
		p->to.sym = s;
552
 
553
		/* string */
554
		t = s->name;
555
		n = strlen(t)+1;
556
		for(;;){
557
			buf[nb++] = *t;
558
			sv++;
559
			if(nb >= NSNAME){
560
				p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
561
				p->to.type = D_SCONST;
562
				p->to.sval = malloc(NSNAME);
563
				memmove(p->to.sval, buf, NSNAME);
564
				nb = 0;
565
			}
566
			if(*t++ == 0)
567
				break;
568
		}
569
 
570
		/* name */
571
		p = newdata(et, off, sizeof(long), D_EXTERN);
572
		off += sizeof(long);
573
		p->to.name = D_STATIC;
574
		p->to.sym = str;
575
		p->to.offset = sv-n;
576
	}
577
 
578
	if(nb > 0){
579
		p = newdata(str, sv-nb, nb, D_STATIC);
580
		p->to.type = D_SCONST;
581
		p->to.sval = malloc(NSNAME);
582
		memmove(p->to.sval, buf, nb);
583
	}
584
 
585
	for(i = 0; i < 3; i++){
586
		newdata(et, off, sizeof(long), D_EXTERN);
587
		off += sizeof(long);
588
	}
589
	et->value = off;
590
	if(sv == 0)
591
		sv = 1;
592
	str->value = sv;
593
	exports = ne;
594
	free(esyms);
595
}