Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "gc.h"
2
 
3
void
4
peep(void)
5
{
6
	Reg *r, *r1, *r2;
7
	Prog *p, *p1;
8
	int t;
9
/*
10
 * complete R structure
11
 */
12
	t = 0;
13
	for(r=firstr; r!=R; r=r1) {
14
		r1 = r->link;
15
		if(r1 == R)
16
			break;
17
		p = r->prog->link;
18
		while(p != r1->prog)
19
		switch(p->as) {
20
		default:
21
			r2 = rega();
22
			r->link = r2;
23
			r2->link = r1;
24
 
25
			r2->prog = p;
26
			r2->p1 = r;
27
			r->s1 = r2;
28
			r2->s1 = r1;
29
			r1->p1 = r2;
30
 
31
			r = r2;
32
			t++;
33
 
34
		case ADATA:
35
		case AGLOBL:
36
		case ANAME:
37
		case ASIGNAME:
38
			p = p->link;
39
		}
40
	}
41
 
42
loop1:
43
	t = 0;
44
	for(r=firstr; r!=R; r=r->link) {
45
		p = r->prog;
46
		if(p->as == AMOVW || p->as == AFMOVS || p->as == AFMOVD)
47
		if(regtyp(&p->to)) {
48
			if(regtyp(&p->from))
49
			if(p->from.type == p->to.type) {
50
				if(copyprop(r)) {
51
					excise(r);
52
					t++;
53
				} else
54
				if(subprop(r) && copyprop(r)) {
55
					excise(r);
56
					t++;
57
				}
58
			}
59
			if(regzer(&p->from))
60
			if(p->to.type == D_REG) {
61
				p->from.type = D_REG;
62
				p->from.reg = REGZERO;
63
				if(copyprop(r)) {
64
					excise(r);
65
					t++;
66
				} else
67
				if(subprop(r) && copyprop(r)) {
68
					excise(r);
69
					t++;
70
				}
71
			}
72
		}
73
	}
74
	if(t)
75
		goto loop1;
76
	/*
77
	 * look for MOVB x,R; MOVB R,R
78
	 */
79
	for(r=firstr; r!=R; r=r->link) {
80
		p = r->prog;
81
		switch(p->as) {
82
		default:
83
			continue;
84
		case AMOVH:
85
		case AMOVHZ:
86
		case AMOVB:
87
		case AMOVBZ:
88
			if(p->to.type != D_REG)
89
				continue;
90
			break;
91
		}
92
		r1 = r->link;
93
		if(r1 == R)
94
			continue;
95
		p1 = r1->prog;
96
		if(p1->as != p->as)
97
			continue;
98
		if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
99
			continue;
100
		if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
101
			continue;
102
		excise(r1);
103
	}
104
 
105
	if(debug['Q'] > 1)
106
		return;	/* allow following code improvement to be suppressed */
107
 
108
	/*
109
	 * look for OP x,y,R; CMP R, $0 -> OPCC x,y,R
110
	 * when OP can set condition codes correctly
111
	 */
112
	for(r=firstr; r!=R; r=r->link) {
113
		p = r->prog;
114
		switch(p->as) {
115
		case ACMP:
116
			if(!regzer(&p->to))
117
				continue;
118
			r1 = r->s1;
119
			if(r1 == R)
120
				continue;
121
			switch(r1->prog->as) {
122
			default:
123
				continue;
124
			case ABCL:
125
			case ABC:
126
				/* the conditions can be complex and these are currently little used */
127
				continue;
128
			case ABEQ:
129
			case ABGE:
130
			case ABGT:
131
			case ABLE:
132
			case ABLT:
133
			case ABNE:
134
			case ABVC:
135
			case ABVS:
136
				break;
137
			}
138
			r1 = r;
139
			do
140
				r1 = uniqp(r1);
141
			while (r1 != R && r1->prog->as == ANOP);
142
			if(r1 == R)
143
				continue;
144
			p1 = r1->prog;
145
			if(p1->to.type != D_REG || p1->to.reg != p->from.reg)
146
				continue;
147
			switch(p1->as) {
148
			case ASUB:
149
			case AADD:
150
			case AXOR:
151
			case AOR:
152
				/* irregular instructions */
153
				if(p1->from.type == D_CONST)
154
					continue;
155
				break;
156
			}
157
			switch(p1->as) {
158
			default:
159
				continue;
160
			case AMOVW:
161
				if(p1->from.type != D_REG)
162
					continue;
163
				continue;
164
			case AANDCC:
165
			case AANDNCC:
166
			case AORCC:
167
			case AORNCC:
168
			case AXORCC:
169
			case ASUBCC:
170
			case ASUBECC:
171
			case ASUBMECC:
172
			case ASUBZECC:
173
			case AADDCC:
174
			case AADDCCC:
175
			case AADDECC:
176
			case AADDMECC:
177
			case AADDZECC:
178
			case ARLWMICC:
179
			case ARLWNMCC:
180
				t = p1->as;
181
				break;
182
			/* don't deal with floating point instructions for now */
183
/*
184
			case AFABS:	t = AFABSCC; break;
185
			case AFADD:	t = AFADDCC; break;
186
			case AFADDS:	t = AFADDSCC; break;
187
			case AFCTIW:	t = AFCTIWCC; break;
188
			case AFCTIWZ:	t = AFCTIWZCC; break;
189
			case AFDIV:	t = AFDIVCC; break;
190
			case AFDIVS:	t = AFDIVSCC; break;
191
			case AFMADD:	t = AFMADDCC; break;
192
			case AFMADDS:	t = AFMADDSCC; break;
193
			case AFMOVD:	t = AFMOVDCC; break;
194
			case AFMSUB:	t = AFMSUBCC; break;
195
			case AFMSUBS:	t = AFMSUBSCC; break;
196
			case AFMUL:	t = AFMULCC; break;
197
			case AFMULS:	t = AFMULSCC; break;
198
			case AFNABS:	t = AFNABSCC; break;
199
			case AFNEG:	t = AFNEGCC; break;
200
			case AFNMADD:	t = AFNMADDCC; break;
201
			case AFNMADDS:	t = AFNMADDSCC; break;
202
			case AFNMSUB:	t = AFNMSUBCC; break;
203
			case AFNMSUBS:	t = AFNMSUBSCC; break;
204
			case AFRSP:	t = AFRSPCC; break;
205
			case AFSUB:	t = AFSUBCC; break;
206
			case AFSUBS:	t = AFSUBSCC; break;
207
			case ACNTLZW:	t = ACNTLZWCC; break;
208
			case AMTFSB0:	t = AMTFSB0CC; break;
209
			case AMTFSB1:	t = AMTFSB1CC; break;
210
*/
211
			case AADD:	t = AADDCC; break;
212
			case AADDV:	t = AADDVCC; break;
213
			case AADDC:	t = AADDCCC; break;
214
			case AADDCV:	t = AADDCVCC; break;
215
			case AADDME:	t = AADDMECC; break;
216
			case AADDMEV:	t = AADDMEVCC; break;
217
			case AADDE:	t = AADDECC; break;
218
			case AADDEV:	t = AADDEVCC; break;
219
			case AADDZE:	t = AADDZECC; break;
220
			case AADDZEV:	t = AADDZEVCC; break;
221
			case AAND:	t = AANDCC; break;
222
			case AANDN:	t = AANDNCC; break;
223
			case ADIVW:	t = ADIVWCC; break;
224
			case ADIVWV:	t = ADIVWVCC; break;
225
			case ADIVWU:	t = ADIVWUCC; break;
226
			case ADIVWUV:	t = ADIVWUVCC; break;
227
			case AEQV:	t = AEQVCC; break;
228
			case AEXTSB:	t = AEXTSBCC; break;
229
			case AEXTSH:	t = AEXTSHCC; break;
230
			case AMULHW:	t = AMULHWCC; break;
231
			case AMULHWU:	t = AMULHWUCC; break;
232
			case AMULLW:	t = AMULLWCC; break;
233
			case AMULLWV:	t = AMULLWVCC; break;
234
			case ANAND:	t = ANANDCC; break;
235
			case ANEG:	t = ANEGCC; break;
236
			case ANEGV:	t = ANEGVCC; break;
237
			case ANOR:	t = ANORCC; break;
238
			case AOR:	t = AORCC; break;
239
			case AORN:	t = AORNCC; break;
240
			case AREM:	t = AREMCC; break;
241
			case AREMV:	t = AREMVCC; break;
242
			case AREMU:	t = AREMUCC; break;
243
			case AREMUV:	t = AREMUVCC; break;
244
			case ARLWMI:	t = ARLWMICC; break;
245
			case ARLWNM:	t = ARLWNMCC; break;
246
			case ASLW:	t = ASLWCC; break;
247
			case ASRAW:	t = ASRAWCC; break;
248
			case ASRW:	t = ASRWCC; break;
249
			case ASUB:	t = ASUBCC; break;
250
			case ASUBV:	t = ASUBVCC; break;
251
			case ASUBC:	t = ASUBCCC; break;
252
			case ASUBCV:	t = ASUBCVCC; break;
253
			case ASUBME:	t = ASUBMECC; break;
254
			case ASUBMEV:	t = ASUBMEVCC; break;
255
			case ASUBE:	t = ASUBECC; break;
256
			case ASUBEV:	t = ASUBEVCC; break;
257
			case ASUBZE:	t = ASUBZECC; break;
258
			case ASUBZEV:	t = ASUBZEVCC; break;
259
			case AXOR:	t = AXORCC; break;
260
				break;
261
			}
262
			if(debug['Q'])
263
				print("cmp %P; %P -> ", p1, p);
264
			p1->as = t;
265
			if(debug['Q'])
266
				print("%P\n", p1);
267
			excise(r);
268
			continue;
269
		}
270
	}
271
}
272
 
273
void
274
excise(Reg *r)
275
{
276
	Prog *p;
277
 
278
	p = r->prog;
279
	p->as = ANOP;
280
	p->from = zprog.from;
281
	p->from3 = zprog.from3;
282
	p->to = zprog.to;
283
	p->reg = zprog.reg; /**/
284
}
285
 
286
Reg*
287
uniqp(Reg *r)
288
{
289
	Reg *r1;
290
 
291
	r1 = r->p1;
292
	if(r1 == R) {
293
		r1 = r->p2;
294
		if(r1 == R || r1->p2link != R)
295
			return R;
296
	} else
297
		if(r->p2 != R)
298
			return R;
299
	return r1;
300
}
301
 
302
Reg*
303
uniqs(Reg *r)
304
{
305
	Reg *r1;
306
 
307
	r1 = r->s1;
308
	if(r1 == R) {
309
		r1 = r->s2;
310
		if(r1 == R)
311
			return R;
312
	} else
313
		if(r->s2 != R)
314
			return R;
315
	return r1;
316
}
317
 
318
/*
319
 * if the system forces R0 to be zero,
320
 * convert references to $0 to references to R0.
321
 */
322
regzer(Adr *a)
323
{
324
	if(R0ISZERO) {
325
		if(a->type == D_CONST)
326
			if(a->sym == S)
327
				if(a->offset == 0)
328
					return 1;
329
		if(a->type == D_REG)
330
			if(a->reg == REGZERO)
331
				return 1;
332
	}
333
	return 0;
334
}
335
 
336
regtyp(Adr *a)
337
{
338
 
339
	if(a->type == D_REG) {
340
		if(!R0ISZERO || a->reg != REGZERO)
341
			return 1;
342
		return 0;
343
	}
344
	if(a->type == D_FREG)
345
		return 1;
346
	return 0;
347
}
348
 
349
/*
350
 * the idea is to substitute
351
 * one register for another
352
 * from one MOV to another
353
 *	MOV	a, R0
354
 *	ADD	b, R0	/ no use of R1
355
 *	MOV	R0, R1
356
 * would be converted to
357
 *	MOV	a, R1
358
 *	ADD	b, R1
359
 *	MOV	R1, R0
360
 * hopefully, then the former or latter MOV
361
 * will be eliminated by copy propagation.
362
 */
363
int
364
subprop(Reg *r0)
365
{
366
	Prog *p;
367
	Adr *v1, *v2;
368
	Reg *r;
369
	int t;
370
 
371
	p = r0->prog;
372
	v1 = &p->from;
373
	if(!regtyp(v1))
374
		return 0;
375
	v2 = &p->to;
376
	if(!regtyp(v2))
377
		return 0;
378
	for(r=uniqp(r0); r!=R; r=uniqp(r)) {
379
		if(uniqs(r) == R)
380
			break;
381
		p = r->prog;
382
		switch(p->as) {
383
		case ABL:
384
			return 0;
385
 
386
		case AADD:
387
		case AADDC:
388
		case AADDCC:
389
		case AADDE:
390
		case AADDECC:
391
		case ASUB:
392
		case ASUBCC:
393
		case ASUBC:
394
		case ASUBCCC:
395
		case ASUBE:
396
		case ASUBECC:
397
		case ASLW:
398
		case ASLWCC:
399
		case ASRW:
400
		case ASRWCC:
401
		case ASRAW:
402
		case ASRAWCC:
403
		case AOR:
404
		case AORCC:
405
		case AORN:
406
		case AORNCC:
407
		case AAND:
408
		case AANDCC:
409
		case AANDN:
410
		case AANDNCC:
411
		case ANAND:
412
		case ANANDCC:
413
		case ANOR:
414
		case ANORCC:
415
		case AXOR:
416
		case AXORCC:
417
		case AMULHW:
418
		case AMULHWU:
419
		case AMULLW:
420
		case ADIVW:
421
		case ADIVWU:
422
		case AREM:
423
		case AREMU:
424
		case ARLWNM:
425
		case ARLWNMCC:
426
 
427
		case AFADD:
428
		case AFADDS:
429
		case AFSUB:
430
		case AFSUBS:
431
		case AFMUL:
432
		case AFMULS:
433
		case AFDIV:
434
		case AFDIVS:
435
			if(p->to.type == v1->type)
436
			if(p->to.reg == v1->reg) {
437
				if(p->reg == NREG)
438
					p->reg = p->to.reg;
439
				goto gotit;
440
			}
441
			break;
442
 
443
		case AADDME:
444
		case AADDMECC:
445
		case AADDZE:
446
		case AADDZECC:
447
		case ASUBME:
448
		case ASUBMECC:
449
		case ASUBZE:
450
		case ASUBZECC:
451
		case ANEG:
452
		case ANEGCC:
453
		case AFNEG:
454
		case AFNEGCC:
455
		case AFMOVS:
456
		case AFMOVD:
457
		case AMOVW:
458
			if(p->to.type == v1->type)
459
			if(p->to.reg == v1->reg)
460
				goto gotit;
461
			break;
462
		}
463
		if(copyau(&p->from, v2) ||
464
		   copyau1(p, v2) ||
465
		   copyau(&p->to, v2))
466
			break;
467
		if(copysub(&p->from, v1, v2, 0) ||
468
		   copysub1(p, v1, v2, 0) ||
469
		   copysub(&p->to, v1, v2, 0))
470
			break;
471
	}
472
	return 0;
473
 
474
gotit:
475
	copysub(&p->to, v1, v2, 1);
476
	if(debug['P']) {
477
		print("gotit: %D->%D\n%P", v1, v2, r->prog);
478
		if(p->from.type == v2->type)
479
			print(" excise");
480
		print("\n");
481
	}
482
	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
483
		p = r->prog;
484
		copysub(&p->from, v1, v2, 1);
485
		copysub1(p, v1, v2, 1);
486
		copysub(&p->to, v1, v2, 1);
487
		if(debug['P'])
488
			print("%P\n", r->prog);
489
	}
490
	t = v1->reg;
491
	v1->reg = v2->reg;
492
	v2->reg = t;
493
	if(debug['P'])
494
		print("%P last\n", r->prog);
495
	return 1;
496
}
497
 
498
/*
499
 * The idea is to remove redundant copies.
500
 *	v1->v2	F=0
501
 *	(use v2	s/v2/v1/)*
502
 *	set v1	F=1
503
 *	use v2	return fail
504
 *	-----------------
505
 *	v1->v2	F=0
506
 *	(use v2	s/v2/v1/)*
507
 *	set v1	F=1
508
 *	set v2	return success
509
 */
510
int
511
copyprop(Reg *r0)
512
{
513
	Prog *p;
514
	Adr *v1, *v2;
515
	Reg *r;
516
 
517
	p = r0->prog;
518
	v1 = &p->from;
519
	v2 = &p->to;
520
	if(copyas(v1, v2))
521
		return 1;
522
	for(r=firstr; r!=R; r=r->link)
523
		r->active = 0;
524
	return copy1(v1, v2, r0->s1, 0);
525
}
526
 
527
copy1(Adr *v1, Adr *v2, Reg *r, int f)
528
{
529
	int t;
530
	Prog *p;
531
 
532
	if(r->active) {
533
		if(debug['P'])
534
			print("act set; return 1\n");
535
		return 1;
536
	}
537
	r->active = 1;
538
	if(debug['P'])
539
		print("copy %D->%D f=%d\n", v1, v2, f);
540
	for(; r != R; r = r->s1) {
541
		p = r->prog;
542
		if(debug['P'])
543
			print("%P", p);
544
		if(!f && uniqp(r) == R) {
545
			f = 1;
546
			if(debug['P'])
547
				print("; merge; f=%d", f);
548
		}
549
		t = copyu(p, v2, A);
550
		switch(t) {
551
		case 2:	/* rar, cant split */
552
			if(debug['P'])
553
				print("; %Drar; return 0\n", v2);
554
			return 0;
555
 
556
		case 3:	/* set */
557
			if(debug['P'])
558
				print("; %Dset; return 1\n", v2);
559
			return 1;
560
 
561
		case 1:	/* used, substitute */
562
		case 4:	/* use and set */
563
			if(f) {
564
				if(!debug['P'])
565
					return 0;
566
				if(t == 4)
567
					print("; %Dused+set and f=%d; return 0\n", v2, f);
568
				else
569
					print("; %Dused and f=%d; return 0\n", v2, f);
570
				return 0;
571
			}
572
			if(copyu(p, v2, v1)) {
573
				if(debug['P'])
574
					print("; sub fail; return 0\n");
575
				return 0;
576
			}
577
			if(debug['P'])
578
				print("; sub%D/%D", v2, v1);
579
			if(t == 4) {
580
				if(debug['P'])
581
					print("; %Dused+set; return 1\n", v2);
582
				return 1;
583
			}
584
			break;
585
		}
586
		if(!f) {
587
			t = copyu(p, v1, A);
588
			if(!f && (t == 2 || t == 3 || t == 4)) {
589
				f = 1;
590
				if(debug['P'])
591
					print("; %Dset and !f; f=%d", v1, f);
592
			}
593
		}
594
		if(debug['P'])
595
			print("\n");
596
		if(r->s2)
597
			if(!copy1(v1, v2, r->s2, f))
598
				return 0;
599
	}
600
	return 1;
601
}
602
 
603
/*
604
 * return
605
 * 1 if v only used (and substitute),
606
 * 2 if read-alter-rewrite
607
 * 3 if set
608
 * 4 if set and used
609
 * 0 otherwise (not touched)
610
 */
611
int
612
copyu(Prog *p, Adr *v, Adr *s)
613
{
614
 
615
	switch(p->as) {
616
 
617
	default:
618
		if(debug['P'])
619
			print(" (???)");
620
		return 2;
621
 
622
	case ANOP:	/* read, write */
623
	case AMOVW:
624
	case AMOVH:
625
	case AMOVHZ:
626
	case AMOVB:
627
	case AMOVBZ:
628
 
629
	case ANEG:
630
	case ANEGCC:
631
	case AADDME:
632
	case AADDMECC:
633
	case AADDZE:
634
	case AADDZECC:
635
	case ASUBME:
636
	case ASUBMECC:
637
	case ASUBZE:
638
	case ASUBZECC:
639
 
640
	case AFCTIW:
641
	case AFCTIWZ:
642
	case AFMOVS:
643
	case AFMOVD:
644
	case AFRSP:
645
	case AFNEG:
646
	case AFNEGCC:
647
		if(s != A) {
648
			if(copysub(&p->from, v, s, 1))
649
				return 1;
650
			if(!copyas(&p->to, v))
651
				if(copysub(&p->to, v, s, 1))
652
					return 1;
653
			return 0;
654
		}
655
		if(copyas(&p->to, v)) {
656
			if(copyau(&p->from, v))
657
				return 4;
658
			return 3;
659
		}
660
		if(copyau(&p->from, v))
661
			return 1;
662
		if(copyau(&p->to, v))
663
			return 1;
664
		return 0;
665
 
666
	case ARLWMI:	/* read read rar */
667
	case ARLWMICC:
668
		if(copyas(&p->to, v))
669
			return 2;
670
		/* fall through */
671
 
672
	case AADD:	/* read read write */
673
	case AADDC:
674
	case AADDE:
675
	case ASUB:
676
	case ASLW:
677
	case ASRW:
678
	case ASRAW:
679
	case AOR:
680
	case AORCC:
681
	case AORN:
682
	case AORNCC:
683
	case AAND:
684
	case AANDCC:
685
	case AANDN:
686
	case AANDNCC:
687
	case ANAND:
688
	case ANANDCC:
689
	case ANOR:
690
	case ANORCC:
691
	case AXOR:
692
	case AMULHW:
693
	case AMULHWU:
694
	case AMULLW:
695
	case ADIVW:
696
	case ADIVWU:
697
	case AREM:
698
	case AREMU:
699
	case ARLWNM:
700
	case ARLWNMCC:
701
 
702
	case AFADDS:
703
	case AFADD:
704
	case AFSUBS:
705
	case AFSUB:
706
	case AFMULS:
707
	case AFMUL:
708
	case AFDIVS:
709
	case AFDIV:
710
		if(s != A) {
711
			if(copysub(&p->from, v, s, 1))
712
				return 1;
713
			if(copysub1(p, v, s, 1))
714
				return 1;
715
			if(!copyas(&p->to, v))
716
				if(copysub(&p->to, v, s, 1))
717
					return 1;
718
			return 0;
719
		}
720
		if(copyas(&p->to, v)) {
721
			if(p->reg == NREG)
722
				p->reg = p->to.reg;
723
			if(copyau(&p->from, v))
724
				return 4;
725
			if(copyau1(p, v))
726
				return 4;
727
			return 3;
728
		}
729
		if(copyau(&p->from, v))
730
			return 1;
731
		if(copyau1(p, v))
732
			return 1;
733
		if(copyau(&p->to, v))
734
			return 1;
735
		return 0;
736
 
737
	case ABEQ:
738
	case ABGT:
739
	case ABGE:
740
	case ABLT:
741
	case ABLE:
742
	case ABNE:
743
	case ABVC:
744
	case ABVS:
745
		break;
746
 
747
	case ACMP:	/* read read */
748
	case ACMPU:
749
	case AFCMPO:
750
	case AFCMPU:
751
		if(s != A) {
752
			if(copysub(&p->from, v, s, 1))
753
				return 1;
754
			return copysub(&p->to, v, s, 1);
755
		}
756
		if(copyau(&p->from, v))
757
			return 1;
758
		if(copyau(&p->to, v))
759
			return 1;
760
		break;
761
 
762
	case ABR:	/* funny */
763
		if(s != A) {
764
			if(copysub(&p->to, v, s, 1))
765
				return 1;
766
			return 0;
767
		}
768
		if(copyau(&p->to, v))
769
			return 1;
770
		return 0;
771
 
772
	case ARETURN:	/* funny */
773
		if(v->type == D_REG)
774
			if(v->reg == REGRET)
775
				return 2;
776
		if(v->type == D_FREG)
777
			if(v->reg == FREGRET)
778
				return 2;
779
 
780
	case ABL:	/* funny */
781
		if(v->type == D_REG) {
782
			if(v->reg <= REGEXT && v->reg > exregoffset)
783
				return 2;
784
			if(v->reg == REGARG)
785
				return 2;
786
		}
787
		if(v->type == D_FREG) {
788
			if(v->reg <= FREGEXT && v->reg > exfregoffset)
789
				return 2;
790
		}
791
 
792
		if(s != A) {
793
			if(copysub(&p->to, v, s, 1))
794
				return 1;
795
			return 0;
796
		}
797
		if(copyau(&p->to, v))
798
			return 4;
799
		return 3;
800
 
801
	case ATEXT:	/* funny */
802
		if(v->type == D_REG)
803
			if(v->reg == REGARG)
804
				return 3;
805
		return 0;
806
	}
807
	return 0;
808
}
809
 
810
int
811
a2type(Prog *p)
812
{
813
 
814
	switch(p->as) {
815
	case AADD:
816
	case AADDC:
817
	case AADDCC:
818
	case AADDCCC:
819
	case AADDE:
820
	case AADDECC:
821
	case AADDME:
822
	case AADDMECC:
823
	case AADDZE:
824
	case AADDZECC:
825
	case ASUB:
826
	case ASUBC:
827
	case ASUBCC:
828
	case ASUBCCC:
829
	case ASUBE:
830
	case ASUBECC:
831
	case ASUBME:
832
	case ASUBMECC:
833
	case ASUBZE:
834
	case ASUBZECC:
835
	case ASLW:
836
	case ASLWCC:
837
	case ASRW:
838
	case ASRWCC:
839
	case ASRAW:
840
	case ASRAWCC:
841
	case AOR:
842
	case AORCC:
843
	case AORN:
844
	case AORNCC:
845
	case AAND:
846
	case AANDCC:
847
	case AANDN:
848
	case AANDNCC:
849
	case AXOR:
850
	case AXORCC:
851
	case ANEG:
852
	case ANEGCC:
853
	case AMULHW:
854
	case AMULHWU:
855
	case AMULLW:
856
	case AMULLWCC:
857
	case ADIVW:
858
	case ADIVWCC:
859
	case ADIVWU:
860
	case ADIVWUCC:
861
	case AREM:
862
	case AREMCC:
863
	case AREMU:
864
	case AREMUCC:
865
	case ANAND:
866
	case ANANDCC:
867
	case ANOR:
868
	case ANORCC:
869
	case ARLWMI:
870
	case ARLWMICC:
871
	case ARLWNM:
872
	case ARLWNMCC:
873
		return D_REG;
874
 
875
	case AFADDS:
876
	case AFADDSCC:
877
	case AFADD:
878
	case AFADDCC:
879
	case AFSUBS:
880
	case AFSUBSCC:
881
	case AFSUB:
882
	case AFSUBCC:
883
	case AFMULS:
884
	case AFMULSCC:
885
	case AFMUL:
886
	case AFMULCC:
887
	case AFDIVS:
888
	case AFDIVSCC:
889
	case AFDIV:
890
	case AFDIVCC:
891
	case AFNEG:
892
	case AFNEGCC:
893
		return D_FREG;
894
	}
895
	return D_NONE;
896
}
897
 
898
/*
899
 * direct reference,
900
 * could be set/use depending on
901
 * semantics
902
 */
903
int
904
copyas(Adr *a, Adr *v)
905
{
906
 
907
	if(regtyp(v))
908
		if(a->type == v->type)
909
		if(a->reg == v->reg)
910
			return 1;
911
	return 0;
912
}
913
 
914
/*
915
 * either direct or indirect
916
 */
917
int
918
copyau(Adr *a, Adr *v)
919
{
920
 
921
	if(copyas(a, v))
922
		return 1;
923
	if(v->type == D_REG)
924
		if(a->type == D_OREG)
925
			if(v->reg == a->reg)
926
				return 1;
927
	return 0;
928
}
929
 
930
int
931
copyau1(Prog *p, Adr *v)
932
{
933
 
934
	if(regtyp(v))
935
		if(p->from.type == v->type || p->to.type == v->type)
936
		if(p->reg == v->reg) {
937
			if(a2type(p) != v->type)
938
				print("botch a2type %P\n", p);
939
			return 1;
940
		}
941
	return 0;
942
}
943
 
944
/*
945
 * substitute s for v in a
946
 * return failure to substitute
947
 */
948
int
949
copysub(Adr *a, Adr *v, Adr *s, int f)
950
{
951
 
952
	if(f)
953
	if(copyau(a, v))
954
		a->reg = s->reg;
955
	return 0;
956
}
957
 
958
int
959
copysub1(Prog *p1, Adr *v, Adr *s, int f)
960
{
961
 
962
	if(f)
963
	if(copyau1(p1, v))
964
		p1->reg = s->reg;
965
	return 0;
966
}