Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"l.h"
2
#define	r0iszero	1
3
 
4
void
5
span(void)
6
{
7
	Prog *p, *q;
8
	Sym *setext;
9
	Optab *o;
10
	int m, bflag;
11
	long c, otxt;
12
 
13
	if(debug['v'])
14
		Bprint(&bso, "%5.2f span\n", cputime());
15
	Bflush(&bso);
16
 
17
	bflag = 0;
18
	c = INITTEXT;
19
	otxt = c;
20
	for(p = firstp; p != P; p = p->link) {
21
		p->pc = c;
22
		o = oplook(p);
23
		m = o->size;
24
		if(m == 0) {
25
			if(p->as == ATEXT) {
26
				curtext = p;
27
				autosize = p->to.offset + 4;
28
				if(p->from3.type == D_CONST) {
29
					if(p->from3.offset & 3)
30
						diag("illegal origin\n%P", p);
31
					if(c > p->from3.offset)
32
						diag("passed origin (#%lux)\n%P", c, p);
33
					else
34
						c = p->from3.offset;
35
					p->pc = c;
36
				}
37
				if(p->from.sym != S)
38
					p->from.sym->value = c;
39
				/* need passes to resolve branches? */
40
				if(c-otxt >= (1L<<15))
41
					bflag = c;
42
				otxt = c;
43
				continue;
44
			}
45
			if(p->as != ANOP)
46
				diag("zero-width instruction\n%P", p);
47
			continue;
48
		}
49
		c += m;
50
	}
51
 
52
	/*
53
	 * if any procedure is large enough to
54
	 * generate a large SBRA branch, then
55
	 * generate extra passes putting branches
56
	 * around jmps to fix. this is rare.
57
	 */
58
	while(bflag) {
59
		if(debug['v'])
60
			Bprint(&bso, "%5.2f span1\n", cputime());
61
		bflag = 0;
62
		c = INITTEXT;
63
		for(p = firstp; p != P; p = p->link) {
64
			p->pc = c;
65
			o = oplook(p);
66
			if((o->type == 16 || o->type == 17) && p->cond) {
67
				otxt = p->cond->pc - c;
68
				if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
69
					q = prg();
70
					q->link = p->link;
71
					p->link = q;
72
					q->as = ABR;
73
					q->to.type = D_BRANCH;
74
					q->cond = p->cond;
75
					p->cond = q;
76
					q = prg();
77
					q->link = p->link;
78
					p->link = q;
79
					q->as = ABR;
80
					q->to.type = D_BRANCH;
81
					q->cond = q->link->link;
82
					addnop(p->link);
83
					addnop(p);
84
					bflag = 1;
85
				}
86
			}
87
			m = o->size;
88
			if(m == 0) {
89
				if(p->as == ATEXT) {
90
					curtext = p;
91
					autosize = p->to.offset + 4;
92
					if(p->from.sym != S)
93
						p->from.sym->value = c;
94
					continue;
95
				}
96
				if(p->as != ANOP)
97
					diag("zero-width instruction\n%P", p);
98
				continue;
99
			}
100
			c += m;
101
		}
102
	}
103
 
104
	c = rnd(c, 8);
105
 
106
	setext = lookup("etext", 0);
107
	if(setext != S) {
108
		setext->value = c;
109
		textsize = c - INITTEXT;
110
	}
111
	if(INITRND)
112
		INITDAT = rnd(c, INITRND);
113
	if(debug['v'])
114
		Bprint(&bso, "tsize = %lux\n", textsize);
115
	Bflush(&bso);
116
}
117
 
118
void
119
xdefine(char *p, int t, long v)
120
{
121
	Sym *s;
122
 
123
	s = lookup(p, 0);
124
	if(s->type == 0 || s->type == SXREF) {
125
		s->type = t;
126
		s->value = v;
127
	}
128
}
129
 
130
long
131
regoff(Adr *a)
132
{
133
 
134
	instoffset = 0;
135
	aclass(a);
136
	return instoffset;
137
}
138
 
139
int
140
aclass(Adr *a)
141
{
142
	Sym *s;
143
	int t;
144
 
145
	switch(a->type) {
146
	case D_NONE:
147
		return C_NONE;
148
 
149
	case D_REG:
150
		return C_REG;
151
 
152
	case D_FREG:
153
		return C_FREG;
154
 
155
	case D_CREG:
156
		return C_CREG;
157
 
158
	case D_SPR:
159
		if(a->offset == D_LR)
160
			return C_LR;
161
		if(a->offset == D_XER)
162
			return C_XER;
163
		if(a->offset == D_CTR)
164
			return C_CTR;
165
		return C_SPR;
166
 
167
	case D_DCR:
168
		return C_SPR;
169
 
170
	case D_SREG:
171
		return C_SREG;
172
 
173
	case D_FPSCR:
174
		return C_FPSCR;
175
 
176
	case D_MSR:
177
		return C_MSR;
178
 
179
	case D_OREG:
180
		switch(a->name) {
181
		case D_EXTERN:
182
		case D_STATIC:
183
			if(a->sym == S)
184
				break;
185
			t = a->sym->type;
186
			if(t == 0 || t == SXREF) {
187
				diag("undefined external: %s in %s",
188
					a->sym->name, TNAME);
189
				a->sym->type = SDATA;
190
			}
191
			if(dlm){
192
				instoffset = a->sym->value + a->offset;
193
				switch(a->sym->type){
194
				case STEXT:
195
				case SLEAF:
196
				case SCONST:
197
				case SUNDEF:
198
					break;
199
				default:
200
					instoffset += INITDAT;
201
				}
202
				return C_ADDR;
203
			}
204
			instoffset = a->sym->value + a->offset - BIG;
205
			if(instoffset >= -BIG && instoffset < BIG)
206
				return C_SEXT;
207
			return C_LEXT;
208
		case D_AUTO:
209
			instoffset = autosize + a->offset;
210
			if(instoffset >= -BIG && instoffset < BIG)
211
				return C_SAUTO;
212
			return C_LAUTO;
213
 
214
		case D_PARAM:
215
			instoffset = autosize + a->offset + 4L;
216
			if(instoffset >= -BIG && instoffset < BIG)
217
				return C_SAUTO;
218
			return C_LAUTO;
219
		case D_NONE:
220
			instoffset = a->offset;
221
			if(instoffset == 0)
222
				return C_ZOREG;
223
			if(instoffset >= -BIG && instoffset < BIG)
224
				return C_SOREG;
225
			return C_LOREG;
226
		}
227
		return C_GOK;
228
 
229
	case D_OPT:
230
		instoffset = a->offset & 31L;
231
		if(a->name == D_NONE)
232
			return C_SCON;
233
		return C_GOK;
234
 
235
	case D_CONST:
236
		switch(a->name) {
237
 
238
		case D_NONE:
239
			instoffset = a->offset;
240
		consize:
241
			if(instoffset >= 0) {
242
				if(r0iszero && instoffset == 0)
243
					return C_ZCON;
244
				if(instoffset <= 0x7fff)
245
					return C_SCON;
246
				if(instoffset <= 0xffff)
247
					return C_ANDCON;
248
				if((instoffset & 0xffff) == 0)
249
					return C_UCON;
250
				return C_LCON;
251
			}
252
			if(instoffset >= -0x8000)
253
				return C_ADDCON;
254
			if((instoffset & 0xffff) == 0)
255
				return C_UCON;
256
			return C_LCON;
257
 
258
		case D_EXTERN:
259
		case D_STATIC:
260
			s = a->sym;
261
			if(s == S)
262
				break;
263
			t = s->type;
264
			if(t == 0 || t == SXREF) {
265
				diag("undefined external: %s in %s",
266
					s->name, TNAME);
267
				s->type = SDATA;
268
			}
269
			if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
270
				instoffset = s->value + a->offset;
271
				return C_LCON;
272
			}
273
			if(s->type == SCONST) {
274
				instoffset = s->value + a->offset;
275
				if(dlm)
276
					return C_LCON;
277
				goto consize;
278
			}
279
			if(!dlm){
280
				instoffset = s->value + a->offset - BIG;
281
				if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
282
					return C_SECON;
283
			}
284
			instoffset = s->value + a->offset + INITDAT;
285
			if(dlm)
286
				return C_LCON;
287
			/* not sure why this barfs */
288
			return C_LCON;
289
		/*
290
			if(instoffset == 0)
291
				return C_ZCON;
292
			if(instoffset >= -0x8000 && instoffset <= 0xffff)
293
				return C_SCON;
294
			if((instoffset & 0xffff) == 0)
295
				return C_UCON;
296
			return C_LCON;
297
		*/
298
 
299
		case D_AUTO:
300
			instoffset = autosize + a->offset;
301
			if(instoffset >= -BIG && instoffset < BIG)
302
				return C_SACON;
303
			return C_LACON;
304
 
305
		case D_PARAM:
306
			instoffset = autosize + a->offset + 4L;
307
			if(instoffset >= -BIG && instoffset < BIG)
308
				return C_SACON;
309
			return C_LACON;
310
		}
311
		return C_GOK;
312
 
313
	case D_BRANCH:
314
		return C_SBRA;
315
	}
316
	return C_GOK;
317
}
318
 
319
Optab*
320
oplook(Prog *p)
321
{
322
	int a1, a2, a3, a4, r;
323
	char *c1, *c3, *c4;
324
	Optab *o, *e;
325
 
326
	a1 = p->optab;
327
	if(a1)
328
		return optab+(a1-1);
329
	a1 = p->from.class;
330
	if(a1 == 0) {
331
		a1 = aclass(&p->from) + 1;
332
		p->from.class = a1;
333
	}
334
	a1--;
335
	a3 = p->from3.class;
336
	if(a3 == 0) {
337
		a3 = aclass(&p->from3) + 1;
338
		p->from3.class = a3;
339
	}
340
	a3--;
341
	a4 = p->to.class;
342
	if(a4 == 0) {
343
		a4 = aclass(&p->to) + 1;
344
		p->to.class = a4;
345
	}
346
	a4--;
347
	a2 = C_NONE;
348
	if(p->reg != NREG)
349
		a2 = C_REG;
350
	r = p->as;
351
	o = oprange[r].start;
352
	if(o == 0)
353
		o = oprange[r].stop; /* just generate an error */
354
	e = oprange[r].stop;
355
	c1 = xcmp[a1];
356
	c3 = xcmp[a3];
357
	c4 = xcmp[a4];
358
	for(; o<e; o++)
359
		if(o->a2 == a2)
360
		if(c1[o->a1])
361
		if(c3[o->a3])
362
		if(c4[o->a4]) {
363
			p->optab = (o-optab)+1;
364
			return o;
365
		}
366
	diag("illegal combination %A %R %R %R %R",
367
		p->as, a1, a2, a3, a4);
368
	if(1||!debug['a'])
369
		prasm(p);
370
	if(o == 0)
371
		errorexit();
372
	return o;
373
}
374
 
375
int
376
cmp(int a, int b)
377
{
378
 
379
	if(a == b)
380
		return 1;
381
	switch(a) {
382
	case C_LCON:
383
		if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
384
			return 1;
385
		break;
386
	case C_ADDCON:
387
		if(b == C_ZCON || b == C_SCON)
388
			return 1;
389
		break;
390
	case C_ANDCON:
391
		if(b == C_ZCON || b == C_SCON)
392
			return 1;
393
		break;
394
	case C_SPR:
395
		if(b == C_LR || b == C_XER || b == C_CTR)
396
			return 1;
397
		break;
398
	case C_UCON:
399
		if(b == C_ZCON)
400
			return 1;
401
		break;
402
	case C_SCON:
403
		if(b == C_ZCON)
404
			return 1;
405
		break;
406
	case C_LACON:
407
		if(b == C_SACON)
408
			return 1;
409
		break;
410
	case C_LBRA:
411
		if(b == C_SBRA)
412
			return 1;
413
		break;
414
	case C_LEXT:
415
		if(b == C_SEXT)
416
			return 1;
417
		break;
418
	case C_LAUTO:
419
		if(b == C_SAUTO)
420
			return 1;
421
		break;
422
	case C_REG:
423
		if(r0iszero && b == C_ZCON)
424
			return 1;
425
		break;
426
	case C_LOREG:
427
		if(b == C_ZOREG || b == C_SOREG)
428
			return 1;
429
		break;
430
	case C_SOREG:
431
		if(b == C_ZOREG)
432
			return 1;
433
		break;
434
 
435
	case C_ANY:
436
		return 1;
437
	}
438
	return 0;
439
}
440
 
441
int
442
ocmp(void *a1, void *a2)
443
{
444
	Optab *p1, *p2;
445
	int n;
446
 
447
	p1 = a1;
448
	p2 = a2;
449
	n = p1->as - p2->as;
450
	if(n)
451
		return n;
452
	n = p1->a1 - p2->a1;
453
	if(n)
454
		return n;
455
	n = p1->a2 - p2->a2;
456
	if(n)
457
		return n;
458
	n = p1->a3 - p2->a3;
459
	if(n)
460
		return n;
461
	n = p1->a4 - p2->a4;
462
	if(n)
463
		return n;
464
	return 0;
465
}
466
 
467
void
468
buildop(void)
469
{
470
	int i, n, r;
471
 
472
	for(i=0; i<C_NCLASS; i++)
473
		for(n=0; n<C_NCLASS; n++)
474
			xcmp[i][n] = cmp(n, i);
475
	for(n=0; optab[n].as != AXXX; n++)
476
		;
477
	qsort(optab, n, sizeof(optab[0]), ocmp);
478
	for(i=0; i<n; i++) {
479
		r = optab[i].as;
480
		oprange[r].start = optab+i;
481
		while(optab[i].as == r)
482
			i++;
483
		oprange[r].stop = optab+i;
484
		i--;
485
 
486
		switch(r)
487
		{
488
		default:
489
			diag("unknown op in build: %A", r);
490
			errorexit();
491
		case ADCBF:	/* unary indexed: op (b+a); op (b) */
492
			oprange[ADCBI] = oprange[r];
493
			oprange[ADCBST] = oprange[r];
494
			oprange[ADCBT] = oprange[r];
495
			oprange[ADCBTST] = oprange[r];
496
			oprange[ADCBZ] = oprange[r];
497
			oprange[AICBI] = oprange[r];
498
			break;
499
		case AECOWX:	/* indexed store: op s,(b+a); op s,(b) */
500
			oprange[ASTWCCC] = oprange[r];
501
			break;
502
		case AREM:	/* macro */
503
			oprange[AREMCC] = oprange[r];
504
			oprange[AREMV] = oprange[r];
505
			oprange[AREMVCC] = oprange[r];
506
			oprange[AREMU] = oprange[r];
507
			oprange[AREMUCC] = oprange[r];
508
			oprange[AREMUV] = oprange[r];
509
			oprange[AREMUVCC] = oprange[r];
510
			break;
511
		case ADIVW:	/* op Rb[,Ra],Rd */
512
			oprange[AMULHW] = oprange[r];
513
			oprange[AMULHWCC] = oprange[r];
514
			oprange[AMULHWU] = oprange[r];
515
			oprange[AMULHWUCC] = oprange[r];
516
			oprange[AMULLWCC] = oprange[r];
517
			oprange[AMULLWVCC] = oprange[r];
518
			oprange[AMULLWV] = oprange[r];
519
			oprange[ADIVWCC] = oprange[r];
520
			oprange[ADIVWV] = oprange[r];
521
			oprange[ADIVWVCC] = oprange[r];
522
			oprange[ADIVWU] = oprange[r];
523
			oprange[ADIVWUCC] = oprange[r];
524
			oprange[ADIVWUV] = oprange[r];
525
			oprange[ADIVWUVCC] = oprange[r];
526
			oprange[AADDCC] = oprange[r];
527
			oprange[AADDCV] = oprange[r];
528
			oprange[AADDCVCC] = oprange[r];
529
			oprange[AADDV] = oprange[r];
530
			oprange[AADDVCC] = oprange[r];
531
			oprange[AADDE] = oprange[r];
532
			oprange[AADDECC] = oprange[r];
533
			oprange[AADDEV] = oprange[r];
534
			oprange[AADDEVCC] = oprange[r];
535
			oprange[ACRAND] = oprange[r];
536
			oprange[ACRANDN] = oprange[r];
537
			oprange[ACREQV] = oprange[r];
538
			oprange[ACRNAND] = oprange[r];
539
			oprange[ACRNOR] = oprange[r];
540
			oprange[ACROR] = oprange[r];
541
			oprange[ACRORN] = oprange[r];
542
			oprange[ACRXOR] = oprange[r];
543
			oprange[AMULCHW] = oprange[r];
544
			oprange[AMULCHWCC] = oprange[r];
545
			oprange[AMULCHWU] = oprange[r];
546
			oprange[AMULCHWUCC] = oprange[r];
547
			oprange[AMULHHW] = oprange[r];
548
			oprange[AMULHHWCC] = oprange[r];
549
			oprange[AMULHHWU] = oprange[r];
550
			oprange[AMULHHWUCC] = oprange[r];
551
			oprange[AMULLHW] = oprange[r];
552
			oprange[AMULLHWCC] = oprange[r];
553
			oprange[AMULLHWU] = oprange[r];
554
			oprange[AMULLHWUCC] = oprange[r];
555
			break;
556
		case AMACCHW:	/* strictly 3 registers */
557
			oprange[AMACCHWCC] = oprange[r];
558
			oprange[AMACCHWS] = oprange[r];
559
			oprange[AMACCHWSCC] = oprange[r];
560
			oprange[AMACCHWSU] = oprange[r];
561
			oprange[AMACCHWSUCC] = oprange[r];
562
			oprange[AMACCHWSUV] = oprange[r];
563
			oprange[AMACCHWSUVCC] = oprange[r];
564
			oprange[AMACCHWSV] = oprange[r];
565
			oprange[AMACCHWSVCC] = oprange[r];
566
			oprange[AMACCHWU] = oprange[r];
567
			oprange[AMACCHWUCC] = oprange[r];
568
			oprange[AMACCHWUV] = oprange[r];
569
			oprange[AMACCHWUVCC] = oprange[r];
570
			oprange[AMACCHWV] = oprange[r];
571
			oprange[AMACCHWVCC] = oprange[r];
572
			oprange[AMACHHW] = oprange[r];
573
			oprange[AMACHHWCC] = oprange[r];
574
			oprange[AMACHHWS] = oprange[r];
575
			oprange[AMACHHWSCC] = oprange[r];
576
			oprange[AMACHHWSU] = oprange[r];
577
			oprange[AMACHHWSUCC] = oprange[r];
578
			oprange[AMACHHWSUV] = oprange[r];
579
			oprange[AMACHHWSUVCC] = oprange[r];
580
			oprange[AMACHHWSV] = oprange[r];
581
			oprange[AMACHHWSVCC] = oprange[r];
582
			oprange[AMACHHWU] = oprange[r];
583
			oprange[AMACHHWUCC] = oprange[r];
584
			oprange[AMACHHWUV] = oprange[r];
585
			oprange[AMACHHWUVCC] = oprange[r];
586
			oprange[AMACHHWV] = oprange[r];
587
			oprange[AMACHHWVCC] = oprange[r];
588
			oprange[AMACLHW] = oprange[r];
589
			oprange[AMACLHWCC] = oprange[r];
590
			oprange[AMACLHWS] = oprange[r];
591
			oprange[AMACLHWSCC] = oprange[r];
592
			oprange[AMACLHWSU] = oprange[r];
593
			oprange[AMACLHWSUCC] = oprange[r];
594
			oprange[AMACLHWSUV] = oprange[r];
595
			oprange[AMACLHWSUVCC] = oprange[r];
596
			oprange[AMACLHWSV] = oprange[r];
597
			oprange[AMACLHWSVCC] = oprange[r];
598
			oprange[AMACLHWU] = oprange[r];
599
			oprange[AMACLHWUCC] = oprange[r];
600
			oprange[AMACLHWUV] = oprange[r];
601
			oprange[AMACLHWUVCC] = oprange[r];
602
			oprange[AMACLHWV] = oprange[r];
603
			oprange[AMACLHWVCC] = oprange[r];
604
			oprange[ANMACCHW] = oprange[r];
605
			oprange[ANMACCHWCC] = oprange[r];
606
			oprange[ANMACCHWS] = oprange[r];
607
			oprange[ANMACCHWSCC] = oprange[r];
608
			oprange[ANMACCHWSV] = oprange[r];
609
			oprange[ANMACCHWSVCC] = oprange[r];
610
			oprange[ANMACCHWV] = oprange[r];
611
			oprange[ANMACCHWVCC] = oprange[r];
612
			oprange[ANMACHHW] = oprange[r];
613
			oprange[ANMACHHWCC] = oprange[r];
614
			oprange[ANMACHHWS] = oprange[r];
615
			oprange[ANMACHHWSCC] = oprange[r];
616
			oprange[ANMACHHWSV] = oprange[r];
617
			oprange[ANMACHHWSVCC] = oprange[r];
618
			oprange[ANMACHHWV] = oprange[r];
619
			oprange[ANMACHHWVCC] = oprange[r];
620
			oprange[ANMACLHW] = oprange[r];
621
			oprange[ANMACLHWCC] = oprange[r];
622
			oprange[ANMACLHWS] = oprange[r];
623
			oprange[ANMACLHWSCC] = oprange[r];
624
			oprange[ANMACLHWSV] = oprange[r];
625
			oprange[ANMACLHWSVCC] = oprange[r];
626
			oprange[ANMACLHWV] = oprange[r];
627
			oprange[ANMACLHWVCC] = oprange[r];
628
			break;
629
		case AMOVBZ:	/* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
630
			oprange[AMOVH] = oprange[r];
631
			oprange[AMOVHZ] = oprange[r];
632
			break;
633
		case AMOVBZU:	/* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */
634
			oprange[AMOVHU] = oprange[r];
635
			oprange[AMOVHZU] = oprange[r];
636
			oprange[AMOVWU] = oprange[r];
637
			oprange[AMOVMW] = oprange[r];
638
			break;
639
		case AAND:	/* logical op Rb,Rs,Ra; no literal */
640
			oprange[AANDN] = oprange[r];
641
			oprange[AANDNCC] = oprange[r];
642
			oprange[AEQV] = oprange[r];
643
			oprange[AEQVCC] = oprange[r];
644
			oprange[ANAND] = oprange[r];
645
			oprange[ANANDCC] = oprange[r];
646
			oprange[ANOR] = oprange[r];
647
			oprange[ANORCC] = oprange[r];
648
			oprange[AORCC] = oprange[r];
649
			oprange[AORN] = oprange[r];
650
			oprange[AORNCC] = oprange[r];
651
			oprange[AXORCC] = oprange[r];
652
			break;
653
		case AADDME:	/* op Ra, Rd */
654
			oprange[AADDMECC] = oprange[r];
655
			oprange[AADDMEV] = oprange[r];
656
			oprange[AADDMEVCC] = oprange[r];
657
			oprange[AADDZE] = oprange[r];
658
			oprange[AADDZECC] = oprange[r];
659
			oprange[AADDZEV] = oprange[r];
660
			oprange[AADDZEVCC] = oprange[r];
661
			oprange[ASUBME] = oprange[r];
662
			oprange[ASUBMECC] = oprange[r];
663
			oprange[ASUBMEV] = oprange[r];
664
			oprange[ASUBMEVCC] = oprange[r];
665
			oprange[ASUBZE] = oprange[r];
666
			oprange[ASUBZECC] = oprange[r];
667
			oprange[ASUBZEV] = oprange[r];
668
			oprange[ASUBZEVCC] = oprange[r];
669
			break;
670
		case AADDC:
671
			oprange[AADDCCC] = oprange[r];
672
			break;
673
		case ABEQ:
674
			oprange[ABGE] = oprange[r];
675
			oprange[ABGT] = oprange[r];
676
			oprange[ABLE] = oprange[r];
677
			oprange[ABLT] = oprange[r];
678
			oprange[ABNE] = oprange[r];
679
			oprange[ABVC] = oprange[r];
680
			oprange[ABVS] = oprange[r];
681
			break;
682
		case ABR:
683
			oprange[ABL] = oprange[r];
684
			break;
685
		case ABC:
686
			oprange[ABCL] = oprange[r];
687
			break;
688
		case AEXTSB:	/* op Rs, Ra */
689
			oprange[AEXTSBCC] = oprange[r];
690
			oprange[AEXTSH] = oprange[r];
691
			oprange[AEXTSHCC] = oprange[r];
692
			oprange[ACNTLZW] = oprange[r];
693
			oprange[ACNTLZWCC] = oprange[r];
694
			break;
695
		case AFABS:	/* fop [s,]d */
696
			oprange[AFABSCC] = oprange[r];
697
			oprange[AFNABS] = oprange[r];
698
			oprange[AFNABSCC] = oprange[r];
699
			oprange[AFNEG] = oprange[r];
700
			oprange[AFNEGCC] = oprange[r];
701
			oprange[AFRSP] = oprange[r];
702
			oprange[AFRSPCC] = oprange[r];
703
			oprange[AFCTIW] = oprange[r];
704
			oprange[AFCTIWCC] = oprange[r];
705
			oprange[AFCTIWZ] = oprange[r];
706
			oprange[AFCTIWZCC] = oprange[r];
707
			oprange[AFRES] = oprange[r];
708
			oprange[AFRESCC] = oprange[r];
709
			oprange[AFRSQRTE] = oprange[r];
710
			oprange[AFRSQRTECC] = oprange[r];
711
			oprange[AFSQRT] = oprange[r];
712
			oprange[AFSQRTCC] = oprange[r];
713
			oprange[AFSQRTS] = oprange[r];
714
			oprange[AFSQRTSCC] = oprange[r];
715
			oprange[AFPRE] = oprange[r];
716
			oprange[AFPRSQRTE] = oprange[r];
717
			oprange[AFPABS] = oprange[r];
718
			oprange[AFPNEG] = oprange[r];
719
			oprange[AFPRSP] = oprange[r];
720
			oprange[AFPNABS] = oprange[r];
721
			oprange[AFSABS] = oprange[r];
722
			oprange[AFSNEG] = oprange[r];
723
			oprange[AFSNABS] = oprange[r];
724
			oprange[AFPCTIW] = oprange[r];
725
			oprange[AFPCTIWZ] = oprange[r];
726
			break;
727
		case AFADD:
728
			oprange[AFADDS] = oprange[r];
729
			oprange[AFADDCC] = oprange[r];
730
			oprange[AFADDSCC] = oprange[r];
731
			oprange[AFDIV] = oprange[r];
732
			oprange[AFDIVS] = oprange[r];
733
			oprange[AFDIVCC] = oprange[r];
734
			oprange[AFDIVSCC] = oprange[r];
735
			oprange[AFSUB] = oprange[r];
736
			oprange[AFSUBS] = oprange[r];
737
			oprange[AFSUBCC] = oprange[r];
738
			oprange[AFSUBSCC] = oprange[r];
739
			oprange[AFPADD] = oprange[r];
740
			oprange[AFPSUB] = oprange[r];
741
			break;
742
		case AFMADD:
743
			oprange[AFMADDCC] = oprange[r];
744
			oprange[AFMADDS] = oprange[r];
745
			oprange[AFMADDSCC] = oprange[r];
746
			oprange[AFMSUB] = oprange[r];
747
			oprange[AFMSUBCC] = oprange[r];
748
			oprange[AFMSUBS] = oprange[r];
749
			oprange[AFMSUBSCC] = oprange[r];
750
			oprange[AFNMADD] = oprange[r];
751
			oprange[AFNMADDCC] = oprange[r];
752
			oprange[AFNMADDS] = oprange[r];
753
			oprange[AFNMADDSCC] = oprange[r];
754
			oprange[AFNMSUB] = oprange[r];
755
			oprange[AFNMSUBCC] = oprange[r];
756
			oprange[AFNMSUBS] = oprange[r];
757
			oprange[AFNMSUBSCC] = oprange[r];
758
			oprange[AFSEL] = oprange[r];
759
			oprange[AFSELCC] = oprange[r];
760
			oprange[AFPSEL] = oprange[r];
761
			oprange[AFPMADD] = oprange[r];
762
			oprange[AFXMADD] = oprange[r];
763
			oprange[AFXCPMADD] = oprange[r];
764
			oprange[AFXCSMADD] = oprange[r];
765
			oprange[AFPNMADD] = oprange[r];
766
			oprange[AFXNMADD] = oprange[r];
767
			oprange[AFXCPNMADD] = oprange[r];
768
			oprange[AFXCSNMADD] = oprange[r];
769
			oprange[AFPMSUB] = oprange[r];
770
			oprange[AFXMSUB] = oprange[r];
771
			oprange[AFXCPMSUB] = oprange[r];
772
			oprange[AFXCSMSUB] = oprange[r];
773
			oprange[AFPNMSUB] = oprange[r];
774
			oprange[AFXNMSUB] = oprange[r];
775
			oprange[AFXCPNMSUB] = oprange[r];
776
			oprange[AFXCSNMSUB] = oprange[r];
777
			oprange[AFXCPNPMA] = oprange[r];
778
			oprange[AFXCSNPMA] = oprange[r];
779
			oprange[AFXCPNSMA] = oprange[r];
780
			oprange[AFXCSNSMA] = oprange[r];
781
			oprange[AFXCXNPMA] = oprange[r];
782
			oprange[AFXCXNSMA] = oprange[r];
783
			oprange[AFXCXMA] = oprange[r];
784
			oprange[AFXCXNMS] = oprange[r];
785
			break;
786
		case AFMUL:
787
			oprange[AFMULS] = oprange[r];
788
			oprange[AFMULCC] = oprange[r];
789
			oprange[AFMULSCC] = oprange[r];
790
			oprange[AFPMUL] = oprange[r];
791
			oprange[AFXMUL] = oprange[r];
792
			oprange[AFXPMUL] = oprange[r];
793
			oprange[AFXSMUL] = oprange[r];
794
			break;
795
		case AFCMPO:
796
			oprange[AFCMPU] = oprange[r];
797
			break;
798
		case AMTFSB0:
799
			oprange[AMTFSB0CC] = oprange[r];
800
			oprange[AMTFSB1] = oprange[r];
801
			oprange[AMTFSB1CC] = oprange[r];
802
			break;
803
		case ANEG:	/* op [Ra,] Rd */
804
			oprange[ANEGCC] = oprange[r];
805
			oprange[ANEGV] = oprange[r];
806
			oprange[ANEGVCC] = oprange[r];
807
			break;
808
		case AOR:	/* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
809
			oprange[AXOR] = oprange[r];
810
			break;
811
		case ASLW:
812
			oprange[ASLWCC] = oprange[r];
813
			oprange[ASRW] = oprange[r];
814
			oprange[ASRWCC] = oprange[r];
815
			break;
816
		case ASRAW:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
817
			oprange[ASRAWCC] = oprange[r];
818
			break;
819
		case ASUB:	/* SUB Ra,Rb,Rd => subf Rd,ra,rb */
820
			oprange[ASUB] = oprange[r];
821
			oprange[ASUBCC] = oprange[r];
822
			oprange[ASUBV] = oprange[r];
823
			oprange[ASUBVCC] = oprange[r];
824
			oprange[ASUBCCC] = oprange[r];
825
			oprange[ASUBCV] = oprange[r];
826
			oprange[ASUBCVCC] = oprange[r];
827
			oprange[ASUBE] = oprange[r];
828
			oprange[ASUBECC] = oprange[r];
829
			oprange[ASUBEV] = oprange[r];
830
			oprange[ASUBEVCC] = oprange[r];
831
			break;
832
		case ASYNC:
833
			oprange[AISYNC] = oprange[r];
834
			break;
835
		case ARLWMI:
836
			oprange[ARLWMICC] = oprange[r];
837
			oprange[ARLWNM] = oprange[r];
838
			oprange[ARLWNMCC] = oprange[r];
839
			break;
840
		case AFMOVD:
841
			oprange[AFMOVDCC] = oprange[r];
842
			oprange[AFMOVDU] = oprange[r];
843
			oprange[AFMOVS] = oprange[r];
844
			oprange[AFMOVSU] = oprange[r];
845
			break;
846
		case AECIWX:
847
			oprange[ALWAR] = oprange[r];
848
			break;
849
		case ASYSCALL:	/* just the op; flow of control */
850
			oprange[ARFI] = oprange[r];
851
			oprange[ARFCI] = oprange[r];
852
			break;
853
		case AMOVHBR:
854
			oprange[AMOVWBR] = oprange[r];
855
			break;
856
		case AFSMOVS:	/* indexed floating loads and stores (fp2) */
857
			oprange[AFSMOVSU] = oprange[r];
858
			oprange[AFSMOVDU] = oprange[r];
859
			oprange[AFXMOVS] = oprange[r];
860
			oprange[AFXMOVSU] = oprange[r];
861
			oprange[AFXMOVDU] = oprange[r];
862
			oprange[AFPMOVS] = oprange[r];
863
			oprange[AFPMOVSU] = oprange[r];
864
			oprange[AFPMOVDU] = oprange[r];
865
			oprange[AFPMOVIW] = oprange[r];
866
			break;
867
		case AFPMOVD:	/* indexed load/store and moves (fp2) */
868
			oprange[AFSMOVD] = oprange[r];
869
			oprange[AFXMOVD] = oprange[r];
870
			break;
871
		case AFMOVSPD:	/* move between fp reg sets (fp2) */
872
			oprange[AFMOVPSD] = oprange[r];
873
			break;
874
		case AADD:
875
		case AANDCC:	/* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
876
		case ACMP:
877
		case ACMPU:
878
		case AEIEIO:
879
		case ALSW:
880
		case AMOVB:	/* macro: move byte with sign extension */
881
		case AMOVBU:	/* macro: move byte with sign extension & update */
882
		case AMOVW:
883
		case AMOVFL:
884
		case AMULLW:	/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
885
		case ASUBC:	/* op r1,$s,r3; op r1[,r2],r3 */
886
		case ASTSW:
887
		case ATLBIE:
888
		case ATW:
889
		case AWORD:
890
		case ANOP:
891
		case ATEXT:
892
			break;
893
		}
894
	}
895
}
896
 
897
enum{
898
	ABSD = 0,
899
	ABSU = 1,
900
	RELD = 2,
901
	RELU = 3,
902
};
903
 
904
int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
905
 
906
typedef struct Reloc Reloc;
907
 
908
struct Reloc
909
{
910
	int n;
911
	int t;
912
	uchar *m;
913
	ulong *a;
914
};
915
 
916
Reloc rels;
917
 
918
static void
919
grow(Reloc *r)
920
{
921
	int t;
922
	uchar *m, *nm;
923
	ulong *a, *na;
924
 
925
	t = r->t;
926
	r->t += 64;
927
	m = r->m;
928
	a = r->a;
929
	r->m = nm = malloc(r->t*sizeof(uchar));
930
	r->a = na = malloc(r->t*sizeof(ulong));
931
	memmove(nm, m, t*sizeof(uchar));
932
	memmove(na, a, t*sizeof(ulong));
933
	free(m);
934
	free(a);
935
}
936
 
937
void
938
dynreloc(Sym *s, long v, int abs, int split, int sext)
939
{
940
	int i, k, n;
941
	uchar *m;
942
	ulong *a;
943
	Reloc *r;
944
 
945
	if(v&3)
946
		diag("bad relocation address");
947
	v >>= 2;
948
	if(s->type == SUNDEF)
949
		k = abs ? ABSU : RELU;
950
	else
951
		k = abs ? ABSD : RELD;
952
	if(split)
953
		k += 4;
954
	if(sext)
955
		k += 2;
956
	/* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
957
	k = modemap[k];
958
	r = &rels;
959
	n = r->n;
960
	if(n >= r->t)
961
		grow(r);
962
	m = r->m;
963
	a = r->a;
964
	for(i = n; i > 0; i--){
965
		if(v < a[i-1]){	/* happens occasionally for data */
966
			m[i] = m[i-1];
967
			a[i] = a[i-1];
968
		}
969
		else
970
			break;
971
	}
972
	m[i] = k;
973
	a[i] = v;
974
	r->n++;
975
}
976
 
977
static int
978
sput(char *s)
979
{
980
	char *p;
981
 
982
	p = s;
983
	while(*s)
984
		cput(*s++);
985
	cput(0);
986
	return s-p+1;
987
}
988
 
989
void
990
asmdyn()
991
{
992
	int i, n, t, c;
993
	Sym *s;
994
	ulong la, ra, *a;
995
	vlong off;
996
	uchar *m;
997
	Reloc *r;
998
 
999
	cflush();
1000
	off = seek(cout, 0, 1);
1001
	lput(0);
1002
	t = 0;
1003
	lput(imports);
1004
	t += 4;
1005
	for(i = 0; i < NHASH; i++)
1006
		for(s = hash[i]; s != S; s = s->link)
1007
			if(s->type == SUNDEF){
1008
				lput(s->sig);
1009
				t += 4;
1010
				t += sput(s->name);
1011
			}
1012
 
1013
	la = 0;
1014
	r = &rels;
1015
	n = r->n;
1016
	m = r->m;
1017
	a = r->a;
1018
	lput(n);
1019
	t += 4;
1020
	for(i = 0; i < n; i++){
1021
		ra = *a-la;
1022
		if(*a < la)
1023
			diag("bad relocation order");
1024
		if(ra < 256)
1025
			c = 0;
1026
		else if(ra < 65536)
1027
			c = 1;
1028
		else
1029
			c = 2;
1030
		cput((c<<6)|*m++);
1031
		t++;
1032
		if(c == 0){
1033
			cput(ra);
1034
			t++;
1035
		}
1036
		else if(c == 1){
1037
			wput(ra);
1038
			t += 2;
1039
		}
1040
		else{
1041
			lput(ra);
1042
			t += 4;
1043
		}
1044
		la = *a++;
1045
	}
1046
 
1047
	cflush();
1048
	seek(cout, off, 0);
1049
	lput(t);
1050
 
1051
	if(debug['v']){
1052
		Bprint(&bso, "import table entries = %d\n", imports);
1053
		Bprint(&bso, "export table entries = %d\n", exports);
1054
	}
1055
}