24 if(p->to.type == D_BRANCH)
41 if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
59 * complete R structure
62 for(r=firstr; r!=R; r=r1) {
91 pc = 0; /* speculating it won't kill */
96 for(r=firstr; r!=R; r=r->link) {
105 if(regtyp(&p->from)) {
111 if(subprop(r) && copyprop(r)) {
119 r1 = rnops(uniqs(r));
122 if(p1->as == AMOVLQZX && p1->from.type == p->to.type && p1->to.type == p->to.type){
134 r1 = rnops(uniqs(r));
137 if(p->to.type != p1->from.type)
139 if((p->as == AMOVBLZX && p1->as == AMOVBQZX)
140 || (p->as == AMOVWLZX && p1->as == AMOVWQZX)
141 || (p->as == AMOVBLSX && p1->as == AMOVBQSX && p1->to.type == p->to.type)
142 || (p->as == AMOVWLSX && p1->as == AMOVWQSX && p1->to.type == p->to.type)) {
147 if(p->as == p1->as) {
162 r1 = rnops(uniqs(r));
165 if(p->as == p1->as && p->to.type == p1->from.type){
175 r1 = rnops(uniqs(r));
178 if((p1->as == AMOVL || p1->as == AMOVQ)
179 && p1->to.type == p->to.type
180 && p1->from.type-D_INDIR == p->to.type
181 && p1->from.index == D_NONE
182 && p1->from.offset == 0){
194 if(p->from.type != D_CONST || needc(p->link))
196 if(p->from.offset == -1){
199 else if(p->as == AADDL)
203 p->from = zprog.from;
205 else if(p->from.offset == 1){
208 else if(p->as == AADDL)
212 p->from = zprog.from;
219 if(p->from.type != D_CONST || needc(p->link))
221 if(p->from.offset == -1) {
224 else if(p->as == ASUBL)
228 p->from = zprog.from;
230 else if(p->from.offset == 1){
233 else if(p->as == ASUBL)
237 p->from = zprog.from;
243 if(p->to.type != D_CONST || p->to.offset != 0 || regtyp(&p->from) == 0)
245 if(p->link == P || (p->link->as != AJEQ && p->link->as != AJNE))
248 while(r1 != R && r1->prog->as == ANOP)
250 if(r1 == R || r1->prog->to.type != p->from.type)
258 /* shift doesnt affect ZF when shift count is zero */
259 if(p1->from.type != D_CONST || p1->from.offset == 0)
289 /* shift doesnt affect ZF when shift count is zero */
290 if(p1->from.type != D_CONST || p1->from.offset == 0)
308 p->from = zprog.from;
320 if(r1 == R || r1->p2link != R)
350 if(t >= D_AX && t <= D_R15)
352 if(t >= D_X0 && t <= D_X0+15)
358 * the idea is to substitute
359 * one register for another
360 * from one MOV to another
362 * ADD b, R0 / no use of R1
364 * would be converted to
368 * hopefully, then the former or latter MOV
369 * will be eliminated by copy propagation.
386 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
394 if(p->to.type != D_NONE)
447 if(p->from.type == D_CX && v1->type == D_CX)
472 * MOV R2, R1 / no use for R1
474 if(p->to.type == v1->type && p->from.type == v2->type){
475 copysub(&p->from, v2, v1, 1);
501 if(p->to.type == v1->type)
505 if(copyau(&p->from, v2) ||
508 if(copysub(&p->from, v1, v2, 0) ||
509 copysub(&p->to, v1, v2, 0))
515 copysub(&p->to, v1, v2, 1);
517 print("gotit: %D->%D\n%P", v1, v2, r->prog);
518 if(p->from.type == v2->type)
522 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
524 copysub(&p->from, v1, v2, 1);
525 copysub(&p->to, v1, v2, 1);
527 print("%P\n", r->prog);
533 print("%P last\n", r->prog);
538 * The idea is to remove redundant copies.
547 * set v2 return success
561 for(r=firstr; r!=R; r=r->link)
563 return copy1(v1, v2, r0->s1, 0);
567 copy1(Adr *v1, Adr *v2, Reg *r, int f)
574 print("act set; return 1\n");
579 print("copy %D->%D f=%d\n", v1, v2, f);
580 for(; r != R; r = r->s1) {
584 if(!f && uniqp(r) == R) {
587 print("; merge; f=%d", f);
591 case 2: /* rar, cant split */
593 print("; %D rar; return 0\n", v2);
598 print("; %D set; return 1\n", v2);
601 case 1: /* used, substitute */
602 case 4: /* use and set */
607 print("; %D used+set and f=%d; return 0\n", v2, f);
609 print("; %D used and f=%d; return 0\n", v2, f);
612 if(copyu(p, v2, v1)) {
614 print("; sub fail; return 0\n");
618 print("; sub %D/%D", v2, v1);
621 print("; %D used+set; return 1\n", v2);
628 if(!f && (t == 2 || t == 3 || t == 4)) {
631 print("; %D set and !f; f=%d", v1, f);
637 if(!copy1(v1, v2, r->s2, f))
645 * 1 if v only used (and substitute),
646 * 2 if read-alter-rewrite
649 * 0 otherwise (not touched)
652 copyu(Prog *p, Adr *v, Adr *s)
659 print("unknown op %A\n", p->as);
660 /* SBBL; ADCL; FLD1; SAHF */
672 if(copyas(&p->to, v))
676 case ALEAL: /* lhs addr, rhs store */
678 if(copyas(&p->from, v))
682 case ANOP: /* rhs store */
713 if(copyas(&p->to, v)) {
715 return copysub(&p->from, v, s, 1);
716 if(copyau(&p->from, v))
746 if(copyas(&p->to, v))
748 if(copyas(&p->from, v))
749 if(p->from.type == D_CX)
753 case AADDB: /* rhs rar */
801 if(copyas(&p->to, v))
805 case ACMPL: /* read only */
816 if(copysub(&p->from, v, s, 1))
818 return copysub(&p->to, v, s, 1);
820 if(copyau(&p->from, v))
822 if(copyau(&p->to, v))
826 case AJGE: /* no reference */
847 if(p->to.type != D_NONE) {
848 if(copyas(&p->to, v))
870 if(v->type == D_AX || v->type == D_DX)
878 if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
882 case AJMP: /* funny */
884 if(copysub(&p->to, v, s, 1))
888 if(copyau(&p->to, v))
892 case ARET: /* funny */
893 if(v->type == REGRET || v->type == FREGRET)
899 case ACALL: /* funny */
900 if(REGEXT && v->type <= REGEXT && v->type > exregoffset)
902 if(REGARG && v->type == REGARG)
906 if(copysub(&p->to, v, s, 1))
910 if(copyau(&p->to, v))
914 case ATEXT: /* funny */
915 if(REGARG && v->type == REGARG)
924 * could be set/use depending on
928 copyas(Adr *a, Adr *v)
930 if(a->type != v->type)
934 if(v->type == D_AUTO || v->type == D_PARAM)
935 if(v->offset == a->offset)
941 * either direct or indirect
944 copyau(Adr *a, Adr *v)
950 if(a->type-D_INDIR == v->type)
952 if(a->index == v->type)
959 * substitute s for v in a
960 * return failure to substitute
963 copysub(Adr *a, Adr *v, Adr *s, int f)
969 if(t >= D_AX && t <= D_R15 || t >= D_X0 && t <= D_X0+15) {
977 if(a->type == t+D_INDIR) {
978 if((s->type == D_BP || s->type == D_R13) && a->index != D_NONE)
979 return 1; /* can't use BP-base with index */
981 a->type = s->type+D_INDIR;