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