Commit 5aeecc45 authored by Ben Shi's avatar Ben Shi Committed by Cherry Zhang

cmd/compile: optimize arm64's code with more shifted operations

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: default avatarCherry Zhang <cherryyz@google.com>
parent d60cf39f
...@@ -255,6 +255,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -255,6 +255,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.Reg = v.Args[1].Reg() p.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.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, case ssa.OpARM64ADDshiftLL,
ssa.OpARM64SUBshiftLL, ssa.OpARM64SUBshiftLL,
ssa.OpARM64ANDshiftLL, ssa.OpARM64ANDshiftLL,
...@@ -317,11 +323,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -317,11 +323,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt p.From.Offset = v.AuxInt
p.Reg = v.Args[0].Reg() 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) 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) 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) genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm64.SHIFT_AR, v.AuxInt)
case ssa.OpARM64MOVDaddr: case ssa.OpARM64MOVDaddr:
p := s.Prog(arm64.AMOVD) p := s.Prog(arm64.AMOVD)
......
...@@ -1605,6 +1605,12 @@ ...@@ -1605,6 +1605,12 @@
(CSEL0 {arm64Negate(bool.Op)} x flagArg(bool)) (CSEL0 {arm64Negate(bool.Op)} x flagArg(bool))
// absorb shifts into ops // 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:(SLLconst [c] y)) && clobberIfDead(x1) -> (ADDshiftLL x0 y [c])
(ADD x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (ADDshiftRL 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]) (ADD x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (ADDshiftRA x0 y [c])
...@@ -1635,6 +1641,12 @@ ...@@ -1635,6 +1641,12 @@
(CMP x0:(SRLconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftRL x1 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 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (CMPshiftRA x0 y [c])
(CMP x0:(SRAconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftRA x1 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 // prefer *const ops to *shift ops
(ADDshiftLL (MOVDconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d])) (ADDshiftLL (MOVDconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d]))
...@@ -1652,8 +1664,20 @@ ...@@ -1652,8 +1664,20 @@
(CMPshiftLL (MOVDconst [c]) x [d]) -> (InvertFlags (CMPconst [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]))) (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]))) (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 // 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))]) (ADDshiftLL x (MOVDconst [c]) [d]) -> (ADDconst x [int64(uint64(c)<<uint64(d))])
(ADDshiftRL 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)]) (ADDshiftRA x (MOVDconst [c]) [d]) -> (ADDconst x [c>>uint64(d)])
...@@ -1681,6 +1705,12 @@ ...@@ -1681,6 +1705,12 @@
(CMPshiftLL x (MOVDconst [c]) [d]) -> (CMPconst x [int64(uint64(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))]) (CMPshiftRL x (MOVDconst [c]) [d]) -> (CMPconst x [int64(uint64(c)>>uint64(d))])
(CMPshiftRA x (MOVDconst [c]) [d]) -> (CMPconst x [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 // simplification with *shift ops
(SUBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVDconst [0]) (SUBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVDconst [0])
......
...@@ -273,6 +273,12 @@ func init() { ...@@ -273,6 +273,12 @@ func init() {
{name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"}, // arg0 compare to arg1, float64 {name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"}, // arg0 compare to arg1, float64
// shifted ops // 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: "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: "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 {name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"}, // arg0 + arg1>>auxInt, signed shift
...@@ -300,6 +306,12 @@ func init() { ...@@ -300,6 +306,12 @@ func init() {
{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt {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: "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: "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 // bitfield ops
// for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff // for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff
......
...@@ -1172,6 +1172,12 @@ const ( ...@@ -1172,6 +1172,12 @@ const (
OpARM64TSTWconst OpARM64TSTWconst
OpARM64FCMPS OpARM64FCMPS
OpARM64FCMPD OpARM64FCMPD
OpARM64MVNshiftLL
OpARM64MVNshiftRL
OpARM64MVNshiftRA
OpARM64NEGshiftLL
OpARM64NEGshiftRL
OpARM64NEGshiftRA
OpARM64ADDshiftLL OpARM64ADDshiftLL
OpARM64ADDshiftRL OpARM64ADDshiftRL
OpARM64ADDshiftRA OpARM64ADDshiftRA
...@@ -1199,6 +1205,12 @@ const ( ...@@ -1199,6 +1205,12 @@ const (
OpARM64CMPshiftLL OpARM64CMPshiftLL
OpARM64CMPshiftRL OpARM64CMPshiftRL
OpARM64CMPshiftRA OpARM64CMPshiftRA
OpARM64CMNshiftLL
OpARM64CMNshiftRL
OpARM64CMNshiftRA
OpARM64TSTshiftLL
OpARM64TSTshiftRL
OpARM64TSTshiftRA
OpARM64BFI OpARM64BFI
OpARM64BFXIL OpARM64BFXIL
OpARM64SBFIZ OpARM64SBFIZ
...@@ -15553,6 +15565,90 @@ var opcodeTable = [...]opInfo{ ...@@ -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", name: "ADDshiftLL",
auxType: auxInt64, auxType: auxInt64,
...@@ -15949,6 +16045,78 @@ var opcodeTable = [...]opInfo{ ...@@ -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", name: "BFI",
auxType: auxInt64, auxType: auxInt64,
......
...@@ -51,6 +51,12 @@ func rewriteValueARM64(v *Value) bool { ...@@ -51,6 +51,12 @@ func rewriteValueARM64(v *Value) bool {
return rewriteValueARM64_OpARM64CMNWconst_0(v) return rewriteValueARM64_OpARM64CMNWconst_0(v)
case OpARM64CMNconst: case OpARM64CMNconst:
return rewriteValueARM64_OpARM64CMNconst_0(v) 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: case OpARM64CMP:
return rewriteValueARM64_OpARM64CMP_0(v) return rewriteValueARM64_OpARM64CMP_0(v)
case OpARM64CMPW: case OpARM64CMPW:
...@@ -259,8 +265,20 @@ func rewriteValueARM64(v *Value) bool { ...@@ -259,8 +265,20 @@ func rewriteValueARM64(v *Value) bool {
return rewriteValueARM64_OpARM64MULW_0(v) || rewriteValueARM64_OpARM64MULW_10(v) || rewriteValueARM64_OpARM64MULW_20(v) return rewriteValueARM64_OpARM64MULW_0(v) || rewriteValueARM64_OpARM64MULW_10(v) || rewriteValueARM64_OpARM64MULW_20(v)
case OpARM64MVN: case OpARM64MVN:
return rewriteValueARM64_OpARM64MVN_0(v) 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: case OpARM64NEG:
return rewriteValueARM64_OpARM64NEG_0(v) 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: case OpARM64NotEqual:
return rewriteValueARM64_OpARM64NotEqual_0(v) return rewriteValueARM64_OpARM64NotEqual_0(v)
case OpARM64OR: case OpARM64OR:
...@@ -317,6 +335,12 @@ func rewriteValueARM64(v *Value) bool { ...@@ -317,6 +335,12 @@ func rewriteValueARM64(v *Value) bool {
return rewriteValueARM64_OpARM64TSTWconst_0(v) return rewriteValueARM64_OpARM64TSTWconst_0(v)
case OpARM64TSTconst: case OpARM64TSTconst:
return rewriteValueARM64_OpARM64TSTconst_0(v) 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: case OpARM64UBFIZ:
return rewriteValueARM64_OpARM64UBFIZ_0(v) return rewriteValueARM64_OpARM64UBFIZ_0(v)
case OpARM64UBFX: case OpARM64UBFX:
...@@ -3340,6 +3364,132 @@ func rewriteValueARM64_OpARM64CMN_0(v *Value) bool { ...@@ -3340,6 +3364,132 @@ func rewriteValueARM64_OpARM64CMN_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true 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 return false
} }
func rewriteValueARM64_OpARM64CMNW_0(v *Value) bool { func rewriteValueARM64_OpARM64CMNW_0(v *Value) bool {
...@@ -3543,6 +3693,132 @@ func rewriteValueARM64_OpARM64CMNconst_0(v *Value) bool { ...@@ -3543,6 +3693,132 @@ func rewriteValueARM64_OpARM64CMNconst_0(v *Value) bool {
} }
return false 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 { func rewriteValueARM64_OpARM64CMP_0(v *Value) bool {
b := v.Block b := v.Block
_ = b _ = b
...@@ -19959,43 +20235,148 @@ func rewriteValueARM64_OpARM64MVN_0(v *Value) bool { ...@@ -19959,43 +20235,148 @@ func rewriteValueARM64_OpARM64MVN_0(v *Value) bool {
v.AuxInt = ^c v.AuxInt = ^c
return true return true
} }
return false // match: (MVN x:(SLLconst [c] y))
} // cond: clobberIfDead(x)
func rewriteValueARM64_OpARM64NEG_0(v *Value) bool { // result: (MVNshiftLL [c] y)
// match: (NEG (MUL x y))
// cond:
// result: (MNEG x y)
for { for {
v_0 := v.Args[0] x := v.Args[0]
if v_0.Op != OpARM64MUL { if x.Op != OpARM64SLLconst {
break break
} }
_ = v_0.Args[1] c := x.AuxInt
x := v_0.Args[0] y := x.Args[0]
y := v_0.Args[1] if !(clobberIfDead(x)) {
v.reset(OpARM64MNEG) break
v.AddArg(x) }
v.reset(OpARM64MVNshiftLL)
v.AuxInt = c
v.AddArg(y) v.AddArg(y)
return true return true
} }
// match: (NEG (MULW x y)) // match: (MVN x:(SRLconst [c] y))
// cond: // cond: clobberIfDead(x)
// result: (MNEGW x y) // result: (MVNshiftRL [c] y)
for { for {
v_0 := v.Args[0] x := v.Args[0]
if v_0.Op != OpARM64MULW { if x.Op != OpARM64SRLconst {
break break
} }
_ = v_0.Args[1] c := x.AuxInt
x := v_0.Args[0] y := x.Args[0]
y := v_0.Args[1] if !(clobberIfDead(x)) {
v.reset(OpARM64MNEGW) break
v.AddArg(x) }
v.reset(OpARM64MVNshiftRL)
v.AuxInt = c
v.AddArg(y) v.AddArg(y)
return true return true
} }
// match: (NEG (MOVDconst [c])) // match: (MVN x:(SRAconst [c] y))
// cond: // cond: clobberIfDead(x)
// result: (MVNshiftRA [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(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]) // result: (MOVDconst [-c])
for { for {
v_0 := v.Args[0] v_0 := v.Args[0]
...@@ -20007,6 +20388,111 @@ func rewriteValueARM64_OpARM64NEG_0(v *Value) bool { ...@@ -20007,6 +20388,111 @@ func rewriteValueARM64_OpARM64NEG_0(v *Value) bool {
v.AuxInt = -c v.AuxInt = -c
return true 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 return false
} }
func rewriteValueARM64_OpARM64NotEqual_0(v *Value) bool { func rewriteValueARM64_OpARM64NotEqual_0(v *Value) bool {
...@@ -29431,6 +29917,132 @@ func rewriteValueARM64_OpARM64TST_0(v *Value) bool { ...@@ -29431,6 +29917,132 @@ func rewriteValueARM64_OpARM64TST_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true 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 return false
} }
func rewriteValueARM64_OpARM64TSTW_0(v *Value) bool { func rewriteValueARM64_OpARM64TSTW_0(v *Value) bool {
...@@ -29570,6 +30182,132 @@ func rewriteValueARM64_OpARM64TSTconst_0(v *Value) bool { ...@@ -29570,6 +30182,132 @@ func rewriteValueARM64_OpARM64TSTconst_0(v *Value) bool {
} }
return false 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 { func rewriteValueARM64_OpARM64UBFIZ_0(v *Value) bool {
// match: (UBFIZ [bfc] (SLLconst [sc] x)) // match: (UBFIZ [bfc] (SLLconst [sc] x))
// cond: sc < getARM64BFwidth(bfc) // cond: sc < getARM64BFwidth(bfc)
......
...@@ -44,7 +44,7 @@ func Pow2Muls(n1, n2 int) (int, int) { ...@@ -44,7 +44,7 @@ func Pow2Muls(n1, n2 int) (int, int) {
// amd64:"SHLQ\t[$]6",-"IMULQ" // amd64:"SHLQ\t[$]6",-"IMULQ"
// 386:"SHLL\t[$]6",-"IMULL" // 386:"SHLL\t[$]6",-"IMULL"
// arm:"SLL\t[$]6",-"MUL" // arm:"SLL\t[$]6",-"MUL"
// arm64:"LSL\t[$]6",-"MUL" // arm64:`NEG\sR[0-9]+<<6,\sR[0-9]+`,-`LSL`,-`MUL`
b := -64 * n2 b := -64 * n2
return a, b return a, b
......
...@@ -183,6 +183,10 @@ func CmpToZero(a, b, d int32, e, f int64) int32 { ...@@ -183,6 +183,10 @@ func CmpToZero(a, b, d int32, e, f int64) int32 {
// arm:`AND`,-`TST` // arm:`AND`,-`TST`
// 386:`ANDL` // 386:`ANDL`
c6 := a&d >= 0 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 { if c0 {
return 1 return 1
} else if c1 { } else if c1 {
...@@ -197,6 +201,10 @@ func CmpToZero(a, b, d int32, e, f int64) int32 { ...@@ -197,6 +201,10 @@ func CmpToZero(a, b, d int32, e, f int64) int32 {
return b + d return b + d
} else if c6 { } else if c6 {
return a & d return a & d
} else if c7 {
return 7
} else if c8 {
return 8
} else { } else {
return 0 return 0
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment