]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/8c/peep.c
8c, 6c: native ROL (cyclic shift) instruction support, improve peephole optimizers
[plan9front.git] / sys / src / cmd / 8c / peep.c
old mode 100755 (executable)
new mode 100644 (file)
index d67f751..482f17a
@@ -67,8 +67,6 @@ peep(void)
        pc = 0; /* speculating it won't kill */
 
 loop1:
-       if(debug['b'])
-               comtarg();
 
        t = 0;
        for(r=firstr; r!=R; r=r->link) {
@@ -139,6 +137,39 @@ loop1:
                                p->from = zprog.from;
                        }
                        break;
+
+               case ACMPL:
+                       if(p->to.type != D_CONST || p->to.offset != 0 || regtyp(&p->from) == 0)
+                               break;
+                       if(p->link == P || (p->link->as != AJEQ && p->link->as != AJNE))
+                               break;
+                       r1 = uniqp(r);
+                       while(r1 != R && r1->prog->as == ANOP)
+                               r1 = uniqp(r1);
+                       if(r1 == R || r1->prog->to.type != p->from.type)
+                               break;
+                       p1 = r1->prog;
+                       switch(p1->as){
+                       case ASALL:
+                       case ASARL:
+                       case ASHLL:
+                       case ASHRL:
+                               /* shift doesnt affect ZF when shift count is zero */
+                               if(p1->from.type != D_CONST || p1->from.offset == 0)
+                                       break;
+                       case AANDL:
+                       case AORL:
+                       case AXORL:
+                       case ANEGL:
+                       case AADDL:
+                       case AADCL:
+                       case ASUBL:
+                       case ASBBL:
+                       case AINCL:
+                       case ADECL:
+                               excise(r);
+                       }
+                       break;
                }
        }
        if(t)
@@ -233,9 +264,6 @@ subprop(Reg *r0)
                        break;
                p = r->prog;
                switch(p->as) {
-               case ACALL:
-                       return 0;
-
                case AIMULL:
                case AIMULW:
                        if(p->to.type != D_NONE)
@@ -252,6 +280,23 @@ subprop(Reg *r0)
                case AMULL:
                case AMULW:
 
+               case AREP:
+               case AREPN:
+               case ALOOP:
+               case ALOOPNE:
+
+               case ACWD:
+               case ACDQ:
+
+               case ASTOSB:
+               case ASTOSL:
+               case AMOVSB:
+               case AMOVSL:
+               case AFSTSW:
+
+               case ACALL:
+                       return 0;
+
                case AROLB:
                case AROLL:
                case AROLW:
@@ -270,16 +315,28 @@ subprop(Reg *r0)
                case ASHRB:
                case ASHRL:
                case ASHRW:
+                       if(p->from.type == D_CX && v1->type == D_CX)
+                               return 0;
+                       break;
 
-               case AREP:
-               case AREPN:
-
-               case ACWD:
-               case ACDQ:
-
-               case AMOVSL:
-               case AFSTSW:
-                       return 0;
+               case AORL:
+               case AANDL:
+               case AXORL:
+               case AADDL:
+               case AADCL:
+                       /*
+                        * can swap when:
+                        *  ADD R2, R1
+                        *  MOV R1, R2
+                        * convert to:
+                        *  ADD R1, R2
+                        *  MOV R2, R1  / no use for R1
+                        */
+                       if(p->to.type == v1->type && p->from.type == v2->type){
+                               copysub(&p->from, v2, v1, 1);
+                               goto gotit;
+                       }
+                       break;
 
                case AMOVL:
                        if(p->to.type == v1->type)
@@ -641,10 +698,21 @@ copyu(Prog *p, Adr *v, Adr *s)
                        return 2;
                goto caseread;
 
-       case AMOVSL:
        case AREP:
        case AREPN:
-               if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
+               if(v->type == D_CX)
+                       return 2;
+               goto caseread;
+
+       case AMOVSB:
+       case AMOVSL:
+               if(v->type == D_DI || v->type == D_SI)
+                       return 2;
+               goto caseread;
+
+       case ASTOSB:
+       case ASTOSL:
+               if(v->type == D_AX || v->type == D_DI)
                        return 2;
                goto caseread;