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
span(void)
5
{
6
	Prog *p;
7
	Sym *setext;
8
	Optab *o;
9
	int m;
10
	long c;
11
 
12
	if(debug['v'])
13
		Bprint(&bso, "%5.2f span\n", cputime());
14
	Bflush(&bso);
15
	c = INITTEXT;
16
	for(p = firstp; p != P; p = p->link) {
17
		p->pc = c;
18
		o = oplook(p);
19
		m = o->size;
20
		if(m == 0) {
21
			if(p->as == ATEXT) {
22
				curtext = p;
23
				autosize = p->to.offset + 4;
24
				if(p->from.sym != S)
25
					p->from.sym->value = c;
26
				continue;
27
			}
28
			if(p->as != ANOP)
29
				diag("zero-width instruction\n%P", p);
30
			continue;
31
		}
32
		c += m;
33
	}
34
	c = rnd(c, 8);
35
 
36
	setext = lookup("etext", 0);
37
	if(setext != S) {
38
		setext->value = c;
39
		textsize = c - INITTEXT;
40
	}
41
	if(INITRND)
42
		INITDAT = rnd(c, INITRND);
43
	if(debug['v'])
44
		Bprint(&bso, "tsize = %lux\n", textsize);
45
	Bflush(&bso);
46
}
47
 
48
void
49
xdefine(char *p, int t, long v)
50
{
51
	Sym *s;
52
 
53
	s = lookup(p, 0);
54
	if(s->type == 0 || s->type == SXREF) {
55
		s->type = t;
56
		s->value = v;
57
	}
58
}
59
 
60
long
61
regoff(Adr *a)
62
{
63
 
64
	instoffset = 0;
65
	aclass(a);
66
	return instoffset;
67
}
68
 
69
int
70
aclass(Adr *a)
71
{
72
	Sym *s;
73
	int t;
74
 
75
	switch(a->type) {
76
	case D_NONE:
77
		return C_NONE;
78
 
79
	case D_REG:
80
		return C_REG;
81
 
82
	case D_FREG:
83
		return C_FREG;
84
 
85
	case D_CREG:
86
		return C_CREG;
87
 
88
	case D_PREG:
89
		if(a->reg == D_FSR)
90
			return C_FSR;
91
		if(a->reg == D_FPQ)
92
			return C_FQ;
93
		return C_PREG;
94
 
95
	case D_OREG:
96
		switch(a->name) {
97
		case D_EXTERN:
98
		case D_STATIC:
99
			if(a->sym == S)
100
				break;
101
			t = a->sym->type;
102
			if(t == 0 || t == SXREF) {
103
				diag("undefined external: %s in %s",
104
					a->sym->name, TNAME);
105
				a->sym->type = SDATA;
106
			}
107
			instoffset = a->sym->value + a->offset - BIG;
108
			if(instoffset >= -BIG && instoffset < BIG) {
109
				if(instoffset & 7)
110
					return C_OSEXT;
111
				return C_ESEXT;
112
			}
113
			if(instoffset & 7)
114
				return C_OLEXT;
115
			return C_ELEXT;
116
		case D_AUTO:
117
			instoffset = autosize + a->offset;
118
			goto dauto;
119
 
120
		case D_PARAM:
121
			instoffset = autosize + a->offset + 4L;
122
		dauto:
123
			if(instoffset >= -BIG && instoffset < BIG) {
124
				if(instoffset & 7)
125
					return C_OSAUTO;
126
				return C_ESAUTO;
127
			}
128
			if(instoffset & 7)
129
				return C_OLAUTO;
130
			return C_ELAUTO;
131
		case D_NONE:
132
			instoffset = a->offset;
133
			if(instoffset == 0)
134
				return C_ZOREG;
135
			if(instoffset >= -BIG && instoffset < BIG)
136
				return C_SOREG;
137
			return C_LOREG;
138
		}
139
		return C_GOK;
140
 
141
	case D_ASI:
142
		if(a->name == D_NONE)
143
			return C_ASI;
144
		return C_GOK;
145
 
146
	case D_CONST:
147
		switch(a->name) {
148
 
149
		case D_NONE:
150
			instoffset = a->offset;
151
		consize:
152
			if(instoffset == 0)
153
				return C_ZCON;
154
			if(instoffset >= -0x1000 && instoffset <= 0xfff)
155
				return C_SCON;
156
			if((instoffset & 0x3ff) == 0)
157
				return C_UCON;
158
			return C_LCON;
159
 
160
		case D_EXTERN:
161
		case D_STATIC:
162
			s = a->sym;
163
			if(s == S)
164
				break;
165
			t = s->type;
166
			if(t == 0 || t == SXREF) {
167
				diag("undefined external: %s in %s",
168
					s->name, TNAME);
169
				s->type = SDATA;
170
			}
171
			if(s->type == STEXT || s->type == SLEAF) {
172
				instoffset = s->value + a->offset;
173
				return C_LCON;
174
			}
175
			if(s->type == SCONST) {
176
				instoffset = s->value + a->offset;
177
				goto consize;
178
			}
179
			instoffset = s->value + a->offset - BIG;
180
			if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
181
				return C_SECON;
182
			instoffset = s->value + a->offset + INITDAT;
183
/* not sure why this barfs */
184
return C_LCON;
185
/*
186
			if(instoffset == 0)
187
				return C_ZCON;
188
			if(instoffset >= -0x1000 && instoffset <= 0xfff)
189
				return C_SCON;
190
			if((instoffset & 0x3ff) == 0)
191
				return C_UCON;
192
			return C_LCON;
193
*/
194
 
195
		case D_AUTO:
196
			instoffset = autosize + a->offset;
197
			if(instoffset >= -BIG && instoffset < BIG)
198
				return C_SACON;
199
			return C_LACON;
200
 
201
		case D_PARAM:
202
			instoffset = autosize + a->offset + 4L;
203
			if(instoffset >= -BIG && instoffset < BIG)
204
				return C_SACON;
205
			return C_LACON;
206
		}
207
		return C_GOK;
208
 
209
	case D_BRANCH:
210
		return C_SBRA;
211
	}
212
	return C_GOK;
213
}
214
 
215
Optab*
216
oplook(Prog *p)
217
{
218
	int a1, a2, a3, r;
219
	char *c1, *c3;
220
	Optab *o, *e;
221
 
222
	a1 = p->optab;
223
	if(a1)
224
		return optab+(a1-1);
225
	a1 = p->from.class;
226
	if(a1 == 0) {
227
		a1 = aclass(&p->from) + 1;
228
		p->from.class = a1;
229
	}
230
	a1--;
231
	a3 = p->to.class;
232
	if(a3 == 0) {
233
		a3 = aclass(&p->to) + 1;
234
		p->to.class = a3;
235
	}
236
	a3--;
237
	a2 = C_NONE;
238
	if(p->reg != NREG)
239
		a2 = C_REG;
240
	r = p->as;
241
	o = oprange[r].start;
242
	if(o == 0)
243
		o = oprange[r].stop; /* just generate an error */
244
	e = oprange[r].stop;
245
	c1 = xcmp[a1];
246
	c3 = xcmp[a3];
247
	for(; o<e; o++)
248
		if(o->a2 == a2)
249
		if(c1[o->a1])
250
		if(c3[o->a3]) {
251
			p->optab = (o-optab)+1;
252
			return o;
253
		}
254
	diag("illegal combination %A %d %d %d",
255
		p->as, a1, a2, a3);
256
	if(1||!debug['a'])
257
		prasm(p);
258
	if(o == 0)
259
		errorexit();
260
	return o;
261
}
262
 
263
int
264
cmp(int a, int b)
265
{
266
 
267
	if(a == b)
268
		return 1;
269
	switch(a) {
270
	case C_LCON:
271
		if(b == C_ZCON || b == C_SCON || b == C_UCON)
272
			return 1;
273
		break;
274
	case C_UCON:
275
		if(b == C_ZCON)
276
			return 1;
277
		break;
278
	case C_SCON:
279
		if(b == C_ZCON)
280
			return 1;
281
		break;
282
	case C_LACON:
283
		if(b == C_SACON)
284
			return 1;
285
		break;
286
	case C_LBRA:
287
		if(b == C_SBRA)
288
			return 1;
289
		break;
290
	case C_ELEXT:
291
		if(b == C_ESEXT)
292
			return 1;
293
		break;
294
	case C_LEXT:
295
		if(b == C_SEXT ||
296
		   b == C_ESEXT || b == C_OSEXT ||
297
		   b == C_ELEXT || b == C_OLEXT)
298
			return 1;
299
		break;
300
	case C_SEXT:
301
		if(b == C_ESEXT || b == C_OSEXT)
302
			return 1;
303
		break;
304
	case C_ELAUTO:
305
		if(b == C_ESAUTO)
306
			return 1;
307
		break;
308
	case C_LAUTO:
309
		if(b == C_SAUTO ||
310
		   b == C_ESAUTO || b == C_OSAUTO ||
311
		   b == C_ELAUTO || b == C_OLAUTO)
312
			return 1;
313
		break;
314
	case C_SAUTO:
315
		if(b == C_ESAUTO || b == C_OSAUTO)
316
			return 1;
317
		break;
318
	case C_REG:
319
		if(b == C_ZCON)
320
			return 1;
321
		break;
322
	case C_LOREG:
323
		if(b == C_ZOREG || b == C_SOREG)
324
			return 1;
325
		break;
326
	case C_SOREG:
327
		if(b == C_ZOREG)
328
			return 1;
329
		break;
330
 
331
	case C_ANY:
332
		return 1;
333
	}
334
	return 0;
335
}
336
 
337
int
338
ocmp(const void *a1, const void *a2)
339
{
340
	Optab *p1, *p2;
341
	int n;
342
 
343
	p1 = (Optab*)a1;
344
	p2 = (Optab*)a2;
345
	n = p1->as - p2->as;
346
	if(n)
347
		return n;
348
	n = p1->a1 - p2->a1;
349
	if(n)
350
		return n;
351
	n = p1->a2 - p2->a2;
352
	if(n)
353
		return n;
354
	n = p1->a3 - p2->a3;
355
	if(n)
356
		return n;
357
	return 0;
358
}
359
 
360
void
361
buildop(void)
362
{
363
	int i, n, r;
364
 
365
	for(i=0; i<C_NCLASS; i++)
366
		for(n=0; n<C_NCLASS; n++)
367
			xcmp[i][n] = cmp(n, i);
368
	for(n=0; optab[n].as != AXXX; n++)
369
		;
370
	qsort(optab, n, sizeof(optab[0]), ocmp);
371
	for(i=0; i<n; i++) {
372
		r = optab[i].as;
373
		oprange[r].start = optab+i;
374
		while(optab[i].as == r)
375
			i++;
376
		oprange[r].stop = optab+i;
377
		i--;
378
 
379
		switch(r)
380
		{
381
		default:
382
			diag("unknown op in build: %A", r);
383
			errorexit();
384
		case AADD:
385
			oprange[AADDX] = oprange[r];
386
			oprange[ASUB] = oprange[r];
387
			oprange[ASUBX] = oprange[r];
388
			oprange[AMUL] = oprange[r];
389
			oprange[AXOR] = oprange[r];
390
			oprange[AXNOR] = oprange[r];
391
			oprange[AAND] = oprange[r];
392
			oprange[AANDN] = oprange[r];
393
			oprange[AOR] = oprange[r];
394
			oprange[AORN] = oprange[r];
395
			oprange[ASLL] = oprange[r];
396
			oprange[ASRL] = oprange[r];
397
			oprange[ASRA] = oprange[r];
398
			oprange[AADDCC] = oprange[r];
399
			oprange[AADDXCC] = oprange[r];
400
			oprange[ATADDCC] = oprange[r];
401
			oprange[ATADDCCTV] = oprange[r];
402
			oprange[ASUBCC] = oprange[r];
403
			oprange[ASUBXCC] = oprange[r];
404
			oprange[ATSUBCC] = oprange[r];
405
			oprange[ATSUBCCTV] = oprange[r];
406
			oprange[AXORCC] = oprange[r];
407
			oprange[AXNORCC] = oprange[r];
408
			oprange[AANDCC] = oprange[r];
409
			oprange[AANDNCC] = oprange[r];
410
			oprange[AORCC] = oprange[r];
411
			oprange[AORNCC] = oprange[r];
412
			oprange[AMULSCC] = oprange[r];
413
			oprange[ASAVE] = oprange[r];
414
			oprange[ARESTORE] = oprange[r];
415
			break;
416
		case AMOVB:
417
			oprange[AMOVH] = oprange[r];
418
			oprange[AMOVHU] = oprange[r];
419
			oprange[AMOVBU] = oprange[r];
420
			oprange[ASWAP] = oprange[r];
421
			oprange[ATAS] = oprange[r];
422
			break;
423
		case ABA:
424
			oprange[ABN] = oprange[r];
425
			oprange[AFBA] = oprange[r];
426
			oprange[AFBN] = oprange[r];
427
			break;
428
		case ABE:
429
			oprange[ABCC] = oprange[r];
430
			oprange[ABCS] = oprange[r];
431
			oprange[ABGE] = oprange[r];
432
			oprange[ABGU] = oprange[r];
433
			oprange[ABG] = oprange[r];
434
			oprange[ABLEU] = oprange[r];
435
			oprange[ABLE] = oprange[r];
436
			oprange[ABL] = oprange[r];
437
			oprange[ABNEG] = oprange[r];
438
			oprange[ABNE] = oprange[r];
439
			oprange[ABPOS] = oprange[r];
440
			oprange[ABVC] = oprange[r];
441
			oprange[ABVS] = oprange[r];
442
 
443
			oprange[AFBE] = oprange[r];
444
			oprange[AFBG] = oprange[r];
445
			oprange[AFBGE] = oprange[r];
446
			oprange[AFBL] = oprange[r];
447
			oprange[AFBLE] = oprange[r];
448
			oprange[AFBLG] = oprange[r];
449
			oprange[AFBNE] = oprange[r];
450
			oprange[AFBO] = oprange[r];
451
			oprange[AFBU] = oprange[r];
452
			oprange[AFBUE] = oprange[r];
453
			oprange[AFBUG] = oprange[r];
454
			oprange[AFBUGE] = oprange[r];
455
			oprange[AFBUL] = oprange[r];
456
			oprange[AFBULE] = oprange[r];
457
			break;
458
		case ATA:
459
			oprange[ATCC] = oprange[r];
460
			oprange[ATCS] = oprange[r];
461
			oprange[ATE] = oprange[r];
462
			oprange[ATGE] = oprange[r];
463
			oprange[ATGU] = oprange[r];
464
			oprange[ATG] = oprange[r];
465
			oprange[ATLEU] = oprange[r];
466
			oprange[ATLE] = oprange[r];
467
			oprange[ATL] = oprange[r];
468
			oprange[ATNEG] = oprange[r];
469
			oprange[ATNE] = oprange[r];
470
			oprange[ATN] = oprange[r];
471
			oprange[ATPOS] = oprange[r];
472
			oprange[ATVC] = oprange[r];
473
			oprange[ATVS] = oprange[r];
474
			break;
475
		case AFADDD:
476
			oprange[AFADDF] = oprange[r];
477
			oprange[AFADDX] = oprange[r];
478
			oprange[AFDIVD] = oprange[r];
479
			oprange[AFDIVF] = oprange[r];
480
			oprange[AFDIVX] = oprange[r];
481
			oprange[AFMULD] = oprange[r];
482
			oprange[AFMULF] = oprange[r];
483
			oprange[AFMULX] = oprange[r];
484
			oprange[AFSUBD] = oprange[r];
485
			oprange[AFSUBF] = oprange[r];
486
			oprange[AFSUBX] = oprange[r];
487
			break;
488
		case AFCMPD:
489
			oprange[AFCMPF] = oprange[r];
490
			oprange[AFCMPX] = oprange[r];
491
			oprange[AFCMPED] = oprange[r];
492
			oprange[AFCMPEF] = oprange[r];
493
			oprange[AFCMPEX] = oprange[r];
494
			break;
495
		case AFABSF:
496
			oprange[AFMOVDF] = oprange[r];
497
			oprange[AFMOVDW] = oprange[r];
498
			oprange[AFMOVFD] = oprange[r];
499
			oprange[AFMOVFW] = oprange[r];
500
			oprange[AFMOVWD] = oprange[r];
501
			oprange[AFMOVWF] = oprange[r];
502
			oprange[AFNEGF] = oprange[r];
503
			oprange[AFSQRTD] = oprange[r];
504
			oprange[AFSQRTF] = oprange[r];
505
			break;
506
		case AFMOVF:
507
		case AFMOVD:
508
		case AMOVW:
509
		case AMOVD:
510
		case AWORD:
511
		case ARETT:
512
		case AJMPL:
513
		case AJMP:
514
		case ACMP:
515
		case ANOP:
516
		case ATEXT:
517
		case ADIV:
518
		case ADIVL:
519
		case AMOD:
520
		case AMODL:
521
			break;
522
		}
523
	}
524
}