1 #include "gc.h"
2
3 void
peep(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
excise(Reg * r)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*
uniqp(Reg * r)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*
uniqs(Reg * r)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 */
regzer(Adr * a)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
regtyp(Adr * a)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
subprop(Reg * r0)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
copyprop(Reg * r0)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
copy1(Adr * v1,Adr * v2,Reg * r,int f)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
copyu(Prog * p,Adr * v,Adr * s)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
a2type(Prog * p)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
copyas(Adr * a,Adr * v)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
copyau(Adr * a,Adr * v)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
copyau1(Prog * p,Adr * v)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
copysub(Adr * a,Adr * v,Adr * s,int f)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
copysub1(Prog * p1,Adr * v,Adr * s,int f)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 }
967