mirror of
https://github.com/golang/go
synced 2024-11-12 07:10:22 -07:00
cmd/compile: allow rotates to be merged with logical ops on arm64
Fixes #48002 Change-Id: Ie3a157d55b291f5ac2ef4845e6ce4fefd84fc642 Reviewed-on: https://go-review.googlesource.com/c/go/+/350912 Trust: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
2d9b486420
commit
6f35430faa
@ -315,6 +315,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
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.OpARM64MVNshiftRO:
|
||||
genshift(s, v.Op.Asm(), 0, v.Args[0].Reg(), v.Reg(), arm64.SHIFT_ROR, v.AuxInt)
|
||||
case ssa.OpARM64ADDshiftLL,
|
||||
ssa.OpARM64SUBshiftLL,
|
||||
ssa.OpARM64ANDshiftLL,
|
||||
@ -342,6 +344,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
ssa.OpARM64ORNshiftRA,
|
||||
ssa.OpARM64BICshiftRA:
|
||||
genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Reg(), arm64.SHIFT_AR, v.AuxInt)
|
||||
case ssa.OpARM64ANDshiftRO,
|
||||
ssa.OpARM64ORshiftRO,
|
||||
ssa.OpARM64XORshiftRO,
|
||||
ssa.OpARM64EONshiftRO,
|
||||
ssa.OpARM64ORNshiftRO,
|
||||
ssa.OpARM64BICshiftRO:
|
||||
genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Reg(), arm64.SHIFT_ROR, v.AuxInt)
|
||||
case ssa.OpARM64MOVDconst:
|
||||
p := s.Prog(v.Op.Asm())
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -389,6 +398,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm64.SHIFT_LR, v.AuxInt)
|
||||
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.OpARM64TSTshiftRO:
|
||||
genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm64.SHIFT_ROR, v.AuxInt)
|
||||
case ssa.OpARM64MOVDaddr:
|
||||
p := s.Prog(arm64.AMOVD)
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
|
@ -1601,6 +1601,7 @@
|
||||
(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)
|
||||
(MVN x:(RORconst [c] y)) && clobberIfDead(x) => (MVNshiftRO [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])
|
||||
@ -1610,21 +1611,27 @@
|
||||
(AND x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ANDshiftLL x0 y [c])
|
||||
(AND x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ANDshiftRL x0 y [c])
|
||||
(AND x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ANDshiftRA x0 y [c])
|
||||
(AND x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ANDshiftRO x0 y [c])
|
||||
(OR x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ORshiftLL x0 y [c]) // useful for combined load
|
||||
(OR x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ORshiftRL x0 y [c])
|
||||
(OR x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ORshiftRA x0 y [c])
|
||||
(OR x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ORshiftRO x0 y [c])
|
||||
(XOR x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (XORshiftLL x0 y [c])
|
||||
(XOR x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (XORshiftRL x0 y [c])
|
||||
(XOR x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (XORshiftRA x0 y [c])
|
||||
(XOR x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (XORshiftRO x0 y [c])
|
||||
(BIC x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (BICshiftLL x0 y [c])
|
||||
(BIC x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (BICshiftRL x0 y [c])
|
||||
(BIC x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (BICshiftRA x0 y [c])
|
||||
(BIC x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (BICshiftRO x0 y [c])
|
||||
(ORN x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ORNshiftLL x0 y [c])
|
||||
(ORN x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ORNshiftRL x0 y [c])
|
||||
(ORN x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ORNshiftRA x0 y [c])
|
||||
(ORN x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ORNshiftRO x0 y [c])
|
||||
(EON x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (EONshiftLL x0 y [c])
|
||||
(EON x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (EONshiftRL x0 y [c])
|
||||
(EON x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (EONshiftRA x0 y [c])
|
||||
(EON x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (EONshiftRO x0 y [c])
|
||||
(CMP x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (CMPshiftLL x0 y [c])
|
||||
(CMP x0:(SLLconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftLL x1 y [c]))
|
||||
(CMP x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (CMPshiftRL x0 y [c])
|
||||
@ -1637,6 +1644,7 @@
|
||||
(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])
|
||||
(TST x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (TSTshiftRO x0 y [c])
|
||||
|
||||
// prefer *const ops to *shift ops
|
||||
(ADDshiftLL (MOVDconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d]))
|
||||
@ -1645,12 +1653,15 @@
|
||||
(ANDshiftLL (MOVDconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d]))
|
||||
(ANDshiftRL (MOVDconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d]))
|
||||
(ANDshiftRA (MOVDconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d]))
|
||||
(ANDshiftRO (MOVDconst [c]) x [d]) => (ANDconst [c] (RORconst <x.Type> x [d]))
|
||||
(ORshiftLL (MOVDconst [c]) x [d]) => (ORconst [c] (SLLconst <x.Type> x [d]))
|
||||
(ORshiftRL (MOVDconst [c]) x [d]) => (ORconst [c] (SRLconst <x.Type> x [d]))
|
||||
(ORshiftRA (MOVDconst [c]) x [d]) => (ORconst [c] (SRAconst <x.Type> x [d]))
|
||||
(ORshiftRO (MOVDconst [c]) x [d]) => (ORconst [c] (RORconst <x.Type> x [d]))
|
||||
(XORshiftLL (MOVDconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d]))
|
||||
(XORshiftRL (MOVDconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d]))
|
||||
(XORshiftRA (MOVDconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d]))
|
||||
(XORshiftRO (MOVDconst [c]) x [d]) => (XORconst [c] (RORconst <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])))
|
||||
@ -1660,11 +1671,13 @@
|
||||
(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]))
|
||||
(TSTshiftRO (MOVDconst [c]) x [d]) => (TSTconst [c] (RORconst <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))])
|
||||
(MVNshiftRO (MOVDconst [c]) [d]) => (MOVDconst [^rotateRight64(c, 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))])
|
||||
@ -1677,21 +1690,27 @@
|
||||
(ANDshiftLL x (MOVDconst [c]) [d]) => (ANDconst x [int64(uint64(c)<<uint64(d))])
|
||||
(ANDshiftRL x (MOVDconst [c]) [d]) => (ANDconst x [int64(uint64(c)>>uint64(d))])
|
||||
(ANDshiftRA x (MOVDconst [c]) [d]) => (ANDconst x [c>>uint64(d)])
|
||||
(ANDshiftRO x (MOVDconst [c]) [d]) => (ANDconst x [rotateRight64(c, d)])
|
||||
(ORshiftLL x (MOVDconst [c]) [d]) => (ORconst x [int64(uint64(c)<<uint64(d))])
|
||||
(ORshiftRL x (MOVDconst [c]) [d]) => (ORconst x [int64(uint64(c)>>uint64(d))])
|
||||
(ORshiftRA x (MOVDconst [c]) [d]) => (ORconst x [c>>uint64(d)])
|
||||
(ORshiftRO x (MOVDconst [c]) [d]) => (ORconst x [rotateRight64(c, d)])
|
||||
(XORshiftLL x (MOVDconst [c]) [d]) => (XORconst x [int64(uint64(c)<<uint64(d))])
|
||||
(XORshiftRL x (MOVDconst [c]) [d]) => (XORconst x [int64(uint64(c)>>uint64(d))])
|
||||
(XORshiftRA x (MOVDconst [c]) [d]) => (XORconst x [c>>uint64(d)])
|
||||
(XORshiftRO x (MOVDconst [c]) [d]) => (XORconst x [rotateRight64(c, d)])
|
||||
(BICshiftLL x (MOVDconst [c]) [d]) => (ANDconst x [^int64(uint64(c)<<uint64(d))])
|
||||
(BICshiftRL x (MOVDconst [c]) [d]) => (ANDconst x [^int64(uint64(c)>>uint64(d))])
|
||||
(BICshiftRA x (MOVDconst [c]) [d]) => (ANDconst x [^(c>>uint64(d))])
|
||||
(BICshiftRO x (MOVDconst [c]) [d]) => (ANDconst x [^rotateRight64(c, d)])
|
||||
(ORNshiftLL x (MOVDconst [c]) [d]) => (ORconst x [^int64(uint64(c)<<uint64(d))])
|
||||
(ORNshiftRL x (MOVDconst [c]) [d]) => (ORconst x [^int64(uint64(c)>>uint64(d))])
|
||||
(ORNshiftRA x (MOVDconst [c]) [d]) => (ORconst x [^(c>>uint64(d))])
|
||||
(ORNshiftRO x (MOVDconst [c]) [d]) => (ORconst x [^rotateRight64(c, d)])
|
||||
(EONshiftLL x (MOVDconst [c]) [d]) => (XORconst x [^int64(uint64(c)<<uint64(d))])
|
||||
(EONshiftRL x (MOVDconst [c]) [d]) => (XORconst x [^int64(uint64(c)>>uint64(d))])
|
||||
(EONshiftRA x (MOVDconst [c]) [d]) => (XORconst x [^(c>>uint64(d))])
|
||||
(EONshiftRO x (MOVDconst [c]) [d]) => (XORconst x [^rotateRight64(c, 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)])
|
||||
@ -1701,6 +1720,7 @@
|
||||
(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)])
|
||||
(TSTshiftRO x (MOVDconst [c]) [d]) => (TSTconst x [rotateRight64(c, d)])
|
||||
|
||||
// simplification with *shift ops
|
||||
(SUBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
@ -1709,21 +1729,27 @@
|
||||
(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
|
||||
(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
|
||||
(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
|
||||
(ANDshiftRO x y:(RORconst x [c]) [d]) && c==d => y
|
||||
(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
|
||||
(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
|
||||
(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
|
||||
(ORshiftRO x y:(RORconst x [c]) [d]) && c==d => y
|
||||
(XORshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(XORshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(XORshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(XORshiftRO x (RORconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(BICshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(BICshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(BICshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(BICshiftRO x (RORconst x [c]) [d]) && c==d => (MOVDconst [0])
|
||||
(EONshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(EONshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(EONshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(EONshiftRO x (RORconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(ORNshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(ORNshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(ORNshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
(ORNshiftRO x (RORconst x [c]) [d]) && c==d => (MOVDconst [-1])
|
||||
|
||||
// Generate rotates with const shift
|
||||
(ADDshiftLL [c] (SRLconst x [64-c]) x) => (RORconst [64-c] x)
|
||||
|
@ -302,6 +302,7 @@ func init() {
|
||||
{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"}, // ^(arg0<<auxInt), auxInt should be in the range 0 to 63.
|
||||
{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"}, // ^(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"}, // ^(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "MVNshiftRO", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"}, // ^(arg0 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "NEGshiftLL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"}, // -(arg0<<auxInt), auxInt should be in the range 0 to 63.
|
||||
{name: "NEGshiftRL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"}, // -(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "NEGshiftRA", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"}, // -(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
@ -314,21 +315,27 @@ func init() {
|
||||
{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"}, // arg0 & (arg1<<auxInt), auxInt should be in the range 0 to 63.
|
||||
{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"}, // arg0 & (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"}, // arg0 & (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ANDshiftRO", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"}, // arg0 & (arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"}, // arg0 | arg1<<auxInt, auxInt should be in the range 0 to 63.
|
||||
{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"}, // arg0 | arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"}, // arg0 | arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ORshiftRO", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"}, // arg0 | arg1 ROR auxInt, signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"}, // arg0 ^ arg1<<auxInt, auxInt should be in the range 0 to 63.
|
||||
{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"}, // arg0 ^ arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"}, // arg0 ^ arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "XORshiftRO", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"}, // arg0 ^ arg1 ROR auxInt, signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"}, // arg0 &^ (arg1<<auxInt), auxInt should be in the range 0 to 63.
|
||||
{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"}, // arg0 &^ (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"}, // arg0 &^ (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "BICshiftRO", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"}, // arg0 &^ (arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "EONshiftLL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"}, // arg0 ^ ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
|
||||
{name: "EONshiftRL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"}, // arg0 ^ ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "EONshiftRA", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"}, // arg0 ^ ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "EONshiftRO", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"}, // arg0 ^ ^(arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ORNshiftLL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"}, // arg0 | ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
|
||||
{name: "ORNshiftRL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"}, // arg0 | ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ORNshiftRA", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"}, // arg0 | ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "ORNshiftRO", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"}, // arg0 | ^(arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt, auxInt should be in the range 0 to 63.
|
||||
{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
|
||||
@ -338,6 +345,7 @@ func init() {
|
||||
{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
|
||||
{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
|
||||
{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
|
||||
{name: "TSTshiftRO", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1 ROR auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
|
||||
|
||||
// bitfield ops
|
||||
// for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff
|
||||
|
@ -1412,6 +1412,7 @@ const (
|
||||
OpARM64MVNshiftLL
|
||||
OpARM64MVNshiftRL
|
||||
OpARM64MVNshiftRA
|
||||
OpARM64MVNshiftRO
|
||||
OpARM64NEGshiftLL
|
||||
OpARM64NEGshiftRL
|
||||
OpARM64NEGshiftRA
|
||||
@ -1424,21 +1425,27 @@ const (
|
||||
OpARM64ANDshiftLL
|
||||
OpARM64ANDshiftRL
|
||||
OpARM64ANDshiftRA
|
||||
OpARM64ANDshiftRO
|
||||
OpARM64ORshiftLL
|
||||
OpARM64ORshiftRL
|
||||
OpARM64ORshiftRA
|
||||
OpARM64ORshiftRO
|
||||
OpARM64XORshiftLL
|
||||
OpARM64XORshiftRL
|
||||
OpARM64XORshiftRA
|
||||
OpARM64XORshiftRO
|
||||
OpARM64BICshiftLL
|
||||
OpARM64BICshiftRL
|
||||
OpARM64BICshiftRA
|
||||
OpARM64BICshiftRO
|
||||
OpARM64EONshiftLL
|
||||
OpARM64EONshiftRL
|
||||
OpARM64EONshiftRA
|
||||
OpARM64EONshiftRO
|
||||
OpARM64ORNshiftLL
|
||||
OpARM64ORNshiftRL
|
||||
OpARM64ORNshiftRA
|
||||
OpARM64ORNshiftRO
|
||||
OpARM64CMPshiftLL
|
||||
OpARM64CMPshiftRL
|
||||
OpARM64CMPshiftRA
|
||||
@ -1448,6 +1455,7 @@ const (
|
||||
OpARM64TSTshiftLL
|
||||
OpARM64TSTshiftRL
|
||||
OpARM64TSTshiftRA
|
||||
OpARM64TSTshiftRO
|
||||
OpARM64BFI
|
||||
OpARM64BFXIL
|
||||
OpARM64SBFIZ
|
||||
@ -18807,6 +18815,20 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MVNshiftRO",
|
||||
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,
|
||||
@ -18984,6 +19006,21 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ANDshiftRO",
|
||||
auxType: auxInt64,
|
||||
argLen: 2,
|
||||
asm: arm64.AAND,
|
||||
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
|
||||
},
|
||||
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: "ORshiftLL",
|
||||
auxType: auxInt64,
|
||||
@ -19029,6 +19066,21 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ORshiftRO",
|
||||
auxType: auxInt64,
|
||||
argLen: 2,
|
||||
asm: arm64.AORR,
|
||||
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
|
||||
},
|
||||
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: "XORshiftLL",
|
||||
auxType: auxInt64,
|
||||
@ -19074,6 +19126,21 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "XORshiftRO",
|
||||
auxType: auxInt64,
|
||||
argLen: 2,
|
||||
asm: arm64.AEOR,
|
||||
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
|
||||
},
|
||||
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: "BICshiftLL",
|
||||
auxType: auxInt64,
|
||||
@ -19119,6 +19186,21 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "BICshiftRO",
|
||||
auxType: auxInt64,
|
||||
argLen: 2,
|
||||
asm: arm64.ABIC,
|
||||
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
|
||||
},
|
||||
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: "EONshiftLL",
|
||||
auxType: auxInt64,
|
||||
@ -19164,6 +19246,21 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "EONshiftRO",
|
||||
auxType: auxInt64,
|
||||
argLen: 2,
|
||||
asm: arm64.AEON,
|
||||
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
|
||||
},
|
||||
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: "ORNshiftLL",
|
||||
auxType: auxInt64,
|
||||
@ -19209,6 +19306,21 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ORNshiftRO",
|
||||
auxType: auxInt64,
|
||||
argLen: 2,
|
||||
asm: arm64.AORN,
|
||||
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
|
||||
},
|
||||
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: "CMPshiftLL",
|
||||
auxType: auxInt64,
|
||||
@ -19317,6 +19429,18 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "TSTshiftRO",
|
||||
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: auxARM64BitField,
|
||||
|
@ -1567,6 +1567,10 @@ func rotateLeft32(v, rotate int64) int64 {
|
||||
return int64(bits.RotateLeft32(uint32(v), int(rotate)))
|
||||
}
|
||||
|
||||
func rotateRight64(v, rotate int64) int64 {
|
||||
return int64(bits.RotateLeft64(uint64(v), int(-rotate)))
|
||||
}
|
||||
|
||||
// encodes the lsb and width for arm(64) bitfield ops into the expected auxInt format.
|
||||
func armBFAuxInt(lsb, width int64) arm64BitField {
|
||||
if lsb < 0 || lsb > 63 {
|
||||
|
@ -29,6 +29,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64ANDshiftRA(v)
|
||||
case OpARM64ANDshiftRL:
|
||||
return rewriteValueARM64_OpARM64ANDshiftRL(v)
|
||||
case OpARM64ANDshiftRO:
|
||||
return rewriteValueARM64_OpARM64ANDshiftRO(v)
|
||||
case OpARM64BIC:
|
||||
return rewriteValueARM64_OpARM64BIC(v)
|
||||
case OpARM64BICshiftLL:
|
||||
@ -37,6 +39,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64BICshiftRA(v)
|
||||
case OpARM64BICshiftRL:
|
||||
return rewriteValueARM64_OpARM64BICshiftRL(v)
|
||||
case OpARM64BICshiftRO:
|
||||
return rewriteValueARM64_OpARM64BICshiftRO(v)
|
||||
case OpARM64CMN:
|
||||
return rewriteValueARM64_OpARM64CMN(v)
|
||||
case OpARM64CMNW:
|
||||
@ -89,6 +93,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64EONshiftRA(v)
|
||||
case OpARM64EONshiftRL:
|
||||
return rewriteValueARM64_OpARM64EONshiftRL(v)
|
||||
case OpARM64EONshiftRO:
|
||||
return rewriteValueARM64_OpARM64EONshiftRO(v)
|
||||
case OpARM64Equal:
|
||||
return rewriteValueARM64_OpARM64Equal(v)
|
||||
case OpARM64FADDD:
|
||||
@ -295,6 +301,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64MVNshiftRA(v)
|
||||
case OpARM64MVNshiftRL:
|
||||
return rewriteValueARM64_OpARM64MVNshiftRL(v)
|
||||
case OpARM64MVNshiftRO:
|
||||
return rewriteValueARM64_OpARM64MVNshiftRO(v)
|
||||
case OpARM64NEG:
|
||||
return rewriteValueARM64_OpARM64NEG(v)
|
||||
case OpARM64NEGshiftLL:
|
||||
@ -315,6 +323,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64ORNshiftRA(v)
|
||||
case OpARM64ORNshiftRL:
|
||||
return rewriteValueARM64_OpARM64ORNshiftRL(v)
|
||||
case OpARM64ORNshiftRO:
|
||||
return rewriteValueARM64_OpARM64ORNshiftRO(v)
|
||||
case OpARM64ORconst:
|
||||
return rewriteValueARM64_OpARM64ORconst(v)
|
||||
case OpARM64ORshiftLL:
|
||||
@ -323,6 +333,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64ORshiftRA(v)
|
||||
case OpARM64ORshiftRL:
|
||||
return rewriteValueARM64_OpARM64ORshiftRL(v)
|
||||
case OpARM64ORshiftRO:
|
||||
return rewriteValueARM64_OpARM64ORshiftRO(v)
|
||||
case OpARM64ROR:
|
||||
return rewriteValueARM64_OpARM64ROR(v)
|
||||
case OpARM64RORW:
|
||||
@ -371,6 +383,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64TSTshiftRA(v)
|
||||
case OpARM64TSTshiftRL:
|
||||
return rewriteValueARM64_OpARM64TSTshiftRL(v)
|
||||
case OpARM64TSTshiftRO:
|
||||
return rewriteValueARM64_OpARM64TSTshiftRO(v)
|
||||
case OpARM64UBFIZ:
|
||||
return rewriteValueARM64_OpARM64UBFIZ(v)
|
||||
case OpARM64UBFX:
|
||||
@ -393,6 +407,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpARM64XORshiftRA(v)
|
||||
case OpARM64XORshiftRL:
|
||||
return rewriteValueARM64_OpARM64XORshiftRL(v)
|
||||
case OpARM64XORshiftRO:
|
||||
return rewriteValueARM64_OpARM64XORshiftRO(v)
|
||||
case OpAbs:
|
||||
v.Op = OpARM64FABSD
|
||||
return true
|
||||
@ -2114,6 +2130,28 @@ func rewriteValueARM64_OpARM64AND(v *Value) bool {
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (AND x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (ANDshiftRO x0 y [c])
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpARM64ANDshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ANDconst(v *Value) bool {
|
||||
@ -2403,6 +2441,60 @@ func rewriteValueARM64_OpARM64ANDshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ANDshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (ANDshiftRO (MOVDconst [c]) x [d])
|
||||
// result: (ANDconst [c] (RORconst <x.Type> x [d]))
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_0.AuxInt)
|
||||
x := v_1
|
||||
v.reset(OpARM64ANDconst)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(d)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (ANDshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (ANDconst x [rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64ANDconst)
|
||||
v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ANDshiftRO x y:(RORconst x [c]) [d])
|
||||
// cond: c==d
|
||||
// result: y
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
y := v_1
|
||||
if y.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(y.AuxInt)
|
||||
if x != y.Args[0] || !(c == d) {
|
||||
break
|
||||
}
|
||||
v.copyOf(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64BIC(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
@ -2487,6 +2579,25 @@ func rewriteValueARM64_OpARM64BIC(v *Value) bool {
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
// match: (BIC x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (BICshiftRO x0 y [c])
|
||||
for {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64BICshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64BICshiftLL(v *Value) bool {
|
||||
@ -2597,6 +2708,42 @@ func rewriteValueARM64_OpARM64BICshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64BICshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (BICshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (ANDconst x [^rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64ANDconst)
|
||||
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (BICshiftRO x (RORconst x [c]) [d])
|
||||
// cond: c==d
|
||||
// result: (MOVDconst [0])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
if x != v_1.Args[0] || !(c == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDconst)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64CMN(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
@ -3937,6 +4084,25 @@ func rewriteValueARM64_OpARM64EON(v *Value) bool {
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
// match: (EON x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (EONshiftRO x0 y [c])
|
||||
for {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64EONshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64EONshiftLL(v *Value) bool {
|
||||
@ -4047,6 +4213,42 @@ func rewriteValueARM64_OpARM64EONshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64EONshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (EONshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (XORconst x [^rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64XORconst)
|
||||
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (EONshiftRO x (RORconst x [c]) [d])
|
||||
// cond: c==d
|
||||
// result: (MOVDconst [-1])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
if x != v_1.Args[0] || !(c == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDconst)
|
||||
v.AuxInt = int64ToAuxInt(-1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64Equal(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (Equal (FlagConstant [fc]))
|
||||
@ -15615,6 +15817,24 @@ func rewriteValueARM64_OpARM64MVN(v *Value) bool {
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
// match: (MVN x:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x)
|
||||
// result: (MVNshiftRO [c] y)
|
||||
for {
|
||||
x := v_0
|
||||
if x.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(x.AuxInt)
|
||||
y := x.Args[0]
|
||||
if !(clobberIfDead(x)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MVNshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64MVNshiftLL(v *Value) bool {
|
||||
@ -15665,6 +15885,22 @@ func rewriteValueARM64_OpARM64MVNshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64MVNshiftRO(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (MVNshiftRO (MOVDconst [c]) [d])
|
||||
// result: (MOVDconst [^rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_0.AuxInt)
|
||||
v.reset(OpARM64MOVDconst)
|
||||
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64NEG(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (NEG (MUL x y))
|
||||
@ -15954,6 +16190,28 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (OR x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (ORshiftRO x0 y [c])
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpARM64ORshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (OR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
|
||||
// cond: cc == OpARM64LessThanU
|
||||
// result: (ROR x (NEG <t> y))
|
||||
@ -17923,6 +18181,25 @@ func rewriteValueARM64_OpARM64ORN(v *Value) bool {
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
// match: (ORN x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (ORNshiftRO x0 y [c])
|
||||
for {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64ORNshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ORNshiftLL(v *Value) bool {
|
||||
@ -18033,6 +18310,42 @@ func rewriteValueARM64_OpARM64ORNshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ORNshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (ORNshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (ORconst x [^rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64ORconst)
|
||||
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ORNshiftRO x (RORconst x [c]) [d])
|
||||
// cond: c==d
|
||||
// result: (MOVDconst [-1])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
if x != v_1.Args[0] || !(c == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDconst)
|
||||
v.AuxInt = int64ToAuxInt(-1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ORconst(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (ORconst [0] x)
|
||||
@ -19970,6 +20283,60 @@ func rewriteValueARM64_OpARM64ORshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ORshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (ORshiftRO (MOVDconst [c]) x [d])
|
||||
// result: (ORconst [c] (RORconst <x.Type> x [d]))
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_0.AuxInt)
|
||||
x := v_1
|
||||
v.reset(OpARM64ORconst)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(d)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (ORshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (ORconst x [rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64ORconst)
|
||||
v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ORshiftRO x y:(RORconst x [c]) [d])
|
||||
// cond: c==d
|
||||
// result: y
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
y := v_1
|
||||
if y.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(y.AuxInt)
|
||||
if x != y.Args[0] || !(c == d) {
|
||||
break
|
||||
}
|
||||
v.copyOf(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64ROR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
@ -21198,6 +21565,28 @@ func rewriteValueARM64_OpARM64TST(v *Value) bool {
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (TST x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (TSTshiftRO x0 y [c])
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpARM64TSTshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64TSTW(v *Value) bool {
|
||||
@ -21364,6 +21753,43 @@ func rewriteValueARM64_OpARM64TSTshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64TSTshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (TSTshiftRO (MOVDconst [c]) x [d])
|
||||
// result: (TSTconst [c] (RORconst <x.Type> x [d]))
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_0.AuxInt)
|
||||
x := v_1
|
||||
v.reset(OpARM64TSTconst)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(d)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (TSTshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (TSTconst x [rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64TSTconst)
|
||||
v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64UBFIZ(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (UBFIZ [bfc] (SLLconst [sc] x))
|
||||
@ -21823,6 +22249,28 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (XOR x0 x1:(RORconst [c] y))
|
||||
// cond: clobberIfDead(x1)
|
||||
// result: (XORshiftRO x0 y [c])
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
x0 := v_0
|
||||
x1 := v_1
|
||||
if x1.Op != OpARM64RORconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(x1.AuxInt)
|
||||
y := x1.Args[0]
|
||||
if !(clobberIfDead(x1)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpARM64XORshiftRO)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg2(x0, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (XOR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
|
||||
// cond: cc == OpARM64LessThanU
|
||||
// result: (ROR x (NEG <t> y))
|
||||
@ -22512,6 +22960,60 @@ func rewriteValueARM64_OpARM64XORshiftRL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpARM64XORshiftRO(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (XORshiftRO (MOVDconst [c]) x [d])
|
||||
// result: (XORconst [c] (RORconst <x.Type> x [d]))
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_0.AuxInt)
|
||||
x := v_1
|
||||
v.reset(OpARM64XORconst)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(d)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (XORshiftRO x (MOVDconst [c]) [d])
|
||||
// result: (XORconst x [rotateRight64(c, d)])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpARM64XORconst)
|
||||
v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (XORshiftRO x (RORconst x [c]) [d])
|
||||
// cond: c==d
|
||||
// result: (MOVDconst [0])
|
||||
for {
|
||||
d := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARM64RORconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
if x != v_1.Args[0] || !(c == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDconst)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM64_OpAddr(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (Addr {sym} base)
|
||||
|
@ -1060,9 +1060,10 @@ const (
|
||||
|
||||
const (
|
||||
// shift types
|
||||
SHIFT_LL = 0 << 22
|
||||
SHIFT_LR = 1 << 22
|
||||
SHIFT_AR = 2 << 22
|
||||
SHIFT_LL = 0 << 22
|
||||
SHIFT_LR = 1 << 22
|
||||
SHIFT_AR = 2 << 22
|
||||
SHIFT_ROR = 3 << 22
|
||||
)
|
||||
|
||||
// Arrangement for ARM64 SIMD instructions
|
||||
|
@ -226,3 +226,26 @@ func checkMaskedRotate32(a []uint32, r int) {
|
||||
a[i] = bits.RotateLeft32(a[3], 4) & 0xFFF00FFF
|
||||
i++
|
||||
}
|
||||
|
||||
// combined arithmetic and rotate on arm64
|
||||
func checkArithmeticWithRotate(a *[1000]uint64) {
|
||||
// arm64: "AND\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
|
||||
a[2] = a[1] & bits.RotateLeft64(a[0], 13)
|
||||
// arm64: "ORR\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
|
||||
a[5] = a[4] | bits.RotateLeft64(a[3], 13)
|
||||
// arm64: "EOR\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
|
||||
a[8] = a[7] ^ bits.RotateLeft64(a[6], 13)
|
||||
// arm64: "MVN\tR[0-9]+@>51, R[0-9]+"
|
||||
a[10] = ^bits.RotateLeft64(a[9], 13)
|
||||
// arm64: "BIC\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
|
||||
a[13] = a[12] &^ bits.RotateLeft64(a[11], 13)
|
||||
// arm64: "EON\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
|
||||
a[16] = a[15] ^ ^bits.RotateLeft64(a[14], 13)
|
||||
// arm64: "ORN\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
|
||||
a[19] = a[18] | ^bits.RotateLeft64(a[17], 13)
|
||||
// arm64: "TST\tR[0-9]+@>51, R[0-9]+"
|
||||
if a[18]&bits.RotateLeft64(a[19], 13) == 0 {
|
||||
a[20] = 1
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user