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 */
322 int
regzer(Adr * a)323 regzer(Adr *a)
324 {
325 if(R0ISZERO) {
326 if(a->type == D_CONST)
327 if(a->sym == S)
328 if(a->offset == 0)
329 return 1;
330 if(a->type == D_REG)
331 if(a->reg == REGZERO)
332 return 1;
333 }
334 return 0;
335 }
336
337 int
regtyp(Adr * a)338 regtyp(Adr *a)
339 {
340
341 if(a->type == D_REG) {
342 if(!R0ISZERO || a->reg != REGZERO)
343 return 1;
344 return 0;
345 }
346 if(a->type == D_FREG)
347 return 1;
348 return 0;
349 }
350
351 /*
352 * the idea is to substitute
353 * one register for another
354 * from one MOV to another
355 * MOV a, R0
356 * ADD b, R0 / no use of R1
357 * MOV R0, R1
358 * would be converted to
359 * MOV a, R1
360 * ADD b, R1
361 * MOV R1, R0
362 * hopefully, then the former or latter MOV
363 * will be eliminated by copy propagation.
364 */
365 int
subprop(Reg * r0)366 subprop(Reg *r0)
367 {
368 Prog *p;
369 Adr *v1, *v2;
370 Reg *r;
371 int t;
372
373 p = r0->prog;
374 v1 = &p->from;
375 if(!regtyp(v1))
376 return 0;
377 v2 = &p->to;
378 if(!regtyp(v2))
379 return 0;
380 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
381 if(uniqs(r) == R)
382 break;
383 p = r->prog;
384 switch(p->as) {
385 case ABL:
386 return 0;
387
388 case AADD:
389 case AADDC:
390 case AADDCC:
391 case AADDE:
392 case AADDECC:
393 case ASUB:
394 case ASUBCC:
395 case ASUBC:
396 case ASUBCCC:
397 case ASUBE:
398 case ASUBECC:
399 case ASLW:
400 case ASLWCC:
401 case ASRW:
402 case ASRWCC:
403 case ASRAW:
404 case ASRAWCC:
405 case AOR:
406 case AORCC:
407 case AORN:
408 case AORNCC:
409 case AAND:
410 case AANDCC:
411 case AANDN:
412 case AANDNCC:
413 case ANAND:
414 case ANANDCC:
415 case ANOR:
416 case ANORCC:
417 case AXOR:
418 case AXORCC:
419 case AMULHW:
420 case AMULHWU:
421 case AMULLW:
422 case ADIVW:
423 case ADIVWU:
424 case AREM:
425 case AREMU:
426 case ARLWNM:
427 case ARLWNMCC:
428
429 case AFADD:
430 case AFADDS:
431 case AFSUB:
432 case AFSUBS:
433 case AFMUL:
434 case AFMULS:
435 case AFDIV:
436 case AFDIVS:
437 if(p->to.type == v1->type)
438 if(p->to.reg == v1->reg) {
439 if(p->reg == NREG)
440 p->reg = p->to.reg;
441 goto gotit;
442 }
443 break;
444
445 case AADDME:
446 case AADDMECC:
447 case AADDZE:
448 case AADDZECC:
449 case ASUBME:
450 case ASUBMECC:
451 case ASUBZE:
452 case ASUBZECC:
453 case ANEG:
454 case ANEGCC:
455 case AFNEG:
456 case AFNEGCC:
457 case AFMOVS:
458 case AFMOVD:
459 case AMOVW:
460 if(p->to.type == v1->type)
461 if(p->to.reg == v1->reg)
462 goto gotit;
463 break;
464 }
465 if(copyau(&p->from, v2) ||
466 copyau1(p, v2) ||
467 copyau(&p->to, v2))
468 break;
469 if(copysub(&p->from, v1, v2, 0) ||
470 copysub1(p, v1, v2, 0) ||
471 copysub(&p->to, v1, v2, 0))
472 break;
473 }
474 return 0;
475
476 gotit:
477 copysub(&p->to, v1, v2, 1);
478 if(debug['P']) {
479 print("gotit: %D->%D\n%P", v1, v2, r->prog);
480 if(p->from.type == v2->type)
481 print(" excise");
482 print("\n");
483 }
484 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
485 p = r->prog;
486 copysub(&p->from, v1, v2, 1);
487 copysub1(p, v1, v2, 1);
488 copysub(&p->to, v1, v2, 1);
489 if(debug['P'])
490 print("%P\n", r->prog);
491 }
492 t = v1->reg;
493 v1->reg = v2->reg;
494 v2->reg = t;
495 if(debug['P'])
496 print("%P last\n", r->prog);
497 return 1;
498 }
499
500 /*
501 * The idea is to remove redundant copies.
502 * v1->v2 F=0
503 * (use v2 s/v2/v1/)*
504 * set v1 F=1
505 * use v2 return fail
506 * -----------------
507 * v1->v2 F=0
508 * (use v2 s/v2/v1/)*
509 * set v1 F=1
510 * set v2 return success
511 */
512 int
copyprop(Reg * r0)513 copyprop(Reg *r0)
514 {
515 Prog *p;
516 Adr *v1, *v2;
517 Reg *r;
518
519 p = r0->prog;
520 v1 = &p->from;
521 v2 = &p->to;
522 if(copyas(v1, v2))
523 return 1;
524 for(r=firstr; r!=R; r=r->link)
525 r->active = 0;
526 return copy1(v1, v2, r0->s1, 0);
527 }
528
529 int
copy1(Adr * v1,Adr * v2,Reg * r,int f)530 copy1(Adr *v1, Adr *v2, Reg *r, int f)
531 {
532 int t;
533 Prog *p;
534
535 if(r->active) {
536 if(debug['P'])
537 print("act set; return 1\n");
538 return 1;
539 }
540 r->active = 1;
541 if(debug['P'])
542 print("copy %D->%D f=%d\n", v1, v2, f);
543 for(; r != R; r = r->s1) {
544 p = r->prog;
545 if(debug['P'])
546 print("%P", p);
547 if(!f && uniqp(r) == R) {
548 f = 1;
549 if(debug['P'])
550 print("; merge; f=%d", f);
551 }
552 t = copyu(p, v2, A);
553 switch(t) {
554 case 2: /* rar, cant split */
555 if(debug['P'])
556 print("; %Drar; return 0\n", v2);
557 return 0;
558
559 case 3: /* set */
560 if(debug['P'])
561 print("; %Dset; return 1\n", v2);
562 return 1;
563
564 case 1: /* used, substitute */
565 case 4: /* use and set */
566 if(f) {
567 if(!debug['P'])
568 return 0;
569 if(t == 4)
570 print("; %Dused+set and f=%d; return 0\n", v2, f);
571 else
572 print("; %Dused and f=%d; return 0\n", v2, f);
573 return 0;
574 }
575 if(copyu(p, v2, v1)) {
576 if(debug['P'])
577 print("; sub fail; return 0\n");
578 return 0;
579 }
580 if(debug['P'])
581 print("; sub%D/%D", v2, v1);
582 if(t == 4) {
583 if(debug['P'])
584 print("; %Dused+set; return 1\n", v2);
585 return 1;
586 }
587 break;
588 }
589 if(!f) {
590 t = copyu(p, v1, A);
591 if(!f && (t == 2 || t == 3 || t == 4)) {
592 f = 1;
593 if(debug['P'])
594 print("; %Dset and !f; f=%d", v1, f);
595 }
596 }
597 if(debug['P'])
598 print("\n");
599 if(r->s2)
600 if(!copy1(v1, v2, r->s2, f))
601 return 0;
602 }
603 return 1;
604 }
605
606 /*
607 * return
608 * 1 if v only used (and substitute),
609 * 2 if read-alter-rewrite
610 * 3 if set
611 * 4 if set and used
612 * 0 otherwise (not touched)
613 */
614 int
copyu(Prog * p,Adr * v,Adr * s)615 copyu(Prog *p, Adr *v, Adr *s)
616 {
617
618 switch(p->as) {
619
620 default:
621 if(debug['P'])
622 print(" (?)");
623 return 2;
624
625 case ANOP: /* read, write */
626 case AMOVW:
627 case AMOVH:
628 case AMOVHZ:
629 case AMOVB:
630 case AMOVBZ:
631
632 case ANEG:
633 case ANEGCC:
634 case AADDME:
635 case AADDMECC:
636 case AADDZE:
637 case AADDZECC:
638 case ASUBME:
639 case ASUBMECC:
640 case ASUBZE:
641 case ASUBZECC:
642
643 case AFCTIW:
644 case AFCTIWZ:
645 case AFMOVS:
646 case AFMOVD:
647 case AFRSP:
648 case AFNEG:
649 case AFNEGCC:
650 if(s != A) {
651 if(copysub(&p->from, v, s, 1))
652 return 1;
653 if(!copyas(&p->to, v))
654 if(copysub(&p->to, v, s, 1))
655 return 1;
656 return 0;
657 }
658 if(copyas(&p->to, v)) {
659 if(copyau(&p->from, v))
660 return 4;
661 return 3;
662 }
663 if(copyau(&p->from, v))
664 return 1;
665 if(copyau(&p->to, v))
666 return 1;
667 return 0;
668
669 case ARLWMI: /* read read rar */
670 case ARLWMICC:
671 if(copyas(&p->to, v))
672 return 2;
673 /* fall through */
674
675 case AADD: /* read read write */
676 case AADDC:
677 case AADDE:
678 case ASUB:
679 case ASLW:
680 case ASRW:
681 case ASRAW:
682 case AOR:
683 case AORCC:
684 case AORN:
685 case AORNCC:
686 case AAND:
687 case AANDCC:
688 case AANDN:
689 case AANDNCC:
690 case ANAND:
691 case ANANDCC:
692 case ANOR:
693 case ANORCC:
694 case AXOR:
695 case AMULHW:
696 case AMULHWU:
697 case AMULLW:
698 case ADIVW:
699 case ADIVWU:
700 case AREM:
701 case AREMU:
702 case ARLWNM:
703 case ARLWNMCC:
704
705 case AFADDS:
706 case AFADD:
707 case AFSUBS:
708 case AFSUB:
709 case AFMULS:
710 case AFMUL:
711 case AFDIVS:
712 case AFDIV:
713 if(s != A) {
714 if(copysub(&p->from, v, s, 1))
715 return 1;
716 if(copysub1(p, v, s, 1))
717 return 1;
718 if(!copyas(&p->to, v))
719 if(copysub(&p->to, v, s, 1))
720 return 1;
721 return 0;
722 }
723 if(copyas(&p->to, v)) {
724 if(p->reg == NREG)
725 p->reg = p->to.reg;
726 if(copyau(&p->from, v))
727 return 4;
728 if(copyau1(p, v))
729 return 4;
730 return 3;
731 }
732 if(copyau(&p->from, v))
733 return 1;
734 if(copyau1(p, v))
735 return 1;
736 if(copyau(&p->to, v))
737 return 1;
738 return 0;
739
740 case ABEQ:
741 case ABGT:
742 case ABGE:
743 case ABLT:
744 case ABLE:
745 case ABNE:
746 case ABVC:
747 case ABVS:
748 break;
749
750 case ACMP: /* read read */
751 case ACMPU:
752 case AFCMPO:
753 case AFCMPU:
754 if(s != A) {
755 if(copysub(&p->from, v, s, 1))
756 return 1;
757 return copysub(&p->to, v, s, 1);
758 }
759 if(copyau(&p->from, v))
760 return 1;
761 if(copyau(&p->to, v))
762 return 1;
763 break;
764
765 case ABR: /* funny */
766 if(s != A) {
767 if(copysub(&p->to, v, s, 1))
768 return 1;
769 return 0;
770 }
771 if(copyau(&p->to, v))
772 return 1;
773 return 0;
774
775 case ARETURN: /* funny */
776 if(v->type == D_REG)
777 if(v->reg == REGRET)
778 return 2;
779 if(v->type == D_FREG)
780 if(v->reg == FREGRET)
781 return 2;
782
783 case ABL: /* funny */
784 if(v->type == D_REG) {
785 if(v->reg <= REGEXT && v->reg > exregoffset)
786 return 2;
787 if(v->reg == REGARG)
788 return 2;
789 }
790 if(v->type == D_FREG) {
791 if(v->reg <= FREGEXT && v->reg > exfregoffset)
792 return 2;
793 }
794
795 if(s != A) {
796 if(copysub(&p->to, v, s, 1))
797 return 1;
798 return 0;
799 }
800 if(copyau(&p->to, v))
801 return 4;
802 return 3;
803
804 case ATEXT: /* funny */
805 if(v->type == D_REG)
806 if(v->reg == REGARG)
807 return 3;
808 return 0;
809 }
810 return 0;
811 }
812
813 int
a2type(Prog * p)814 a2type(Prog *p)
815 {
816
817 switch(p->as) {
818 case AADD:
819 case AADDC:
820 case AADDCC:
821 case AADDCCC:
822 case AADDE:
823 case AADDECC:
824 case AADDME:
825 case AADDMECC:
826 case AADDZE:
827 case AADDZECC:
828 case ASUB:
829 case ASUBC:
830 case ASUBCC:
831 case ASUBCCC:
832 case ASUBE:
833 case ASUBECC:
834 case ASUBME:
835 case ASUBMECC:
836 case ASUBZE:
837 case ASUBZECC:
838 case ASLW:
839 case ASLWCC:
840 case ASRW:
841 case ASRWCC:
842 case ASRAW:
843 case ASRAWCC:
844 case AOR:
845 case AORCC:
846 case AORN:
847 case AORNCC:
848 case AAND:
849 case AANDCC:
850 case AANDN:
851 case AANDNCC:
852 case AXOR:
853 case AXORCC:
854 case ANEG:
855 case ANEGCC:
856 case AMULHW:
857 case AMULHWU:
858 case AMULLW:
859 case AMULLWCC:
860 case ADIVW:
861 case ADIVWCC:
862 case ADIVWU:
863 case ADIVWUCC:
864 case AREM:
865 case AREMCC:
866 case AREMU:
867 case AREMUCC:
868 case ANAND:
869 case ANANDCC:
870 case ANOR:
871 case ANORCC:
872 case ARLWMI:
873 case ARLWMICC:
874 case ARLWNM:
875 case ARLWNMCC:
876 return D_REG;
877
878 case AFADDS:
879 case AFADDSCC:
880 case AFADD:
881 case AFADDCC:
882 case AFSUBS:
883 case AFSUBSCC:
884 case AFSUB:
885 case AFSUBCC:
886 case AFMULS:
887 case AFMULSCC:
888 case AFMUL:
889 case AFMULCC:
890 case AFDIVS:
891 case AFDIVSCC:
892 case AFDIV:
893 case AFDIVCC:
894 case AFNEG:
895 case AFNEGCC:
896 return D_FREG;
897 }
898 return D_NONE;
899 }
900
901 /*
902 * direct reference,
903 * could be set/use depending on
904 * semantics
905 */
906 int
copyas(Adr * a,Adr * v)907 copyas(Adr *a, Adr *v)
908 {
909
910 if(regtyp(v))
911 if(a->type == v->type)
912 if(a->reg == v->reg)
913 return 1;
914 return 0;
915 }
916
917 /*
918 * either direct or indirect
919 */
920 int
copyau(Adr * a,Adr * v)921 copyau(Adr *a, Adr *v)
922 {
923
924 if(copyas(a, v))
925 return 1;
926 if(v->type == D_REG)
927 if(a->type == D_OREG)
928 if(v->reg == a->reg)
929 return 1;
930 return 0;
931 }
932
933 int
copyau1(Prog * p,Adr * v)934 copyau1(Prog *p, Adr *v)
935 {
936
937 if(regtyp(v))
938 if(p->from.type == v->type || p->to.type == v->type)
939 if(p->reg == v->reg) {
940 if(a2type(p) != v->type)
941 print("botch a2type %P\n", p);
942 return 1;
943 }
944 return 0;
945 }
946
947 /*
948 * substitute s for v in a
949 * return failure to substitute
950 */
951 int
copysub(Adr * a,Adr * v,Adr * s,int f)952 copysub(Adr *a, Adr *v, Adr *s, int f)
953 {
954
955 if(f)
956 if(copyau(a, v))
957 a->reg = s->reg;
958 return 0;
959 }
960
961 int
copysub1(Prog * p1,Adr * v,Adr * s,int f)962 copysub1(Prog *p1, Adr *v, Adr *s, int f)
963 {
964
965 if(f)
966 if(copyau1(p1, v))
967 p1->reg = s->reg;
968 return 0;
969 }
970