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)
346 if(a->index != D_NONE)
348 if(b->index != D_NONE)
351 if((o >= D_R0 && o < D_R0+NREG) ||
352 (o >= D_A0 && o < D_A0+NREG))
355 if(o >= D_A0 && o < D_A0+NREG) {
356 if(o != (b->type&D_MASK))
358 if(a->offset != b->offset)
360 o = a->type & I_MASK;
362 o = b->type & I_MASK;
363 if(o == I_INDIR || o == I_INDDEC)
368 o = b->type & I_MASK;
370 b->type += I_INDINC-I_INDIR;
374 b->type += I_INDIR-I_INDDEC;
389 if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR))
390 while(a->offset == 0 && a->index == D_NONE)
468 print("unknown asize %A\n", p->as);
473 usedin(int t, Adr *a)
476 if((a->type&D_MASK) == t)
478 if((a->index&D_MASK) == t)
493 if(p->to.type == D_CCR)
512 if(p->to.type >= D_A0 && p->to.type < D_A0+8)
519 findop(Reg *r, int t, int o, int s)
540 if(usedin(t, &p->from))
542 if(usedin(t, &p->to)) {
545 if(p->to.index == D_NONE)
546 if(p->from.type == D_CONST)
547 if(p->from.offset == s)
559 if(t >= D_R0 && t < D_R0+8)
561 if(t >= D_A0 && t < D_A0+8)
563 if(t >= D_F0 && t < D_F0+8)
578 * the idea is to substitute
579 * one register for another
580 * from one MOV to another
582 * ADD b, R0 / no use of R1
584 * would be converted to
588 * hopefully, then the former or latter MOVL
589 * will be eliminated by copy propagation.
601 if(!regtyp(v1->type))
604 if(!regtyp(v2->type))
606 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
611 case ADIVUW: /* these set Rn and Rn+1 */
621 if(p->to.type == v1->type)
624 if(copyau(&p->from, v2) || copyau(&p->to, v2))
626 if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0))
632 copysub(&p->to, v1, v2, p, 1);
634 print("gotit: %D->%D\n%P", v1, v2, r->prog);
635 if(p->from.type == v2->type)
639 if(p->from.type == v2->type)
641 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
643 copysub(&p->from, v1, v2, p, 1);
644 copysub(&p->to, v1, v2, p, 1);
646 print("%P\n", r->prog);
652 print("%P last\n", r->prog);
657 * The idea is to remove redundant copies.
666 * set v2 return success
680 for(r=firstr; r!=R; r=r->link)
682 return copy1(v1, v2, r0->s1, 0);
686 copy1(Adr *v1, Adr *v2, Reg *r, int f)
692 print("copyret 1\n");
697 print("copy %D->%D\n", v1, v2);
698 for(; r != R; r = r->s1) {
700 print("%P", r->prog);
701 if(!f && uniqp(r) == R) {
704 print("; merge; f=%d", f);
706 t = copyu(r->prog, v2, A);
708 case 2: /* rar, cant split */
710 print("; rar return 0\n");
714 print("; set; return 1\n");
716 case 1: /* used, substitute */
717 case 4: /* use and set */
720 print("; used and f; return 0\n");
723 if(copyu(r->prog, v2, v1)) {
725 print("; sub fail; return 0\n");
729 print("; substitute");
732 print("; used and set; return 1\n");
738 t = copyu(r->prog, v1, A);
739 if(!f && (t == 2 || t == 3 || t == 4)) {
741 print("; f set used");
748 if(!copy1(v1, v2, r->s2, f))
756 * 1 if v only used (and substitute),
757 * 2 if read-alter-rewrite
760 * 0 otherwise (not touched)
763 copyu(Prog *p, Adr *v, Adr *s)
771 print("unknown op %A\n", p->as);
774 case APEA: /* rhs addr */
775 if(copyas(&p->to, v))
779 case ALEA: /* lhs addr, rhs store */
780 if(copyas(&p->from, v))
783 case AMOVL: /* rhs store */
791 if(copyas(&p->to, v)) {
793 return copysub(&p->from, v, s, p, 1);
794 if(copyau(&p->from, v))
800 case AADDL: /* rhs rar */
837 case AMOVW: /* only sets part of register */
852 if(copyas(&p->to, v))
856 case ADBF: /* lhs rar */
857 if(copyas(&p->from, v))
861 case ACMPL: /* read only */
873 if(copysub(&p->from, v, s, p, 1))
875 return copysub(&p->to, v, s, p, 1);
877 if(copyau(&p->from, v))
879 if(copyau(&p->to, v))
883 case ABRA: /* no reference */
908 case ADIVUW: /* these set Rn and Rn+1 */
913 if(t == p->to.type || t == p->to.type+1)
917 case ARTS: /* funny */
919 if(t == D_R0 || t == D_F0)
921 if(t >= D_R0 && t < D_R0+NREG)
922 if(t-D_R0 > exregoffset)
924 if(t >= D_A0 && t < D_A0+NREG)
925 if(t-D_A0 > exaregoffset)
927 if(t >= D_F0 && t < D_F0+NREG)
928 if(t-D_F0 > exfregoffset)
932 case ABSR: /* funny */
934 if(t >= D_R0 && t < D_R0+NREG)
935 if(t-D_R0 > exregoffset)
937 if(t >= D_A0 && t < D_A0+NREG)
938 if(t-D_A0 > exaregoffset)
940 if(t >= D_F0 && t < D_F0+NREG)
941 if(t-D_F0 > exfregoffset)
950 * could be set/use depending on
954 copyas(Adr *a, Adr *v)
957 if(a->type != v->type)
961 if(v->type == D_AUTO || v->type == D_PARAM) {
962 if(v->offset == a->offset)
973 tasas(Adr *a, Adr *v)
977 if(a->index != D_NONE)
979 if(v->index != D_NONE)
982 if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8)
986 if(a->displace != v->displace)
992 * either direct or indirect
995 copyau(Adr *a, Adr *v)
1003 if((a->type & D_MASK) == t)
1005 if((a->index & D_MASK) == t)
1012 * substitute s for v in a
1013 * return failure to substitute
1016 copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f)
1022 if(t >= D_F0 && t < D_F0+8) {
1027 if(t >= D_R0 && t < D_R0+8) {
1032 if(!(t >= D_A0 && t < D_A0+8))
1048 if(a == &p->from && !regtyp(p->to.type))
1058 if((a->type & D_MASK) == t) {
1059 if((s->type ^ t) & ~(NREG-1))
1062 a->type = (a->type & ~D_MASK) | s->type;
1065 if((a->index & D_MASK) == t) {
1067 a->index = (a->index & ~D_MASK) | s->type;