]> 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
index 5f61925d73e93fdffe807073859969af2d475bf3..482f17a65c835adce7c1b8e027d5313d5e1a4017 100644 (file)
@@ -137,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)
@@ -231,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)
@@ -250,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:
@@ -268,19 +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 ASTOSB:
-               case ASTOSL:
-               case AMOVSB:
-               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)