mirror of
https://github.com/golang/go
synced 2024-11-12 05:30:21 -07:00
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: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
d60cf39f8e
commit
5aeecc4530
@ -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)
|
||||
|
@ -1605,6 +1605,12 @@
|
||||
(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])
|
||||
@ -1635,6 +1641,12 @@
|
||||
(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]))
|
||||
@ -1652,8 +1664,20 @@
|
||||
(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)])
|
||||
@ -1681,6 +1705,12 @@
|
||||
(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])
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,6 +20235,111 @@ func rewriteValueARM64_OpARM64MVN_0(v *Value) bool {
|
||||
v.AuxInt = ^c
|
||||
return true
|
||||
}
|
||||
// match: (MVN x:(SLLconst [c] y))
|
||||
// cond: clobberIfDead(x)
|
||||
// result: (MVNshiftLL [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(OpARM64MVNshiftLL)
|
||||
v.AuxInt = c
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
// match: (MVN x:(SRLconst [c] y))
|
||||
// cond: clobberIfDead(x)
|
||||
// result: (MVNshiftRL [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(OpARM64MVNshiftRL)
|
||||
v.AuxInt = c
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
// match: (MVN x:(SRAconst [c] y))
|
||||
// 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 {
|
||||
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user