]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize arm64's code with more shifted operations
authorBen Shi <powerman1st@163.com>
Thu, 27 Sep 2018 06:21:14 +0000 (06:21 +0000)
committerCherry Zhang <cherryyz@google.com>
Fri, 28 Sep 2018 15:05:17 +0000 (15:05 +0000)
This CL optimizes arm64's NEG/MVN/TST/CMN with a shifted operand.

1. The total size of pkg/android_arm64 decreases about 0.2KB, excluding
cmd/compile/ .

2. The go1 benchmark shows no regression, excluding noise.
name                     old time/op    new time/op    delta
BinaryTree17-4              16.4s ± 1%     16.4s ± 1%    ~     (p=0.914 n=29+29)
Fannkuch11-4                8.72s ± 0%     8.72s ± 0%    ~     (p=0.274 n=30+29)
FmtFprintfEmpty-4           174ns ± 0%     174ns ± 0%    ~     (all equal)
FmtFprintfString-4          370ns ± 0%     370ns ± 0%    ~     (all equal)
FmtFprintfInt-4             419ns ± 0%     419ns ± 0%    ~     (all equal)
FmtFprintfIntInt-4          672ns ± 1%     675ns ± 2%    ~     (p=0.217 n=28+30)
FmtFprintfPrefixedInt-4     806ns ± 0%     806ns ± 0%    ~     (p=0.402 n=30+28)
FmtFprintfFloat-4          1.09µs ± 0%    1.09µs ± 0%  +0.02%  (p=0.011 n=22+27)
FmtManyArgs-4              2.67µs ± 0%    2.68µs ± 0%    ~     (p=0.279 n=29+30)
GobDecode-4                33.1ms ± 1%    33.1ms ± 0%    ~     (p=0.052 n=28+29)
GobEncode-4                29.6ms ± 0%    29.6ms ± 0%  +0.08%  (p=0.013 n=28+29)
Gzip-4                      1.38s ± 2%     1.39s ± 2%    ~     (p=0.071 n=29+29)
Gunzip-4                    139ms ± 0%     139ms ± 0%    ~     (p=0.265 n=29+29)
HTTPClientServer-4          789µs ± 4%     785µs ± 4%    ~     (p=0.206 n=29+28)
JSONEncode-4               49.7ms ± 0%    49.6ms ± 0%  -0.24%  (p=0.000 n=30+30)
JSONDecode-4                266ms ± 1%     267ms ± 1%  +0.34%  (p=0.000 n=30+30)
Mandelbrot200-4            16.6ms ± 0%    16.6ms ± 0%    ~     (p=0.835 n=28+30)
GoParse-4                  15.9ms ± 0%    15.8ms ± 0%  -0.29%  (p=0.000 n=27+30)
RegexpMatchEasy0_32-4       380ns ± 0%     381ns ± 0%  +0.18%  (p=0.000 n=30+30)
RegexpMatchEasy0_1K-4      1.18µs ± 0%    1.19µs ± 0%  +0.23%  (p=0.000 n=30+30)
RegexpMatchEasy1_32-4       357ns ± 0%     358ns ± 0%  +0.28%  (p=0.000 n=29+29)
RegexpMatchEasy1_1K-4      2.04µs ± 0%    2.04µs ± 0%  +0.06%  (p=0.006 n=30+30)
RegexpMatchMedium_32-4      589ns ± 0%     590ns ± 0%  +0.24%  (p=0.000 n=28+30)
RegexpMatchMedium_1K-4      162µs ± 0%     162µs ± 0%  -0.01%  (p=0.027 n=26+29)
RegexpMatchHard_32-4       9.58µs ± 0%    9.58µs ± 0%    ~     (p=0.935 n=30+30)
RegexpMatchHard_1K-4        287µs ± 0%     287µs ± 0%    ~     (p=0.387 n=29+30)
Revcomp-4                   2.50s ± 0%     2.50s ± 0%  -0.10%  (p=0.020 n=28+28)
Template-4                  310ms ± 0%     310ms ± 1%    ~     (p=0.406 n=30+30)
TimeParse-4                1.68µs ± 0%    1.68µs ± 0%  +0.03%  (p=0.014 n=30+17)
TimeFormat-4               1.65µs ± 0%    1.66µs ± 0%  +0.32%  (p=0.000 n=27+29)
[Geo mean]                  247µs          247µs       +0.05%

name                     old speed      new speed      delta
GobDecode-4              23.2MB/s ± 0%  23.2MB/s ± 0%  -0.08%  (p=0.032 n=27+29)
GobEncode-4              26.0MB/s ± 0%  25.9MB/s ± 0%  -0.10%  (p=0.011 n=29+29)
Gzip-4                   14.1MB/s ± 2%  14.0MB/s ± 2%    ~     (p=0.081 n=29+29)
Gunzip-4                  139MB/s ± 0%   139MB/s ± 0%    ~     (p=0.290 n=29+29)
JSONEncode-4             39.0MB/s ± 0%  39.1MB/s ± 0%  +0.25%  (p=0.000 n=29+30)
JSONDecode-4             7.30MB/s ± 1%  7.28MB/s ± 1%  -0.33%  (p=0.000 n=30+30)
GoParse-4                3.65MB/s ± 0%  3.66MB/s ± 0%  +0.29%  (p=0.000 n=27+30)
RegexpMatchEasy0_32-4    84.1MB/s ± 0%  84.0MB/s ± 0%  -0.17%  (p=0.000 n=30+28)
RegexpMatchEasy0_1K-4     864MB/s ± 0%   862MB/s ± 0%  -0.24%  (p=0.000 n=30+30)
RegexpMatchEasy1_32-4    89.5MB/s ± 0%  89.3MB/s ± 0%  -0.18%  (p=0.000 n=28+24)
RegexpMatchEasy1_1K-4     502MB/s ± 0%   502MB/s ± 0%  -0.05%  (p=0.008 n=30+29)
RegexpMatchMedium_32-4   1.70MB/s ± 0%  1.69MB/s ± 0%  -0.59%  (p=0.000 n=29+30)
RegexpMatchMedium_1K-4   6.31MB/s ± 0%  6.31MB/s ± 0%  +0.05%  (p=0.005 n=30+26)
RegexpMatchHard_32-4     3.34MB/s ± 0%  3.34MB/s ± 0%    ~     (all equal)
RegexpMatchHard_1K-4     3.57MB/s ± 0%  3.57MB/s ± 0%    ~     (all equal)
Revcomp-4                 102MB/s ± 0%   102MB/s ± 0%  +0.10%  (p=0.022 n=28+28)
Template-4               6.26MB/s ± 0%  6.26MB/s ± 1%    ~     (p=0.768 n=30+30)
[Geo mean]               24.2MB/s       24.1MB/s       -0.08%

Change-Id: I494f9db7f8a568a00e9c74ae25086a58b2221683
Reviewed-on: https://go-review.googlesource.com/137976
Run-TryBot: Ben Shi <powerman1st@163.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/gen/ARM64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteARM64.go
test/codegen/arithmetic.go
test/codegen/comparisons.go

index 482442cd22532c23c650e370d38f92d3fb4fa9ae..87703dd80df82ae989a5444959f2cde1f36b9808 100644 (file)
@@ -255,6 +255,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.Reg = v.Args[1].Reg()
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
+       case ssa.OpARM64MVNshiftLL, ssa.OpARM64NEGshiftLL:
+               genshift(s, v.Op.Asm(), 0, v.Args[0].Reg(), v.Reg(), arm64.SHIFT_LL, v.AuxInt)
+       case ssa.OpARM64MVNshiftRL, ssa.OpARM64NEGshiftRL:
+               genshift(s, v.Op.Asm(), 0, v.Args[0].Reg(), v.Reg(), arm64.SHIFT_LR, v.AuxInt)
+       case ssa.OpARM64MVNshiftRA, ssa.OpARM64NEGshiftRA:
+               genshift(s, v.Op.Asm(), 0, v.Args[0].Reg(), v.Reg(), arm64.SHIFT_AR, v.AuxInt)
        case ssa.OpARM64ADDshiftLL,
                ssa.OpARM64SUBshiftLL,
                ssa.OpARM64ANDshiftLL,
@@ -317,11 +323,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.From.Type = obj.TYPE_CONST
                p.From.Offset = v.AuxInt
                p.Reg = v.Args[0].Reg()
-       case ssa.OpARM64CMPshiftLL:
+       case ssa.OpARM64CMPshiftLL, ssa.OpARM64CMNshiftLL, ssa.OpARM64TSTshiftLL:
                genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm64.SHIFT_LL, v.AuxInt)
-       case ssa.OpARM64CMPshiftRL:
+       case ssa.OpARM64CMPshiftRL, ssa.OpARM64CMNshiftRL, ssa.OpARM64TSTshiftRL:
                genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm64.SHIFT_LR, v.AuxInt)
-       case ssa.OpARM64CMPshiftRA:
+       case ssa.OpARM64CMPshiftRA, ssa.OpARM64CMNshiftRA, ssa.OpARM64TSTshiftRA:
                genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm64.SHIFT_AR, v.AuxInt)
        case ssa.OpARM64MOVDaddr:
                p := s.Prog(arm64.AMOVD)
index 3fce018d45ef520a75e36fba8304010187bc892c..659081ec8b01cabd58848d0206b26e97f98a2d55 100644 (file)
       (CSEL0 {arm64Negate(bool.Op)} x flagArg(bool))
 
 // absorb shifts into ops
+(NEG x:(SLLconst [c] y)) && clobberIfDead(x) -> (NEGshiftLL [c] y)
+(NEG x:(SRLconst [c] y)) && clobberIfDead(x) -> (NEGshiftRL [c] y)
+(NEG x:(SRAconst [c] y)) && clobberIfDead(x) -> (NEGshiftRA [c] y)
+(MVN x:(SLLconst [c] y)) && clobberIfDead(x) -> (MVNshiftLL [c] y)
+(MVN x:(SRLconst [c] y)) && clobberIfDead(x) -> (MVNshiftRL [c] y)
+(MVN x:(SRAconst [c] y)) && clobberIfDead(x) -> (MVNshiftRA [c] y)
 (ADD x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (ADDshiftLL x0 y [c])
 (ADD x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (ADDshiftRL x0 y [c])
 (ADD x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (ADDshiftRA x0 y [c])
 (CMP x0:(SRLconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftRL x1 y [c]))
 (CMP x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (CMPshiftRA x0 y [c])
 (CMP x0:(SRAconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftRA x1 y [c]))
+(CMN x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (CMNshiftLL x0 y [c])
+(CMN x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (CMNshiftRL x0 y [c])
+(CMN x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (CMNshiftRA x0 y [c])
+(TST x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (TSTshiftLL x0 y [c])
+(TST x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (TSTshiftRL x0 y [c])
+(TST x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (TSTshiftRA x0 y [c])
 
 // prefer *const ops to *shift ops
 (ADDshiftLL (MOVDconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d]))
 (CMPshiftLL (MOVDconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
 (CMPshiftRL (MOVDconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
 (CMPshiftRA (MOVDconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
+(CMNshiftLL (MOVDconst [c]) x [d]) -> (CMNconst [c] (SLLconst <x.Type> x [d]))
+(CMNshiftRL (MOVDconst [c]) x [d]) -> (CMNconst [c] (SRLconst <x.Type> x [d]))
+(CMNshiftRA (MOVDconst [c]) x [d]) -> (CMNconst [c] (SRAconst <x.Type> x [d]))
+(TSTshiftLL (MOVDconst [c]) x [d]) -> (TSTconst [c] (SLLconst <x.Type> x [d]))
+(TSTshiftRL (MOVDconst [c]) x [d]) -> (TSTconst [c] (SRLconst <x.Type> x [d]))
+(TSTshiftRA (MOVDconst [c]) x [d]) -> (TSTconst [c] (SRAconst <x.Type> x [d]))
 
 // constant folding in *shift ops
+(MVNshiftLL (MOVDconst [c]) [d]) -> (MOVDconst [^int64(uint64(c)<<uint64(d))])
+(MVNshiftRL (MOVDconst [c]) [d]) -> (MOVDconst [^int64(uint64(c)>>uint64(d))])
+(MVNshiftRA (MOVDconst [c]) [d]) -> (MOVDconst [^(c>>uint64(d))])
+(NEGshiftLL (MOVDconst [c]) [d]) -> (MOVDconst [-int64(uint64(c)<<uint64(d))])
+(NEGshiftRL (MOVDconst [c]) [d]) -> (MOVDconst [-int64(uint64(c)>>uint64(d))])
+(NEGshiftRA (MOVDconst [c]) [d]) -> (MOVDconst [-(c>>uint64(d))])
 (ADDshiftLL x (MOVDconst [c]) [d]) -> (ADDconst x [int64(uint64(c)<<uint64(d))])
 (ADDshiftRL x (MOVDconst [c]) [d]) -> (ADDconst x [int64(uint64(c)>>uint64(d))])
 (ADDshiftRA x (MOVDconst [c]) [d]) -> (ADDconst x [c>>uint64(d)])
 (CMPshiftLL x (MOVDconst [c]) [d]) -> (CMPconst x [int64(uint64(c)<<uint64(d))])
 (CMPshiftRL x (MOVDconst [c]) [d]) -> (CMPconst x [int64(uint64(c)>>uint64(d))])
 (CMPshiftRA x (MOVDconst [c]) [d]) -> (CMPconst x [c>>uint64(d)])
+(CMNshiftLL x (MOVDconst [c]) [d]) -> (CMNconst x [int64(uint64(c)<<uint64(d))])
+(CMNshiftRL x (MOVDconst [c]) [d]) -> (CMNconst x [int64(uint64(c)>>uint64(d))])
+(CMNshiftRA x (MOVDconst [c]) [d]) -> (CMNconst x [c>>uint64(d)])
+(TSTshiftLL x (MOVDconst [c]) [d]) -> (TSTconst x [int64(uint64(c)<<uint64(d))])
+(TSTshiftRL x (MOVDconst [c]) [d]) -> (TSTconst x [int64(uint64(c)>>uint64(d))])
+(TSTshiftRA x (MOVDconst [c]) [d]) -> (TSTconst x [c>>uint64(d)])
 
 // simplification with *shift ops
 (SUBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVDconst [0])
index 4381c081b7b25c70715cf738f01fbb199ffb303c..fc0a41527b2e719b397be40ccf1b37a0b4a085c2 100644 (file)
@@ -273,6 +273,12 @@ func init() {
                {name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"},                  // arg0 compare to arg1, float64
 
                // shifted ops
+               {name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0<<auxInt)
+               {name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), unsigned shift
+               {name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), signed shift
+               {name: "NEGshiftLL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0<<auxInt)
+               {name: "NEGshiftRL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), unsigned shift
+               {name: "NEGshiftRA", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), signed shift
                {name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1<<auxInt
                {name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, unsigned shift
                {name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, signed shift
@@ -300,6 +306,12 @@ func init() {
                {name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt
                {name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift
                {name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift
+               {name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1<<auxInt) compare to 0
+               {name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, unsigned shift
+               {name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, signed shift
+               {name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1<<auxInt) compare to 0
+               {name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, unsigned shift
+               {name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, signed shift
 
                // bitfield ops
                // for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff
index fe63633750dec9cf6fd7cbf2add6aa75003b410d..5f5345ad5ca2d97ffe395f5251960e4900599459 100644 (file)
@@ -1172,6 +1172,12 @@ const (
        OpARM64TSTWconst
        OpARM64FCMPS
        OpARM64FCMPD
+       OpARM64MVNshiftLL
+       OpARM64MVNshiftRL
+       OpARM64MVNshiftRA
+       OpARM64NEGshiftLL
+       OpARM64NEGshiftRL
+       OpARM64NEGshiftRA
        OpARM64ADDshiftLL
        OpARM64ADDshiftRL
        OpARM64ADDshiftRA
@@ -1199,6 +1205,12 @@ const (
        OpARM64CMPshiftLL
        OpARM64CMPshiftRL
        OpARM64CMPshiftRA
+       OpARM64CMNshiftLL
+       OpARM64CMNshiftRL
+       OpARM64CMNshiftRA
+       OpARM64TSTshiftLL
+       OpARM64TSTshiftRL
+       OpARM64TSTshiftRA
        OpARM64BFI
        OpARM64BFXIL
        OpARM64SBFIZ
@@ -15553,6 +15565,90 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:    "MVNshiftLL",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     arm64.AMVN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+                       outputs: []outputInfo{
+                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+                       },
+               },
+       },
+       {
+               name:    "MVNshiftRL",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     arm64.AMVN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+                       outputs: []outputInfo{
+                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+                       },
+               },
+       },
+       {
+               name:    "MVNshiftRA",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     arm64.AMVN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+                       outputs: []outputInfo{
+                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+                       },
+               },
+       },
+       {
+               name:    "NEGshiftLL",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     arm64.ANEG,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+                       outputs: []outputInfo{
+                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+                       },
+               },
+       },
+       {
+               name:    "NEGshiftRL",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     arm64.ANEG,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+                       outputs: []outputInfo{
+                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+                       },
+               },
+       },
+       {
+               name:    "NEGshiftRA",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     arm64.ANEG,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+                       outputs: []outputInfo{
+                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+                       },
+               },
+       },
        {
                name:    "ADDshiftLL",
                auxType: auxInt64,
@@ -15949,6 +16045,78 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:    "CMNshiftLL",
+               auxType: auxInt64,
+               argLen:  2,
+               asm:     arm64.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
+       {
+               name:    "CMNshiftRL",
+               auxType: auxInt64,
+               argLen:  2,
+               asm:     arm64.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
+       {
+               name:    "CMNshiftRA",
+               auxType: auxInt64,
+               argLen:  2,
+               asm:     arm64.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
+       {
+               name:    "TSTshiftLL",
+               auxType: auxInt64,
+               argLen:  2,
+               asm:     arm64.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
+       {
+               name:    "TSTshiftRL",
+               auxType: auxInt64,
+               argLen:  2,
+               asm:     arm64.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
+       {
+               name:    "TSTshiftRA",
+               auxType: auxInt64,
+               argLen:  2,
+               asm:     arm64.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
        {
                name:         "BFI",
                auxType:      auxInt64,
index f07ab4209087fa4ecfc6e0030dd8887994c868fa..95011eab480694bdce4e7067a8fe6db1886fec5f 100644 (file)
@@ -51,6 +51,12 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64CMNWconst_0(v)
        case OpARM64CMNconst:
                return rewriteValueARM64_OpARM64CMNconst_0(v)
+       case OpARM64CMNshiftLL:
+               return rewriteValueARM64_OpARM64CMNshiftLL_0(v)
+       case OpARM64CMNshiftRA:
+               return rewriteValueARM64_OpARM64CMNshiftRA_0(v)
+       case OpARM64CMNshiftRL:
+               return rewriteValueARM64_OpARM64CMNshiftRL_0(v)
        case OpARM64CMP:
                return rewriteValueARM64_OpARM64CMP_0(v)
        case OpARM64CMPW:
@@ -259,8 +265,20 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64MULW_0(v) || rewriteValueARM64_OpARM64MULW_10(v) || rewriteValueARM64_OpARM64MULW_20(v)
        case OpARM64MVN:
                return rewriteValueARM64_OpARM64MVN_0(v)
+       case OpARM64MVNshiftLL:
+               return rewriteValueARM64_OpARM64MVNshiftLL_0(v)
+       case OpARM64MVNshiftRA:
+               return rewriteValueARM64_OpARM64MVNshiftRA_0(v)
+       case OpARM64MVNshiftRL:
+               return rewriteValueARM64_OpARM64MVNshiftRL_0(v)
        case OpARM64NEG:
                return rewriteValueARM64_OpARM64NEG_0(v)
+       case OpARM64NEGshiftLL:
+               return rewriteValueARM64_OpARM64NEGshiftLL_0(v)
+       case OpARM64NEGshiftRA:
+               return rewriteValueARM64_OpARM64NEGshiftRA_0(v)
+       case OpARM64NEGshiftRL:
+               return rewriteValueARM64_OpARM64NEGshiftRL_0(v)
        case OpARM64NotEqual:
                return rewriteValueARM64_OpARM64NotEqual_0(v)
        case OpARM64OR:
@@ -317,6 +335,12 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64TSTWconst_0(v)
        case OpARM64TSTconst:
                return rewriteValueARM64_OpARM64TSTconst_0(v)
+       case OpARM64TSTshiftLL:
+               return rewriteValueARM64_OpARM64TSTshiftLL_0(v)
+       case OpARM64TSTshiftRA:
+               return rewriteValueARM64_OpARM64TSTshiftRA_0(v)
+       case OpARM64TSTshiftRL:
+               return rewriteValueARM64_OpARM64TSTshiftRL_0(v)
        case OpARM64UBFIZ:
                return rewriteValueARM64_OpARM64UBFIZ_0(v)
        case OpARM64UBFX:
@@ -3340,6 +3364,132 @@ func rewriteValueARM64_OpARM64CMN_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (CMN x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (CMNshiftLL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64CMNshiftLL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMN x1:(SLLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (CMNshiftLL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64CMNshiftLL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMN x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (CMNshiftRL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64CMNshiftRL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMN x1:(SRLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (CMNshiftRL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64CMNshiftRL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMN x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (CMNshiftRA x0 y [c])
+       for {
+               _ = v.Args[1]
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64CMNshiftRA)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMN x1:(SRAconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (CMNshiftRA x0 y [c])
+       for {
+               _ = v.Args[1]
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64CMNshiftRA)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
        return false
 }
 func rewriteValueARM64_OpARM64CMNW_0(v *Value) bool {
@@ -3543,6 +3693,132 @@ func rewriteValueARM64_OpARM64CMNconst_0(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM64_OpARM64CMNshiftLL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftLL (MOVDconst [c]) x [d])
+       // cond:
+       // result: (CMNconst [c] (SLLconst <x.Type> x [d]))
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARM64CMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (CMNshiftLL x (MOVDconst [c]) [d])
+       // cond:
+       // result: (CMNconst x [int64(uint64(c)<<uint64(d))])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARM64CMNconst)
+               v.AuxInt = int64(uint64(c) << uint64(d))
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64CMNshiftRA_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftRA (MOVDconst [c]) x [d])
+       // cond:
+       // result: (CMNconst [c] (SRAconst <x.Type> x [d]))
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARM64CMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (CMNshiftRA x (MOVDconst [c]) [d])
+       // cond:
+       // result: (CMNconst x [c>>uint64(d)])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARM64CMNconst)
+               v.AuxInt = c >> uint64(d)
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64CMNshiftRL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftRL (MOVDconst [c]) x [d])
+       // cond:
+       // result: (CMNconst [c] (SRLconst <x.Type> x [d]))
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARM64CMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (CMNshiftRL x (MOVDconst [c]) [d])
+       // cond:
+       // result: (CMNconst x [int64(uint64(c)>>uint64(d))])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARM64CMNconst)
+               v.AuxInt = int64(uint64(c) >> uint64(d))
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpARM64CMP_0(v *Value) bool {
        b := v.Block
        _ = b
@@ -19959,47 +20235,152 @@ func rewriteValueARM64_OpARM64MVN_0(v *Value) bool {
                v.AuxInt = ^c
                return true
        }
-       return false
-}
-func rewriteValueARM64_OpARM64NEG_0(v *Value) bool {
-       // match: (NEG (MUL x y))
-       // cond:
-       // result: (MNEG x y)
+       // match: (MVN x:(SLLconst [c] y))
+       // cond: clobberIfDead(x)
+       // result: (MVNshiftLL [c] y)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64MUL {
+               x := v.Args[0]
+               if x.Op != OpARM64SLLconst {
                        break
                }
-               _ = v_0.Args[1]
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               v.reset(OpARM64MNEG)
-               v.AddArg(x)
+               c := x.AuxInt
+               y := x.Args[0]
+               if !(clobberIfDead(x)) {
+                       break
+               }
+               v.reset(OpARM64MVNshiftLL)
+               v.AuxInt = c
                v.AddArg(y)
                return true
        }
-       // match: (NEG (MULW x y))
-       // cond:
-       // result: (MNEGW x y)
+       // match: (MVN x:(SRLconst [c] y))
+       // cond: clobberIfDead(x)
+       // result: (MVNshiftRL [c] y)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64MULW {
+               x := v.Args[0]
+               if x.Op != OpARM64SRLconst {
                        break
                }
-               _ = v_0.Args[1]
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               v.reset(OpARM64MNEGW)
-               v.AddArg(x)
+               c := x.AuxInt
+               y := x.Args[0]
+               if !(clobberIfDead(x)) {
+                       break
+               }
+               v.reset(OpARM64MVNshiftRL)
+               v.AuxInt = c
                v.AddArg(y)
                return true
        }
-       // match: (NEG (MOVDconst [c]))
-       // cond:
-       // result: (MOVDconst [-c])
+       // match: (MVN x:(SRAconst [c] y))
+       // cond: clobberIfDead(x)
+       // result: (MVNshiftRA [c] y)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64MOVDconst {
+               x := v.Args[0]
+               if x.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x.AuxInt
+               y := x.Args[0]
+               if !(clobberIfDead(x)) {
+                       break
+               }
+               v.reset(OpARM64MVNshiftRA)
+               v.AuxInt = c
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64MVNshiftLL_0(v *Value) bool {
+       // match: (MVNshiftLL (MOVDconst [c]) [d])
+       // cond:
+       // result: (MOVDconst [^int64(uint64(c)<<uint64(d))])
+       for {
+               d := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = ^int64(uint64(c) << uint64(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64MVNshiftRA_0(v *Value) bool {
+       // match: (MVNshiftRA (MOVDconst [c]) [d])
+       // cond:
+       // result: (MOVDconst [^(c>>uint64(d))])
+       for {
+               d := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = ^(c >> uint64(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64MVNshiftRL_0(v *Value) bool {
+       // match: (MVNshiftRL (MOVDconst [c]) [d])
+       // cond:
+       // result: (MOVDconst [^int64(uint64(c)>>uint64(d))])
+       for {
+               d := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = ^int64(uint64(c) >> uint64(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64NEG_0(v *Value) bool {
+       // match: (NEG (MUL x y))
+       // cond:
+       // result: (MNEG x y)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MUL {
+                       break
+               }
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               v.reset(OpARM64MNEG)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (NEG (MULW x y))
+       // cond:
+       // result: (MNEGW x y)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MULW {
+                       break
+               }
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               v.reset(OpARM64MNEGW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (NEG (MOVDconst [c]))
+       // cond:
+       // result: (MOVDconst [-c])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
                        break
                }
                c := v_0.AuxInt
@@ -20007,6 +20388,111 @@ func rewriteValueARM64_OpARM64NEG_0(v *Value) bool {
                v.AuxInt = -c
                return true
        }
+       // match: (NEG x:(SLLconst [c] y))
+       // cond: clobberIfDead(x)
+       // result: (NEGshiftLL [c] y)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x.AuxInt
+               y := x.Args[0]
+               if !(clobberIfDead(x)) {
+                       break
+               }
+               v.reset(OpARM64NEGshiftLL)
+               v.AuxInt = c
+               v.AddArg(y)
+               return true
+       }
+       // match: (NEG x:(SRLconst [c] y))
+       // cond: clobberIfDead(x)
+       // result: (NEGshiftRL [c] y)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x.AuxInt
+               y := x.Args[0]
+               if !(clobberIfDead(x)) {
+                       break
+               }
+               v.reset(OpARM64NEGshiftRL)
+               v.AuxInt = c
+               v.AddArg(y)
+               return true
+       }
+       // match: (NEG x:(SRAconst [c] y))
+       // cond: clobberIfDead(x)
+       // result: (NEGshiftRA [c] y)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x.AuxInt
+               y := x.Args[0]
+               if !(clobberIfDead(x)) {
+                       break
+               }
+               v.reset(OpARM64NEGshiftRA)
+               v.AuxInt = c
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64NEGshiftLL_0(v *Value) bool {
+       // match: (NEGshiftLL (MOVDconst [c]) [d])
+       // cond:
+       // result: (MOVDconst [-int64(uint64(c)<<uint64(d))])
+       for {
+               d := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = -int64(uint64(c) << uint64(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64NEGshiftRA_0(v *Value) bool {
+       // match: (NEGshiftRA (MOVDconst [c]) [d])
+       // cond:
+       // result: (MOVDconst [-(c>>uint64(d))])
+       for {
+               d := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = -(c >> uint64(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64NEGshiftRL_0(v *Value) bool {
+       // match: (NEGshiftRL (MOVDconst [c]) [d])
+       // cond:
+       // result: (MOVDconst [-int64(uint64(c)>>uint64(d))])
+       for {
+               d := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = -int64(uint64(c) >> uint64(d))
+               return true
+       }
        return false
 }
 func rewriteValueARM64_OpARM64NotEqual_0(v *Value) bool {
@@ -29431,6 +29917,132 @@ func rewriteValueARM64_OpARM64TST_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (TST x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (TSTshiftLL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64TSTshiftLL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (TST x1:(SLLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (TSTshiftLL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64TSTshiftLL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (TST x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (TSTshiftRL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64TSTshiftRL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (TST x1:(SRLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (TSTshiftRL x0 y [c])
+       for {
+               _ = v.Args[1]
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64TSTshiftRL)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (TST x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (TSTshiftRA x0 y [c])
+       for {
+               _ = v.Args[1]
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64TSTshiftRA)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (TST x1:(SRAconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (TSTshiftRA x0 y [c])
+       for {
+               _ = v.Args[1]
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
+                       break
+               }
+               v.reset(OpARM64TSTshiftRA)
+               v.AuxInt = c
+               v.AddArg(x0)
+               v.AddArg(y)
+               return true
+       }
        return false
 }
 func rewriteValueARM64_OpARM64TSTW_0(v *Value) bool {
@@ -29570,6 +30182,132 @@ func rewriteValueARM64_OpARM64TSTconst_0(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM64_OpARM64TSTshiftLL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TSTshiftLL (MOVDconst [c]) x [d])
+       // cond:
+       // result: (TSTconst [c] (SLLconst <x.Type> x [d]))
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARM64TSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (TSTshiftLL x (MOVDconst [c]) [d])
+       // cond:
+       // result: (TSTconst x [int64(uint64(c)<<uint64(d))])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARM64TSTconst)
+               v.AuxInt = int64(uint64(c) << uint64(d))
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64TSTshiftRA_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TSTshiftRA (MOVDconst [c]) x [d])
+       // cond:
+       // result: (TSTconst [c] (SRAconst <x.Type> x [d]))
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARM64TSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (TSTshiftRA x (MOVDconst [c]) [d])
+       // cond:
+       // result: (TSTconst x [c>>uint64(d)])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARM64TSTconst)
+               v.AuxInt = c >> uint64(d)
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64TSTshiftRL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TSTshiftRL (MOVDconst [c]) x [d])
+       // cond:
+       // result: (TSTconst [c] (SRLconst <x.Type> x [d]))
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARM64TSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (TSTshiftRL x (MOVDconst [c]) [d])
+       // cond:
+       // result: (TSTconst x [int64(uint64(c)>>uint64(d))])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARM64TSTconst)
+               v.AuxInt = int64(uint64(c) >> uint64(d))
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpARM64UBFIZ_0(v *Value) bool {
        // match: (UBFIZ [bfc] (SLLconst [sc] x))
        // cond: sc < getARM64BFwidth(bfc)
index 05a28695d49e415aacbf45f357eeff83c88b54e4..8e2a2109488590cf37c156b6f2d3b5bc38e6bd6a 100644 (file)
@@ -44,7 +44,7 @@ func Pow2Muls(n1, n2 int) (int, int) {
        // amd64:"SHLQ\t[$]6",-"IMULQ"
        // 386:"SHLL\t[$]6",-"IMULL"
        // arm:"SLL\t[$]6",-"MUL"
-       // arm64:"LSL\t[$]6",-"MUL"
+       // arm64:`NEG\sR[0-9]+<<6,\sR[0-9]+`,-`LSL`,-`MUL`
        b := -64 * n2
 
        return a, b
index d5bade97cce8f690a30a4bb7e12d8d7f7996238d..072393f3a6f7ce2c54e0648f1fe86d9b5d186ee5 100644 (file)
@@ -183,6 +183,10 @@ func CmpToZero(a, b, d int32, e, f int64) int32 {
        // arm:`AND`,-`TST`
        // 386:`ANDL`
        c6 := a&d >= 0
+       // arm64:`TST\sR[0-9]+<<3,\sR[0-9]+`
+       c7 := e&(f<<3) < 0
+       // arm64:`CMN\sR[0-9]+<<3,\sR[0-9]+`
+       c8 := e+(f<<3) < 0
        if c0 {
                return 1
        } else if c1 {
@@ -197,6 +201,10 @@ func CmpToZero(a, b, d int32, e, f int64) int32 {
                return b + d
        } else if c6 {
                return a & d
+       } else if c7 {
+               return 7
+       } else if c8 {
+               return 8
        } else {
                return 0
        }