10 * complete R structure
13 for(r=firstr; r!=R; r=r1) {
44 * propigate move's by renaming
47 for(r=firstr; r!=R; r=r->link) {
49 if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED)
50 if(regtyp(p->from.type))
56 if(subprop(r) && copyprop(r)) {
64 for(r=firstr; r!=R; r=r->link) {
67 * convert (A) ... A++ into (A)++
68 * and A-- ... (A) into --(A)
70 t = aregind(&p->from);
76 r1 = findop(r, t, AADDL, s);
80 p->from.type += I_INDINC - I_INDIR;
84 r1 = findop(r, t, ASUBL, s);
86 p->from.type += I_INDDEC - I_INDIR;
96 r1 = findop(r, t, AADDL, s);
98 p->to.type += I_INDINC - I_INDIR;
102 r1 = findop(r, t, ASUBL, s);
104 if(usedin(t, &p->from))
106 p->to.type += I_INDDEC - I_INDIR;
111 * get rid of unneeded save/restore CCR
113 if(p->from.type == D_CCR) {
124 if(findtst(r, r->prog, 0))
128 * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP
130 if(p->as == ATSTB && (r1 = r->s1)) {
131 if((r1->prog->as == ABLT && (r2 = r1->s1)) ||
132 (r1->prog->as == ABGE && (r2 = r1->s2))) {
135 if(p1->from.type == D_CONST)
136 if(p1->from.offset == 128)
138 if(tasas(&p->to, &p1->to)) {
153 p->from = zprog.from;
165 if(r1 == R || r1->p2link != R)
190 * chase backward all cc setting.
191 * returns 1 if all set same.
194 findtst(Reg *r0, Prog *rp, int n)
203 for(r=r0->p2; r!=R; r=r->p2link) {
204 c = setcc(r->prog, rp);
209 if(findtst(r, rp, n) == 0)
215 c = setcc(r->prog, rp);
226 * returns -1 if no change
227 * returns 1 if set the same
228 * returns 0 if set different
231 setcc(Prog *p, Prog *rp)
239 print("unknown setcc %A\n", p->as);
282 if(p->to.type >= D_A0 && p->to.type < D_A0+8)
315 if(asize(p->as) != s)
317 if(compat(&rp->to, &p->to))
323 if(p->to.type >= D_A0 && p->to.type < D_A0+8)
326 if(asize(p->as) != s)
328 if(compat(&rp->to, &p->to))
330 if(compat(&rp->to, &p->from))
336 if((rp->to.type&D_MASK) == p->to.type)
342 compat(Adr *a, Adr *b)
347 if((o >= D_R0 && o < D_R0+NREG) ||
348 (o >= D_A0 && o < D_A0+NREG))
351 if(o >= D_A0 && o < D_A0+NREG) {
352 if(o != (b->type&D_MASK))
354 if(a->offset != b->offset)
356 o = a->type & I_MASK;
358 o = b->type & I_MASK;
359 if(o == I_INDIR || o == I_INDDEC)
364 o = b->type & I_MASK;
366 b->type += I_INDINC-I_INDIR;
370 b->type += I_INDIR-I_INDDEC;
385 if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR))
386 while(a->offset == 0)
464 print("unknown asize %A\n", p->as);
469 usedin(int t, Adr *a)
472 if((a->type&D_MASK) == t)
487 if(p->to.type == D_CCR)
506 if(p->to.type >= D_A0 && p->to.type < D_A0+8)
513 findop(Reg *r, int t, int o, int s)
534 if(usedin(t, &p->from))
536 if(usedin(t, &p->to)) {
539 if(p->from.type == D_CONST)
540 if(p->from.offset == s)
552 if(t >= D_R0 && t < D_R0+8)
554 if(t >= D_A0 && t < D_A0+8)
556 if(t >= D_F0 && t < D_F0+8)
571 * the idea is to substitute
572 * one register for another
573 * from one MOV to another
575 * ADD b, R0 / no use of R1
577 * would be converted to
581 * hopefully, then the former or latter MOVL
582 * will be eliminated by copy propagation.
594 if(!regtyp(v1->type))
597 if(!regtyp(v2->type))
599 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
604 case ADIVUW: /* these set Rn and Rn+1 */
614 if(p->to.type == v1->type)
617 if(copyau(&p->from, v2) || copyau(&p->to, v2))
619 if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0))
625 copysub(&p->to, v1, v2, p, 1);
627 print("gotit: %D->%D\n%P", v1, v2, r->prog);
628 if(p->from.type == v2->type)
632 if(p->from.type == v2->type)
634 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
636 copysub(&p->from, v1, v2, p, 1);
637 copysub(&p->to, v1, v2, p, 1);
639 print("%P\n", r->prog);
645 print("%P last\n", r->prog);
650 * The idea is to remove redundant copies.
659 * set v2 return success
673 for(r=firstr; r!=R; r=r->link)
675 return copy1(v1, v2, r0->s1, 0);
679 copy1(Adr *v1, Adr *v2, Reg *r, int f)
685 print("copyret 1\n");
690 print("copy %D->%D\n", v1, v2);
691 for(; r != R; r = r->s1) {
693 print("%P", r->prog);
694 if(!f && uniqp(r) == R) {
697 print("; merge; f=%d", f);
699 t = copyu(r->prog, v2, A);
701 case 2: /* rar, cant split */
703 print("; rar return 0\n");
707 print("; set; return 1\n");
709 case 1: /* used, substitute */
710 case 4: /* use and set */
713 print("; used and f; return 0\n");
716 if(copyu(r->prog, v2, v1)) {
718 print("; sub fail; return 0\n");
722 print("; substitute");
725 print("; used and set; return 1\n");
731 t = copyu(r->prog, v1, A);
732 if(!f && (t == 2 || t == 3 || t == 4)) {
734 print("; f set used");
741 if(!copy1(v1, v2, r->s2, f))
749 * 1 if v only used (and substitute),
750 * 2 if read-alter-rewrite
753 * 0 otherwise (not touched)
756 copyu(Prog *p, Adr *v, Adr *s)
764 print("unknown op %A\n", p->as);
767 case APEA: /* rhs addr */
768 if(copyas(&p->to, v))
772 case ALEA: /* lhs addr, rhs store */
773 if(copyas(&p->from, v))
776 case AMOVL: /* rhs store */
784 if(copyas(&p->to, v)) {
786 return copysub(&p->from, v, s, p, 1);
787 if(copyau(&p->from, v))
793 case AADDL: /* rhs rar */
830 case AMOVW: /* only sets part of register */
845 if(copyas(&p->to, v))
849 case ADBF: /* lhs rar */
850 if(copyas(&p->from, v))
854 case ACMPL: /* read only */
866 if(copysub(&p->from, v, s, p, 1))
868 return copysub(&p->to, v, s, p, 1);
870 if(copyau(&p->from, v))
872 if(copyau(&p->to, v))
876 case ABRA: /* no reference */
901 case ADIVUW: /* these set Rn and Rn+1 */
906 if(t == p->to.type || t == p->to.type+1)
910 case ARTS: /* funny */
912 if(t == D_R0 || t == D_F0)
914 if(t >= D_R0 && t < D_R0+NREG)
915 if(t-D_R0 > exregoffset)
917 if(t >= D_A0 && t < D_A0+NREG)
918 if(t-D_A0 > exaregoffset)
920 if(t >= D_F0 && t < D_F0+NREG)
921 if(t-D_F0 > exfregoffset)
925 case ABSR: /* funny */
927 if(t >= D_R0 && t < D_R0+NREG)
928 if(t-D_R0 > exregoffset)
930 if(t >= D_A0 && t < D_A0+NREG)
931 if(t-D_A0 > exaregoffset)
933 if(t >= D_F0 && t < D_F0+NREG)
934 if(t-D_F0 > exfregoffset)
936 if(copyau(&p->to, v))
945 * could be set/use depending on
949 copyas(Adr *a, Adr *v)
952 if(a->type != v->type)
956 if(v->type == D_AUTO || v->type == D_PARAM) {
957 if(v->offset == a->offset)
968 tasas(Adr *a, Adr *v)
973 if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8)
977 if(a->displace != v->displace)
983 * either direct or indirect
986 copyau(Adr *a, Adr *v)
994 if((a->type & D_MASK) == t)
1001 * substitute s for v in a
1002 * return failure to substitute
1005 copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f)
1011 if(t >= D_F0 && t < D_F0+8) {
1016 if(t >= D_R0 && t < D_R0+8) {
1021 if(!(t >= D_A0 && t < D_A0+8))
1037 if(a == &p->from && !regtyp(p->to.type))
1047 if((a->type & D_MASK) == t) {
1048 if((s->type ^ t) & ~(NREG-1))
1051 a->type = (a->type & ~D_MASK) | s->type;