]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: finish implementing comparisons
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Jul 2015 19:47:00 +0000 (12:47 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Jul 2015 20:44:11 +0000 (20:44 +0000)
Change-Id: I4e496c7c7239111133631f76ca25e14be64800c6
Reviewed-on: https://go-review.googlesource.com/12656
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/gen/AMD64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteAMD64.go

index 2b6962a9791d8170ee1dc2864a0ab4ca0235ee17..b8831793fc0db20e31c3d132cee485e503f78b92 100644 (file)
@@ -1702,7 +1702,8 @@ func genValue(v *ssa.Value) {
        case ssa.OpAMD64SETEQ, ssa.OpAMD64SETNE,
                ssa.OpAMD64SETL, ssa.OpAMD64SETLE,
                ssa.OpAMD64SETG, ssa.OpAMD64SETGE,
-               ssa.OpAMD64SETB:
+               ssa.OpAMD64SETB, ssa.OpAMD64SETBE,
+               ssa.OpAMD64SETA, ssa.OpAMD64SETAE:
                p := Prog(v.Op.Asm())
                p.To.Type = obj.TYPE_REG
                p.To.Reg = regnum(v)
@@ -1725,6 +1726,19 @@ func movZero(as int, width int64, nbytes int64, offset int64, regnum int16) (nle
        return nleft, offset
 }
 
+var blockJump = [...]struct{ asm, invasm int }{
+       ssa.BlockAMD64EQ:  {x86.AJEQ, x86.AJNE},
+       ssa.BlockAMD64NE:  {x86.AJNE, x86.AJEQ},
+       ssa.BlockAMD64LT:  {x86.AJLT, x86.AJGE},
+       ssa.BlockAMD64GE:  {x86.AJGE, x86.AJLT},
+       ssa.BlockAMD64LE:  {x86.AJLE, x86.AJGT},
+       ssa.BlockAMD64GT:  {x86.AJGT, x86.AJLE},
+       ssa.BlockAMD64ULT: {x86.AJCS, x86.AJCC},
+       ssa.BlockAMD64UGE: {x86.AJCC, x86.AJCS},
+       ssa.BlockAMD64UGT: {x86.AJHI, x86.AJLS},
+       ssa.BlockAMD64ULE: {x86.AJLS, x86.AJHI},
+}
+
 func genBlock(b, next *ssa.Block, branches []branch) []branch {
        lineno = b.Line
        switch b.Kind {
@@ -1742,85 +1756,24 @@ func genBlock(b, next *ssa.Block, branches []branch) []branch {
                        p.To.Type = obj.TYPE_BRANCH
                        branches = append(branches, branch{p, b.Succs[0]})
                }
-       case ssa.BlockAMD64EQ:
-               if b.Succs[0] == next {
-                       p := Prog(x86.AJNE)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[1]})
-               } else if b.Succs[1] == next {
-                       p := Prog(x86.AJEQ)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-               } else {
-                       p := Prog(x86.AJEQ)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-                       q := Prog(obj.AJMP)
-                       q.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{q, b.Succs[1]})
-               }
-       case ssa.BlockAMD64NE:
-               if b.Succs[0] == next {
-                       p := Prog(x86.AJEQ)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[1]})
-               } else if b.Succs[1] == next {
-                       p := Prog(x86.AJNE)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-               } else {
-                       p := Prog(x86.AJNE)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-                       q := Prog(obj.AJMP)
-                       q.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{q, b.Succs[1]})
-               }
-       case ssa.BlockAMD64LT:
-               if b.Succs[0] == next {
-                       p := Prog(x86.AJGE)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[1]})
-               } else if b.Succs[1] == next {
-                       p := Prog(x86.AJLT)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-               } else {
-                       p := Prog(x86.AJLT)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-                       q := Prog(obj.AJMP)
-                       q.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{q, b.Succs[1]})
-               }
-       case ssa.BlockAMD64ULT:
-               if b.Succs[0] == next {
-                       p := Prog(x86.AJCC)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[1]})
-               } else if b.Succs[1] == next {
-                       p := Prog(x86.AJCS)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-               } else {
-                       p := Prog(x86.AJCS)
-                       p.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{p, b.Succs[0]})
-                       q := Prog(obj.AJMP)
-                       q.To.Type = obj.TYPE_BRANCH
-                       branches = append(branches, branch{q, b.Succs[1]})
-               }
-       case ssa.BlockAMD64UGT:
-               if b.Succs[0] == next {
-                       p := Prog(x86.AJLS)
+       case ssa.BlockAMD64EQ, ssa.BlockAMD64NE,
+               ssa.BlockAMD64LT, ssa.BlockAMD64GE,
+               ssa.BlockAMD64LE, ssa.BlockAMD64GT,
+               ssa.BlockAMD64ULT, ssa.BlockAMD64UGT,
+               ssa.BlockAMD64ULE, ssa.BlockAMD64UGE:
+
+               jmp := blockJump[b.Kind]
+               switch next {
+               case b.Succs[0]:
+                       p := Prog(jmp.invasm)
                        p.To.Type = obj.TYPE_BRANCH
                        branches = append(branches, branch{p, b.Succs[1]})
-               } else if b.Succs[1] == next {
-                       p := Prog(x86.AJHI)
+               case b.Succs[1]:
+                       p := Prog(jmp.asm)
                        p.To.Type = obj.TYPE_BRANCH
                        branches = append(branches, branch{p, b.Succs[0]})
-               } else {
-                       p := Prog(x86.AJHI)
+               default:
+                       p := Prog(jmp.asm)
                        p.To.Type = obj.TYPE_BRANCH
                        branches = append(branches, branch{p, b.Succs[0]})
                        q := Prog(obj.AJMP)
index 59f556408073c754c38a07a6706867ee3190ddcc..f1ae4f6a82c0bb9e1461f082920fc85a3b20705a 100644 (file)
 
 // block rewrites
 (If (SETL cmp) yes no) -> (LT cmp yes no)
+(If (SETLE cmp) yes no) -> (LE cmp yes no)
+(If (SETG cmp) yes no) -> (GT cmp yes no)
+(If (SETGE cmp) yes no) -> (GE cmp yes no)
 (If (SETEQ cmp) yes no) -> (EQ cmp yes no)
 (If (SETNE cmp) yes no) -> (NE cmp yes no)
 (If (SETB cmp) yes no) -> (ULT cmp yes no)
+(If (SETBE cmp) yes no) -> (ULE cmp yes no)
+(If (SETA cmp) yes no) -> (UGT cmp yes no)
+(If (SETAE cmp) yes no) -> (UGE cmp yes no)
 (If cond yes no) && cond.Op == OpAMD64MOVBload -> (NE (TESTB <TypeFlags> cond cond) yes no)
 
 (StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem)
index 382d666ae61c8b93775cae0ff1ba749f088e9a01..382d64c9de28e00a3768603946afec1645ca0561 100644 (file)
@@ -123,6 +123,9 @@ func init() {
                {name: "SETG", reg: flagsgp, asm: "SETGT"},  // extract signed > condition from arg0
                {name: "SETGE", reg: flagsgp, asm: "SETGE"}, // extract signed >= condition from arg0
                {name: "SETB", reg: flagsgp, asm: "SETCS"},  // extract unsigned < condition from arg0
+               {name: "SETBE", reg: flagsgp, asm: "SETLS"}, // extract unsigned <= condition from arg0
+               {name: "SETA", reg: flagsgp, asm: "SETHI"},  // extract unsigned > condition from arg0
+               {name: "SETAE", reg: flagsgp, asm: "SETCC"}, // extract unsigned >= condition from arg0
 
                {name: "CMOVQCC", reg: cmov}, // carry clear
 
index 0b15801ced494588023b8bb9b85e17d051b75269..8c1ef0b9d9f0a56ed44bb172c54bb362f48ff14b 100644 (file)
@@ -74,6 +74,9 @@ const (
        OpAMD64SETG
        OpAMD64SETGE
        OpAMD64SETB
+       OpAMD64SETBE
+       OpAMD64SETA
+       OpAMD64SETAE
        OpAMD64CMOVQCC
        OpAMD64MOVBQSX
        OpAMD64MOVBQZX
@@ -532,6 +535,42 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name: "SETBE",
+               asm:  x86.ASETLS,
+               reg: regInfo{
+                       inputs: []regMask{
+                               8589934592, // .FLAGS
+                       },
+                       outputs: []regMask{
+                               65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+                       },
+               },
+       },
+       {
+               name: "SETA",
+               asm:  x86.ASETHI,
+               reg: regInfo{
+                       inputs: []regMask{
+                               8589934592, // .FLAGS
+                       },
+                       outputs: []regMask{
+                               65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+                       },
+               },
+       },
+       {
+               name: "SETAE",
+               asm:  x86.ASETCC,
+               reg: regInfo{
+                       inputs: []regMask{
+                               8589934592, // .FLAGS
+                       },
+                       outputs: []regMask{
+                               65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+                       },
+               },
+       },
        {
                name: "CMOVQCC",
                reg: regInfo{
index 4b63c97ebb97f1a5c4eb667ef49ffd0cd2734553..f8642a7bb54a2fe92afd6d9c0b929e4d10be93f2 100644 (file)
@@ -2589,6 +2589,66 @@ func rewriteBlockAMD64(b *Block) bool {
                }
                goto ende4d36879bb8e1bd8facaa8c91ba99dcc
        ende4d36879bb8e1bd8facaa8c91ba99dcc:
+               ;
+               // match: (If (SETLE cmp) yes no)
+               // cond:
+               // result: (LE cmp yes no)
+               {
+                       v := b.Control
+                       if v.Op != OpAMD64SETLE {
+                               goto end40df18679690e8f9005d8642fab44654
+                       }
+                       cmp := v.Args[0]
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Kind = BlockAMD64LE
+                       b.Control = cmp
+                       b.Succs[0] = yes
+                       b.Succs[1] = no
+                       return true
+               }
+               goto end40df18679690e8f9005d8642fab44654
+       end40df18679690e8f9005d8642fab44654:
+               ;
+               // match: (If (SETG cmp) yes no)
+               // cond:
+               // result: (GT cmp yes no)
+               {
+                       v := b.Control
+                       if v.Op != OpAMD64SETG {
+                               goto endb1faff07a84ae08a4b05a4a7e71eb740
+                       }
+                       cmp := v.Args[0]
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Kind = BlockAMD64GT
+                       b.Control = cmp
+                       b.Succs[0] = yes
+                       b.Succs[1] = no
+                       return true
+               }
+               goto endb1faff07a84ae08a4b05a4a7e71eb740
+       endb1faff07a84ae08a4b05a4a7e71eb740:
+               ;
+               // match: (If (SETGE cmp) yes no)
+               // cond:
+               // result: (GE cmp yes no)
+               {
+                       v := b.Control
+                       if v.Op != OpAMD64SETGE {
+                               goto enda9211ccfa5b0ab8eafc0017630c542b6
+                       }
+                       cmp := v.Args[0]
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Kind = BlockAMD64GE
+                       b.Control = cmp
+                       b.Succs[0] = yes
+                       b.Succs[1] = no
+                       return true
+               }
+               goto enda9211ccfa5b0ab8eafc0017630c542b6
+       enda9211ccfa5b0ab8eafc0017630c542b6:
                ;
                // match: (If (SETEQ cmp) yes no)
                // cond:
@@ -2649,6 +2709,66 @@ func rewriteBlockAMD64(b *Block) bool {
                }
                goto end04935012db9defeafceef8175f803ea2
        end04935012db9defeafceef8175f803ea2:
+               ;
+               // match: (If (SETBE cmp) yes no)
+               // cond:
+               // result: (ULE cmp yes no)
+               {
+                       v := b.Control
+                       if v.Op != OpAMD64SETBE {
+                               goto endfe0178f6f4406945ca8966817d04be60
+                       }
+                       cmp := v.Args[0]
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Kind = BlockAMD64ULE
+                       b.Control = cmp
+                       b.Succs[0] = yes
+                       b.Succs[1] = no
+                       return true
+               }
+               goto endfe0178f6f4406945ca8966817d04be60
+       endfe0178f6f4406945ca8966817d04be60:
+               ;
+               // match: (If (SETA cmp) yes no)
+               // cond:
+               // result: (UGT cmp yes no)
+               {
+                       v := b.Control
+                       if v.Op != OpAMD64SETA {
+                               goto endbd22a7d56a98d85e4e132ff952dae262
+                       }
+                       cmp := v.Args[0]
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Kind = BlockAMD64UGT
+                       b.Control = cmp
+                       b.Succs[0] = yes
+                       b.Succs[1] = no
+                       return true
+               }
+               goto endbd22a7d56a98d85e4e132ff952dae262
+       endbd22a7d56a98d85e4e132ff952dae262:
+               ;
+               // match: (If (SETAE cmp) yes no)
+               // cond:
+               // result: (UGE cmp yes no)
+               {
+                       v := b.Control
+                       if v.Op != OpAMD64SETAE {
+                               goto end9bea9963c3c5dfb97249a5feb8287f94
+                       }
+                       cmp := v.Args[0]
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Kind = BlockAMD64UGE
+                       b.Control = cmp
+                       b.Succs[0] = yes
+                       b.Succs[1] = no
+                       return true
+               }
+               goto end9bea9963c3c5dfb97249a5feb8287f94
+       end9bea9963c3c5dfb97249a5feb8287f94:
                ;
                // match: (If cond yes no)
                // cond: cond.Op == OpAMD64MOVBload