summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2023-03-21 09:25:43 -0700
committerKeith Randall <khr@golang.org>2023-04-21 21:05:46 +0000
commitcedf5008a84d3726f98fac551a4016bf0a91157f (patch)
treea75ad1fde9937d7c0a15b42479b610333fb65c4a
parente9c2607ab47b63993cb5ee54c934d67baba7fc95 (diff)
downloadgo-git-cedf5008a84d3726f98fac551a4016bf0a91157f.tar.gz
cmd/compile: introduce separate memory op combining pass
Memory op combining is currently done using arch-specific rewrite rules. Instead, do them as a arch-independent rewrite pass. This ensures that all architectures (with unaligned loads & stores) get equal treatment. This removes a lot of rewrite rules. The new pass is a bit more comprehensive. It handles things like out-of-order writes and is careful not to apply partial optimizations that then block further optimizations. Change-Id: I780ff3bb052475cd725a923309616882d25b8d9e Reviewed-on: https://go-review.googlesource.com/c/go/+/478475 Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/_gen/386.rules155
-rw-r--r--src/cmd/compile/internal/ssa/_gen/AMD64.rules492
-rw-r--r--src/cmd/compile/internal/ssa/_gen/ARM64.rules916
-rw-r--r--src/cmd/compile/internal/ssa/_gen/PPC64.rules324
-rw-r--r--src/cmd/compile/internal/ssa/_gen/PPC64Ops.go12
-rw-r--r--src/cmd/compile/internal/ssa/_gen/S390X.rules375
-rw-r--r--src/cmd/compile/internal/ssa/compile.go5
-rw-r--r--src/cmd/compile/internal/ssa/config.go42
-rw-r--r--src/cmd/compile/internal/ssa/memcombine.go737
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go12
-rw-r--r--src/cmd/compile/internal/ssa/rewrite386.go786
-rw-r--r--src/cmd/compile/internal/ssa/rewriteAMD64.go2991
-rw-r--r--src/cmd/compile/internal/ssa/rewriteARM64.go5615
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go2307
-rw-r--r--src/cmd/compile/internal/ssa/rewriteS390X.go1728
-rw-r--r--src/cmd/compile/internal/ssa/value.go16
-rw-r--r--src/cmd/compile/internal/test/memcombine_test.go73
17 files changed, 1769 insertions, 14817 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/386.rules b/src/cmd/compile/internal/ssa/_gen/386.rules
index 4dfe05d0e9..d92dddd377 100644
--- a/src/cmd/compile/internal/ssa/_gen/386.rules
+++ b/src/cmd/compile/internal/ssa/_gen/386.rules
@@ -52,6 +52,7 @@
(OffPtr [off] ptr) => (ADDLconst [int32(off)] ptr)
(Bswap32 ...) => (BSWAPL ...)
+(Bswap16 x) => (ROLWconst [8] x)
(Sqrt ...) => (SQRTSD ...)
(Sqrt32 ...) => (SQRTSS ...)
@@ -918,160 +919,6 @@
// Convert LEAL1 back to ADDL if we can
(LEAL1 [0] {nil} x y) => (ADDL x y)
-// Combining byte loads into larger (unaligned) loads.
-// There are many ways these combinations could occur. This is
-// designed to match the way encoding/binary.LittleEndian does it.
-(ORL x0:(MOVBload [i0] {s} p mem)
- s0:(SHLLconst [8] x1:(MOVBload [i1] {s} p mem)))
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, s0)
- => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
-
-(ORL x0:(MOVBload [i] {s} p0 mem)
- s0:(SHLLconst [8] x1:(MOVBload [i] {s} p1 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, s0)
- => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
-
-(ORL o0:(ORL
- x0:(MOVWload [i0] {s} p mem)
- s0:(SHLLconst [16] x1:(MOVBload [i2] {s} p mem)))
- s1:(SHLLconst [24] x2:(MOVBload [i3] {s} p mem)))
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && clobber(x0, x1, x2, s0, s1, o0)
- => @mergePoint(b,x0,x1,x2) (MOVLload [i0] {s} p mem)
-
-(ORL o0:(ORL
- x0:(MOVWload [i] {s} p0 mem)
- s0:(SHLLconst [16] x1:(MOVBload [i] {s} p1 mem)))
- s1:(SHLLconst [24] x2:(MOVBload [i] {s} p2 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && o0.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && sequentialAddresses(p1, p2, 1)
- && mergePoint(b,x0,x1,x2) != nil
- && clobber(x0, x1, x2, s0, s1, o0)
- => @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p0 mem)
-
-// Combine constant stores into larger (unaligned) stores.
-(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
- && x.Uses == 1
- && a.Off() + 1 == c.Off()
- && clobber(x)
- => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
-(MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
- && x.Uses == 1
- && a.Off() + 1 == c.Off()
- && clobber(x)
- => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
-
-(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
- && x.Uses == 1
- && a.Off() == c.Off()
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
-(MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
- && x.Uses == 1
- && a.Off() == c.Off()
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
-
-(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
- && x.Uses == 1
- && a.Off() + 2 == c.Off()
- && clobber(x)
- => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
-(MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
- && x.Uses == 1
- && ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
- && clobber(x)
- => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
-
-(MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
- && x.Uses == 1
- && a.Off() == c.Off()
- && sequentialAddresses(p0, p1, 2)
- && clobber(x)
- => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
-(MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
- && x.Uses == 1
- && a.Off() == c.Off()
- && sequentialAddresses(p0, p1, 2)
- && clobber(x)
- => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
-
-// Combine stores into larger (unaligned) stores.
-(MOVBstore [i] {s} p (SHR(W|L)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHR(W|L)const [8] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i] {s} p w mem)
-(MOVBstore [i] {s} p (SHRLconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SHRLconst [j-8] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-1] {s} p w0 mem)
-
-(MOVBstore [i] {s} p1 (SHR(W|L)const [8] w) x:(MOVBstore [i] {s} p0 w mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p0 w x:(MOVBstore {s} [i] p1 (SHR(W|L)const [8] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p1 (SHRLconst [j] w) x:(MOVBstore [i] {s} p0 w0:(SHRLconst [j-8] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstore [i] {s} p0 w0 mem)
-
-(MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVLstore [i-2] {s} p w mem)
-(MOVWstore [i] {s} p (SHRLconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRLconst [j-16] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVLstore [i-2] {s} p w0 mem)
-
-(MOVWstore [i] {s} p1 (SHRLconst [16] w) x:(MOVWstore [i] {s} p0 w mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && clobber(x)
- => (MOVLstore [i] {s} p0 w mem)
-(MOVWstore [i] {s} p1 (SHRLconst [j] w) x:(MOVWstore [i] {s} p0 w0:(SHRLconst [j-16] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && clobber(x)
- => (MOVLstore [i] {s} p0 w0 mem)
-
// For PIC, break floating-point constant loading into two instructions so we have
// a register to use for holding the address of the constant pool entry.
(MOVSSconst [c]) && config.ctxt.Flag_shared => (MOVSSconst2 (MOVSSconst1 [c]))
diff --git a/src/cmd/compile/internal/ssa/_gen/AMD64.rules b/src/cmd/compile/internal/ssa/_gen/AMD64.rules
index 6f9cb3698f..602c9723a6 100644
--- a/src/cmd/compile/internal/ssa/_gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/AMD64.rules
@@ -110,6 +110,7 @@
(BitLen8 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL (MOVBQZX <x.Type> x))))
(Bswap(64|32) ...) => (BSWAP(Q|L) ...)
+(Bswap16 x) => (ROLWconst [8] x)
(PopCount(64|32) ...) => (POPCNT(Q|L) ...)
(PopCount16 x) => (POPCNTL (MOVWQZX <typ.UInt32> x))
@@ -1469,397 +1470,6 @@
// Convert LEAQ1 back to ADDQ if we can
(LEAQ1 [0] x y) && v.Aux == nil => (ADDQ x y)
-// Combining byte loads into larger (unaligned) loads.
-// There are many ways these combinations could occur. This is
-// designed to match the way encoding/binary.LittleEndian does it.
-
-// Little-endian loads
-
-(OR(L|Q) x0:(MOVBload [i0] {s} p mem)
- sh:(SHL(L|Q)const [8] x1:(MOVBload [i1] {s} p mem)))
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
-
-(OR(L|Q) x0:(MOVBload [i] {s} p0 mem)
- sh:(SHL(L|Q)const [8] x1:(MOVBload [i] {s} p1 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
-
-(OR(L|Q) x0:(MOVWload [i0] {s} p mem)
- sh:(SHL(L|Q)const [16] x1:(MOVWload [i1] {s} p mem)))
- && i1 == i0+2
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem)
-
-(OR(L|Q) x0:(MOVWload [i] {s} p0 mem)
- sh:(SHL(L|Q)const [16] x1:(MOVWload [i] {s} p1 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem)
-
-(ORQ x0:(MOVLload [i0] {s} p mem)
- sh:(SHLQconst [32] x1:(MOVLload [i1] {s} p mem)))
- && i1 == i0+4
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem)
-
-(ORQ x0:(MOVLload [i] {s} p0 mem)
- sh:(SHLQconst [32] x1:(MOVLload [i] {s} p1 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p0, p1, 4)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVQload [i] {s} p0 mem)
-
-(OR(L|Q)
- s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem))
- or:(OR(L|Q)
- s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem))
- y))
- && i1 == i0+1
- && j1 == j0+8
- && j0 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
-
-(OR(L|Q)
- s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem))
- or:(OR(L|Q)
- s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem))
- y))
- && j1 == j0+8
- && j0 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y)
-
-(ORQ
- s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem))
- or:(ORQ
- s0:(SHLQconst [j0] x0:(MOVWload [i0] {s} p mem))
- y))
- && i1 == i0+2
- && j1 == j0+16
- && j0 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
-
-(ORQ
- s1:(SHLQconst [j1] x1:(MOVWload [i] {s} p1 mem))
- or:(ORQ
- s0:(SHLQconst [j0] x0:(MOVWload [i] {s} p0 mem))
- y))
- && j1 == j0+16
- && j0 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i] {s} p0 mem)) y)
-
-// Big-endian loads
-
-(OR(L|Q)
- x1:(MOVBload [i1] {s} p mem)
- sh:(SHL(L|Q)const [8] x0:(MOVBload [i0] {s} p mem)))
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem))
-
-(OR(L|Q)
- x1:(MOVBload [i] {s} p1 mem)
- sh:(SHL(L|Q)const [8] x0:(MOVBload [i] {s} p0 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem))
-
-(OR(L|Q)
- r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem))
- sh:(SHL(L|Q)const [16] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))))
- && i1 == i0+2
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem))
-
-(OR(L|Q)
- r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem))
- sh:(SHL(L|Q)const [16] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem))
-
-(ORQ
- r1:(BSWAPL x1:(MOVLload [i1] {s} p mem))
- sh:(SHLQconst [32] r0:(BSWAPL x0:(MOVLload [i0] {s} p mem))))
- && i1 == i0+4
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem))
-
-(ORQ
- r1:(BSWAPL x1:(MOVLload [i] {s} p1 mem))
- sh:(SHLQconst [32] r0:(BSWAPL x0:(MOVLload [i] {s} p0 mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p0, p1, 4)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i] {s} p0 mem))
-
-(OR(L|Q)
- s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem))
- or:(OR(L|Q)
- s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem))
- y))
- && i1 == i0+1
- && j1 == j0-8
- && j1 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
-
-(OR(L|Q)
- s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem))
- or:(OR(L|Q)
- s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem))
- y))
- && j1 == j0-8
- && j1 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y)
-
-(ORQ
- s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem)))
- or:(ORQ
- s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)))
- y))
- && i1 == i0+2
- && j1 == j0-16
- && j1 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, r0, r1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y)
-
-(ORQ
- s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem)))
- or:(ORQ
- s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem)))
- y))
- && j1 == j0-16
- && j1 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, r0, r1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i] {s} p0 mem))) y)
-
-// Combine 2 byte stores + shift into rolw 8 + word store
-(MOVBstore [i] {s} p w
- x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
- && x0.Uses == 1
- && clobber(x0)
- => (MOVWstore [i-1] {s} p (ROLWconst <typ.UInt16> [8] w) mem)
-(MOVBstore [i] {s} p1 w
- x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem))
- && x0.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x0)
- => (MOVWstore [i] {s} p0 (ROLWconst <typ.UInt16> [8] w) mem)
-
-// Combine stores + shifts into bswap and larger (unaligned) stores
-(MOVBstore [i] {s} p w
- x2:(MOVBstore [i-1] {s} p (SHRLconst [8] w)
- x1:(MOVBstore [i-2] {s} p (SHRLconst [16] w)
- x0:(MOVBstore [i-3] {s} p (SHRLconst [24] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && clobber(x0, x1, x2)
- => (MOVLstore [i-3] {s} p (BSWAPL <typ.UInt32> w) mem)
-(MOVBstore [i] {s} p3 w
- x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w)
- x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w)
- x0:(MOVBstore [i] {s} p0 (SHRLconst [24] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && sequentialAddresses(p1, p2, 1)
- && sequentialAddresses(p2, p3, 1)
- && clobber(x0, x1, x2)
- => (MOVLstore [i] {s} p0 (BSWAPL <typ.UInt32> w) mem)
-
-(MOVBstore [i] {s} p w
- x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w)
- x5:(MOVBstore [i-2] {s} p (SHRQconst [16] w)
- x4:(MOVBstore [i-3] {s} p (SHRQconst [24] w)
- x3:(MOVBstore [i-4] {s} p (SHRQconst [32] w)
- x2:(MOVBstore [i-5] {s} p (SHRQconst [40] w)
- x1:(MOVBstore [i-6] {s} p (SHRQconst [48] w)
- x0:(MOVBstore [i-7] {s} p (SHRQconst [56] w) mem))))))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && x3.Uses == 1
- && x4.Uses == 1
- && x5.Uses == 1
- && x6.Uses == 1
- && clobber(x0, x1, x2, x3, x4, x5, x6)
- => (MOVQstore [i-7] {s} p (BSWAPQ <typ.UInt64> w) mem)
-(MOVBstore [i] {s} p7 w
- x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w)
- x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w)
- x4:(MOVBstore [i] {s} p4 (SHRQconst [24] w)
- x3:(MOVBstore [i] {s} p3 (SHRQconst [32] w)
- x2:(MOVBstore [i] {s} p2 (SHRQconst [40] w)
- x1:(MOVBstore [i] {s} p1 (SHRQconst [48] w)
- x0:(MOVBstore [i] {s} p0 (SHRQconst [56] w) mem))))))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && x3.Uses == 1
- && x4.Uses == 1
- && x5.Uses == 1
- && x6.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && sequentialAddresses(p1, p2, 1)
- && sequentialAddresses(p2, p3, 1)
- && sequentialAddresses(p3, p4, 1)
- && sequentialAddresses(p4, p5, 1)
- && sequentialAddresses(p5, p6, 1)
- && sequentialAddresses(p6, p7, 1)
- && clobber(x0, x1, x2, x3, x4, x5, x6)
- => (MOVQstore [i] {s} p0 (BSWAPQ <typ.UInt64> w) mem)
-
-// Combine constant stores into larger (unaligned) stores.
-(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off()))
- && clobber(x)
- => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
-(MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off()))
- && clobber(x)
- => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
-(MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off()))
- && clobber(x)
- => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
-(MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off()))
- && clobber(x)
- => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
-(MOVLstoreconst [c] {s} p1 x:(MOVLstoreconst [a] {s} p0 mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off()))
- && clobber(x)
- => (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
-(MOVLstoreconst [a] {s} p0 x:(MOVLstoreconst [c] {s} p1 mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off()))
- && clobber(x)
- => (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
(MOVQstoreconst [c] {s} p1 x:(MOVQstoreconst [a] {s} p0 mem))
&& config.useSSE
&& x.Uses == 1
@@ -1877,86 +1487,6 @@
&& clobber(x)
=> (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p0 mem)
-// Combine stores into larger (unaligned) stores. Little endian.
-(MOVBstore [i] {s} p (SHR(W|L|Q)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHR(W|L|Q)const [8] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i] {s} p w mem)
-(MOVBstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVBstore [i-1] {s} p w0:(SHR(L|Q)const [j-8] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-1] {s} p w0 mem)
-(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) x:(MOVBstore [i] {s} p0 w mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVBstore [i] {s} p0 w0:(SHR(L|Q)const [j-8] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 1)
- && clobber(x)
- => (MOVWstore [i] {s} p0 w0 mem)
-
-(MOVWstore [i] {s} p (SHR(L|Q)const [16] w) x:(MOVWstore [i-2] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVLstore [i-2] {s} p w mem)
-(MOVWstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVWstore [i-2] {s} p w0:(SHR(L|Q)const [j-16] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVLstore [i-2] {s} p w0 mem)
-(MOVWstore [i] {s} p1 (SHR(L|Q)const [16] w) x:(MOVWstore [i] {s} p0 w mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && clobber(x)
- => (MOVLstore [i] {s} p0 w mem)
-(MOVWstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVWstore [i] {s} p0 w0:(SHR(L|Q)const [j-16] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 2)
- && clobber(x)
- => (MOVLstore [i] {s} p0 w0 mem)
-
-(MOVLstore [i] {s} p (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVQstore [i-4] {s} p w mem)
-(MOVLstore [i] {s} p (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p w0:(SHRQconst [j-32] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVQstore [i-4] {s} p w0 mem)
-(MOVLstore [i] {s} p1 (SHRQconst [32] w) x:(MOVLstore [i] {s} p0 w mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 4)
- && clobber(x)
- => (MOVQstore [i] {s} p0 w mem)
-(MOVLstore [i] {s} p1 (SHRQconst [j] w) x:(MOVLstore [i] {s} p0 w0:(SHRQconst [j-32] w) mem))
- && x.Uses == 1
- && sequentialAddresses(p0, p1, 4)
- && clobber(x)
- => (MOVQstore [i] {s} p0 w0 mem)
-
-(MOVBstore [c3] {s} p3 (SHRQconst [56] w)
- x1:(MOVWstore [c2] {s} p2 (SHRQconst [40] w)
- x2:(MOVLstore [c1] {s} p1 (SHRQconst [8] w)
- x3:(MOVBstore [c0] {s} p0 w mem))))
- && x1.Uses == 1
- && x2.Uses == 1
- && x3.Uses == 1
- && sequentialAddresses(p0, p1, int64(1 + c0 - c1))
- && sequentialAddresses(p0, p2, int64(5 + c0 - c2))
- && sequentialAddresses(p0, p3, int64(7 + c0 - c3))
- && clobber(x1, x2, x3)
- => (MOVQstore [c0] {s} p0 w mem)
-
(MOVBstore [i] {s} p
x1:(MOVBload [j] {s2} p2 mem)
mem2:(MOVBstore [i-1] {s} p
@@ -2195,26 +1725,6 @@
(MOVWstore [i] {s} p x:(ROLWconst [8] w) mem) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBEWstore [i] {s} p w mem)
(MOVBEWstore [i] {s} p x:(ROLWconst [8] w) mem) && x.Uses == 1 => (MOVWstore [i] {s} p w mem)
-(ORQ x0:(MOVBELload [i0] {s} p mem)
- sh:(SHLQconst [32] x1:(MOVBELload [i1] {s} p mem)))
- && i0 == i1+4
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVBEQload [i1] {s} p mem)
-
-(ORQ x0:(MOVBELload [i] {s} p0 mem)
- sh:(SHLQconst [32] x1:(MOVBELload [i] {s} p1 mem)))
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && sequentialAddresses(p1, p0, 4)
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVBEQload [i] {s} p1 mem)
-
(SAR(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l) => (SARX(Q|L)load [off] {sym} ptr x mem)
(SHL(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l) => (SHLX(Q|L)load [off] {sym} ptr x mem)
(SHR(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l) => (SHRX(Q|L)load [off] {sym} ptr x mem)
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
index 6dd45f11dc..7b2016bff2 100644
--- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
@@ -103,6 +103,7 @@
(Bswap64 ...) => (REV ...)
(Bswap32 ...) => (REVW ...)
+(Bswap16 ...) => (REV16W ...)
(BitRev64 ...) => (RBIT ...)
(BitRev32 ...) => (RBITW ...)
@@ -481,6 +482,9 @@
(STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem))
(STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))))
+(MOVDstorezero {s} [i] ptr x:(MOVDstorezero {s} [i+8] ptr mem)) && x.Uses == 1 && clobber(x) => (MOVQstorezero {s} [i] ptr mem)
+(MOVDstorezero {s} [i] ptr x:(MOVDstorezero {s} [i-8] ptr mem)) && x.Uses == 1 && clobber(x) => (MOVQstorezero {s} [i-8] ptr mem)
+
// strip off fractional word move
(Move [s] dst src mem) && s%16 != 0 && s%16 <= 8 && s > 16 =>
(Move [8]
@@ -1927,918 +1931,6 @@
(ORshiftRL [rc] (ANDconst [ac] y) (SLLconst [lc] x)) && lc < rc && ac == ^((1<<uint(64-rc)-1))
=> (BFXIL [armBFAuxInt(rc-lc, 64-rc)] y x)
-// do combined loads
-// little endian loads
-// b[0] | b[1]<<8 => load 16-bit
-(ORshiftLL <t> [8]
- y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))
- y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
- && i1 == i0+1
- && x0.Uses == 1 && x1.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, y0, y1)
- => @mergePoint(b,x0,x1) (MOVHUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(ORshiftLL <t> [8]
- y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))
- y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x0, x1, y0, y1)
- => @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr0 idx0 mem)
-(ORshiftLL <t> [8]
- y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- && x0.Uses == 1 && x1.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, y0, y1)
- => @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr idx mem)
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 => load 32-bit
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- x0:(MOVHUload [i0] {s} p mem)
- y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i3] {s} p mem)))
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && clobber(x0, x1, x2, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- x0:(MOVHUloadidx ptr0 idx0 mem)
- y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADD ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 idx0 mem)
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- x0:(MOVHUloadidx ptr idx mem)
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && clobber(x0, x1, x2, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr idx mem)
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- x0:(MOVHUloadidx2 ptr0 idx0 mem)
- y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADDshiftLL [1] ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 (SLLconst <idx0.Type> [1] idx0) mem)
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4]<<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 => load 64-bit
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- x0:(MOVWUload [i0] {s} p mem)
- y1:(MOVDnop x1:(MOVBUload [i4] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [i6] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [i7] {s} p mem)))
- && i4 == i0+4
- && i5 == i0+5
- && i6 == i0+6
- && i7 == i0+7
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- x0:(MOVWUloadidx ptr0 idx0 mem)
- y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [6] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 idx0 mem)
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- x0:(MOVWUloadidx4 ptr0 idx0 mem)
- y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADDshiftLL [2] ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [6] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 (SLLconst <idx0.Type> [2] idx0) mem)
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- x0:(MOVWUloadidx ptr idx mem)
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
- y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr idx mem)
-
-// b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0] => load 32-bit
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
- y0:(MOVDnop x0:(MOVBUload [i3] {s} p mem)))
- y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i1] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [i0] {s} p mem)))
- && i1 == i0+1
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3) != nil
- && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- => @mergePoint(b,x0,x1,x2,x3) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
- y0:(MOVDnop x0:(MOVBUload [3] {s} p mem)))
- y1:(MOVDnop x1:(MOVBUload [2] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- => @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr0 idx0 mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
- y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3) != nil
- && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- => @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr idx mem)
-
-// b[7]<<56 | b[6]<<48 | b[5]<<40 | b[4]<<32 | b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0] => load 64-bit
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
- y0:(MOVDnop x0:(MOVBUload [i7] {s} p mem)))
- y1:(MOVDnop x1:(MOVBUload [i6] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [i4] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [i3] {s} p mem)))
- y5:(MOVDnop x5:(MOVBUload [i2] {s} p mem)))
- y6:(MOVDnop x6:(MOVBUload [i1] {s} p mem)))
- y7:(MOVDnop x7:(MOVBUload [i0] {s} p mem)))
- && i1 == i0+1
- && i2 == i0+2
- && i3 == i0+3
- && i4 == i0+4
- && i5 == i0+5
- && i6 == i0+6
- && i7 == i0+7
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
- && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
- && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- => @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
- y0:(MOVDnop x0:(MOVBUload [7] {s} p mem)))
- y1:(MOVDnop x1:(MOVBUload [6] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [4] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [3] {s} p mem)))
- y5:(MOVDnop x5:(MOVBUload [2] {s} p mem)))
- y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
- && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- => @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr0 idx0 mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
- y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
- y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
- y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- y7:(MOVDnop x7:(MOVBUloadidx ptr idx mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
- && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
- && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- => @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr idx mem)
-
-// big endian loads
-// b[1] | b[0]<<8 => load 16-bit, reverse
-(ORshiftLL <t> [8]
- y0:(MOVDnop x0:(MOVBUload [i1] {s} p mem))
- y1:(MOVDnop x1:(MOVBUload [i0] {s} p mem)))
- && i1 == i0+1
- && x0.Uses == 1 && x1.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, y0, y1)
- => @mergePoint(b,x0,x1) (REV16W <t> (MOVHUload <t> [i0] {s} p mem))
-(ORshiftLL <t> [8]
- y0:(MOVDnop x0:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))
- y1:(MOVDnop x1:(MOVBUloadidx ptr0 idx0 mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x0, x1, y0, y1)
- => @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr0 idx0 mem))
-(ORshiftLL <t> [8]
- y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [1] idx) mem))
- y1:(MOVDnop x1:(MOVBUloadidx ptr idx mem)))
- && x0.Uses == 1 && x1.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, y0, y1)
- => @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr idx mem))
-
-// b[3] | b[2]<<8 | b[1]<<16 | b[0]<<24 => load 32-bit, reverse
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- y0:(REV16W x0:(MOVHUload [i2] {s} p mem))
- y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i0] {s} p mem)))
- && i1 == i0+1
- && i2 == i0+2
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && clobber(x0, x1, x2, y0, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- y0:(REV16W x0:(MOVHUload [2] {s} p mem))
- y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr0 idx0 mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, y0, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
- y0:(REV16W x0:(MOVHUloadidx ptr (ADDconst [2] idx) mem))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr idx mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
- && o0.Uses == 1
- && mergePoint(b,x0,x1,x2) != nil
- && clobber(x0, x1, x2, y0, y1, y2, o0)
- => @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
-
-// b[7] | b[6]<<8 | b[5]<<16 | b[4]<<24 | b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 => load 64-bit, reverse
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- y0:(REVW x0:(MOVWUload [i4] {s} p mem))
- y1:(MOVDnop x1:(MOVBUload [i3] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [i1] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [i0] {s} p mem)))
- && i1 == i0+1
- && i2 == i0+2
- && i3 == i0+3
- && i4 == i0+4
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- y0:(REVW x0:(MOVWUload [4] {s} p mem))
- y1:(MOVDnop x1:(MOVBUload [3] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- y4:(MOVDnop x4:(MOVBUloadidx ptr0 idx0 mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
- y0:(REVW x0:(MOVWUloadidx ptr (ADDconst [4] idx) mem))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- y4:(MOVDnop x4:(MOVBUloadidx ptr idx mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4) != nil
- && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
- => @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr idx mem))
-
-// b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3] => load 32-bit, reverse
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
- y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)))
- y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
- && i1 == i0+1
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3) != nil
- && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- => @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
- y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)))
- y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- => @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
- y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3) != nil
- && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- => @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
-
-// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7] => load 64-bit, reverse
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
- y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)))
- y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
- y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem)))
- y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem)))
- y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem)))
- y7:(MOVDnop x7:(MOVBUload [i7] {s} p mem)))
- && i1 == i0+1
- && i2 == i0+2
- && i3 == i0+3
- && i4 == i0+4
- && i5 == i0+5
- && i6 == i0+6
- && i7 == i0+7
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
- && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
- && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- => @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
- y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)))
- y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
- y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
- y4:(MOVDnop x4:(MOVBUload [4] {s} p mem)))
- y5:(MOVDnop x5:(MOVBUload [5] {s} p mem)))
- y6:(MOVDnop x6:(MOVBUload [6] {s} p mem)))
- y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)))
- && s == nil
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
- && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- => @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
- y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)))
- y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
- y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
- y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
- y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
- y7:(MOVDnop x7:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
- && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
- && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
- && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
- && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- => @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr idx mem))
-
-// Combine zero stores into larger (unaligned) stores.
-(MOVBstorezero [i] {s} ptr0 x:(MOVBstorezero [j] {s} ptr1 mem))
- && x.Uses == 1
- && areAdjacentOffsets(int64(i),int64(j),1)
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVBstorezero [1] {s} (ADD ptr0 idx0) x:(MOVBstorezeroidx ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstorezeroidx ptr1 idx1 mem)
-(MOVBstorezeroidx ptr (ADDconst [1] idx) x:(MOVBstorezeroidx ptr idx mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstorezeroidx ptr idx mem)
-(MOVHstorezero [i] {s} ptr0 x:(MOVHstorezero [j] {s} ptr1 mem))
- && x.Uses == 1
- && areAdjacentOffsets(int64(i),int64(j),2)
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVWstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVHstorezero [2] {s} (ADD ptr0 idx0) x:(MOVHstorezeroidx ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVWstorezeroidx ptr1 idx1 mem)
-(MOVHstorezeroidx ptr (ADDconst [2] idx) x:(MOVHstorezeroidx ptr idx mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstorezeroidx ptr idx mem)
-(MOVHstorezero [2] {s} (ADDshiftLL [1] ptr0 idx0) x:(MOVHstorezeroidx2 ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVWstorezeroidx ptr1 (SLLconst <idx1.Type> [1] idx1) mem)
-(MOVWstorezero [i] {s} ptr0 x:(MOVWstorezero [j] {s} ptr1 mem))
- && x.Uses == 1
- && areAdjacentOffsets(int64(i),int64(j),4)
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVDstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVWstorezero [4] {s} (ADD ptr0 idx0) x:(MOVWstorezeroidx ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVDstorezeroidx ptr1 idx1 mem)
-(MOVWstorezeroidx ptr (ADDconst [4] idx) x:(MOVWstorezeroidx ptr idx mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVDstorezeroidx ptr idx mem)
-(MOVWstorezero [4] {s} (ADDshiftLL [2] ptr0 idx0) x:(MOVWstorezeroidx4 ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVDstorezeroidx ptr1 (SLLconst <idx1.Type> [2] idx1) mem)
-(MOVDstorezero [i] {s} ptr0 x:(MOVDstorezero [j] {s} ptr1 mem))
- && x.Uses == 1
- && areAdjacentOffsets(int64(i),int64(j),8)
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVQstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVDstorezero [8] {s} p0:(ADD ptr0 idx0) x:(MOVDstorezeroidx ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVQstorezero [0] {s} p0 mem)
-(MOVDstorezero [8] {s} p0:(ADDshiftLL [3] ptr0 idx0) x:(MOVDstorezeroidx8 ptr1 idx1 mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVQstorezero [0] {s} p0 mem)
-
-// Combine stores into larger (unaligned) stores.
-(MOVBstore [i] {s} ptr0 (SRLconst [8] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] w) x:(MOVBstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstoreidx ptr (ADDconst [1] idx) (SRLconst [8] w) x:(MOVBstoreidx ptr idx w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstoreidx ptr idx w mem)
-(MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstore [i] {s} ptr0 (SRLconst [8] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] w) mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w0 mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w0 mem)
-(MOVBstore [i] {s} ptr0 (UBFX [bfc] w) x:(MOVBstore [i-1] {s} ptr1 w0:(UBFX [bfc2] w) mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb()
- && bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb()
- && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w0 mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [bfc] w) x:(MOVBstoreidx ptr1 idx1 w0:(UBFX [bfc2] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb()
- && bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb()
- && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w0 mem)
-(MOVBstore [i] {s} ptr0 (SRLconst [j] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr0 w0 mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr1 idx1 w0 mem)
-(MOVHstore [i] {s} ptr0 (SRLconst [16] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVWstore [i-2] {s} ptr0 w mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVWstoreidx ptr1 idx1 w mem)
-(MOVHstoreidx ptr (ADDconst [2] idx) (SRLconst [16] w) x:(MOVHstoreidx ptr idx w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWstoreidx ptr idx w mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
-(MOVHstore [i] {s} ptr0 (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVWstore [i-2] {s} ptr0 w mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVWstoreidx ptr1 idx1 w mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
-(MOVHstore [i] {s} ptr0 (SRLconst [16] (MOVDreg w)) x:(MOVHstore [i-2] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVWstore [i-2] {s} ptr0 w mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVWstoreidx ptr1 idx1 w mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx2 ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
-(MOVHstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVHstore [i-2] {s} ptr1 w0:(SRLconst [j-16] w) mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVWstore [i-2] {s} ptr0 w0 mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx ptr1 idx1 w0:(SRLconst [j-16] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVWstoreidx ptr1 idx1 w0 mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx2 ptr1 idx1 w0:(SRLconst [j-16] w) mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w0 mem)
-(MOVWstore [i] {s} ptr0 (SRLconst [32] w) x:(MOVWstore [i-4] {s} ptr1 w mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVDstore [i-4] {s} ptr0 w mem)
-(MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVDstoreidx ptr1 idx1 w mem)
-(MOVWstoreidx ptr (ADDconst [4] idx) (SRLconst [32] w) x:(MOVWstoreidx ptr idx w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVDstoreidx ptr idx w mem)
-(MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx4 ptr1 idx1 w mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w mem)
-(MOVWstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVWstore [i-4] {s} ptr1 w0:(SRLconst [j-32] w) mem))
- && x.Uses == 1
- && isSamePtr(ptr0, ptr1)
- && clobber(x)
- => (MOVDstore [i-4] {s} ptr0 w0 mem)
-(MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx ptr1 idx1 w0:(SRLconst [j-32] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVDstoreidx ptr1 idx1 w0 mem)
-(MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx4 ptr1 idx1 w0:(SRLconst [j-32] w) mem))
- && x.Uses == 1
- && s == nil
- && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
- && clobber(x)
- => (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w0 mem)
-(MOVBstore [i] {s} ptr w
- x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
- x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
- x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w)
- x3:(MOVBstore [i-4] {s} ptr (SRLconst [32] w)
- x4:(MOVBstore [i-5] {s} ptr (SRLconst [40] w)
- x5:(MOVBstore [i-6] {s} ptr (SRLconst [48] w)
- x6:(MOVBstore [i-7] {s} ptr (SRLconst [56] w) mem))))))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && x3.Uses == 1
- && x4.Uses == 1
- && x5.Uses == 1
- && x6.Uses == 1
- && clobber(x0, x1, x2, x3, x4, x5, x6)
- => (MOVDstore [i-7] {s} ptr (REV <typ.UInt64> w) mem)
-(MOVBstore [7] {s} p w
- x0:(MOVBstore [6] {s} p (SRLconst [8] w)
- x1:(MOVBstore [5] {s} p (SRLconst [16] w)
- x2:(MOVBstore [4] {s} p (SRLconst [24] w)
- x3:(MOVBstore [3] {s} p (SRLconst [32] w)
- x4:(MOVBstore [2] {s} p (SRLconst [40] w)
- x5:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [48] w)
- x6:(MOVBstoreidx ptr0 idx0 (SRLconst [56] w) mem))))))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && x3.Uses == 1
- && x4.Uses == 1
- && x5.Uses == 1
- && x6.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2, x3, x4, x5, x6)
- => (MOVDstoreidx ptr0 idx0 (REV <typ.UInt64> w) mem)
-(MOVBstore [i] {s} ptr w
- x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w)
- x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w)
- x2:(MOVBstore [i-3] {s} ptr (UBFX [armBFAuxInt(24, 8)] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && clobber(x0, x1, x2)
- => (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
-(MOVBstore [3] {s} p w
- x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w)
- x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (UBFX [armBFAuxInt(16, 16)] w)
- x2:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(24, 8)] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2)
- => (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
-(MOVBstoreidx ptr (ADDconst [3] idx) w
- x0:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(8, 24)] w)
- x1:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(16, 16)] w)
- x2:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(24, 8)] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && clobber(x0, x1, x2)
- => (MOVWstoreidx ptr idx (REVW <typ.UInt32> w) mem)
-(MOVBstoreidx ptr idx w
- x0:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 24)] w)
- x1:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(16, 16)] w)
- x2:(MOVBstoreidx ptr (ADDconst [3] idx) (UBFX [armBFAuxInt(24, 8)] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && clobber(x0, x1, x2)
- => (MOVWstoreidx ptr idx w mem)
-(MOVBstore [i] {s} ptr w
- x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w))
- x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] (MOVDreg w))
- x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] (MOVDreg w)) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && clobber(x0, x1, x2)
- => (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
-(MOVBstore [3] {s} p w
- x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w))
- x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] (MOVDreg w))
- x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] (MOVDreg w)) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2)
- => (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
-(MOVBstore [i] {s} ptr w
- x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
- x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
- x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && clobber(x0, x1, x2)
- => (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
-(MOVBstore [3] {s} p w
- x0:(MOVBstore [2] {s} p (SRLconst [8] w)
- x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] w)
- x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] w) mem))))
- && x0.Uses == 1
- && x1.Uses == 1
- && x2.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && isSamePtr(p1, p)
- && clobber(x0, x1, x2)
- => (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
-(MOVBstoreidx ptr (ADDconst [1] idx) w x:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(8, 8)] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstoreidx ptr idx (REV16W <typ.UInt16> w) mem)
-(MOVBstoreidx ptr idx w x:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 8)] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstoreidx ptr idx w mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem))
- && x.Uses == 1
- && s == nil
- && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
- && clobber(x)
- => (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
-
// FP simplification
(FNEGS (FMULS x y)) => (FNMULS x y)
(FNEGD (FMULD x y)) => (FNMULD x y)
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
index bdb630a28f..e51338a064 100644
--- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
@@ -845,8 +845,8 @@
(MOVWstoreidx ptr idx (MOV(W|WZ)reg x) mem) => (MOVWstoreidx ptr idx x mem)
(MOVBstoreidx ptr idx (SRWconst (MOV(H|HZ)reg x) [c]) mem) && c <= 8 => (MOVBstoreidx ptr idx (SRWconst <typ.UInt32> x [c]) mem)
(MOVBstoreidx ptr idx (SRWconst (MOV(W|WZ)reg x) [c]) mem) && c <= 24 => (MOVBstoreidx ptr idx (SRWconst <typ.UInt32> x [c]) mem)
-(MOVHBRstore {sym} ptr (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHBRstore {sym} ptr x mem)
-(MOVWBRstore {sym} ptr (MOV(W|WZ)reg x) mem) => (MOVWBRstore {sym} ptr x mem)
+(MOVHBRstore ptr (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHBRstore ptr x mem)
+(MOVWBRstore ptr (MOV(W|WZ)reg x) mem) => (MOVWBRstore ptr x mem)
// Lose W-widening ops fed to compare-W
(CMP(W|WU) x (MOV(W|WZ)reg y)) => (CMP(W|WU) x y)
@@ -958,307 +958,6 @@
(F(ADD|SUB) (FMUL x y) z) && x.Block.Func.useFMA(v) => (FM(ADD|SUB) x y z)
(F(ADDS|SUBS) (FMULS x y) z) && x.Block.Func.useFMA(v) => (FM(ADDS|SUBS) x y z)
-// The following statements are found in encoding/binary functions UintXX (load) and PutUintXX (store)
-// and convert the statements in these functions from multiple single byte loads or stores to
-// the single largest possible load or store.
-// Some are marked big or little endian based on the order in which the bytes are loaded or stored,
-// not on the ordering of the machine. These are intended for little endian machines.
-// To implement for big endian machines, most rules would have to be duplicated but the
-// resulting rule would be reversed, i. e., MOVHZload on little endian would be MOVHBRload on big endian
-// and vice versa.
-// b[0] | b[1]<<8 => load 16-bit Little endian
-(OR <t> x0:(MOVBZload [i0] {s} p mem)
- o1:(SL(W|D)const x1:(MOVBZload [i1] {s} p mem) [8]))
- && !config.BigEndian
- && i1 == i0+1
- && x0.Uses ==1 && x1.Uses == 1
- && o1.Uses == 1
- && mergePoint(b, x0, x1) != nil
- && clobber(x0, x1, o1)
- => @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
-
-// b[0]<<8 | b[1] => load 16-bit Big endian on Little endian arch.
-// Use byte-reverse indexed load for 2 bytes.
-(OR <t> x0:(MOVBZload [i1] {s} p mem)
- o1:(SL(W|D)const x1:(MOVBZload [i0] {s} p mem) [8]))
- && !config.BigEndian
- && i1 == i0+1
- && x0.Uses ==1 && x1.Uses == 1
- && o1.Uses == 1
- && mergePoint(b, x0, x1) != nil
- && clobber(x0, x1, o1)
- => @mergePoint(b,x0,x1) (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[0]<<n+8 | b[1]<<n => load 16-bit Big endian (where n%8== 0)
-// Use byte-reverse indexed load for 2 bytes,
-// then shift left to the correct position. Used to match subrules
-// from longer rules.
-(OR <t> s0:(SL(W|D)const x0:(MOVBZload [i1] {s} p mem) [n1])
- s1:(SL(W|D)const x1:(MOVBZload [i0] {s} p mem) [n2]))
- && !config.BigEndian
- && i1 == i0+1
- && n1%8 == 0
- && n2 == n1+8
- && x0.Uses == 1 && x1.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1
- && mergePoint(b, x0, x1) != nil
- && clobber(x0, x1, s0, s1)
- => @mergePoint(b,x0,x1) (SLDconst <t> (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [n1])
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 => load 32-bit Little endian
-// Use byte-reverse indexed load for 4 bytes.
-(OR <t> s1:(SL(W|D)const x2:(MOVBZload [i3] {s} p mem) [24])
- o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i2] {s} p mem) [16])
- x0:(MOVHZload [i0] {s} p mem)))
- && !config.BigEndian
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1
- && o0.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1
- && mergePoint(b, x0, x1, x2) != nil
- && clobber(x0, x1, x2, s0, s1, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
-
-// b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3] => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load for 4 bytes with computed address.
-// Could be used to match subrules of a longer rule.
-(OR <t> s1:(SL(W|D)const x2:(MOVBZload [i0] {s} p mem) [24])
- o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i1] {s} p mem) [16])
- x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem)))
- && !config.BigEndian
- && i1 == i0+1
- && i2 == i0+2
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && o0.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1
- && mergePoint(b, x0, x1, x2) != nil
- && clobber(x0, x1, x2, s0, s1, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[3] | b[2]<<8 | b[1]<<16 | b[0]<<24 => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load for 4 bytes with computed address.
-// Could be used to match subrules of a longer rule.
-(OR <t> x0:(MOVBZload [i3] {s} p mem)
- o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i2] {s} p mem) [8])
- s1:(SL(W|D)const x2:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [16])))
- && !config.BigEndian
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && o0.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1
- && mergePoint(b, x0, x1, x2) != nil
- && clobber(x0, x1, x2, s0, s1, o0)
- => @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load to for 4 bytes with computed address.
-// Used to match longer rules.
-(OR <t> s2:(SLDconst x2:(MOVBZload [i3] {s} p mem) [32])
- o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i2] {s} p mem) [40])
- s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [48])))
- && !config.BigEndian
- && i2 == i0+2
- && i3 == i0+3
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && o0.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1
- && mergePoint(b, x0, x1, x2) != nil
- && clobber(x0, x1, x2, s0, s1, s2, o0)
- => @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
-
-// b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load for 4 bytes with constant address.
-// Used to match longer rules.
-(OR <t> s2:(SLDconst x2:(MOVBZload [i0] {s} p mem) [56])
- o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48])
- s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem) [32])))
- && !config.BigEndian
- && i1 == i0+1
- && i2 == i0+2
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && o0.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1
- && mergePoint(b, x0, x1, x2) != nil
- && clobber(x0, x1, x2, s0, s1, s2, o0)
- => @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4] <<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 => load 64-bit Little endian
-// Rules with commutative ops and many operands will result in extremely large functions in rewritePPC64,
-// so matching shorter previously defined subrules is important.
-// Offset must be multiple of 4 for MOVD
-(OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56])
- o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])
- o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])
- o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])
- x0:(MOVWZload {s} [i0] p mem)))))
- && !config.BigEndian
- && i4 == i0+4
- && i5 == i0+5
- && i6 == i0+6
- && i7 == i0+7
- && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1
- && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
- && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
- && mergePoint(b, x0, x4, x5, x6, x7) != nil
- && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)
- => @mergePoint(b,x0,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
-
-// b[7] | b[6]<<8 | b[5]<<16 | b[4]<<24 | b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 load 64-bit Big endian ordered bytes on Little endian arch
-// Use byte-reverse indexed load of 8 bytes.
-// Rules with commutative ops and many operands can result in extremely large functions in rewritePPC64,
-// so matching shorter previously defined subrules is important.
-(OR <t> s0:(SLDconst x0:(MOVBZload [i0] {s} p mem) [56])
- o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48])
- o1:(OR <t> s2:(SLDconst x2:(MOVBZload [i2] {s} p mem) [40])
- o2:(OR <t> s3:(SLDconst x3:(MOVBZload [i3] {s} p mem) [32])
- x4:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i4] p) mem)))))
- && !config.BigEndian
- && i1 == i0+1
- && i2 == i0+2
- && i3 == i0+3
- && i4 == i0+4
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
- && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
- && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
- && mergePoint(b, x0, x1, x2, x3, x4) != nil
- && clobber(x0, x1, x2, x3, x4, o0, o1, o2, s0, s1, s2, s3)
- => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7] => load 64-bit Big endian ordered bytes on Little endian arch
-// Use byte-reverse indexed load of 8 bytes.
-// Rules with commutative ops and many operands can result in extremely large functions in rewritePPC64,
-// so matching shorter previously defined subrules is important.
-(OR <t> x7:(MOVBZload [i7] {s} p mem)
- o5:(OR <t> s6:(SLDconst x6:(MOVBZload [i6] {s} p mem) [8])
- o4:(OR <t> s5:(SLDconst x5:(MOVBZload [i5] {s} p mem) [16])
- o3:(OR <t> s4:(SLDconst x4:(MOVBZload [i4] {s} p mem) [24])
- s0:(SL(W|D)const x3:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])))))
- && !config.BigEndian
- && i4 == i0+4
- && i5 == i0+5
- && i6 == i0+6
- && i7 == i0+7
- && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
- && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
- && s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
- && mergePoint(b, x3, x4, x5, x6, x7) != nil
- && clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)
- => @mergePoint(b,x3,x4,x5,x6,x7) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// 2 byte store Little endian as in:
-// b[0] = byte(v >> 16)
-// b[1] = byte(v >> 24)
-// Added for use in matching longer rules.
-(MOVBstore [i1] {s} p (SR(W|D)const w [24])
- x0:(MOVBstore [i0] {s} p (SR(W|D)const w [16]) mem))
- && !config.BigEndian
- && x0.Uses == 1
- && i1 == i0+1
- && clobber(x0)
- => (MOVHstore [i0] {s} p (SRWconst <typ.UInt16> w [16]) mem)
-
-// 2 byte store Little endian as in:
-// b[0] = byte(v)
-// b[1] = byte(v >> 8)
-(MOVBstore [i1] {s} p (SR(W|D)const w [8])
- x0:(MOVBstore [i0] {s} p w mem))
- && !config.BigEndian
- && x0.Uses == 1
- && i1 == i0+1
- && clobber(x0)
- => (MOVHstore [i0] {s} p w mem)
-
-// 4 byte store Little endian as in:
-// b[0:1] = uint16(v)
-// b[2:3] = uint16(v >> 16)
-(MOVHstore [i1] {s} p (SR(W|D)const w [16])
- x0:(MOVHstore [i0] {s} p w mem))
- && !config.BigEndian
- && x0.Uses == 1
- && i1 == i0+2
- && clobber(x0)
- => (MOVWstore [i0] {s} p w mem)
-
-// 4 byte store Big endian as in:
-// b[0] = byte(v >> 24)
-// b[1] = byte(v >> 16)
-// b[2] = byte(v >> 8)
-// b[3] = byte(v)
-// Use byte-reverse indexed 4 byte store.
-(MOVBstore [i3] {s} p w
- x0:(MOVBstore [i2] {s} p (SRWconst w [8])
- x1:(MOVBstore [i1] {s} p (SRWconst w [16])
- x2:(MOVBstore [i0] {s} p (SRWconst w [24]) mem))))
- && !config.BigEndian
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
- && i1 == i0+1 && i2 == i0+2 && i3 == i0+3
- && clobber(x0, x1, x2)
- => (MOVWBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
-
-// The 2 byte store appears after the 4 byte store so that the
-// match for the 2 byte store is not done first.
-// If the 4 byte store is based on the 2 byte store then there are
-// variations on the MOVDaddr subrule that would require additional
-// rules to be written.
-
-// 2 byte store Big endian as in:
-// b[0] = byte(v >> 8)
-// b[1] = byte(v)
-(MOVBstore [i1] {s} p w x0:(MOVBstore [i0] {s} p (SRWconst w [8]) mem))
- && !config.BigEndian
- && x0.Uses == 1
- && i1 == i0+1
- && clobber(x0)
- => (MOVHBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
-
-// 8 byte store Little endian as in:
-// b[0] = byte(v)
-// b[1] = byte(v >> 8)
-// b[2] = byte(v >> 16)
-// b[3] = byte(v >> 24)
-// b[4] = byte(v >> 32)
-// b[5] = byte(v >> 40)
-// b[6] = byte(v >> 48)
-// b[7] = byte(v >> 56)
-// Built on previously defined rules
-// Offset must be multiple of 4 for MOVDstore
-(MOVBstore [i7] {s} p (SRDconst w [56])
- x0:(MOVBstore [i6] {s} p (SRDconst w [48])
- x1:(MOVBstore [i5] {s} p (SRDconst w [40])
- x2:(MOVBstore [i4] {s} p (SRDconst w [32])
- x3:(MOVWstore [i0] {s} p w mem)))))
- && !config.BigEndian
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
- && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
- && clobber(x0, x1, x2, x3)
- => (MOVDstore [i0] {s} p w mem)
-
-// 8 byte store Big endian as in:
-// b[0] = byte(v >> 56)
-// b[1] = byte(v >> 48)
-// b[2] = byte(v >> 40)
-// b[3] = byte(v >> 32)
-// b[4] = byte(v >> 24)
-// b[5] = byte(v >> 16)
-// b[6] = byte(v >> 8)
-// b[7] = byte(v)
-// Use byte-reverse indexed 8 byte store.
-(MOVBstore [i7] {s} p w
- x0:(MOVBstore [i6] {s} p (SRDconst w [8])
- x1:(MOVBstore [i5] {s} p (SRDconst w [16])
- x2:(MOVBstore [i4] {s} p (SRDconst w [24])
- x3:(MOVBstore [i3] {s} p (SRDconst w [32])
- x4:(MOVBstore [i2] {s} p (SRDconst w [40])
- x5:(MOVBstore [i1] {s} p (SRDconst w [48])
- x6:(MOVBstore [i0] {s} p (SRDconst w [56]) mem))))))))
- && !config.BigEndian
- && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1
- && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
- && clobber(x0, x1, x2, x3, x4, x5, x6)
- => (MOVDBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
-
// Arch-specific inlining for small or disjoint runtime.memmove
(SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore _ src s3:(MOVDstore {t} _ dst mem)))))
&& sz >= 0
@@ -1287,3 +986,22 @@
// Use byte reverse instructions on Power10
(Bswap(16|32|64) x) && buildcfg.GOPPC64>=10 => (BR(H|W|D) x)
+
+// Fold bit reversal into loads.
+(BR(W|H) x:(MOV(W|H)Zload [off] {sym} ptr mem)) && x.Uses == 1 => @x.Block (MOV(W|H)BRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+(BR(W|H) x:(MOV(W|H)Zloadidx ptr idx mem)) && x.Uses == 1 => @x.Block (MOV(W|H)Zreg (MOV(W|H)BRloadidx ptr idx mem))
+(BRD x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 => @x.Block (MOVDBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+(BRD x:(MOVDloadidx ptr idx mem)) && x.Uses == 1 => @x.Block (MOVDBRloadidx ptr idx mem)
+
+// Fold bit reversal into stores.
+(MOV(D|W|H)store [off] {sym} ptr r:(BR(D|W|H) val) mem) && r.Uses == 1 => (MOV(D|W|H)BRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
+(MOV(D|W|H)storeidx ptr idx r:(BR(D|W|H) val) mem) && r.Uses == 1 => (MOV(D|W|H)BRstoreidx ptr idx val mem)
+
+// GOPPC64<10 rules.
+// These Bswap operations should only be introduced by the memcombine pass in places where they can be folded into loads or stores.
+(Bswap(32|16) x:(MOV(W|H)Zload [off] {sym} ptr mem)) => @x.Block (MOV(W|H)BRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+(Bswap(32|16) x:(MOV(W|H)Zloadidx ptr idx mem)) => @x.Block (MOV(W|H)Zreg (MOV(W|H)BRloadidx ptr idx mem))
+(Bswap64 x:(MOVDload [off] {sym} ptr mem)) => @x.Block (MOVDBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+(Bswap64 x:(MOVDloadidx ptr idx mem)) => @x.Block (MOVDBRloadidx ptr idx mem)
+(MOV(D|W|H)store [off] {sym} ptr (Bswap(64|32|16) val) mem) => (MOV(D|W|H)BRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
+(MOV(D|W|H)storeidx ptr idx (Bswap(64|32|16) val) mem) => (MOV(D|W|H)BRstoreidx ptr idx val mem)
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
index 3e644478c4..4be362373c 100644
--- a/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
@@ -331,9 +331,9 @@ func init() {
// Load bytes in reverse endian order of the arch from arg0 into a 64 bit register, all zero extend.
// The generated instructions are indexed loads with no offset field in the instruction so the aux fields are not used.
// In these cases the index register field is set to 0 and the full address is in the base register.
- {name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes reverse order
- {name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes zero extend reverse order
- {name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes zero extend reverse order
+ {name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", typ: "UInt64", faultOnNilArg0: true}, // load 8 bytes reverse order
+ {name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", typ: "UInt32", faultOnNilArg0: true}, // load 4 bytes zero extend reverse order
+ {name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", typ: "UInt16", faultOnNilArg0: true}, // load 2 bytes zero extend reverse order
// In these cases an index register is used in addition to a base register
// Loads from memory location arg[0] + arg[1].
@@ -355,9 +355,9 @@ func init() {
// Store bytes in the reverse endian order of the arch into arg0.
// These are indexed stores with no offset field in the instruction so the auxint fields are not used.
- {name: "MOVDBRstore", argLength: 3, reg: gpstore, asm: "MOVDBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes reverse order
- {name: "MOVWBRstore", argLength: 3, reg: gpstore, asm: "MOVWBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes reverse order
- {name: "MOVHBRstore", argLength: 3, reg: gpstore, asm: "MOVHBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes reverse order
+ {name: "MOVDBRstore", argLength: 3, reg: gpstore, asm: "MOVDBR", typ: "Mem", faultOnNilArg0: true}, // store 8 bytes reverse order
+ {name: "MOVWBRstore", argLength: 3, reg: gpstore, asm: "MOVWBR", typ: "Mem", faultOnNilArg0: true}, // store 4 bytes reverse order
+ {name: "MOVHBRstore", argLength: 3, reg: gpstore, asm: "MOVHBR", typ: "Mem", faultOnNilArg0: true}, // store 2 bytes reverse order
// Floating point loads from arg0+aux+auxint
{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load double float
diff --git a/src/cmd/compile/internal/ssa/_gen/S390X.rules b/src/cmd/compile/internal/ssa/_gen/S390X.rules
index 8c8c6ae251..a9d62c79ce 100644
--- a/src/cmd/compile/internal/ssa/_gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/_gen/S390X.rules
@@ -1294,365 +1294,6 @@
&& clobber(g)
=> ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
-// Combine constant stores into larger (unaligned) stores.
-// Avoid SB because constant stores to relative offsets are
-// emulated by the assembler and also can't handle unaligned offsets.
-(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
- && p.Op != OpSB
- && x.Uses == 1
- && a.Off() + 1 == c.Off()
- && clobber(x)
- => (MOVHstoreconst [makeValAndOff(c.Val()&0xff | a.Val()<<8, a.Off())] {s} p mem)
-(MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
- && p.Op != OpSB
- && x.Uses == 1
- && a.Off() + 2 == c.Off()
- && clobber(x)
- => (MOVWstore [a.Off()] {s} p (MOVDconst [int64(c.Val()&0xffff | a.Val()<<16)]) mem)
-(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
- && p.Op != OpSB
- && x.Uses == 1
- && a.Off() + 4 == c.Off()
- && clobber(x)
- => (MOVDstore [a.Off()] {s} p (MOVDconst [c.Val64()&0xffffffff | a.Val64()<<32]) mem)
-
-// Combine stores into larger (unaligned) stores.
-// It doesn't work on global data (based on SB) because stores with relative addressing
-// require that the memory operand be aligned.
-(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRDconst [8] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w0:(SRDconst [j] w) x:(MOVBstore [i-1] {s} p (SRDconst [j+8] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} p w0 mem)
-(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRWconst [8] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w0:(SRWconst [j] w) x:(MOVBstore [i-1] {s} p (SRWconst [j+8] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHstore [i-1] {s} p w0 mem)
-(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-2] {s} p w mem)
-(MOVHstore [i] {s} p w0:(SRDconst [j] w) x:(MOVHstore [i-2] {s} p (SRDconst [j+16] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-2] {s} p w0 mem)
-(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRWconst [16] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-2] {s} p w mem)
-(MOVHstore [i] {s} p w0:(SRWconst [j] w) x:(MOVHstore [i-2] {s} p (SRWconst [j+16] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVWstore [i-2] {s} p w0 mem)
-(MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVDstore [i-4] {s} p w mem)
-(MOVWstore [i] {s} p w0:(SRDconst [j] w) x:(MOVWstore [i-4] {s} p (SRDconst [j+32] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVDstore [i-4] {s} p w0 mem)
-
-// Combine stores into larger (unaligned) stores with the bytes reversed (little endian).
-// Store-with-bytes-reversed instructions do not support relative memory addresses,
-// so these stores can't operate on global data (SB).
-(MOVBstore [i] {s} p (SRDconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHBRstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p (SRDconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRDconst [j-8] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHBRstore [i-1] {s} p w0 mem)
-(MOVBstore [i] {s} p (SRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHBRstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p (SRWconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRWconst [j-8] w) mem))
- && p.Op != OpSB
- && x.Uses == 1
- && clobber(x)
- => (MOVHBRstore [i-1] {s} p w0 mem)
-(MOVHBRstore [i] {s} p (SRDconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWBRstore [i-2] {s} p w mem)
-(MOVHBRstore [i] {s} p (SRDconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRDconst [j-16] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWBRstore [i-2] {s} p w0 mem)
-(MOVHBRstore [i] {s} p (SRWconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWBRstore [i-2] {s} p w mem)
-(MOVHBRstore [i] {s} p (SRWconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRWconst [j-16] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVWBRstore [i-2] {s} p w0 mem)
-(MOVWBRstore [i] {s} p (SRDconst [32] w) x:(MOVWBRstore [i-4] {s} p w mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVDBRstore [i-4] {s} p w mem)
-(MOVWBRstore [i] {s} p (SRDconst [j] w) x:(MOVWBRstore [i-4] {s} p w0:(SRDconst [j-32] w) mem))
- && x.Uses == 1
- && clobber(x)
- => (MOVDBRstore [i-4] {s} p w0 mem)
-
-(MOVBstore [7] {s} p1 (SRDconst w)
- x1:(MOVHBRstore [5] {s} p1 (SRDconst w)
- x2:(MOVWBRstore [1] {s} p1 (SRDconst w)
- x3:(MOVBstore [0] {s} p1 w mem))))
- && x1.Uses == 1
- && x2.Uses == 1
- && x3.Uses == 1
- && clobber(x1, x2, x3)
- => (MOVDBRstore {s} p1 w mem)
-
-// Combining byte loads into larger (unaligned) loads.
-
-// Big-endian loads
-
-(ORW x1:(MOVBZload [i1] {s} p mem)
- sh:(SLWconst [8] x0:(MOVBZload [i0] {s} p mem)))
- && i1 == i0+1
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
-
-(OR x1:(MOVBZload [i1] {s} p mem)
- sh:(SLDconst [8] x0:(MOVBZload [i0] {s} p mem)))
- && i1 == i0+1
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
-
-(ORW x1:(MOVHZload [i1] {s} p mem)
- sh:(SLWconst [16] x0:(MOVHZload [i0] {s} p mem)))
- && i1 == i0+2
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
-
-(OR x1:(MOVHZload [i1] {s} p mem)
- sh:(SLDconst [16] x0:(MOVHZload [i0] {s} p mem)))
- && i1 == i0+2
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
-
-(OR x1:(MOVWZload [i1] {s} p mem)
- sh:(SLDconst [32] x0:(MOVWZload [i0] {s} p mem)))
- && i1 == i0+4
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVDload [i0] {s} p mem)
-
-(ORW
- s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
- or:(ORW
- s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
- y))
- && i1 == i0+1
- && j1 == j0-8
- && j1 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
-
-(OR
- s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
- or:(OR
- s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
- y))
- && i1 == i0+1
- && j1 == j0-8
- && j1 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
-
-(OR
- s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem))
- or:(OR
- s1:(SLDconst [j1] x1:(MOVHZload [i1] {s} p mem))
- y))
- && i1 == i0+2
- && j1 == j0-16
- && j1 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
-
-// Little-endian loads
-
-(ORW x0:(MOVBZload [i0] {s} p mem)
- sh:(SLWconst [8] x1:(MOVBZload [i1] {s} p mem)))
- && p.Op != OpSB
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
-
-(OR x0:(MOVBZload [i0] {s} p mem)
- sh:(SLDconst [8] x1:(MOVBZload [i1] {s} p mem)))
- && p.Op != OpSB
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
-
-(ORW r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
- sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
- && i1 == i0+2
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (MOVWBRload [i0] {s} p mem)
-
-(OR r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
- sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
- && i1 == i0+2
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
-
-(OR r0:(MOVWZreg x0:(MOVWBRload [i0] {s} p mem))
- sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRload [i1] {s} p mem))))
- && i1 == i0+4
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- => @mergePoint(b,x0,x1) (MOVDBRload [i0] {s} p mem)
-
-(ORW
- s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
- or:(ORW
- s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
- y))
- && p.Op != OpSB
- && i1 == i0+1
- && j1 == j0+8
- && j0 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
-
-(OR
- s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
- or:(OR
- s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
- y))
- && p.Op != OpSB
- && i1 == i0+1
- && j1 == j0+8
- && j0 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
-
-(OR
- s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem)))
- or:(OR
- s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)))
- y))
- && i1 == i0+2
- && j1 == j0+16
- && j0 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, r0, r1, s0, s1, or)
- => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
-
// Combine stores into store multiples.
// 32-bit
(MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem))
@@ -1701,3 +1342,19 @@
// Convert 32-bit store multiples into 64-bit stores.
(STM2 [i] {s} p (SRDconst [32] x) x mem) => (MOVDstore [i] {s} p x mem)
+
+// Fold bit reversal into loads.
+(MOVWBR x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 => @x.Block (MOVWZreg (MOVWBRload [off] {sym} ptr mem)) // need zero extension?
+(MOVWBR x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 => @x.Block (MOVWZreg (MOVWBRloadidx [off] {sym} ptr idx mem)) // need zero extension?
+(MOVDBR x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 => @x.Block (MOVDBRload [off] {sym} ptr mem)
+(MOVDBR x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 => @x.Block (MOVDBRloadidx [off] {sym} ptr idx mem)
+
+// Fold bit reversal into stores.
+(MOV(D|W)store [off] {sym} ptr r:(MOV(D|W)BR x) mem) && r.Uses == 1 => (MOV(D|W)BRstore [off] {sym} ptr x mem)
+(MOV(D|W)storeidx [off] {sym} ptr idx r:(MOV(D|W)BR x) mem) && r.Uses == 1 => (MOV(D|W)BRstoreidx [off] {sym} ptr idx x mem)
+
+// Special bswap16 rules
+(Bswap16 x:(MOVHZload [off] {sym} ptr mem)) => @x.Block (MOVHZreg (MOVHBRload [off] {sym} ptr mem))
+(Bswap16 x:(MOVHZloadidx [off] {sym} ptr idx mem)) => @x.Block (MOVHZreg (MOVHBRloadidx [off] {sym} ptr idx mem))
+(MOVHstore [off] {sym} ptr (Bswap16 val) mem) => (MOVHBRstore [off] {sym} ptr val mem)
+(MOVHstoreidx [off] {sym} ptr idx (Bswap16 val) mem) => (MOVHBRstoreidx [off] {sym} ptr idx val mem)
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 54de1746b7..8618cf34cd 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -482,6 +482,7 @@ var passes = [...]pass{
{name: "branchelim", fn: branchelim},
{name: "late fuse", fn: fuseLate},
{name: "dse", fn: dse},
+ {name: "memcombine", fn: memcombine},
{name: "writebarrier", fn: writebarrier, required: true}, // expand write barrier ops
{name: "insert resched checks", fn: insertLoopReschedChecks,
disabled: !buildcfg.Experiment.PreemptibleLoops}, // insert resched checks in loops.
@@ -580,6 +581,10 @@ var passOrder = [...]constraint{
{"regalloc", "stackframe"},
// trim needs regalloc to be done first.
{"regalloc", "trim"},
+ // memcombine works better if fuse happens first, to help merge stores.
+ {"late fuse", "memcombine"},
+ // memcombine is a arch-independent pass.
+ {"memcombine", "lower"},
}
func init() {
diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go
index 6a3990500b..0740d9b7b0 100644
--- a/src/cmd/compile/internal/ssa/config.go
+++ b/src/cmd/compile/internal/ssa/config.go
@@ -6,6 +6,7 @@ package ssa
import (
"cmd/compile/internal/abi"
+ "cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
"cmd/internal/obj"
@@ -50,6 +51,10 @@ type Config struct {
Race bool // race detector enabled
BigEndian bool //
UseFMA bool // Use hardware FMA operation
+ unalignedOK bool // Unaligned loads/stores are ok
+ haveBswap64 bool // architecture implements Bswap64
+ haveBswap32 bool // architecture implements Bswap32
+ haveBswap16 bool // architecture implements Bswap16
}
type (
@@ -192,6 +197,10 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
c.FPReg = framepointerRegAMD64
c.LinkReg = linkRegAMD64
c.hasGReg = true
+ c.unalignedOK = true
+ c.haveBswap64 = true
+ c.haveBswap32 = true
+ c.haveBswap16 = true
case "386":
c.PtrSize = 4
c.RegSize = 4
@@ -204,6 +213,9 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
c.FPReg = framepointerReg386
c.LinkReg = linkReg386
c.hasGReg = false
+ c.unalignedOK = true
+ c.haveBswap32 = true
+ c.haveBswap16 = true
case "arm":
c.PtrSize = 4
c.RegSize = 4
@@ -230,6 +242,10 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
c.FPReg = framepointerRegARM64
c.LinkReg = linkRegARM64
c.hasGReg = true
+ c.unalignedOK = true
+ c.haveBswap64 = true
+ c.haveBswap32 = true
+ c.haveBswap16 = true
case "ppc64":
c.BigEndian = true
fallthrough
@@ -249,6 +265,14 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
c.FPReg = framepointerRegPPC64
c.LinkReg = linkRegPPC64
c.hasGReg = true
+ c.unalignedOK = true
+ // Note: ppc64 has register bswap ops only when GOPPC64>=10.
+ // But it has bswap+load and bswap+store ops for all ppc64 variants.
+ // That is the sense we're using them here - they are only used
+ // in contexts where they can be merged with a load or store.
+ c.haveBswap64 = true
+ c.haveBswap32 = true
+ c.haveBswap16 = true
case "mips64":
c.BigEndian = true
fallthrough
@@ -288,6 +312,10 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
c.hasGReg = true
c.noDuffDevice = true
c.BigEndian = true
+ c.unalignedOK = true
+ c.haveBswap64 = true
+ c.haveBswap32 = true
+ c.haveBswap16 = true // only for loads&stores, see ppc64 comment
case "mips":
c.BigEndian = true
fallthrough
@@ -387,3 +415,17 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
}
func (c *Config) Ctxt() *obj.Link { return c.ctxt }
+
+func (c *Config) haveByteSwap(size int64) bool {
+ switch size {
+ case 8:
+ return c.haveBswap64
+ case 4:
+ return c.haveBswap32
+ case 2:
+ return c.haveBswap16
+ default:
+ base.Fatalf("bad size %d\n", size)
+ return false
+ }
+}
diff --git a/src/cmd/compile/internal/ssa/memcombine.go b/src/cmd/compile/internal/ssa/memcombine.go
new file mode 100644
index 0000000000..fc0b665b34
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/memcombine.go
@@ -0,0 +1,737 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+import (
+ "cmd/compile/internal/base"
+ "cmd/compile/internal/types"
+ "cmd/internal/src"
+ "sort"
+)
+
+// memcombine combines smaller loads and stores into larger ones.
+// We ensure this generates good code for encoding/binary operations.
+// It may help other cases also.
+func memcombine(f *Func) {
+ // This optimization requires that the architecture has
+ // unaligned loads and unaligned stores.
+ if !f.Config.unalignedOK {
+ return
+ }
+
+ memcombineLoads(f)
+ memcombineStores(f)
+}
+
+func memcombineLoads(f *Func) {
+ // Find "OR trees" to start with.
+ mark := f.newSparseSet(f.NumValues())
+ defer f.retSparseSet(mark)
+ var order []*Value
+
+ // Mark all values that are the argument of an OR.
+ for _, b := range f.Blocks {
+ for _, v := range b.Values {
+ if v.Op == OpOr16 || v.Op == OpOr32 || v.Op == OpOr64 {
+ mark.add(v.Args[0].ID)
+ mark.add(v.Args[1].ID)
+ }
+ }
+ }
+ for _, b := range f.Blocks {
+ for _, v := range b.Values {
+ if v.Op != OpOr16 && v.Op != OpOr32 && v.Op != OpOr64 {
+ continue
+ }
+ if mark.contains(v.ID) {
+ // marked - means it is not the root of an OR tree
+ continue
+ }
+ // Add the OR tree rooted at v to the order.
+ // We use BFS here, but any walk that puts roots before leaves would work.
+ i := len(order)
+ order = append(order, v)
+ for ; i < len(order); i++ {
+ x := order[i]
+ for j := 0; j < 2; j++ {
+ a := x.Args[j]
+ if a.Op == OpOr16 || a.Op == OpOr32 || a.Op == OpOr64 {
+ order = append(order, a)
+ }
+ }
+ }
+ }
+ for _, v := range order {
+ max := f.Config.RegSize
+ switch v.Op {
+ case OpOr64:
+ case OpOr32:
+ max = 4
+ case OpOr16:
+ max = 2
+ default:
+ continue
+ }
+ for n := max; n > 1; n /= 2 {
+ if combineLoads(v, n) {
+ break
+ }
+ }
+ }
+ }
+}
+
+// A BaseAddress represents the address ptr+idx, where
+// ptr is a pointer type and idx is an integer type.
+// idx may be nil, in which case it is treated as 0.
+type BaseAddress struct {
+ ptr *Value
+ idx *Value
+}
+
+// splitPtr returns the base address of ptr and any
+// constant offset from that base.
+// BaseAddress{ptr,nil},0 is always a valid result, but splitPtr
+// tries to peel away as many constants into off as possible.
+func splitPtr(ptr *Value) (BaseAddress, int64) {
+ var idx *Value
+ var off int64
+ for {
+ if ptr.Op == OpOffPtr {
+ off += ptr.AuxInt
+ ptr = ptr.Args[0]
+ } else if ptr.Op == OpAddPtr {
+ if idx != nil {
+ // We have two or more indexing values.
+ // Pick the first one we found.
+ return BaseAddress{ptr: ptr, idx: idx}, off
+ }
+ idx = ptr.Args[1]
+ if idx.Op == OpAdd32 || idx.Op == OpAdd64 {
+ if idx.Args[0].Op == OpConst32 || idx.Args[0].Op == OpConst64 {
+ off += idx.Args[0].AuxInt
+ idx = idx.Args[1]
+ } else if idx.Args[1].Op == OpConst32 || idx.Args[1].Op == OpConst64 {
+ off += idx.Args[1].AuxInt
+ idx = idx.Args[0]
+ }
+ }
+ ptr = ptr.Args[0]
+ } else {
+ return BaseAddress{ptr: ptr, idx: idx}, off
+ }
+ }
+}
+
+func combineLoads(root *Value, n int64) bool {
+ orOp := root.Op
+ var shiftOp Op
+ switch orOp {
+ case OpOr64:
+ shiftOp = OpLsh64x64
+ case OpOr32:
+ shiftOp = OpLsh32x64
+ case OpOr16:
+ shiftOp = OpLsh16x64
+ default:
+ return false
+ }
+
+ // Find n values that are ORed together with the above op.
+ a := make([]*Value, 0, 8)
+ v := root
+ for int64(len(a)) < n {
+ if v.Args[0].Op == orOp {
+ a = append(a, v.Args[1])
+ v = v.Args[0]
+ } else if v.Args[1].Op == orOp {
+ a = append(a, v.Args[0])
+ v = v.Args[1]
+ } else if int64(len(a)) == n-2 {
+ a = append(a, v.Args[0])
+ a = append(a, v.Args[1])
+ v = nil
+ } else {
+ return false
+ }
+ }
+ tail := v // Value to OR in beyond the ones we're working with (or nil if none).
+
+ // Check that the first entry to see what ops we're looking for.
+ // All the entries should be of the form shift(extend(load)), maybe with no shift.
+ v = a[0]
+ if v.Op == shiftOp {
+ v = v.Args[0]
+ }
+ var extOp Op
+ if orOp == OpOr64 && (v.Op == OpZeroExt8to64 || v.Op == OpZeroExt16to64 || v.Op == OpZeroExt32to64) ||
+ orOp == OpOr32 && (v.Op == OpZeroExt8to32 || v.Op == OpZeroExt16to32) ||
+ orOp == OpOr16 && v.Op == OpZeroExt8to16 {
+ extOp = v.Op
+ v = v.Args[0]
+ } else {
+ return false
+ }
+ if v.Op != OpLoad {
+ return false
+ }
+ base, _ := splitPtr(v.Args[0])
+ mem := v.Args[1]
+ size := v.Type.Size()
+
+ if root.Block.Func.Config.arch == "S390X" {
+ // s390x can't handle unaligned accesses to global variables.
+ if base.ptr.Op == OpAddr {
+ return false
+ }
+ }
+
+ // Check all the entries, extract useful info.
+ type LoadRecord struct {
+ load *Value
+ offset int64 // offset of load address from base
+ shift int64
+ }
+ r := make([]LoadRecord, n, 8)
+ for i := int64(0); i < n; i++ {
+ v := a[i]
+ if v.Uses != 1 {
+ return false
+ }
+ shift := int64(0)
+ if v.Op == shiftOp {
+ if v.Args[1].Op != OpConst64 {
+ return false
+ }
+ shift = v.Args[1].AuxInt
+ v = v.Args[0]
+ if v.Uses != 1 {
+ return false
+ }
+ }
+ if v.Op != extOp {
+ return false
+ }
+ load := v.Args[0]
+ if load.Op != OpLoad {
+ return false
+ }
+ if load.Uses != 1 {
+ return false
+ }
+ if load.Args[1] != mem {
+ return false
+ }
+ p, off := splitPtr(load.Args[0])
+ if p != base {
+ return false
+ }
+ r[i] = LoadRecord{load: load, offset: off, shift: shift}
+ }
+
+ // Sort in memory address order.
+ sort.Slice(r, func(i, j int) bool {
+ return r[i].offset < r[j].offset
+ })
+
+ // Check that we have contiguous offsets.
+ for i := int64(0); i < n; i++ {
+ if r[i].offset != r[0].offset+i*size {
+ return false
+ }
+ }
+
+ // Check for reads in little-endian or big-endian order.
+ shift0 := r[0].shift
+ isLittleEndian := true
+ for i := int64(0); i < n; i++ {
+ if r[i].shift != shift0+i*size*8 {
+ isLittleEndian = false
+ break
+ }
+ }
+ isBigEndian := true
+ for i := int64(0); i < n; i++ {
+ if r[i].shift != shift0-i*size*8 {
+ isBigEndian = false
+ break
+ }
+ }
+ if !isLittleEndian && !isBigEndian {
+ return false
+ }
+
+ // Find a place to put the new load.
+ // This is tricky, because it has to be at a point where
+ // its memory argument is live. We can't just put it in root.Block.
+ // We use the block of the latest load.
+ loads := make([]*Value, n, 8)
+ for i := int64(0); i < n; i++ {
+ loads[i] = r[i].load
+ }
+ loadBlock := mergePoint(root.Block, loads...)
+ if loadBlock == nil {
+ return false
+ }
+ // Find a source position to use.
+ pos := src.NoXPos
+ for _, load := range loads {
+ if load.Block == loadBlock {
+ pos = load.Pos
+ break
+ }
+ }
+ if pos == src.NoXPos {
+ return false
+ }
+
+ // Check to see if we need byte swap before storing.
+ needSwap := isLittleEndian && root.Block.Func.Config.BigEndian ||
+ isBigEndian && !root.Block.Func.Config.BigEndian
+ if needSwap && (size != 1 || !root.Block.Func.Config.haveByteSwap(n)) {
+ return false
+ }
+
+ // This is the commit point.
+
+ // First, issue load at lowest address.
+ v = loadBlock.NewValue2(pos, OpLoad, sizeType(n*size), r[0].load.Args[0], mem)
+
+ // Byte swap if needed,
+ if needSwap {
+ v = byteSwap(loadBlock, pos, v)
+ }
+
+ // Extend if needed.
+ if n*size < root.Type.Size() {
+ v = zeroExtend(loadBlock, pos, v, n*size, root.Type.Size())
+ }
+
+ // Shift if needed.
+ if isLittleEndian && shift0 != 0 {
+ v = leftShift(loadBlock, pos, v, shift0)
+ }
+ if isBigEndian && shift0-(n-1)*8 != 0 {
+ v = leftShift(loadBlock, pos, v, shift0-(n-1)*8)
+ }
+
+ // Install. If there's a tail, make the root (OR v tail).
+ // If not, do (Copy v).
+ if tail != nil {
+ root.SetArg(0, v)
+ root.SetArg(1, tail)
+ } else {
+ root.reset(OpCopy)
+ root.AddArg(v)
+ }
+
+ // Clobber the loads, just to prevent additional work being done on
+ // subtrees (which are now unreachable).
+ for i := int64(0); i < n; i++ {
+ clobber(r[i].load)
+ }
+ return true
+}
+
+func memcombineStores(f *Func) {
+ mark := f.newSparseSet(f.NumValues())
+ defer f.retSparseSet(mark)
+ var order []*Value
+
+ for _, b := range f.Blocks {
+ // Mark all stores which are not last in a store sequence.
+ mark.clear()
+ for _, v := range b.Values {
+ if v.Op == OpStore {
+ mark.add(v.MemoryArg().ID)
+ }
+ }
+
+ // pick an order for visiting stores such that
+ // later stores come earlier in the ordering.
+ order = order[:0]
+ for _, v := range b.Values {
+ if v.Op != OpStore {
+ continue
+ }
+ if mark.contains(v.ID) {
+ continue // not last in a chain of stores
+ }
+ for {
+ order = append(order, v)
+ v = v.Args[2]
+ if v.Block != b || v.Op != OpStore {
+ break
+ }
+ }
+ }
+
+ // Look for combining opportunities at each store in queue order.
+ for _, v := range order {
+ if v.Op != OpStore { // already rewritten
+ continue
+ }
+
+ size := v.Aux.(*types.Type).Size()
+ if size >= f.Config.RegSize || size == 0 {
+ continue
+ }
+
+ for n := f.Config.RegSize / size; n > 1; n /= 2 {
+ if combineStores(v, n) {
+ continue
+ }
+ }
+ }
+ }
+}
+
+// Try to combine the n stores ending in root.
+// Returns true if successful.
+func combineStores(root *Value, n int64) bool {
+ // Helper functions.
+ type StoreRecord struct {
+ store *Value
+ offset int64
+ }
+ getShiftBase := func(a []StoreRecord) *Value {
+ x := a[0].store.Args[1]
+ y := a[1].store.Args[1]
+ switch x.Op {
+ case OpTrunc64to8, OpTrunc64to16, OpTrunc64to32, OpTrunc32to8, OpTrunc32to16, OpTrunc16to8:
+ x = x.Args[0]
+ default:
+ return nil
+ }
+ switch y.Op {
+ case OpTrunc64to8, OpTrunc64to16, OpTrunc64to32, OpTrunc32to8, OpTrunc32to16, OpTrunc16to8:
+ y = y.Args[0]
+ default:
+ return nil
+ }
+ var x2 *Value
+ switch x.Op {
+ case OpRsh64Ux64, OpRsh32Ux64, OpRsh16Ux64:
+ x2 = x.Args[0]
+ default:
+ }
+ var y2 *Value
+ switch y.Op {
+ case OpRsh64Ux64, OpRsh32Ux64, OpRsh16Ux64:
+ y2 = y.Args[0]
+ default:
+ }
+ if y2 == x {
+ // a shift of x and x itself.
+ return x
+ }
+ if x2 == y {
+ // a shift of y and y itself.
+ return y
+ }
+ if x2 == y2 {
+ // 2 shifts both of the same argument.
+ return x2
+ }
+ return nil
+ }
+ isShiftBase := func(v, base *Value) bool {
+ val := v.Args[1]
+ switch val.Op {
+ case OpTrunc64to8, OpTrunc64to16, OpTrunc64to32, OpTrunc32to8, OpTrunc32to16, OpTrunc16to8:
+ val = val.Args[0]
+ default:
+ return false
+ }
+ if val == base {
+ return true
+ }
+ switch val.Op {
+ case OpRsh64Ux64, OpRsh32Ux64, OpRsh16Ux64:
+ val = val.Args[0]
+ default:
+ return false
+ }
+ return val == base
+ }
+ shift := func(v, base *Value) int64 {
+ val := v.Args[1]
+ switch val.Op {
+ case OpTrunc64to8, OpTrunc64to16, OpTrunc64to32, OpTrunc32to8, OpTrunc32to16, OpTrunc16to8:
+ val = val.Args[0]
+ default:
+ return -1
+ }
+ if val == base {
+ return 0
+ }
+ switch val.Op {
+ case OpRsh64Ux64, OpRsh32Ux64, OpRsh16Ux64:
+ val = val.Args[1]
+ default:
+ return -1
+ }
+ if val.Op != OpConst64 {
+ return -1
+ }
+ return val.AuxInt
+ }
+
+ // Element size of the individual stores.
+ size := root.Aux.(*types.Type).Size()
+ if size*n > root.Block.Func.Config.RegSize {
+ return false
+ }
+
+ // Gather n stores to look at. Check easy conditions we require.
+ a := make([]StoreRecord, 0, 8)
+ rbase, roff := splitPtr(root.Args[0])
+ if root.Block.Func.Config.arch == "S390X" {
+ // s390x can't handle unaligned accesses to global variables.
+ if rbase.ptr.Op == OpAddr {
+ return false
+ }
+ }
+ a = append(a, StoreRecord{root, roff})
+ for i, x := int64(1), root.Args[2]; i < n; i, x = i+1, x.Args[2] {
+ if x.Op != OpStore {
+ return false
+ }
+ if x.Block != root.Block {
+ return false
+ }
+ if x.Uses != 1 { // Note: root can have more than one use.
+ return false
+ }
+ if x.Aux.(*types.Type).Size() != size {
+ return false
+ }
+ base, off := splitPtr(x.Args[0])
+ if base != rbase {
+ return false
+ }
+ a = append(a, StoreRecord{x, off})
+ }
+ // Before we sort, grab the memory arg the result should have.
+ mem := a[n-1].store.Args[2]
+
+ // Sort stores in increasing address order.
+ sort.Slice(a, func(i, j int) bool {
+ return a[i].offset < a[j].offset
+ })
+
+ // Check that everything is written to sequential locations.
+ for i := int64(0); i < n; i++ {
+ if a[i].offset != a[0].offset+i*size {
+ return false
+ }
+ }
+
+ // Memory location we're going to write at (the lowest one).
+ ptr := a[0].store.Args[0]
+
+ // Check for constant stores
+ isConst := true
+ for i := int64(0); i < n; i++ {
+ switch a[i].store.Args[1].Op {
+ case OpConst32, OpConst16, OpConst8:
+ default:
+ isConst = false
+ break
+ }
+ }
+ if isConst {
+ // Modify root to do all the stores.
+ var c int64
+ mask := int64(1)<<(8*size) - 1
+ for i := int64(0); i < n; i++ {
+ s := 8 * size * int64(i)
+ if root.Block.Func.Config.BigEndian {
+ s = 8*size*(n-1) - s
+ }
+ c |= (a[i].store.Args[1].AuxInt & mask) << s
+ }
+ var cv *Value
+ switch size * n {
+ case 2:
+ cv = root.Block.Func.ConstInt16(types.Types[types.TUINT16], int16(c))
+ case 4:
+ cv = root.Block.Func.ConstInt32(types.Types[types.TUINT32], int32(c))
+ case 8:
+ cv = root.Block.Func.ConstInt64(types.Types[types.TUINT64], c)
+ }
+
+ // Move all the stores to the root.
+ for i := int64(0); i < n; i++ {
+ v := a[i].store
+ if v == root {
+ v.Aux = cv.Type // widen store type
+ v.SetArg(0, ptr)
+ v.SetArg(1, cv)
+ v.SetArg(2, mem)
+ } else {
+ clobber(v)
+ v.Type = types.Types[types.TBOOL] // erase memory type
+ }
+ }
+ return true
+ }
+
+ // Check that all the shift/trunc are of the same base value.
+ shiftBase := getShiftBase(a)
+ if shiftBase == nil {
+ return false
+ }
+ for i := int64(0); i < n; i++ {
+ if !isShiftBase(a[i].store, shiftBase) {
+ return false
+ }
+ }
+
+ // Check for writes in little-endian or big-endian order.
+ isLittleEndian := true
+ shift0 := shift(a[0].store, shiftBase)
+ for i := int64(1); i < n; i++ {
+ if shift(a[i].store, shiftBase) != shift0+i*8 {
+ isLittleEndian = false
+ break
+ }
+ }
+ isBigEndian := true
+ for i := int64(1); i < n; i++ {
+ if shift(a[i].store, shiftBase) != shift0-i*8 {
+ isBigEndian = false
+ break
+ }
+ }
+ if !isLittleEndian && !isBigEndian {
+ return false
+ }
+
+ // Check to see if we need byte swap before storing.
+ needSwap := isLittleEndian && root.Block.Func.Config.BigEndian ||
+ isBigEndian && !root.Block.Func.Config.BigEndian
+ if needSwap && (size != 1 || !root.Block.Func.Config.haveByteSwap(n)) {
+ return false
+ }
+
+ // This is the commit point.
+
+ // Modify root to do all the stores.
+ sv := shiftBase
+ if isLittleEndian && shift0 != 0 {
+ sv = rightShift(root.Block, root.Pos, sv, shift0)
+ }
+ if isBigEndian && shift0-(n-1)*8 != 0 {
+ sv = rightShift(root.Block, root.Pos, sv, shift0-(n-1)*8)
+ }
+ if sv.Type.Size() > size*n {
+ sv = truncate(root.Block, root.Pos, sv, sv.Type.Size(), size*n)
+ }
+ if needSwap {
+ sv = byteSwap(root.Block, root.Pos, sv)
+ }
+
+ // Move all the stores to the root.
+ for i := int64(0); i < n; i++ {
+ v := a[i].store
+ if v == root {
+ v.Aux = sv.Type // widen store type
+ v.SetArg(0, ptr)
+ v.SetArg(1, sv)
+ v.SetArg(2, mem)
+ } else {
+ clobber(v)
+ v.Type = types.Types[types.TBOOL] // erase memory type
+ }
+ }
+ return true
+}
+
+func sizeType(size int64) *types.Type {
+ switch size {
+ case 8:
+ return types.Types[types.TUINT64]
+ case 4:
+ return types.Types[types.TUINT32]
+ case 2:
+ return types.Types[types.TUINT16]
+ default:
+ base.Fatalf("bad size %d\n", size)
+ return nil
+ }
+}
+
+func truncate(b *Block, pos src.XPos, v *Value, from, to int64) *Value {
+ switch from*10 + to {
+ case 82:
+ return b.NewValue1(pos, OpTrunc64to16, types.Types[types.TUINT16], v)
+ case 84:
+ return b.NewValue1(pos, OpTrunc64to32, types.Types[types.TUINT32], v)
+ case 42:
+ return b.NewValue1(pos, OpTrunc32to16, types.Types[types.TUINT16], v)
+ default:
+ base.Fatalf("bad sizes %d %d\n", from, to)
+ return nil
+ }
+}
+func zeroExtend(b *Block, pos src.XPos, v *Value, from, to int64) *Value {
+ switch from*10 + to {
+ case 24:
+ return b.NewValue1(pos, OpZeroExt16to32, types.Types[types.TUINT32], v)
+ case 28:
+ return b.NewValue1(pos, OpZeroExt16to64, types.Types[types.TUINT64], v)
+ case 48:
+ return b.NewValue1(pos, OpZeroExt32to64, types.Types[types.TUINT64], v)
+ default:
+ base.Fatalf("bad sizes %d %d\n", from, to)
+ return nil
+ }
+}
+
+func leftShift(b *Block, pos src.XPos, v *Value, shift int64) *Value {
+ s := b.Func.ConstInt64(types.Types[types.TUINT64], shift)
+ size := v.Type.Size()
+ switch size {
+ case 8:
+ return b.NewValue2(pos, OpLsh64x64, v.Type, v, s)
+ case 4:
+ return b.NewValue2(pos, OpLsh32x64, v.Type, v, s)
+ case 2:
+ return b.NewValue2(pos, OpLsh16x64, v.Type, v, s)
+ default:
+ base.Fatalf("bad size %d\n", size)
+ return nil
+ }
+}
+func rightShift(b *Block, pos src.XPos, v *Value, shift int64) *Value {
+ s := b.Func.ConstInt64(types.Types[types.TUINT64], shift)
+ size := v.Type.Size()
+ switch size {
+ case 8:
+ return b.NewValue2(pos, OpRsh64Ux64, v.Type, v, s)
+ case 4:
+ return b.NewValue2(pos, OpRsh32Ux64, v.Type, v, s)
+ case 2:
+ return b.NewValue2(pos, OpRsh16Ux64, v.Type, v, s)
+ default:
+ base.Fatalf("bad size %d\n", size)
+ return nil
+ }
+}
+func byteSwap(b *Block, pos src.XPos, v *Value) *Value {
+ switch v.Type.Size() {
+ case 8:
+ return b.NewValue1(pos, OpBswap64, v.Type, v)
+ case 4:
+ return b.NewValue1(pos, OpBswap32, v.Type, v)
+ case 2:
+ return b.NewValue1(pos, OpBswap16, v.Type, v)
+
+ default:
+ v.Fatalf("bad size %d\n", v.Type.Size())
+ return nil
+ }
+}
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 16052abbde..5e04805ba7 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -29470,10 +29470,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "MOVDBRload",
- auxType: auxSymOff,
argLen: 2,
faultOnNilArg0: true,
- symEffect: SymRead,
asm: ppc64.AMOVDBR,
reg: regInfo{
inputs: []inputInfo{
@@ -29486,10 +29484,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "MOVWBRload",
- auxType: auxSymOff,
argLen: 2,
faultOnNilArg0: true,
- symEffect: SymRead,
asm: ppc64.AMOVWBR,
reg: regInfo{
inputs: []inputInfo{
@@ -29502,10 +29498,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "MOVHBRload",
- auxType: auxSymOff,
argLen: 2,
faultOnNilArg0: true,
- symEffect: SymRead,
asm: ppc64.AMOVHBR,
reg: regInfo{
inputs: []inputInfo{
@@ -29684,10 +29678,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "MOVDBRstore",
- auxType: auxSym,
argLen: 3,
faultOnNilArg0: true,
- symEffect: SymWrite,
asm: ppc64.AMOVDBR,
reg: regInfo{
inputs: []inputInfo{
@@ -29698,10 +29690,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "MOVWBRstore",
- auxType: auxSym,
argLen: 3,
faultOnNilArg0: true,
- symEffect: SymWrite,
asm: ppc64.AMOVWBR,
reg: regInfo{
inputs: []inputInfo{
@@ -29712,10 +29702,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "MOVHBRstore",
- auxType: auxSym,
argLen: 3,
faultOnNilArg0: true,
- symEffect: SymWrite,
asm: ppc64.AMOVHBR,
reg: regInfo{
inputs: []inputInfo{
diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go
index 550e7d5e4b..b0512676c9 100644
--- a/src/cmd/compile/internal/ssa/rewrite386.go
+++ b/src/cmd/compile/internal/ssa/rewrite386.go
@@ -278,6 +278,8 @@ func rewriteValue386(v *Value) bool {
case OpAvg32u:
v.Op = Op386AVGLU
return true
+ case OpBswap16:
+ return rewriteValue386_OpBswap16(v)
case OpBswap32:
v.Op = Op386BSWAPL
return true
@@ -3715,266 +3717,6 @@ func rewriteValue386_Op386MOVBstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVBstore [i] {s} p (SHRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != Op386SHRWconst || auxIntToInt16(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRLconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != Op386SHRLconst || auxIntToInt32(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHRWconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != Op386SHRWconst || auxIntToInt16(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHRLconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != Op386SHRLconst || auxIntToInt32(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRLconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SHRLconst [j-8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != Op386SHRLconst {
- break
- }
- j := auxIntToInt32(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != Op386SHRLconst || auxIntToInt32(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRWconst [8] w) x:(MOVBstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != Op386SHRWconst || auxIntToInt16(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRLconst [8] w) x:(MOVBstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != Op386SHRLconst || auxIntToInt32(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p0 w x:(MOVBstore {s} [i] p1 (SHRWconst [8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- w := v_1
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p1 := x.Args[0]
- x_1 := x.Args[1]
- if x_1.Op != Op386SHRWconst || auxIntToInt16(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p0 w x:(MOVBstore {s} [i] p1 (SHRLconst [8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- w := v_1
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p1 := x.Args[0]
- x_1 := x.Args[1]
- if x_1.Op != Op386SHRLconst || auxIntToInt32(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRLconst [j] w) x:(MOVBstore [i] {s} p0 w0:(SHRLconst [j-8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != Op386SHRLconst {
- break
- }
- j := auxIntToInt32(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != Op386SHRLconst || auxIntToInt32(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
return false
}
func rewriteValue386_Op386MOVBstoreconst(v *Value) bool {
@@ -4025,108 +3767,6 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
- // cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
- // result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != Op386MOVBstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- if p != x.Args[0] || !(x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p, mem)
- return true
- }
- // match: (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
- // cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
- // result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != Op386MOVBstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- if p != x.Args[0] || !(x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p, mem)
- return true
- }
- // match: (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
- // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- x := v_1
- if x.Op != Op386MOVBstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p0 := x.Args[0]
- if !(x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
- // match: (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
- // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- x := v_1
- if x.Op != Op386MOVBstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p1 := x.Args[0]
- if !(x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(Op386MOVWstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
return false
}
func rewriteValue386_Op386MOVLload(v *Value) bool {
@@ -5258,115 +4898,6 @@ func rewriteValue386_Op386MOVWstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVLstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != Op386SHRLconst || auxIntToInt32(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p (SHRLconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVLstore [i-2] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != Op386SHRLconst {
- break
- }
- j := auxIntToInt32(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != Op386SHRLconst || auxIntToInt32(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p1 (SHRLconst [16] w) x:(MOVWstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != Op386SHRLconst || auxIntToInt32(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p1 (SHRLconst [j] w) x:(MOVWstore [i] {s} p0 w0:(SHRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != Op386SHRLconst {
- break
- }
- j := auxIntToInt32(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != Op386MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != Op386SHRLconst || auxIntToInt32(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
return false
}
func rewriteValue386_Op386MOVWstoreconst(v *Value) bool {
@@ -5417,108 +4948,6 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
- // cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
- // result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != Op386MOVWstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- if p != x.Args[0] || !(x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p, mem)
- return true
- }
- // match: (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
- // cond: x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x)
- // result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != Op386MOVWstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+2 == ValAndOff(c).Off() && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p, mem)
- return true
- }
- // match: (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
- // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- x := v_1
- if x.Op != Op386MOVWstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p0 := x.Args[0]
- if !(x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
- // match: (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
- // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- x := v_1
- if x.Op != Op386MOVWstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p1 := x.Args[0]
- if !(x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(Op386MOVLstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
return false
}
func rewriteValue386_Op386MULL(v *Value) bool {
@@ -6237,8 +5666,6 @@ func rewriteValue386_Op386NOTL(v *Value) bool {
func rewriteValue386_Op386ORL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (ORL x (MOVLconst [c]))
// result: (ORLconst [c] x)
for {
@@ -6290,203 +5717,6 @@ func rewriteValue386_Op386ORL(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (ORL x0:(MOVBload [i0] {s} p mem) s0:(SHLLconst [8] x1:(MOVBload [i1] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, s0)
- // result: @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != Op386MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- s0 := v_1
- if s0.Op != Op386SHLLconst || auxIntToInt32(s0.AuxInt) != 8 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != Op386MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, Op386MOVWload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORL x0:(MOVBload [i] {s} p0 mem) s0:(SHLLconst [8] x1:(MOVBload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, s0)
- // result: @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != Op386MOVBload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- s0 := v_1
- if s0.Op != Op386SHLLconst || auxIntToInt32(s0.AuxInt) != 8 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != Op386MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, Op386MOVWload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (ORL o0:(ORL x0:(MOVWload [i0] {s} p mem) s0:(SHLLconst [16] x1:(MOVBload [i2] {s} p mem))) s1:(SHLLconst [24] x2:(MOVBload [i3] {s} p mem)))
- // cond: i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVLload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != Op386ORL {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- x0 := o0_0
- if x0.Op != Op386MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- s0 := o0_1
- if s0.Op != Op386SHLLconst || auxIntToInt32(s0.AuxInt) != 16 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != Op386MOVBload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- s1 := v_1
- if s1.Op != Op386SHLLconst || auxIntToInt32(s1.AuxInt) != 24 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != Op386MOVBload {
- continue
- }
- i3 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] || !(i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, Op386MOVLload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- }
- break
- }
- // match: (ORL o0:(ORL x0:(MOVWload [i] {s} p0 mem) s0:(SHLLconst [16] x1:(MOVBload [i] {s} p1 mem))) s1:(SHLLconst [24] x2:(MOVBload [i] {s} p2 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && sequentialAddresses(p0, p1, 2) && sequentialAddresses(p1, p2, 1) && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != Op386ORL {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- x0 := o0_0
- if x0.Op != Op386MOVWload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- s0 := o0_1
- if s0.Op != Op386SHLLconst || auxIntToInt32(s0.AuxInt) != 16 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != Op386MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] {
- continue
- }
- s1 := v_1
- if s1.Op != Op386SHLLconst || auxIntToInt32(s1.AuxInt) != 24 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != Op386MOVBload || auxIntToInt32(x2.AuxInt) != i || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- p2 := x2.Args[0]
- if mem != x2.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && sequentialAddresses(p0, p1, 2) && sequentialAddresses(p1, p2, 1) && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, Op386MOVLload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- }
- break
- }
return false
}
func rewriteValue386_Op386ORLconst(v *Value) bool {
@@ -8483,6 +7713,18 @@ func rewriteValue386_OpAddr(v *Value) bool {
return true
}
}
+func rewriteValue386_OpBswap16(v *Value) bool {
+ v_0 := v.Args[0]
+ // match: (Bswap16 x)
+ // result: (ROLWconst [8] x)
+ for {
+ x := v_0
+ v.reset(Op386ROLWconst)
+ v.AuxInt = int16ToAuxInt(8)
+ v.AddArg(x)
+ return true
+ }
+}
func rewriteValue386_OpConst16(v *Value) bool {
// match: (Const16 [c])
// result: (MOVLconst [int32(c)])
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index 2cc80408a3..117ab46975 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -620,6 +620,8 @@ func rewriteValueAMD64(v *Value) bool {
return rewriteValueAMD64_OpBitLen64(v)
case OpBitLen8:
return rewriteValueAMD64_OpBitLen8(v)
+ case OpBswap16:
+ return rewriteValueAMD64_OpBswap16(v)
case OpBswap32:
v.Op = OpAMD64BSWAPL
return true
@@ -10482,823 +10484,6 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVBstore [i] {s} p w x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
- // cond: x0.Uses == 1 && clobber(x0)
- // result: (MOVWstore [i-1] {s} p (ROLWconst <typ.UInt16> [8] w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpAMD64SHRWconst || auxIntToInt8(x0_1.AuxInt) != 8 || w != x0_1.Args[0] || !(x0.Uses == 1 && clobber(x0)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, typ.UInt16)
- v0.AuxInt = int8ToAuxInt(8)
- v0.AddArg(w)
- v.AddArg3(p, v0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 w x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem))
- // cond: x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0)
- // result: (MOVWstore [i] {s} p0 (ROLWconst <typ.UInt16> [8] w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- p0 := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpAMD64SHRWconst || auxIntToInt8(x0_1.AuxInt) != 8 || w != x0_1.Args[0] || !(x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, typ.UInt16)
- v0.AuxInt = int8ToAuxInt(8)
- v0.AddArg(w)
- v.AddArg3(p0, v0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x2:(MOVBstore [i-1] {s} p (SHRLconst [8] w) x1:(MOVBstore [i-2] {s} p (SHRLconst [16] w) x0:(MOVBstore [i-3] {s} p (SHRLconst [24] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
- // result: (MOVLstore [i-3] {s} p (BSWAPL <typ.UInt32> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x2 := v_2
- if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i-1 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if p != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpAMD64SHRLconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] {
- break
- }
- x1 := x2.Args[2]
- if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpAMD64SHRLconst || auxIntToInt8(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x0 := x1.Args[2]
- if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i-3 || auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpAMD64SHRLconst || auxIntToInt8(x0_1.AuxInt) != 24 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 3)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, typ.UInt32)
- v0.AddArg(w)
- v.AddArg3(p, v0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p3 w x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w) x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w) x0:(MOVBstore [i] {s} p0 (SHRLconst [24] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2)
- // result: (MOVLstore [i] {s} p0 (BSWAPL <typ.UInt32> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p3 := v_0
- w := v_1
- x2 := v_2
- if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- p2 := x2.Args[0]
- x2_1 := x2.Args[1]
- if x2_1.Op != OpAMD64SHRLconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] {
- break
- }
- x1 := x2.Args[2]
- if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- p1 := x1.Args[0]
- x1_1 := x1.Args[1]
- if x1_1.Op != OpAMD64SHRLconst || auxIntToInt8(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x0 := x1.Args[2]
- if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- p0 := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpAMD64SHRLconst || auxIntToInt8(x0_1.AuxInt) != 24 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, typ.UInt32)
- v0.AddArg(w)
- v.AddArg3(p0, v0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w) x5:(MOVBstore [i-2] {s} p (SHRQconst [16] w) x4:(MOVBstore [i-3] {s} p (SHRQconst [24] w) x3:(MOVBstore [i-4] {s} p (SHRQconst [32] w) x2:(MOVBstore [i-5] {s} p (SHRQconst [40] w) x1:(MOVBstore [i-6] {s} p (SHRQconst [48] w) x0:(MOVBstore [i-7] {s} p (SHRQconst [56] w) mem))))))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)
- // result: (MOVQstore [i-7] {s} p (BSWAPQ <typ.UInt64> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x6 := v_2
- if x6.Op != OpAMD64MOVBstore || auxIntToInt32(x6.AuxInt) != i-1 || auxToSym(x6.Aux) != s {
- break
- }
- _ = x6.Args[2]
- if p != x6.Args[0] {
- break
- }
- x6_1 := x6.Args[1]
- if x6_1.Op != OpAMD64SHRQconst || auxIntToInt8(x6_1.AuxInt) != 8 || w != x6_1.Args[0] {
- break
- }
- x5 := x6.Args[2]
- if x5.Op != OpAMD64MOVBstore || auxIntToInt32(x5.AuxInt) != i-2 || auxToSym(x5.Aux) != s {
- break
- }
- _ = x5.Args[2]
- if p != x5.Args[0] {
- break
- }
- x5_1 := x5.Args[1]
- if x5_1.Op != OpAMD64SHRQconst || auxIntToInt8(x5_1.AuxInt) != 16 || w != x5_1.Args[0] {
- break
- }
- x4 := x5.Args[2]
- if x4.Op != OpAMD64MOVBstore || auxIntToInt32(x4.AuxInt) != i-3 || auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[2]
- if p != x4.Args[0] {
- break
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpAMD64SHRQconst || auxIntToInt8(x4_1.AuxInt) != 24 || w != x4_1.Args[0] {
- break
- }
- x3 := x4.Args[2]
- if x3.Op != OpAMD64MOVBstore || auxIntToInt32(x3.AuxInt) != i-4 || auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[2]
- if p != x3.Args[0] {
- break
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpAMD64SHRQconst || auxIntToInt8(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
- break
- }
- x2 := x3.Args[2]
- if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i-5 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if p != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 40 || w != x2_1.Args[0] {
- break
- }
- x1 := x2.Args[2]
- if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i-6 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 48 || w != x1_1.Args[0] {
- break
- }
- x0 := x1.Args[2]
- if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i-7 || auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpAMD64SHRQconst || auxIntToInt8(x0_1.AuxInt) != 56 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(i - 7)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, typ.UInt64)
- v0.AddArg(w)
- v.AddArg3(p, v0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p7 w x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w) x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w) x4:(MOVBstore [i] {s} p4 (SHRQconst [24] w) x3:(MOVBstore [i] {s} p3 (SHRQconst [32] w) x2:(MOVBstore [i] {s} p2 (SHRQconst [40] w) x1:(MOVBstore [i] {s} p1 (SHRQconst [48] w) x0:(MOVBstore [i] {s} p0 (SHRQconst [56] w) mem))))))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && sequentialAddresses(p3, p4, 1) && sequentialAddresses(p4, p5, 1) && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6)
- // result: (MOVQstore [i] {s} p0 (BSWAPQ <typ.UInt64> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p7 := v_0
- w := v_1
- x6 := v_2
- if x6.Op != OpAMD64MOVBstore || auxIntToInt32(x6.AuxInt) != i || auxToSym(x6.Aux) != s {
- break
- }
- _ = x6.Args[2]
- p6 := x6.Args[0]
- x6_1 := x6.Args[1]
- if x6_1.Op != OpAMD64SHRQconst || auxIntToInt8(x6_1.AuxInt) != 8 || w != x6_1.Args[0] {
- break
- }
- x5 := x6.Args[2]
- if x5.Op != OpAMD64MOVBstore || auxIntToInt32(x5.AuxInt) != i || auxToSym(x5.Aux) != s {
- break
- }
- _ = x5.Args[2]
- p5 := x5.Args[0]
- x5_1 := x5.Args[1]
- if x5_1.Op != OpAMD64SHRQconst || auxIntToInt8(x5_1.AuxInt) != 16 || w != x5_1.Args[0] {
- break
- }
- x4 := x5.Args[2]
- if x4.Op != OpAMD64MOVBstore || auxIntToInt32(x4.AuxInt) != i || auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[2]
- p4 := x4.Args[0]
- x4_1 := x4.Args[1]
- if x4_1.Op != OpAMD64SHRQconst || auxIntToInt8(x4_1.AuxInt) != 24 || w != x4_1.Args[0] {
- break
- }
- x3 := x4.Args[2]
- if x3.Op != OpAMD64MOVBstore || auxIntToInt32(x3.AuxInt) != i || auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[2]
- p3 := x3.Args[0]
- x3_1 := x3.Args[1]
- if x3_1.Op != OpAMD64SHRQconst || auxIntToInt8(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
- break
- }
- x2 := x3.Args[2]
- if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- p2 := x2.Args[0]
- x2_1 := x2.Args[1]
- if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 40 || w != x2_1.Args[0] {
- break
- }
- x1 := x2.Args[2]
- if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- p1 := x1.Args[0]
- x1_1 := x1.Args[1]
- if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 48 || w != x1_1.Args[0] {
- break
- }
- x0 := x1.Args[2]
- if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- p0 := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpAMD64SHRQconst || auxIntToInt8(x0_1.AuxInt) != 56 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && sequentialAddresses(p3, p4, 1) && sequentialAddresses(p4, p5, 1) && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, typ.UInt64)
- v0.AddArg(w)
- v.AddArg3(p0, v0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRWconst || auxIntToInt8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRLconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRQconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHRWconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpAMD64SHRWconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHRLconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpAMD64SHRLconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHRQconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpAMD64SHRQconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRLconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SHRLconst [j-8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRLconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SHRQconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SHRQconst [j-8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRQconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRWconst [8] w) x:(MOVBstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRWconst || auxIntToInt8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRLconst [8] w) x:(MOVBstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRQconst [8] w) x:(MOVBstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHRWconst [8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- w := v_1
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p1 := x.Args[0]
- x_1 := x.Args[1]
- if x_1.Op != OpAMD64SHRWconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHRLconst [8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- w := v_1
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p1 := x.Args[0]
- x_1 := x.Args[1]
- if x_1.Op != OpAMD64SHRLconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHRQconst [8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- w := v_1
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p1 := x.Args[0]
- x_1 := x.Args[1]
- if x_1.Op != OpAMD64SHRQconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRLconst [j] w) x:(MOVBstore [i] {s} p0 w0:(SHRLconst [j-8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRLconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p1 (SHRQconst [j] w) x:(MOVBstore [i] {s} p0 w0:(SHRQconst [j-8] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)
- // result: (MOVWstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRQconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
- // match: (MOVBstore [c3] {s} p3 (SHRQconst [56] w) x1:(MOVWstore [c2] {s} p2 (SHRQconst [40] w) x2:(MOVLstore [c1] {s} p1 (SHRQconst [8] w) x3:(MOVBstore [c0] {s} p0 w mem))))
- // cond: x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && sequentialAddresses(p0, p1, int64(1 + c0 - c1)) && sequentialAddresses(p0, p2, int64(5 + c0 - c2)) && sequentialAddresses(p0, p3, int64(7 + c0 - c3)) && clobber(x1, x2, x3)
- // result: (MOVQstore [c0] {s} p0 w mem)
- for {
- c3 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p3 := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 56 {
- break
- }
- w := v_1.Args[0]
- x1 := v_2
- if x1.Op != OpAMD64MOVWstore {
- break
- }
- c2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- p2 := x1.Args[0]
- x1_1 := x1.Args[1]
- if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 40 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpAMD64MOVLstore {
- break
- }
- c1 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- p1 := x2.Args[0]
- x2_1 := x2.Args[1]
- if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] {
- break
- }
- x3 := x2.Args[2]
- if x3.Op != OpAMD64MOVBstore {
- break
- }
- c0 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- break
- }
- mem := x3.Args[2]
- p0 := x3.Args[0]
- if w != x3.Args[1] || !(x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && sequentialAddresses(p0, p1, int64(1+c0-c1)) && sequentialAddresses(p0, p2, int64(5+c0-c2)) && sequentialAddresses(p0, p3, int64(7+c0-c3)) && clobber(x1, x2, x3)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(c0)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
// match: (MOVBstore [i] {s} p x1:(MOVBload [j] {s2} p2 mem) mem2:(MOVBstore [i-1] {s} p x2:(MOVBload [j-1] {s2} p2 mem) mem))
// cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2)
// result: (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem)
@@ -11388,58 +10573,6 @@ func rewriteValueAMD64_OpAMD64MOVBstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)
- // result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- x := v_1
- if x.Op != OpAMD64MOVBstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p0 := x.Args[0]
- if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
- // match: (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)
- // result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- x := v_1
- if x.Op != OpAMD64MOVBstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p1 := x.Args[0]
- if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVWstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
return false
}
func rewriteValueAMD64_OpAMD64MOVLQSX(v *Value) bool {
@@ -12019,115 +11152,6 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVLstore [i] {s} p (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVQstore [i-4] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 32 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVLstore [i] {s} p (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p w0:(SHRQconst [j-32] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVQstore [i-4] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRQconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVLstore [i] {s} p1 (SHRQconst [32] w) x:(MOVLstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x)
- // result: (MOVQstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 32 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVLstore [i] {s} p1 (SHRQconst [j] w) x:(MOVLstore [i] {s} p0 w0:(SHRQconst [j-32] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x)
- // result: (MOVQstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRQconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
// match: (MOVLstore [i] {s} p x1:(MOVLload [j] {s2} p2 mem) mem2:(MOVLstore [i-4] {s} p x2:(MOVLload [j-4] {s2} p2 mem) mem))
// cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2)
// result: (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem)
@@ -12575,8 +11599,6 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool {
func rewriteValueAMD64_OpAMD64MOVLstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (MOVLstoreconst [sc] {s} (ADDQconst [off] ptr) mem)
// cond: ValAndOff(sc).canAdd32(off)
// result: (MOVLstoreconst [ValAndOff(sc).addOffset32(off)] {s} ptr mem)
@@ -12620,62 +11642,6 @@ func rewriteValueAMD64_OpAMD64MOVLstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVLstoreconst [c] {s} p1 x:(MOVLstoreconst [a] {s} p0 mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)
- // result: (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- x := v_1
- if x.Op != OpAMD64MOVLstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p0 := x.Args[0]
- if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(a.Off())
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64)
- v0.AuxInt = int64ToAuxInt(a.Val64()&0xffffffff | c.Val64()<<32)
- v.AddArg3(p0, v0, mem)
- return true
- }
- // match: (MOVLstoreconst [a] {s} p0 x:(MOVLstoreconst [c] {s} p1 mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)
- // result: (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- x := v_1
- if x.Op != OpAMD64MOVLstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p1 := x.Args[0]
- if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVQstore)
- v.AuxInt = int32ToAuxInt(a.Off())
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64)
- v0.AuxInt = int64ToAuxInt(a.Val64()&0xffffffff | c.Val64()<<32)
- v.AddArg3(p0, v0, mem)
- return true
- }
return false
}
func rewriteValueAMD64_OpAMD64MOVOload(v *Value) bool {
@@ -14387,224 +13353,6 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVLstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p (SHRQconst [16] w) x:(MOVWstore [i-2] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVLstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p (SHRLconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVLstore [i-2] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRLconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p (SHRQconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRQconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVLstore [i-2] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpAMD64SHRQconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p1 (SHRLconst [16] w) x:(MOVWstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p1 (SHRQconst [16] w) x:(MOVWstore [i] {s} p0 w mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstore [i] {s} p0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p1 (SHRLconst [j] w) x:(MOVWstore [i] {s} p0 w0:(SHRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRLconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p1 (SHRQconst [j] w) x:(MOVWstore [i] {s} p0 w0:(SHRQconst [j-16] w) mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)
- // result: (MOVLstore [i] {s} p0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpAMD64SHRQconst {
- break
- }
- j := auxIntToInt8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- p0 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstore)
- v.AuxInt = int32ToAuxInt(i)
- v.Aux = symToAux(s)
- v.AddArg3(p0, w0, mem)
- return true
- }
// match: (MOVWstore [i] {s} p x1:(MOVWload [j] {s2} p2 mem) mem2:(MOVWstore [i-2] {s} p x2:(MOVWload [j-2] {s2} p2 mem) mem))
// cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2)
// result: (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem)
@@ -14716,58 +13464,6 @@ func rewriteValueAMD64_OpAMD64MOVWstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)
- // result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
- for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p1 := v_0
- x := v_1
- if x.Op != OpAMD64MOVWstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p0 := x.Args[0]
- if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
- // match: (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
- // cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)
- // result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
- for {
- a := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p0 := v_0
- x := v_1
- if x.Op != OpAMD64MOVWstoreconst {
- break
- }
- c := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- p1 := x.Args[0]
- if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)) {
- break
- }
- v.reset(OpAMD64MOVLstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
return false
}
func rewriteValueAMD64_OpAMD64MULL(v *Value) bool {
@@ -16017,8 +14713,6 @@ func rewriteValueAMD64_OpAMD64NOTQ(v *Value) bool {
func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (ORL (SHLL (MOVLconst [1]) y) x)
// result: (BTSL x y)
for {
@@ -16084,584 +14778,6 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (ORL x0:(MOVBload [i0] {s} p mem) sh:(SHLLconst [8] x1:(MOVBload [i1] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORL x0:(MOVBload [i] {s} p0 mem) sh:(SHLLconst [8] x1:(MOVBload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (ORL x0:(MOVWload [i0] {s} p mem) sh:(SHLLconst [16] x1:(MOVWload [i1] {s} p mem)))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORL x0:(MOVWload [i] {s} p0 mem) sh:(SHLLconst [16] x1:(MOVWload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVWload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (ORL s1:(SHLLconst [j1] x1:(MOVBload [i1] {s} p mem)) or:(ORL s0:(SHLLconst [j0] x0:(MOVBload [i0] {s} p mem)) y))
- // cond: i1 == i0+1 && j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpAMD64SHLLconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- or := v_1
- if or.Op != OpAMD64ORL {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpAMD64SHLLconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpAMD64ORL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64SHLLconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg2(p, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORL s1:(SHLLconst [j1] x1:(MOVBload [i] {s} p1 mem)) or:(ORL s0:(SHLLconst [j0] x0:(MOVBload [i] {s} p0 mem)) y))
- // cond: j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpAMD64SHLLconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- or := v_1
- if or.Op != OpAMD64ORL {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpAMD64SHLLconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpAMD64ORL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64SHLLconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v2.AuxInt = int32ToAuxInt(i)
- v2.Aux = symToAux(s)
- v2.AddArg2(p0, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORL x1:(MOVBload [i1] {s} p mem) sh:(SHLLconst [8] x0:(MOVBload [i0] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type)
- v.copyOf(v0)
- v0.AuxInt = int8ToAuxInt(8)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORL x1:(MOVBload [i] {s} p1 mem) sh:(SHLLconst [8] x0:(MOVBload [i] {s} p0 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type)
- v.copyOf(v0)
- v0.AuxInt = int8ToAuxInt(8)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v1.AuxInt = int32ToAuxInt(i)
- v1.Aux = symToAux(s)
- v1.AddArg2(p0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORL r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)) sh:(SHLLconst [16] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r1 := v_0
- if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- r0 := sh.Args[0]
- if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORL r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem)) sh:(SHLLconst [16] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r1 := v_0
- if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- r0 := sh.Args[0]
- if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVWload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32)
- v1.AuxInt = int32ToAuxInt(i)
- v1.Aux = symToAux(s)
- v1.AddArg2(p0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORL s0:(SHLLconst [j0] x0:(MOVBload [i0] {s} p mem)) or:(ORL s1:(SHLLconst [j1] x1:(MOVBload [i1] {s} p mem)) y))
- // cond: i1 == i0+1 && j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpAMD64SHLLconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- or := v_1
- if or.Op != OpAMD64ORL {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpAMD64SHLLconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpAMD64ORL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpAMD64SHLLconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16)
- v2.AuxInt = int8ToAuxInt(8)
- v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v3.AuxInt = int32ToAuxInt(i0)
- v3.Aux = symToAux(s)
- v3.AddArg2(p, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORL s0:(SHLLconst [j0] x0:(MOVBload [i] {s} p0 mem)) or:(ORL s1:(SHLLconst [j1] x1:(MOVBload [i] {s} p1 mem)) y))
- // cond: j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpAMD64SHLLconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- or := v_1
- if or.Op != OpAMD64ORL {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpAMD64SHLLconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpAMD64ORL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpAMD64SHLLconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16)
- v2.AuxInt = int8ToAuxInt(8)
- v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v3.AuxInt = int32ToAuxInt(i)
- v3.Aux = symToAux(s)
- v3.AddArg2(p0, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
// match: (ORL x l:(MOVLload [off] {sym} ptr mem))
// cond: canMergeLoadClobber(v, l, x) && clobber(l)
// result: (ORLload x [off] {sym} ptr mem)
@@ -16946,8 +15062,6 @@ func rewriteValueAMD64_OpAMD64ORLmodify(v *Value) bool {
func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (ORQ (SHLQ (MOVQconst [1]) y) x)
// result: (BTSQ x y)
for {
@@ -17147,1020 +15261,6 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (ORQ x0:(MOVBload [i0] {s} p mem) sh:(SHLQconst [8] x1:(MOVBload [i1] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORQ x0:(MOVBload [i] {s} p0 mem) sh:(SHLQconst [8] x1:(MOVBload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (ORQ x0:(MOVWload [i0] {s} p mem) sh:(SHLQconst [16] x1:(MOVWload [i1] {s} p mem)))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORQ x0:(MOVWload [i] {s} p0 mem) sh:(SHLQconst [16] x1:(MOVWload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVWload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (ORQ x0:(MOVLload [i0] {s} p mem) sh:(SHLQconst [32] x1:(MOVLload [i1] {s} p mem)))
- // cond: i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVLload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVLload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVQload, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORQ x0:(MOVLload [i] {s} p0 mem) sh:(SHLQconst [32] x1:(MOVLload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 4) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVQload [i] {s} p0 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVLload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVLload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 4) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVQload, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (ORQ s1:(SHLQconst [j1] x1:(MOVBload [i1] {s} p mem)) or:(ORQ s0:(SHLQconst [j0] x0:(MOVBload [i0] {s} p mem)) y))
- // cond: i1 == i0+1 && j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg2(p, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ s1:(SHLQconst [j1] x1:(MOVBload [i] {s} p1 mem)) or:(ORQ s0:(SHLQconst [j0] x0:(MOVBload [i] {s} p0 mem)) y))
- // cond: j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v2.AuxInt = int32ToAuxInt(i)
- v2.Aux = symToAux(s)
- v2.AddArg2(p0, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem)) or:(ORQ s0:(SHLQconst [j0] x0:(MOVWload [i0] {s} p mem)) y))
- // cond: i1 == i0+2 && j1 == j0+16 && j0 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+2 && j1 == j0+16 && j0%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg2(p, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ s1:(SHLQconst [j1] x1:(MOVWload [i] {s} p1 mem)) or:(ORQ s0:(SHLQconst [j0] x0:(MOVWload [i] {s} p0 mem)) y))
- // cond: j1 == j0+16 && j0 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i] {s} p0 mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVWload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(j1 == j0+16 && j0%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32)
- v2.AuxInt = int32ToAuxInt(i)
- v2.Aux = symToAux(s)
- v2.AddArg2(p0, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ x1:(MOVBload [i1] {s} p mem) sh:(SHLQconst [8] x0:(MOVBload [i0] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type)
- v.copyOf(v0)
- v0.AuxInt = int8ToAuxInt(8)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORQ x1:(MOVBload [i] {s} p1 mem) sh:(SHLQconst [8] x0:(MOVBload [i] {s} p0 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type)
- v.copyOf(v0)
- v0.AuxInt = int8ToAuxInt(8)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16)
- v1.AuxInt = int32ToAuxInt(i)
- v1.Aux = symToAux(s)
- v1.AddArg2(p0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORQ r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)) sh:(SHLQconst [16] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r1 := v_0
- if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- r0 := sh.Args[0]
- if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORQ r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem)) sh:(SHLQconst [16] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r1 := v_0
- if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 {
- continue
- }
- r0 := sh.Args[0]
- if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVWload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32)
- v1.AuxInt = int32ToAuxInt(i)
- v1.Aux = symToAux(s)
- v1.AddArg2(p0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORQ r1:(BSWAPL x1:(MOVLload [i1] {s} p mem)) sh:(SHLQconst [32] r0:(BSWAPL x0:(MOVLload [i0] {s} p mem))))
- // cond: i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r1 := v_0
- if r1.Op != OpAMD64BSWAPL {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVLload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 {
- continue
- }
- r0 := sh.Args[0]
- if r0.Op != OpAMD64BSWAPL {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVLload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVQload, typ.UInt64)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORQ r1:(BSWAPL x1:(MOVLload [i] {s} p1 mem)) sh:(SHLQconst [32] r0:(BSWAPL x0:(MOVLload [i] {s} p0 mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 4) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i] {s} p0 mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r1 := v_0
- if r1.Op != OpAMD64BSWAPL {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVLload {
- continue
- }
- i := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p1 := x1.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 {
- continue
- }
- r0 := sh.Args[0]
- if r0.Op != OpAMD64BSWAPL {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVLload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- p0 := x0.Args[0]
- if mem != x0.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p0, p1, 4) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpAMD64MOVQload, typ.UInt64)
- v1.AuxInt = int32ToAuxInt(i)
- v1.Aux = symToAux(s)
- v1.AddArg2(p0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORQ s0:(SHLQconst [j0] x0:(MOVBload [i0] {s} p mem)) or:(ORQ s1:(SHLQconst [j1] x1:(MOVBload [i1] {s} p mem)) y))
- // cond: i1 == i0+1 && j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16)
- v2.AuxInt = int8ToAuxInt(8)
- v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v3.AuxInt = int32ToAuxInt(i0)
- v3.Aux = symToAux(s)
- v3.AddArg2(p, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ s0:(SHLQconst [j0] x0:(MOVBload [i] {s} p0 mem)) or:(ORQ s1:(SHLQconst [j1] x1:(MOVBload [i] {s} p1 mem)) y))
- // cond: j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpAMD64MOVBload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 1) && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16)
- v2.AuxInt = int8ToAuxInt(8)
- v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16)
- v3.AuxInt = int32ToAuxInt(i)
- v3.Aux = symToAux(s)
- v3.AddArg2(p0, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))) or:(ORQ s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem))) y))
- // cond: i1 == i0+2 && j1 == j0-16 && j1 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- r0 := s0.Args[0]
- if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- r1 := s1.Args[0]
- if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVWload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+2 && j1 == j0-16 && j1%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpAMD64BSWAPL, typ.UInt32)
- v3 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32)
- v3.AuxInt = int32ToAuxInt(i0)
- v3.Aux = symToAux(s)
- v3.AddArg2(p, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORQ s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))) or:(ORQ s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem))) y))
- // cond: j1 == j0-16 && j1 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i] {s} p0 mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpAMD64SHLQconst {
- continue
- }
- j0 := auxIntToInt8(s0.AuxInt)
- r0 := s0.Args[0]
- if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpAMD64MOVWload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- or := v_1
- if or.Op != OpAMD64ORQ {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpAMD64SHLQconst {
- continue
- }
- j1 := auxIntToInt8(s1.AuxInt)
- r1 := s1.Args[0]
- if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpAMD64MOVWload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(j1 == j0-16 && j1%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && sequentialAddresses(p0, p1, 2) && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpAMD64BSWAPL, typ.UInt32)
- v3 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32)
- v3.AuxInt = int32ToAuxInt(i)
- v3.Aux = symToAux(s)
- v3.AddArg2(p0, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
// match: (ORQ x l:(MOVQload [off] {sym} ptr mem))
// cond: canMergeLoadClobber(v, l, x) && clobber(l)
// result: (ORQload x [off] {sym} ptr mem)
@@ -18186,81 +15286,6 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
}
break
}
- // match: (ORQ x0:(MOVBELload [i0] {s} p mem) sh:(SHLQconst [32] x1:(MOVBELload [i1] {s} p mem)))
- // cond: i0 == i1+4 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVBEQload [i1] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVBELload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVBELload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i0 == i1+4 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVBEQload, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i1)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORQ x0:(MOVBELload [i] {s} p0 mem) sh:(SHLQconst [32] x1:(MOVBELload [i] {s} p1 mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p1, p0, 4) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVBEQload [i] {s} p1 mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpAMD64MOVBELload {
- continue
- }
- i := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p0 := x0.Args[0]
- sh := v_1
- if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpAMD64MOVBELload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if mem != x1.Args[1] || !(x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && sequentialAddresses(p1, p0, 4) && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpAMD64MOVBEQload, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i)
- v0.Aux = symToAux(s)
- v0.AddArg2(p1, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueAMD64_OpAMD64ORQconst(v *Value) bool {
@@ -27794,6 +24819,18 @@ func rewriteValueAMD64_OpBitLen8(v *Value) bool {
}
return false
}
+func rewriteValueAMD64_OpBswap16(v *Value) bool {
+ v_0 := v.Args[0]
+ // match: (Bswap16 x)
+ // result: (ROLWconst [8] x)
+ for {
+ x := v_0
+ v.reset(OpAMD64ROLWconst)
+ v.AuxInt = int8ToAuxInt(8)
+ v.AddArg(x)
+ return true
+ }
+}
func rewriteValueAMD64_OpCeil(v *Value) bool {
v_0 := v.Args[0]
// match: (Ceil x)
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index ca1704fe41..b655c62720 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -545,6 +545,9 @@ func rewriteValueARM64(v *Value) bool {
return true
case OpBitRev8:
return rewriteValueARM64_OpBitRev8(v)
+ case OpBswap16:
+ v.Op = OpARM64REV16W
+ return true
case OpBswap32:
v.Op = OpARM64REVW
return true
@@ -8726,7 +8729,6 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
- typ := &b.Func.Config.Types
// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
@@ -8910,1327 +8912,6 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVBstore [i] {s} ptr0 (SRLconst [8] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] w) x:(MOVBstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
- continue
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 8) {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 8) {
- continue
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 24) {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 24) {
- continue
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr0 (SRLconst [8] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
- break
- }
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- break
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
- continue
- }
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- continue
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] w) mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst {
- break
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst {
- continue
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr0 (UBFX [bfc] w) x:(MOVBstore [i-1] {s} ptr1 w0:(UBFX [bfc2] w) mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8 && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64UBFX {
- break
- }
- bfc := auxIntToArm64BitField(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpARM64UBFX {
- break
- }
- bfc2 := auxIntToArm64BitField(w0.AuxInt)
- if w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && bfc.getARM64BFwidth() == 32-bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32-bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb()-8 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [bfc] w) x:(MOVBstoreidx ptr1 idx1 w0:(UBFX [bfc2] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8 && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64UBFX {
- continue
- }
- bfc := auxIntToArm64BitField(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64UBFX {
- continue
- }
- bfc2 := auxIntToArm64BitField(w0.AuxInt)
- if w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && bfc.getARM64BFwidth() == 32-bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32-bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb()-8 && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr0 (SRLconst [j] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst {
- break
- }
- j := auxIntToInt64(v_1.AuxInt)
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- break
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 {
- break
- }
- w0_0 := w0.Args[0]
- if w0_0.Op != OpARM64MOVDreg || w != w0_0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr1 idx1 w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst {
- continue
- }
- j := auxIntToInt64(v_1.AuxInt)
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- continue
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 {
- continue
- }
- w0_0 := w0.Args[0]
- if w0_0.Op != OpARM64MOVDreg || w != w0_0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr1, idx1, w0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) x3:(MOVBstore [i-4] {s} ptr (SRLconst [32] w) x4:(MOVBstore [i-5] {s} ptr (SRLconst [40] w) x5:(MOVBstore [i-6] {s} ptr (SRLconst [48] w) x6:(MOVBstore [i-7] {s} ptr (SRLconst [56] w) mem))))))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)
- // result: (MOVDstore [i-7] {s} ptr (REV <typ.UInt64> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if ptr != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] {
- break
- }
- x3 := x2.Args[2]
- if x3.Op != OpARM64MOVBstore || auxIntToInt32(x3.AuxInt) != i-4 || auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] {
- break
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64SRLconst || auxIntToInt64(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
- break
- }
- x4 := x3.Args[2]
- if x4.Op != OpARM64MOVBstore || auxIntToInt32(x4.AuxInt) != i-5 || auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[2]
- if ptr != x4.Args[0] {
- break
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpARM64SRLconst || auxIntToInt64(x4_1.AuxInt) != 40 || w != x4_1.Args[0] {
- break
- }
- x5 := x4.Args[2]
- if x5.Op != OpARM64MOVBstore || auxIntToInt32(x5.AuxInt) != i-6 || auxToSym(x5.Aux) != s {
- break
- }
- _ = x5.Args[2]
- if ptr != x5.Args[0] {
- break
- }
- x5_1 := x5.Args[1]
- if x5_1.Op != OpARM64SRLconst || auxIntToInt64(x5_1.AuxInt) != 48 || w != x5_1.Args[0] {
- break
- }
- x6 := x5.Args[2]
- if x6.Op != OpARM64MOVBstore || auxIntToInt32(x6.AuxInt) != i-7 || auxToSym(x6.Aux) != s {
- break
- }
- mem := x6.Args[2]
- if ptr != x6.Args[0] {
- break
- }
- x6_1 := x6.Args[1]
- if x6_1.Op != OpARM64SRLconst || auxIntToInt64(x6_1.AuxInt) != 56 || w != x6_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)) {
- break
- }
- v.reset(OpARM64MOVDstore)
- v.AuxInt = int32ToAuxInt(i - 7)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x6.Pos, OpARM64REV, typ.UInt64)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [7] {s} p w x0:(MOVBstore [6] {s} p (SRLconst [8] w) x1:(MOVBstore [5] {s} p (SRLconst [16] w) x2:(MOVBstore [4] {s} p (SRLconst [24] w) x3:(MOVBstore [3] {s} p (SRLconst [32] w) x4:(MOVBstore [2] {s} p (SRLconst [40] w) x5:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [48] w) x6:(MOVBstoreidx ptr0 idx0 (SRLconst [56] w) mem))))))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6)
- // result: (MOVDstoreidx ptr0 idx0 (REV <typ.UInt64> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 7 {
- break
- }
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 6 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 5 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != 4 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if p != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] {
- break
- }
- x3 := x2.Args[2]
- if x3.Op != OpARM64MOVBstore || auxIntToInt32(x3.AuxInt) != 3 || auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[2]
- if p != x3.Args[0] {
- break
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64SRLconst || auxIntToInt64(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
- break
- }
- x4 := x3.Args[2]
- if x4.Op != OpARM64MOVBstore || auxIntToInt32(x4.AuxInt) != 2 || auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[2]
- if p != x4.Args[0] {
- break
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpARM64SRLconst || auxIntToInt64(x4_1.AuxInt) != 40 || w != x4_1.Args[0] {
- break
- }
- x5 := x4.Args[2]
- if x5.Op != OpARM64MOVBstore || auxIntToInt32(x5.AuxInt) != 1 || auxToSym(x5.Aux) != s {
- break
- }
- _ = x5.Args[2]
- p1 := x5.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- x5_1 := x5.Args[1]
- if x5_1.Op != OpARM64SRLconst || auxIntToInt64(x5_1.AuxInt) != 48 || w != x5_1.Args[0] {
- continue
- }
- x6 := x5.Args[2]
- if x6.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x6.Args[3]
- ptr0 := x6.Args[0]
- idx0 := x6.Args[1]
- x6_2 := x6.Args[2]
- if x6_2.Op != OpARM64SRLconst || auxIntToInt64(x6_2.AuxInt) != 56 || w != x6_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6)) {
- continue
- }
- v.reset(OpARM64MOVDstoreidx)
- v0 := b.NewValue0(x5.Pos, OpARM64REV, typ.UInt64)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstore [i-3] {s} ptr (UBFX [armBFAuxInt(24, 8)] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
- // result: (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if ptr != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64UBFX || auxIntToArm64BitField(x0_1.AuxInt) != armBFAuxInt(8, 24) || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64UBFX || auxIntToArm64BitField(x1_1.AuxInt) != armBFAuxInt(16, 16) || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
- break
- }
- mem := x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64UBFX || auxIntToArm64BitField(x2_1.AuxInt) != armBFAuxInt(24, 8) || w != x2_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 3)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x2.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(24, 8)] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)
- // result: (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 3 {
- break
- }
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 2 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64UBFX || auxIntToArm64BitField(x0_1.AuxInt) != armBFAuxInt(8, 24) || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64UBFX || auxIntToArm64BitField(x1_1.AuxInt) != armBFAuxInt(16, 16) || w != x1_1.Args[0] {
- continue
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x2.Args[3]
- ptr0 := x2.Args[0]
- idx0 := x2.Args[1]
- x2_2 := x2.Args[2]
- if x2_2.Op != OpARM64UBFX || auxIntToArm64BitField(x2_2.AuxInt) != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(x1.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] (MOVDreg w)) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] (MOVDreg w)) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
- // result: (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if ptr != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 {
- break
- }
- x0_1_0 := x0_1.Args[0]
- if x0_1_0.Op != OpARM64MOVDreg || w != x0_1_0.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 {
- break
- }
- x1_1_0 := x1_1.Args[0]
- if x1_1_0.Op != OpARM64MOVDreg || w != x1_1_0.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
- break
- }
- mem := x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 {
- break
- }
- x2_1_0 := x2_1.Args[0]
- if x2_1_0.Op != OpARM64MOVDreg || w != x2_1_0.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 3)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x2.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w)) x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] (MOVDreg w)) x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] (MOVDreg w)) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)
- // result: (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 3 {
- break
- }
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 2 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 {
- break
- }
- x0_1_0 := x0_1.Args[0]
- if x0_1_0.Op != OpARM64MOVDreg || w != x0_1_0.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 {
- continue
- }
- x1_1_0 := x1_1.Args[0]
- if x1_1_0.Op != OpARM64MOVDreg || w != x1_1_0.Args[0] {
- continue
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x2.Args[3]
- ptr0 := x2.Args[0]
- idx0 := x2.Args[1]
- x2_2 := x2.Args[2]
- if x2_2.Op != OpARM64SRLconst || auxIntToInt64(x2_2.AuxInt) != 24 {
- continue
- }
- x2_2_0 := x2_2.Args[0]
- if x2_2_0.Op != OpARM64MOVDreg || w != x2_2_0.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(x1.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
- // result: (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if ptr != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
- break
- }
- mem := x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 3)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x2.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (SRLconst [8] w) x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] w) x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)
- // result: (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 3 {
- break
- }
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 2 || auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- continue
- }
- x2 := x1.Args[2]
- if x2.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x2.Args[3]
- ptr0 := x2.Args[0]
- idx0 := x2.Args[1]
- x2_2 := x2.Args[2]
- if x2_2.Op != OpARM64SRLconst || auxIntToInt64(x2_2.AuxInt) != 24 || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(x1.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpARM64SRLconst || auxIntToInt64(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr1 := v_0_0
- idx1 := v_0_1
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr0 := x.Args[0]
- idx0 := x.Args[1]
- x_2 := x.Args[2]
- if x_2.Op != OpARM64SRLconst || auxIntToInt64(x_2.AuxInt) != 8 || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpARM64UBFX || auxIntToArm64BitField(x_1.AuxInt) != armBFAuxInt(8, 8) || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr1 := v_0_0
- idx1 := v_0_1
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr0 := x.Args[0]
- idx0 := x.Args[1]
- x_2 := x.Args[2]
- if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpARM64SRLconst || auxIntToInt64(x_1.AuxInt) != 8 {
- break
- }
- x_1_0 := x_1.Args[0]
- if x_1_0.Op != OpARM64MOVDreg || w != x_1_0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr1 := v_0_0
- idx1 := v_0_1
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr0 := x.Args[0]
- idx0 := x.Args[1]
- x_2 := x.Args[2]
- if x_2.Op != OpARM64SRLconst || auxIntToInt64(x_2.AuxInt) != 8 {
- continue
- }
- x_2_0 := x_2.Args[0]
- if x_2_0.Op != OpARM64MOVDreg || w != x_2_0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
- // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr := v_0
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpARM64UBFX || auxIntToArm64BitField(x_1.AuxInt) != armBFAuxInt(8, 24) || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg3(ptr, v0, mem)
- return true
- }
- // match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr1 := v_0_0
- idx1 := v_0_1
- w := v_1
- x := v_2
- if x.Op != OpARM64MOVBstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr0 := x.Args[0]
- idx0 := x.Args[1]
- x_2 := x.Args[2]
- if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 24) || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg4(ptr0, idx0, v0, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueARM64_OpARM64MOVBstoreidx(v *Value) bool {
@@ -10238,8 +8919,6 @@ func rewriteValueARM64_OpARM64MOVBstoreidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (MOVBstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (MOVBstore [int32(c)] ptr val mem)
@@ -10375,205 +9054,6 @@ func rewriteValueARM64_OpARM64MOVBstoreidx(v *Value) bool {
v.AddArg4(ptr, idx, x, mem)
return true
}
- // match: (MOVBstoreidx ptr (ADDconst [1] idx) (SRLconst [8] w) x:(MOVBstoreidx ptr idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx ptr idx w mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
- break
- }
- idx := v_1.Args[0]
- if v_2.Op != OpARM64SRLconst || auxIntToInt64(v_2.AuxInt) != 8 {
- break
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpARM64MOVBstoreidx {
- break
- }
- mem := x.Args[3]
- if ptr != x.Args[0] || idx != x.Args[1] || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr, idx, w, mem)
- return true
- }
- // match: (MOVBstoreidx ptr (ADDconst [3] idx) w x0:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(24, 8)] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
- // result: (MOVWstoreidx ptr idx (REVW <typ.UInt32> w) mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 3 {
- break
- }
- idx := v_1.Args[0]
- w := v_2
- x0 := v_3
- if x0.Op != OpARM64MOVBstoreidx {
- break
- }
- _ = x0.Args[3]
- if ptr != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 2 || idx != x0_1.Args[0] {
- break
- }
- x0_2 := x0.Args[2]
- if x0_2.Op != OpARM64UBFX || auxIntToArm64BitField(x0_2.AuxInt) != armBFAuxInt(8, 24) || w != x0_2.Args[0] {
- break
- }
- x1 := x0.Args[3]
- if x1.Op != OpARM64MOVBstoreidx {
- break
- }
- _ = x1.Args[3]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] {
- break
- }
- x1_2 := x1.Args[2]
- if x1_2.Op != OpARM64UBFX || auxIntToArm64BitField(x1_2.AuxInt) != armBFAuxInt(16, 16) || w != x1_2.Args[0] {
- break
- }
- x2 := x1.Args[3]
- if x2.Op != OpARM64MOVBstoreidx {
- break
- }
- mem := x2.Args[3]
- if ptr != x2.Args[0] || idx != x2.Args[1] {
- break
- }
- x2_2 := x2.Args[2]
- if x2_2.Op != OpARM64UBFX || auxIntToArm64BitField(x2_2.AuxInt) != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64REVW, typ.UInt32)
- v0.AddArg(w)
- v.AddArg4(ptr, idx, v0, mem)
- return true
- }
- // match: (MOVBstoreidx ptr idx w x0:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr (ADDconst [3] idx) (UBFX [armBFAuxInt(24, 8)] w) mem))))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
- // result: (MOVWstoreidx ptr idx w mem)
- for {
- ptr := v_0
- idx := v_1
- w := v_2
- x0 := v_3
- if x0.Op != OpARM64MOVBstoreidx {
- break
- }
- _ = x0.Args[3]
- if ptr != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 1 || idx != x0_1.Args[0] {
- break
- }
- x0_2 := x0.Args[2]
- if x0_2.Op != OpARM64UBFX || auxIntToArm64BitField(x0_2.AuxInt) != armBFAuxInt(8, 24) || w != x0_2.Args[0] {
- break
- }
- x1 := x0.Args[3]
- if x1.Op != OpARM64MOVBstoreidx {
- break
- }
- _ = x1.Args[3]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 2 || idx != x1_1.Args[0] {
- break
- }
- x1_2 := x1.Args[2]
- if x1_2.Op != OpARM64UBFX || auxIntToArm64BitField(x1_2.AuxInt) != armBFAuxInt(16, 16) || w != x1_2.Args[0] {
- break
- }
- x2 := x1.Args[3]
- if x2.Op != OpARM64MOVBstoreidx {
- break
- }
- mem := x2.Args[3]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 3 || idx != x2_1.Args[0] {
- break
- }
- x2_2 := x2.Args[2]
- if x2_2.Op != OpARM64UBFX || auxIntToArm64BitField(x2_2.AuxInt) != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v.AddArg4(ptr, idx, w, mem)
- return true
- }
- // match: (MOVBstoreidx ptr (ADDconst [1] idx) w x:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(8, 8)] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx ptr idx (REV16W <typ.UInt16> w) mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
- break
- }
- idx := v_1.Args[0]
- w := v_2
- x := v_3
- if x.Op != OpARM64MOVBstoreidx {
- break
- }
- mem := x.Args[3]
- if ptr != x.Args[0] || idx != x.Args[1] {
- break
- }
- x_2 := x.Args[2]
- if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
- v0.AddArg(w)
- v.AddArg4(ptr, idx, v0, mem)
- return true
- }
- // match: (MOVBstoreidx ptr idx w x:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 8)] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx ptr idx w mem)
- for {
- ptr := v_0
- idx := v_1
- w := v_2
- x := v_3
- if x.Op != OpARM64MOVBstoreidx {
- break
- }
- mem := x.Args[3]
- if ptr != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpARM64ADDconst || auxIntToInt64(x_1.AuxInt) != 1 || idx != x_1.Args[0] {
- break
- }
- x_2 := x.Args[2]
- if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstoreidx)
- v.AddArg4(ptr, idx, w, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
@@ -10643,65 +9123,6 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
v.AddArg3(ptr, idx, mem)
return true
}
- // match: (MOVBstorezero [i] {s} ptr0 x:(MOVBstorezero [j] {s} ptr1 mem))
- // cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),1) && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVHstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- x := v_1
- if x.Op != OpARM64MOVBstorezero {
- break
- }
- j := auxIntToInt32(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- ptr1 := x.Args[0]
- if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 1) && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstorezero)
- v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
- v.Aux = symToAux(s)
- v.AddArg2(ptr0, mem)
- return true
- }
- // match: (MOVBstorezero [1] {s} (ADD ptr0 idx0) x:(MOVBstorezeroidx ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVHstorezeroidx ptr1 idx1 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 1 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- x := v_1
- if x.Op != OpARM64MOVBstorezeroidx {
- continue
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVHstorezeroidx)
- v.AddArg3(ptr1, idx1, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueARM64_OpARM64MOVBstorezeroidx(v *Value) bool {
@@ -10744,27 +9165,6 @@ func rewriteValueARM64_OpARM64MOVBstorezeroidx(v *Value) bool {
v.AddArg2(idx, mem)
return true
}
- // match: (MOVBstorezeroidx ptr (ADDconst [1] idx) x:(MOVBstorezeroidx ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstorezeroidx ptr idx mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
- break
- }
- idx := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVBstorezeroidx {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] || idx != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVHstorezeroidx)
- v.AddArg3(ptr, idx, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
@@ -11331,6 +9731,48 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
+ // match: (MOVDstorezero {s} [i] ptr x:(MOVDstorezero {s} [i+8] ptr mem))
+ // cond: x.Uses == 1 && clobber(x)
+ // result: (MOVQstorezero {s} [i] ptr mem)
+ for {
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
+ ptr := v_0
+ x := v_1
+ if x.Op != OpARM64MOVDstorezero || auxIntToInt32(x.AuxInt) != i+8 || auxToSym(x.Aux) != s {
+ break
+ }
+ mem := x.Args[1]
+ if ptr != x.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ break
+ }
+ v.reset(OpARM64MOVQstorezero)
+ v.AuxInt = int32ToAuxInt(i)
+ v.Aux = symToAux(s)
+ v.AddArg2(ptr, mem)
+ return true
+ }
+ // match: (MOVDstorezero {s} [i] ptr x:(MOVDstorezero {s} [i-8] ptr mem))
+ // cond: x.Uses == 1 && clobber(x)
+ // result: (MOVQstorezero {s} [i-8] ptr mem)
+ for {
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
+ ptr := v_0
+ x := v_1
+ if x.Op != OpARM64MOVDstorezero || auxIntToInt32(x.AuxInt) != i-8 || auxToSym(x.Aux) != s {
+ break
+ }
+ mem := x.Args[1]
+ if ptr != x.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ break
+ }
+ v.reset(OpARM64MOVQstorezero)
+ v.AuxInt = int32ToAuxInt(i - 8)
+ v.Aux = symToAux(s)
+ v.AddArg2(ptr, mem)
+ return true
+ }
// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
@@ -11412,98 +9854,6 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
v.AddArg3(ptr, idx, mem)
return true
}
- // match: (MOVDstorezero [i] {s} ptr0 x:(MOVDstorezero [j] {s} ptr1 mem))
- // cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),8) && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVQstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- x := v_1
- if x.Op != OpARM64MOVDstorezero {
- break
- }
- j := auxIntToInt32(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- ptr1 := x.Args[0]
- if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 8) && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVQstorezero)
- v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
- v.Aux = symToAux(s)
- v.AddArg2(ptr0, mem)
- return true
- }
- // match: (MOVDstorezero [8] {s} p0:(ADD ptr0 idx0) x:(MOVDstorezeroidx ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVQstorezero [0] {s} p0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 8 {
- break
- }
- s := auxToSym(v.Aux)
- p0 := v_0
- if p0.Op != OpARM64ADD {
- break
- }
- _ = p0.Args[1]
- p0_0 := p0.Args[0]
- p0_1 := p0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p0_0, p0_1 = _i0+1, p0_1, p0_0 {
- ptr0 := p0_0
- idx0 := p0_1
- x := v_1
- if x.Op != OpARM64MOVDstorezeroidx {
- continue
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVQstorezero)
- v.AuxInt = int32ToAuxInt(0)
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
- break
- }
- // match: (MOVDstorezero [8] {s} p0:(ADDshiftLL [3] ptr0 idx0) x:(MOVDstorezeroidx8 ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVQstorezero [0] {s} p0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 8 {
- break
- }
- s := auxToSym(v.Aux)
- p0 := v_0
- if p0.Op != OpARM64ADDshiftLL || auxIntToInt64(p0.AuxInt) != 3 {
- break
- }
- idx0 := p0.Args[1]
- ptr0 := p0.Args[0]
- x := v_1
- if x.Op != OpARM64MOVDstorezeroidx8 {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVQstorezero)
- v.AuxInt = int32ToAuxInt(0)
- v.Aux = symToAux(s)
- v.AddArg2(p0, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVDstorezeroidx(v *Value) bool {
@@ -12645,412 +10995,6 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVHstore [i] {s} ptr0 (SRLconst [16] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVWstore [i-2] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVWstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
- continue
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx2 {
- break
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(1)
- v0.AddArg(idx1)
- v.AddArg4(ptr1, v0, w, mem)
- return true
- }
- // match: (MOVHstore [i] {s} ptr0 (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVWstore [i-2] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(16, 16) {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVHstore [2] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVWstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(16, 16) {
- continue
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(16, 16) {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx2 {
- break
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(1)
- v0.AddArg(idx1)
- v.AddArg4(ptr1, v0, w, mem)
- return true
- }
- // match: (MOVHstore [i] {s} ptr0 (SRLconst [16] (MOVDreg w)) x:(MOVHstore [i-2] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVWstore [i-2] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
- break
- }
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- break
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVWstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
- continue
- }
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- continue
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx2 ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
- break
- }
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpARM64MOVDreg {
- break
- }
- w := v_1_0.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx2 {
- break
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(1)
- v0.AddArg(idx1)
- v.AddArg4(ptr1, v0, w, mem)
- return true
- }
- // match: (MOVHstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVHstore [i-2] {s} ptr1 w0:(SRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVWstore [i-2] {s} ptr0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst {
- break
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w0, mem)
- return true
- }
- // match: (MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx ptr1 idx1 w0:(SRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVWstoreidx ptr1 idx1 w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst {
- continue
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVWstoreidx)
- v.AddArg4(ptr1, idx1, w0, mem)
- return true
- }
- break
- }
- // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx2 ptr1 idx1 w0:(SRLconst [j-16] w) mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- if v_1.Op != OpARM64SRLconst {
- break
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstoreidx2 {
- break
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(1)
- v0.AddArg(idx1)
- v.AddArg4(ptr1, v0, w0, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVHstoreidx(v *Value) bool {
@@ -13227,31 +11171,6 @@ func rewriteValueARM64_OpARM64MOVHstoreidx(v *Value) bool {
v.AddArg4(ptr, idx, x, mem)
return true
}
- // match: (MOVHstoreidx ptr (ADDconst [2] idx) (SRLconst [16] w) x:(MOVHstoreidx ptr idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstoreidx ptr idx w mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 2 {
- break
- }
- idx := v_1.Args[0]
- if v_2.Op != OpARM64SRLconst || auxIntToInt64(v_2.AuxInt) != 16 {
- break
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpARM64MOVHstoreidx {
- break
- }
- mem := x.Args[3]
- if ptr != x.Args[0] || idx != x.Args[1] || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstoreidx)
- v.AddArg4(ptr, idx, w, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVHstoreidx2(v *Value) bool {
@@ -13435,95 +11354,6 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
v.AddArg3(ptr, idx, mem)
return true
}
- // match: (MOVHstorezero [i] {s} ptr0 x:(MOVHstorezero [j] {s} ptr1 mem))
- // cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),2) && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVWstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- x := v_1
- if x.Op != OpARM64MOVHstorezero {
- break
- }
- j := auxIntToInt32(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- ptr1 := x.Args[0]
- if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 2) && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstorezero)
- v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
- v.Aux = symToAux(s)
- v.AddArg2(ptr0, mem)
- return true
- }
- // match: (MOVHstorezero [2] {s} (ADD ptr0 idx0) x:(MOVHstorezeroidx ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVWstorezeroidx ptr1 idx1 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- x := v_1
- if x.Op != OpARM64MOVHstorezeroidx {
- continue
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVWstorezeroidx)
- v.AddArg3(ptr1, idx1, mem)
- return true
- }
- break
- }
- // match: (MOVHstorezero [2] {s} (ADDshiftLL [1] ptr0 idx0) x:(MOVHstorezeroidx2 ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVWstorezeroidx ptr1 (SLLconst <idx1.Type> [1] idx1) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 2 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- x := v_1
- if x.Op != OpARM64MOVHstorezeroidx2 {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstorezeroidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(1)
- v0.AddArg(idx1)
- v.AddArg3(ptr1, v0, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVHstorezeroidx(v *Value) bool {
@@ -13624,27 +11454,6 @@ func rewriteValueARM64_OpARM64MOVHstorezeroidx(v *Value) bool {
v.AddArg3(ptr, idx, mem)
return true
}
- // match: (MOVHstorezeroidx ptr (ADDconst [2] idx) x:(MOVHstorezeroidx ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstorezeroidx ptr idx mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 2 {
- break
- }
- idx := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVHstorezeroidx {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] || idx != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVWstorezeroidx)
- v.AddArg3(ptr, idx, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVHstorezeroidx2(v *Value) bool {
@@ -14862,206 +12671,6 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVWstore [i] {s} ptr0 (SRLconst [32] w) x:(MOVWstore [i-4] {s} ptr1 w mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVDstore [i-4] {s} ptr0 w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 32 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w, mem)
- return true
- }
- // match: (MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVDstoreidx ptr1 idx1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 4 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 32 {
- continue
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVDstoreidx)
- v.AddArg4(ptr1, idx1, w, mem)
- return true
- }
- break
- }
- // match: (MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx4 ptr1 idx1 w mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 4 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 32 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstoreidx4 {
- break
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(2)
- v0.AddArg(idx1)
- v.AddArg4(ptr1, v0, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVWstore [i-4] {s} ptr1 w0:(SRLconst [j-32] w) mem))
- // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVDstore [i-4] {s} ptr0 w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- if v_1.Op != OpARM64SRLconst {
- break
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- w0 := x.Args[1]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(ptr0, w0, mem)
- return true
- }
- // match: (MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx ptr1 idx1 w0:(SRLconst [j-32] w) mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVDstoreidx ptr1 idx1 w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 4 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- if v_1.Op != OpARM64SRLconst {
- continue
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstoreidx {
- continue
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVDstoreidx)
- v.AddArg4(ptr1, idx1, w0, mem)
- return true
- }
- break
- }
- // match: (MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx4 ptr1 idx1 w0:(SRLconst [j-32] w) mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w0 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 4 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- if v_1.Op != OpARM64SRLconst {
- break
- }
- j := auxIntToInt64(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstoreidx4 {
- break
- }
- mem := x.Args[3]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- w0 := x.Args[2]
- if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstoreidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(2)
- v0.AddArg(idx1)
- v.AddArg4(ptr1, v0, w0, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVWstoreidx(v *Value) bool {
@@ -15176,31 +12785,6 @@ func rewriteValueARM64_OpARM64MOVWstoreidx(v *Value) bool {
v.AddArg4(ptr, idx, x, mem)
return true
}
- // match: (MOVWstoreidx ptr (ADDconst [4] idx) (SRLconst [32] w) x:(MOVWstoreidx ptr idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDstoreidx ptr idx w mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 4 {
- break
- }
- idx := v_1.Args[0]
- if v_2.Op != OpARM64SRLconst || auxIntToInt64(v_2.AuxInt) != 32 {
- break
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpARM64MOVWstoreidx {
- break
- }
- mem := x.Args[3]
- if ptr != x.Args[0] || idx != x.Args[1] || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstoreidx)
- v.AddArg4(ptr, idx, w, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVWstoreidx4(v *Value) bool {
@@ -15356,95 +12940,6 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
v.AddArg3(ptr, idx, mem)
return true
}
- // match: (MOVWstorezero [i] {s} ptr0 x:(MOVWstorezero [j] {s} ptr1 mem))
- // cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),4) && isSamePtr(ptr0, ptr1) && clobber(x)
- // result: (MOVDstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- ptr0 := v_0
- x := v_1
- if x.Op != OpARM64MOVWstorezero {
- break
- }
- j := auxIntToInt32(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- ptr1 := x.Args[0]
- if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 4) && isSamePtr(ptr0, ptr1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstorezero)
- v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
- v.Aux = symToAux(s)
- v.AddArg2(ptr0, mem)
- return true
- }
- // match: (MOVWstorezero [4] {s} (ADD ptr0 idx0) x:(MOVWstorezeroidx ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
- // result: (MOVDstorezeroidx ptr1 idx1 mem)
- for {
- if auxIntToInt32(v.AuxInt) != 4 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADD {
- break
- }
- _ = v_0.Args[1]
- v_0_0 := v_0.Args[0]
- v_0_1 := v_0.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
- ptr0 := v_0_0
- idx0 := v_0_1
- x := v_1
- if x.Op != OpARM64MOVWstorezeroidx {
- continue
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
- continue
- }
- v.reset(OpARM64MOVDstorezeroidx)
- v.AddArg3(ptr1, idx1, mem)
- return true
- }
- break
- }
- // match: (MOVWstorezero [4] {s} (ADDshiftLL [2] ptr0 idx0) x:(MOVWstorezeroidx4 ptr1 idx1 mem))
- // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
- // result: (MOVDstorezeroidx ptr1 (SLLconst <idx1.Type> [2] idx1) mem)
- for {
- if auxIntToInt32(v.AuxInt) != 4 {
- break
- }
- s := auxToSym(v.Aux)
- if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
- break
- }
- idx0 := v_0.Args[1]
- ptr0 := v_0.Args[0]
- x := v_1
- if x.Op != OpARM64MOVWstorezeroidx4 {
- break
- }
- mem := x.Args[2]
- ptr1 := x.Args[0]
- idx1 := x.Args[1]
- if !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstorezeroidx)
- v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
- v0.AuxInt = int64ToAuxInt(2)
- v0.AddArg(idx1)
- v.AddArg3(ptr1, v0, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVWstorezeroidx(v *Value) bool {
@@ -15513,27 +13008,6 @@ func rewriteValueARM64_OpARM64MOVWstorezeroidx(v *Value) bool {
v.AddArg3(ptr, idx, mem)
return true
}
- // match: (MOVWstorezeroidx ptr (ADDconst [4] idx) x:(MOVWstorezeroidx ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDstorezeroidx ptr idx mem)
- for {
- ptr := v_0
- if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 4 {
- break
- }
- idx := v_1.Args[0]
- x := v_2
- if x.Op != OpARM64MOVWstorezeroidx {
- break
- }
- mem := x.Args[2]
- if ptr != x.Args[0] || idx != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpARM64MOVDstorezeroidx)
- v.AddArg3(ptr, idx, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64MOVWstorezeroidx4(v *Value) bool {
@@ -17529,7 +15003,6 @@ func rewriteValueARM64_OpARM64NotEqual(v *Value) bool {
func rewriteValueARM64_OpARM64OR(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
// match: (OR x (MOVDconst [c]))
// result: (ORconst [c] x)
for {
@@ -17709,1558 +15182,6 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
}
break
}
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [i3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i1] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i0] {s} p mem)))
- // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- s0 := o1.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload {
- continue
- }
- i3 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o1.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y2 := o0.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- continue
- }
- i1 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- continue
- }
- y3 := v_1
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload {
- continue
- }
- i0 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3)
- v0 := b.NewValue0(x3.Pos, OpARM64MOVWUload, t)
- v.copyOf(v0)
- v0.Aux = symToAux(s)
- v1 := b.NewValue0(x3.Pos, OpOffPtr, p.Type)
- v1.AuxInt = int64ToAuxInt(int64(i0))
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr0 idx0 mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- s0 := o1.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload || auxIntToInt32(x0.AuxInt) != 3 {
- continue
- }
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o1.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 2 || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y2 := o0.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 1 || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- p1 := x2.Args[0]
- if p1.Op != OpARM64ADD {
- continue
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x2.Args[1] {
- continue
- }
- y3 := v_1
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x3.Args[2]
- ptr0 := x3.Args[0]
- idx0 := x3.Args[1]
- if mem != x3.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3)
- v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr0, idx0, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr idx mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- s0 := o1.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- continue
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 3 {
- continue
- }
- idx := x0_1.Args[0]
- y1 := o1.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- continue
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 2 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- continue
- }
- y2 := o0.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- continue
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 1 || idx != x2_1.Args[0] || mem != x2.Args[2] {
- continue
- }
- y3 := v_1
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] || idx != x3.Args[1] || mem != x3.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3)
- v0 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [i7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i1] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [i0] {s} p mem)))
- // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
- continue
- }
- _ = o2.Args[1]
- o3 := o2.Args[0]
- if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
- continue
- }
- _ = o3.Args[1]
- o4 := o3.Args[0]
- if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
- continue
- }
- _ = o4.Args[1]
- o5 := o4.Args[0]
- if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
- continue
- }
- _ = o5.Args[1]
- s0 := o5.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload {
- continue
- }
- i7 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o5.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- continue
- }
- i6 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y2 := o4.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- continue
- }
- i5 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- continue
- }
- y3 := o3.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload {
- continue
- }
- i4 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- continue
- }
- y4 := o2.Args[1]
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload {
- continue
- }
- i3 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- y5 := o1.Args[1]
- if y5.Op != OpARM64MOVDnop {
- continue
- }
- x5 := y5.Args[0]
- if x5.Op != OpARM64MOVBUload {
- continue
- }
- i2 := auxIntToInt32(x5.AuxInt)
- if auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- y6 := o0.Args[1]
- if y6.Op != OpARM64MOVDnop {
- continue
- }
- x6 := y6.Args[0]
- if x6.Op != OpARM64MOVBUload {
- continue
- }
- i1 := auxIntToInt32(x6.AuxInt)
- if auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- if p != x6.Args[0] || mem != x6.Args[1] {
- continue
- }
- y7 := v_1
- if y7.Op != OpARM64MOVDnop {
- continue
- }
- x7 := y7.Args[0]
- if x7.Op != OpARM64MOVBUload {
- continue
- }
- i0 := auxIntToInt32(x7.AuxInt)
- if auxToSym(x7.Aux) != s {
- continue
- }
- _ = x7.Args[1]
- if p != x7.Args[0] || mem != x7.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(x7.Pos, OpARM64MOVDload, t)
- v.copyOf(v0)
- v0.Aux = symToAux(s)
- v1 := b.NewValue0(x7.Pos, OpOffPtr, p.Type)
- v1.AuxInt = int64ToAuxInt(int64(i0))
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr0 idx0 mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
- continue
- }
- _ = o2.Args[1]
- o3 := o2.Args[0]
- if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
- continue
- }
- _ = o3.Args[1]
- o4 := o3.Args[0]
- if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
- continue
- }
- _ = o4.Args[1]
- o5 := o4.Args[0]
- if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
- continue
- }
- _ = o5.Args[1]
- s0 := o5.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload || auxIntToInt32(x0.AuxInt) != 7 {
- continue
- }
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o5.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 6 || auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y2 := o4.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 5 || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- continue
- }
- y3 := o3.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 4 || auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- continue
- }
- y4 := o2.Args[1]
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 3 || auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- y5 := o1.Args[1]
- if y5.Op != OpARM64MOVDnop {
- continue
- }
- x5 := y5.Args[0]
- if x5.Op != OpARM64MOVBUload || auxIntToInt32(x5.AuxInt) != 2 || auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- y6 := o0.Args[1]
- if y6.Op != OpARM64MOVDnop {
- continue
- }
- x6 := y6.Args[0]
- if x6.Op != OpARM64MOVBUload || auxIntToInt32(x6.AuxInt) != 1 || auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- p1 := x6.Args[0]
- if p1.Op != OpARM64ADD {
- continue
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x6.Args[1] {
- continue
- }
- y7 := v_1
- if y7.Op != OpARM64MOVDnop {
- continue
- }
- x7 := y7.Args[0]
- if x7.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x7.Args[2]
- ptr0 := x7.Args[0]
- idx0 := x7.Args[1]
- if mem != x7.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr0, idx0, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [7] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr idx mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr idx mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
- continue
- }
- _ = o2.Args[1]
- o3 := o2.Args[0]
- if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
- continue
- }
- _ = o3.Args[1]
- o4 := o3.Args[0]
- if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
- continue
- }
- _ = o4.Args[1]
- o5 := o4.Args[0]
- if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
- continue
- }
- _ = o5.Args[1]
- s0 := o5.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- continue
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 7 {
- continue
- }
- idx := x0_1.Args[0]
- y1 := o5.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- continue
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 6 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- continue
- }
- y2 := o4.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- continue
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 5 || idx != x2_1.Args[0] || mem != x2.Args[2] {
- continue
- }
- y3 := o3.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] {
- continue
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 4 || idx != x3_1.Args[0] || mem != x3.Args[2] {
- continue
- }
- y4 := o2.Args[1]
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x4.Args[2]
- if ptr != x4.Args[0] {
- continue
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpARM64ADDconst || auxIntToInt64(x4_1.AuxInt) != 3 || idx != x4_1.Args[0] || mem != x4.Args[2] {
- continue
- }
- y5 := o1.Args[1]
- if y5.Op != OpARM64MOVDnop {
- continue
- }
- x5 := y5.Args[0]
- if x5.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x5.Args[2]
- if ptr != x5.Args[0] {
- continue
- }
- x5_1 := x5.Args[1]
- if x5_1.Op != OpARM64ADDconst || auxIntToInt64(x5_1.AuxInt) != 2 || idx != x5_1.Args[0] || mem != x5.Args[2] {
- continue
- }
- y6 := o0.Args[1]
- if y6.Op != OpARM64MOVDnop {
- continue
- }
- x6 := y6.Args[0]
- if x6.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x6.Args[2]
- if ptr != x6.Args[0] {
- continue
- }
- x6_1 := x6.Args[1]
- if x6_1.Op != OpARM64ADDconst || auxIntToInt64(x6_1.AuxInt) != 1 || idx != x6_1.Args[0] || mem != x6.Args[2] {
- continue
- }
- y7 := v_1
- if y7.Op != OpARM64MOVDnop {
- continue
- }
- x7 := y7.Args[0]
- if x7.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x7.Args[2]
- if ptr != x7.Args[0] || idx != x7.Args[1] || mem != x7.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
- // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- // result: @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- s0 := o1.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o1.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y2 := o0.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- continue
- }
- i2 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- continue
- }
- y3 := v_1
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload {
- continue
- }
- i3 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3)
- v0 := b.NewValue0(x3.Pos, OpARM64REVW, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x3.Pos, OpARM64MOVWUload, t)
- v1.Aux = symToAux(s)
- v2 := b.NewValue0(x3.Pos, OpOffPtr, p.Type)
- v2.AuxInt = int64ToAuxInt(int64(i0))
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- // result: @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- s0 := o1.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- continue
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := o1.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 {
- continue
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- continue
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x1.Args[1] {
- continue
- }
- y2 := o0.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 2 || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- p := x2.Args[0]
- if mem != x2.Args[1] {
- continue
- }
- y3 := v_1
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 3 || auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3)
- v0 := b.NewValue0(x3.Pos, OpARM64REVW, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x3.Pos, OpARM64MOVWUloadidx, t)
- v1.AddArg3(ptr0, idx0, mem)
- v0.AddArg(v1)
- return true
- }
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
- // result: @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- s0 := o1.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- continue
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- idx := x0.Args[1]
- y1 := o1.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- continue
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- continue
- }
- y2 := o0.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- continue
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] {
- continue
- }
- y3 := v_1
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] {
- continue
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 3 || idx != x3_1.Args[0] || mem != x3.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3)
- v0 := b.NewValue0(v.Pos, OpARM64REVW, t)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
- v1.AddArg3(ptr, idx, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [i7] {s} p mem)))
- // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
- continue
- }
- _ = o2.Args[1]
- o3 := o2.Args[0]
- if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
- continue
- }
- _ = o3.Args[1]
- o4 := o3.Args[0]
- if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
- continue
- }
- _ = o4.Args[1]
- o5 := o4.Args[0]
- if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
- continue
- }
- _ = o5.Args[1]
- s0 := o5.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o5.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y2 := o4.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- continue
- }
- i2 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- continue
- }
- y3 := o3.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload {
- continue
- }
- i3 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- continue
- }
- y4 := o2.Args[1]
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload {
- continue
- }
- i4 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- y5 := o1.Args[1]
- if y5.Op != OpARM64MOVDnop {
- continue
- }
- x5 := y5.Args[0]
- if x5.Op != OpARM64MOVBUload {
- continue
- }
- i5 := auxIntToInt32(x5.AuxInt)
- if auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- y6 := o0.Args[1]
- if y6.Op != OpARM64MOVDnop {
- continue
- }
- x6 := y6.Args[0]
- if x6.Op != OpARM64MOVBUload {
- continue
- }
- i6 := auxIntToInt32(x6.AuxInt)
- if auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- if p != x6.Args[0] || mem != x6.Args[1] {
- continue
- }
- y7 := v_1
- if y7.Op != OpARM64MOVDnop {
- continue
- }
- x7 := y7.Args[0]
- if x7.Op != OpARM64MOVBUload {
- continue
- }
- i7 := auxIntToInt32(x7.AuxInt)
- if auxToSym(x7.Aux) != s {
- continue
- }
- _ = x7.Args[1]
- if p != x7.Args[0] || mem != x7.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(x7.Pos, OpARM64REV, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x7.Pos, OpARM64MOVDload, t)
- v1.Aux = symToAux(s)
- v2 := b.NewValue0(x7.Pos, OpOffPtr, p.Type)
- v2.AuxInt = int64ToAuxInt(int64(i0))
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
- continue
- }
- _ = o2.Args[1]
- o3 := o2.Args[0]
- if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
- continue
- }
- _ = o3.Args[1]
- o4 := o3.Args[0]
- if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
- continue
- }
- _ = o4.Args[1]
- o5 := o4.Args[0]
- if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
- continue
- }
- _ = o5.Args[1]
- s0 := o5.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- continue
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := o5.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 {
- continue
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- continue
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x1.Args[1] {
- continue
- }
- y2 := o4.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 2 || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- p := x2.Args[0]
- if mem != x2.Args[1] {
- continue
- }
- y3 := o3.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 3 || auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- continue
- }
- y4 := o2.Args[1]
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 4 || auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- y5 := o1.Args[1]
- if y5.Op != OpARM64MOVDnop {
- continue
- }
- x5 := y5.Args[0]
- if x5.Op != OpARM64MOVBUload || auxIntToInt32(x5.AuxInt) != 5 || auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- y6 := o0.Args[1]
- if y6.Op != OpARM64MOVDnop {
- continue
- }
- x6 := y6.Args[0]
- if x6.Op != OpARM64MOVBUload || auxIntToInt32(x6.AuxInt) != 6 || auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- if p != x6.Args[0] || mem != x6.Args[1] {
- continue
- }
- y7 := v_1
- if y7.Op != OpARM64MOVDnop {
- continue
- }
- x7 := y7.Args[0]
- if x7.Op != OpARM64MOVBUload || auxIntToInt32(x7.AuxInt) != 7 || auxToSym(x7.Aux) != s {
- continue
- }
- _ = x7.Args[1]
- if p != x7.Args[0] || mem != x7.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(x7.Pos, OpARM64REV, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x7.Pos, OpARM64MOVDloadidx, t)
- v1.AddArg3(ptr0, idx0, mem)
- v0.AddArg(v1)
- return true
- }
- }
- break
- }
- // match: (OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
- // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr idx mem))
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
- continue
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
- continue
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
- continue
- }
- _ = o2.Args[1]
- o3 := o2.Args[0]
- if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
- continue
- }
- _ = o3.Args[1]
- o4 := o3.Args[0]
- if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
- continue
- }
- _ = o4.Args[1]
- o5 := o4.Args[0]
- if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
- continue
- }
- _ = o5.Args[1]
- s0 := o5.Args[0]
- if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- y0 := s0.Args[0]
- if y0.Op != OpARM64MOVDnop {
- continue
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- continue
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- idx := x0.Args[1]
- y1 := o5.Args[1]
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- continue
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- continue
- }
- y2 := o4.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- continue
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] {
- continue
- }
- y3 := o3.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] {
- continue
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 3 || idx != x3_1.Args[0] || mem != x3.Args[2] {
- continue
- }
- y4 := o2.Args[1]
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x4.Args[2]
- if ptr != x4.Args[0] {
- continue
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpARM64ADDconst || auxIntToInt64(x4_1.AuxInt) != 4 || idx != x4_1.Args[0] || mem != x4.Args[2] {
- continue
- }
- y5 := o1.Args[1]
- if y5.Op != OpARM64MOVDnop {
- continue
- }
- x5 := y5.Args[0]
- if x5.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x5.Args[2]
- if ptr != x5.Args[0] {
- continue
- }
- x5_1 := x5.Args[1]
- if x5_1.Op != OpARM64ADDconst || auxIntToInt64(x5_1.AuxInt) != 5 || idx != x5_1.Args[0] || mem != x5.Args[2] {
- continue
- }
- y6 := o0.Args[1]
- if y6.Op != OpARM64MOVDnop {
- continue
- }
- x6 := y6.Args[0]
- if x6.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x6.Args[2]
- if ptr != x6.Args[0] {
- continue
- }
- x6_1 := x6.Args[1]
- if x6_1.Op != OpARM64ADDconst || auxIntToInt64(x6_1.AuxInt) != 6 || idx != x6_1.Args[0] || mem != x6.Args[2] {
- continue
- }
- y7 := v_1
- if y7.Op != OpARM64MOVDnop {
- continue
- }
- x7 := y7.Args[0]
- if x7.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x7.Args[2]
- if ptr != x7.Args[0] {
- continue
- }
- x7_1 := x7.Args[1]
- if x7_1.Op != OpARM64ADDconst || auxIntToInt64(x7_1.AuxInt) != 7 || idx != x7_1.Args[0] || mem != x7.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(v.Pos, OpARM64REV, t)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
- v1.AddArg3(ptr, idx, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
return false
}
func rewriteValueARM64_OpARM64ORN(v *Value) bool {
@@ -19768,1452 +15689,6 @@ func rewriteValueARM64_OpARM64ORshiftLL(v *Value) bool {
v.AddArg2(y, x)
return true
}
- // match: (ORshiftLL <t> [8] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
- // result: @mergePoint(b,x0,x1) (MOVHUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 8 {
- break
- }
- y0 := v_0
- if y0.Op != OpARM64MOVDnop {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := v_1
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- break
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
- break
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpARM64MOVHUload, t)
- v.copyOf(v0)
- v0.Aux = symToAux(s)
- v1 := b.NewValue0(x1.Pos, OpOffPtr, p.Type)
- v1.AuxInt = int64ToAuxInt(int64(i0))
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- // match: (ORshiftLL <t> [8] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)
- // result: @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr0 idx0 mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 8 {
- break
- }
- y0 := v_0
- if y0.Op != OpARM64MOVDnop {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := v_1
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 {
- break
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x1.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpARM64MOVHUloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr0, idx0, mem)
- return true
- }
- break
- }
- // match: (ORshiftLL <t> [8] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
- // result: @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr idx mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 8 {
- break
- }
- y0 := v_0
- if y0.Op != OpARM64MOVDnop {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- idx := x0.Args[1]
- y1 := v_1
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
- break
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpARM64MOVHUloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] x0:(MOVHUload [i0] {s} p mem) y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i3] {s} p mem)))
- // cond: i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- x0 := o0.Args[0]
- if x0.Op != OpARM64MOVHUload {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- break
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- break
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- break
- }
- i3 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] || !(i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y1, y2, o0)) {
- break
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, OpARM64MOVWUload, t)
- v.copyOf(v0)
- v0.Aux = symToAux(s)
- v1 := b.NewValue0(x2.Pos, OpOffPtr, p.Type)
- v1.AuxInt = int64ToAuxInt(int64(i0))
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 idx0 mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- x0 := o0.Args[0]
- if x0.Op != OpARM64MOVHUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 2 {
- break
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x1.Args[1] {
- continue
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 3 || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- p := x2.Args[0]
- if mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr0, idx0, mem)
- return true
- }
- break
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx ptr idx mem) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr idx mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- x0 := o0.Args[0]
- if x0.Op != OpARM64MOVHUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- idx := x0.Args[1]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 2 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- break
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 3 || idx != x2_1.Args[0] || mem != x2.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y1, y2, o0)) {
- break
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx2 ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADDshiftLL [1] ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 (SLLconst <idx0.Type> [1] idx0) mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- x0 := o0.Args[0]
- if x0.Op != OpARM64MOVHUloadidx2 {
- break
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 2 {
- break
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADDshiftLL || auxIntToInt64(p1.AuxInt) != 1 {
- break
- }
- idx1 := p1.Args[1]
- ptr1 := p1.Args[0]
- if mem != x1.Args[1] {
- break
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 3 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- p := x2.Args[0]
- if mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)) {
- break
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x2.Pos, OpARM64SLLconst, idx0.Type)
- v1.AuxInt = int64ToAuxInt(1)
- v1.AddArg(idx0)
- v0.AddArg3(ptr0, v1, mem)
- return true
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUload [i0] {s} p mem) y1:(MOVDnop x1:(MOVBUload [i4] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i7] {s} p mem)))
- // cond: i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- x0 := o2.Args[0]
- if x0.Op != OpARM64MOVWUload {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- break
- }
- i4 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- break
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- break
- }
- i5 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- break
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- break
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload {
- break
- }
- i6 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- break
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- break
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload {
- break
- }
- i7 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] || !(i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
- break
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(x4.Pos, OpARM64MOVDload, t)
- v.copyOf(v0)
- v0.Aux = symToAux(s)
- v1 := b.NewValue0(x4.Pos, OpOffPtr, p.Type)
- v1.AuxInt = int64ToAuxInt(int64(i0))
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 idx0 mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- x0 := o2.Args[0]
- if x0.Op != OpARM64MOVWUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 4 {
- break
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x1.Args[1] {
- continue
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 5 || auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- p := x2.Args[0]
- if mem != x2.Args[1] {
- continue
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- continue
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 6 || auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- continue
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 7 || auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(x4.Pos, OpARM64MOVDloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr0, idx0, mem)
- return true
- }
- break
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx4 ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADDshiftLL [2] ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 (SLLconst <idx0.Type> [2] idx0) mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- x0 := o2.Args[0]
- if x0.Op != OpARM64MOVWUloadidx4 {
- break
- }
- mem := x0.Args[2]
- ptr0 := x0.Args[0]
- idx0 := x0.Args[1]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 4 {
- break
- }
- s := auxToSym(x1.Aux)
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADDshiftLL || auxIntToInt64(p1.AuxInt) != 2 {
- break
- }
- idx1 := p1.Args[1]
- ptr1 := p1.Args[0]
- if mem != x1.Args[1] {
- break
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 5 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- p := x2.Args[0]
- if mem != x2.Args[1] {
- break
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- break
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 6 || auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- break
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- break
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 7 || auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
- break
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(x4.Pos, OpARM64MOVDloadidx, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x4.Pos, OpARM64SLLconst, idx0.Type)
- v1.AuxInt = int64ToAuxInt(2)
- v1.AddArg(idx0)
- v0.AddArg3(ptr0, v1, mem)
- return true
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr idx mem) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr idx mem)
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- x0 := o2.Args[0]
- if x0.Op != OpARM64MOVWUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- idx := x0.Args[1]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 4 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- break
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 5 || idx != x2_1.Args[0] || mem != x2.Args[2] {
- break
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- break
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] {
- break
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 6 || idx != x3_1.Args[0] || mem != x3.Args[2] {
- break
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- break
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x4.Args[2]
- if ptr != x4.Args[0] {
- break
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpARM64ADDconst || auxIntToInt64(x4_1.AuxInt) != 7 || idx != x4_1.Args[0] || mem != x4.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
- break
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
- v.copyOf(v0)
- v0.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (ORshiftLL <t> [8] y0:(MOVDnop x0:(MOVBUload [i1] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i0] {s} p mem)))
- // cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
- // result: @mergePoint(b,x0,x1) (REV16W <t> (MOVHUload <t> [i0] {s} p mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 8 {
- break
- }
- y0 := v_0
- if y0.Op != OpARM64MOVDnop {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload {
- break
- }
- i1 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := v_1
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- break
- }
- i0 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
- break
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpARM64REV16W, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpARM64MOVHUload, t)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- // match: (ORshiftLL <t> [8] y0:(MOVDnop x0:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr0 idx0 mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)
- // result: @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr0 idx0 mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 8 {
- break
- }
- y0 := v_0
- if y0.Op != OpARM64MOVDnop {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUload || auxIntToInt32(x0.AuxInt) != 1 {
- break
- }
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p1 := x0.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- y1 := v_1
- if y1.Op != OpARM64MOVDnop {
- continue
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x1.Args[2]
- ptr0 := x1.Args[0]
- idx0 := x1.Args[1]
- if mem != x1.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpARM64REV16W, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpARM64MOVHUloadidx, t)
- v1.AddArg3(ptr0, idx0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORshiftLL <t> [8] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [1] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr idx mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
- // result: @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr idx mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 8 {
- break
- }
- y0 := v_0
- if y0.Op != OpARM64MOVDnop {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVBUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 1 {
- break
- }
- idx := x0_1.Args[0]
- y1 := v_1
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] || idx != x1.Args[1] || mem != x1.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
- break
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpARM64REV16W, t)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpARM64MOVHUloadidx, t)
- v1.AddArg3(ptr, idx, mem)
- v0.AddArg(v1)
- return true
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUload [i2] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i0] {s} p mem)))
- // cond: i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- y0 := o0.Args[0]
- if y0.Op != OpARM64REV16W {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVHUload {
- break
- }
- i2 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- break
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- break
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- break
- }
- i0 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] || !(i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)) {
- break
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, OpARM64REVW, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x2.Pos, OpARM64MOVWUload, t)
- v1.Aux = symToAux(s)
- v2 := b.NewValue0(x2.Pos, OpOffPtr, p.Type)
- v2.AuxInt = int64ToAuxInt(int64(i0))
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUload [2] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr0 idx0 mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y0, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- y0 := o0.Args[0]
- if y0.Op != OpARM64REV16W {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVHUload || auxIntToInt32(x0.AuxInt) != 2 {
- break
- }
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- p1 := x1.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x1.Args[1] {
- continue
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- continue
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x2.Args[2]
- ptr0 := x2.Args[0]
- idx0 := x2.Args[1]
- if mem != x2.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y0, y1, y2, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x1.Pos, OpARM64REVW, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpARM64MOVWUloadidx, t)
- v1.AddArg3(ptr0, idx0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORshiftLL <t> [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUloadidx ptr (ADDconst [2] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr idx mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)
- // result: @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 24 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
- break
- }
- _ = o0.Args[1]
- y0 := o0.Args[0]
- if y0.Op != OpARM64REV16W {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVHUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 2 {
- break
- }
- idx := x0_1.Args[0]
- y1 := o0.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- break
- }
- y2 := v_1
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] || idx != x2.Args[1] || mem != x2.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)) {
- break
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(v.Pos, OpARM64REVW, t)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
- v1.AddArg3(ptr, idx, mem)
- v0.AddArg(v1)
- return true
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] y0:(REVW x0:(MOVWUload [i4] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i3] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i1] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i0] {s} p mem)))
- // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- y0 := o2.Args[0]
- if y0.Op != OpARM64REVW {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVWUload {
- break
- }
- i4 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload {
- break
- }
- i3 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- break
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload {
- break
- }
- i2 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- break
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- break
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload {
- break
- }
- i1 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- break
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- break
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUload {
- break
- }
- i0 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)) {
- break
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(x4.Pos, OpARM64REV, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x4.Pos, OpARM64MOVDload, t)
- v1.Aux = symToAux(s)
- v2 := b.NewValue0(x4.Pos, OpOffPtr, p.Type)
- v2.AuxInt = int64ToAuxInt(int64(i0))
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] y0:(REVW x0:(MOVWUload [4] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [3] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr0 idx0 mem)))
- // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- y0 := o2.Args[0]
- if y0.Op != OpARM64REVW {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVWUload || auxIntToInt32(x0.AuxInt) != 4 {
- break
- }
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 3 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- break
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 2 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- break
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- break
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 1 || auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[1]
- p1 := x3.Args[0]
- if p1.Op != OpARM64ADD {
- break
- }
- _ = p1.Args[1]
- p1_0 := p1.Args[0]
- p1_1 := p1.Args[1]
- for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
- ptr1 := p1_0
- idx1 := p1_1
- if mem != x3.Args[1] {
- continue
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- continue
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUloadidx {
- continue
- }
- _ = x4.Args[2]
- ptr0 := x4.Args[0]
- idx0 := x4.Args[1]
- if mem != x4.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(x3.Pos, OpARM64REV, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x3.Pos, OpARM64MOVDloadidx, t)
- v1.AddArg3(ptr0, idx0, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] y0:(REVW x0:(MOVWUloadidx ptr (ADDconst [4] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr idx mem)))
- // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr idx mem))
- for {
- t := v.Type
- if auxIntToInt64(v.AuxInt) != 56 {
- break
- }
- o0 := v_0
- if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
- break
- }
- _ = o0.Args[1]
- o1 := o0.Args[0]
- if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
- break
- }
- _ = o1.Args[1]
- o2 := o1.Args[0]
- if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
- break
- }
- _ = o2.Args[1]
- y0 := o2.Args[0]
- if y0.Op != OpARM64REVW {
- break
- }
- x0 := y0.Args[0]
- if x0.Op != OpARM64MOVWUloadidx {
- break
- }
- mem := x0.Args[2]
- ptr := x0.Args[0]
- x0_1 := x0.Args[1]
- if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 4 {
- break
- }
- idx := x0_1.Args[0]
- y1 := o2.Args[1]
- if y1.Op != OpARM64MOVDnop {
- break
- }
- x1 := y1.Args[0]
- if x1.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x1.Args[2]
- if ptr != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 3 || idx != x1_1.Args[0] || mem != x1.Args[2] {
- break
- }
- y2 := o1.Args[1]
- if y2.Op != OpARM64MOVDnop {
- break
- }
- x2 := y2.Args[0]
- if x2.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x2.Args[2]
- if ptr != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] {
- break
- }
- y3 := o0.Args[1]
- if y3.Op != OpARM64MOVDnop {
- break
- }
- x3 := y3.Args[0]
- if x3.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x3.Args[2]
- if ptr != x3.Args[0] {
- break
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 1 || idx != x3_1.Args[0] || mem != x3.Args[2] {
- break
- }
- y4 := v_1
- if y4.Op != OpARM64MOVDnop {
- break
- }
- x4 := y4.Args[0]
- if x4.Op != OpARM64MOVBUloadidx {
- break
- }
- _ = x4.Args[2]
- if ptr != x4.Args[0] || idx != x4.Args[1] || mem != x4.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)) {
- break
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(v.Pos, OpARM64REV, t)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
- v1.AddArg3(ptr, idx, mem)
- v0.AddArg(v1)
- return true
- }
return false
}
func rewriteValueARM64_OpARM64ORshiftRA(v *Value) bool {
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index c9930516bc..b5e3901f9f 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -445,6 +445,12 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpPPC64ANDCCconst(v)
case OpPPC64ANDN:
return rewriteValuePPC64_OpPPC64ANDN(v)
+ case OpPPC64BRD:
+ return rewriteValuePPC64_OpPPC64BRD(v)
+ case OpPPC64BRH:
+ return rewriteValuePPC64_OpPPC64BRH(v)
+ case OpPPC64BRW:
+ return rewriteValuePPC64_OpPPC64BRW(v)
case OpPPC64CLRLSLDI:
return rewriteValuePPC64_OpPPC64CLRLSLDI(v)
case OpPPC64CMP:
@@ -1134,6 +1140,8 @@ func rewriteValuePPC64_OpBitLen64(v *Value) bool {
}
func rewriteValuePPC64_OpBswap16(v *Value) bool {
v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
// match: (Bswap16 x)
// cond: buildcfg.GOPPC64>=10
// result: (BRH x)
@@ -1146,10 +1154,51 @@ func rewriteValuePPC64_OpBswap16(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (Bswap16 x:(MOVHZload [off] {sym} ptr mem))
+ // result: @x.Block (MOVHBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVHZload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpPPC64MOVHBRload, typ.UInt16)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg(ptr)
+ v0.AddArg2(v1, mem)
+ return true
+ }
+ // match: (Bswap16 x:(MOVHZloadidx ptr idx mem))
+ // result: @x.Block (MOVHZreg (MOVHBRloadidx ptr idx mem))
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVHZloadidx {
+ break
+ }
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVHZreg, typ.Int64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(v.Pos, OpPPC64MOVHBRloadidx, typ.Int16)
+ v1.AddArg3(ptr, idx, mem)
+ v0.AddArg(v1)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpBswap32(v *Value) bool {
v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
// match: (Bswap32 x)
// cond: buildcfg.GOPPC64>=10
// result: (BRW x)
@@ -1162,10 +1211,51 @@ func rewriteValuePPC64_OpBswap32(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (Bswap32 x:(MOVWZload [off] {sym} ptr mem))
+ // result: @x.Block (MOVWBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVWZload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpPPC64MOVWBRload, typ.UInt32)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg(ptr)
+ v0.AddArg2(v1, mem)
+ return true
+ }
+ // match: (Bswap32 x:(MOVWZloadidx ptr idx mem))
+ // result: @x.Block (MOVWZreg (MOVWBRloadidx ptr idx mem))
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVWZloadidx {
+ break
+ }
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVWZreg, typ.Int64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(v.Pos, OpPPC64MOVWBRloadidx, typ.Int32)
+ v1.AddArg3(ptr, idx, mem)
+ v0.AddArg(v1)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpBswap64(v *Value) bool {
v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
// match: (Bswap64 x)
// cond: buildcfg.GOPPC64>=10
// result: (BRD x)
@@ -1178,6 +1268,43 @@ func rewriteValuePPC64_OpBswap64(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (Bswap64 x:(MOVDload [off] {sym} ptr mem))
+ // result: @x.Block (MOVDBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVDload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpPPC64MOVDBRload, typ.UInt64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg(ptr)
+ v0.AddArg2(v1, mem)
+ return true
+ }
+ // match: (Bswap64 x:(MOVDloadidx ptr idx mem))
+ // result: @x.Block (MOVDBRloadidx ptr idx mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVDloadidx {
+ break
+ }
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDBRloadidx, typ.Int64)
+ v.copyOf(v0)
+ v0.AddArg3(ptr, idx, mem)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpCom16(v *Value) bool {
@@ -4222,6 +4349,163 @@ func rewriteValuePPC64_OpPPC64ANDN(v *Value) bool {
}
return false
}
+func rewriteValuePPC64_OpPPC64BRD(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (BRD x:(MOVDload [off] {sym} ptr mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVDBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVDload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpPPC64MOVDBRload, typ.UInt64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg(ptr)
+ v0.AddArg2(v1, mem)
+ return true
+ }
+ // match: (BRD x:(MOVDloadidx ptr idx mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVDBRloadidx ptr idx mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVDloadidx {
+ break
+ }
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDBRloadidx, typ.Int64)
+ v.copyOf(v0)
+ v0.AddArg3(ptr, idx, mem)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpPPC64BRH(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (BRH x:(MOVHZload [off] {sym} ptr mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVHBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVHZload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpPPC64MOVHBRload, typ.UInt16)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg(ptr)
+ v0.AddArg2(v1, mem)
+ return true
+ }
+ // match: (BRH x:(MOVHZloadidx ptr idx mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVHZreg (MOVHBRloadidx ptr idx mem))
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVHZloadidx {
+ break
+ }
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVHZreg, typ.Int64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(v.Pos, OpPPC64MOVHBRloadidx, typ.Int16)
+ v1.AddArg3(ptr, idx, mem)
+ v0.AddArg(v1)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpPPC64BRW(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (BRW x:(MOVWZload [off] {sym} ptr mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVWBRload (MOVDaddr <ptr.Type> [off] {sym} ptr) mem)
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVWZload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpPPC64MOVWBRload, typ.UInt32)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg(ptr)
+ v0.AddArg2(v1, mem)
+ return true
+ }
+ // match: (BRW x:(MOVWZloadidx ptr idx mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVWZreg (MOVWBRloadidx ptr idx mem))
+ for {
+ x := v_0
+ if x.Op != OpPPC64MOVWZloadidx {
+ break
+ }
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVWZreg, typ.Int64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(v.Pos, OpPPC64MOVWBRloadidx, typ.Int32)
+ v1.AddArg3(ptr, idx, mem)
+ v0.AddArg(v1)
+ return true
+ }
+ return false
+}
func rewriteValuePPC64_OpPPC64CLRLSLDI(v *Value) bool {
v_0 := v.Args[0]
// match: (CLRLSLDI [c] (SRWconst [s] x))
@@ -6891,7 +7175,6 @@ func rewriteValuePPC64_OpPPC64MOVBstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
- config := b.Func.Config
typ := &b.Func.Config.Types
// match: (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(int64(off1)+off2)
@@ -7196,437 +7479,6 @@ func rewriteValuePPC64_OpPPC64MOVBstore(v *Value) bool {
v.AddArg3(ptr, v0, mem)
return true
}
- // match: (MOVBstore [i1] {s} p (SRWconst w [24]) x0:(MOVBstore [i0] {s} p (SRWconst w [16]) mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)
- // result: (MOVHstore [i0] {s} p (SRWconst <typ.UInt16> w [16]) mem)
- for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRWconst || auxIntToInt64(v_1.AuxInt) != 24 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpPPC64SRWconst || auxIntToInt64(x0_1.AuxInt) != 16 || w != x0_1.Args[0] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)) {
- break
- }
- v.reset(OpPPC64MOVHstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpPPC64SRWconst, typ.UInt16)
- v0.AuxInt = int64ToAuxInt(16)
- v0.AddArg(w)
- v.AddArg3(p, v0, mem)
- return true
- }
- // match: (MOVBstore [i1] {s} p (SRDconst w [24]) x0:(MOVBstore [i0] {s} p (SRDconst w [16]) mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)
- // result: (MOVHstore [i0] {s} p (SRWconst <typ.UInt16> w [16]) mem)
- for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRDconst || auxIntToInt64(v_1.AuxInt) != 24 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpPPC64SRDconst || auxIntToInt64(x0_1.AuxInt) != 16 || w != x0_1.Args[0] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)) {
- break
- }
- v.reset(OpPPC64MOVHstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x0.Pos, OpPPC64SRWconst, typ.UInt16)
- v0.AuxInt = int64ToAuxInt(16)
- v0.AddArg(w)
- v.AddArg3(p, v0, mem)
- return true
- }
- // match: (MOVBstore [i1] {s} p (SRWconst w [8]) x0:(MOVBstore [i0] {s} p w mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)
- // result: (MOVHstore [i0] {s} p w mem)
- for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRWconst || auxIntToInt64(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] || w != x0.Args[1] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)) {
- break
- }
- v.reset(OpPPC64MOVHstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i1] {s} p (SRDconst w [8]) x0:(MOVBstore [i0] {s} p w mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)
- // result: (MOVHstore [i0] {s} p w mem)
- for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRDconst || auxIntToInt64(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] || w != x0.Args[1] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)) {
- break
- }
- v.reset(OpPPC64MOVHstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i3] {s} p w x0:(MOVBstore [i2] {s} p (SRWconst w [8]) x1:(MOVBstore [i1] {s} p (SRWconst w [16]) x2:(MOVBstore [i0] {s} p (SRWconst w [24]) mem))))
- // cond: !config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && clobber(x0, x1, x2)
- // result: (MOVWBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
- for {
- i3 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i2 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpPPC64SRWconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpPPC64MOVBstore {
- break
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpPPC64SRWconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- mem := x2.Args[2]
- if p != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpPPC64SRWconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] || !(!config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && clobber(x0, x1, x2)) {
- break
- }
- v.reset(OpPPC64MOVWBRstore)
- v0 := b.NewValue0(x2.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg(p)
- v.AddArg3(v0, w, mem)
- return true
- }
- // match: (MOVBstore [i1] {s} p w x0:(MOVBstore [i0] {s} p (SRWconst w [8]) mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)
- // result: (MOVHBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
- for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpPPC64SRWconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)) {
- break
- }
- v.reset(OpPPC64MOVHBRstore)
- v0 := b.NewValue0(x0.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg(p)
- v.AddArg3(v0, w, mem)
- return true
- }
- // match: (MOVBstore [i7] {s} p (SRDconst w [56]) x0:(MOVBstore [i6] {s} p (SRDconst w [48]) x1:(MOVBstore [i5] {s} p (SRDconst w [40]) x2:(MOVBstore [i4] {s} p (SRDconst w [32]) x3:(MOVWstore [i0] {s} p w mem)))))
- // cond: !config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3)
- // result: (MOVDstore [i0] {s} p w mem)
- for {
- i7 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRDconst || auxIntToInt64(v_1.AuxInt) != 56 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i6 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpPPC64SRDconst || auxIntToInt64(x0_1.AuxInt) != 48 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpPPC64MOVBstore {
- break
- }
- i5 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpPPC64SRDconst || auxIntToInt64(x1_1.AuxInt) != 40 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpPPC64MOVBstore {
- break
- }
- i4 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if p != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpPPC64SRDconst || auxIntToInt64(x2_1.AuxInt) != 32 || w != x2_1.Args[0] {
- break
- }
- x3 := x2.Args[2]
- if x3.Op != OpPPC64MOVWstore {
- break
- }
- i0 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- break
- }
- mem := x3.Args[2]
- if p != x3.Args[0] || w != x3.Args[1] || !(!config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3)) {
- break
- }
- v.reset(OpPPC64MOVDstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i7] {s} p w x0:(MOVBstore [i6] {s} p (SRDconst w [8]) x1:(MOVBstore [i5] {s} p (SRDconst w [16]) x2:(MOVBstore [i4] {s} p (SRDconst w [24]) x3:(MOVBstore [i3] {s} p (SRDconst w [32]) x4:(MOVBstore [i2] {s} p (SRDconst w [40]) x5:(MOVBstore [i1] {s} p (SRDconst w [48]) x6:(MOVBstore [i0] {s} p (SRDconst w [56]) mem))))))))
- // cond: !config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3, x4, x5, x6)
- // result: (MOVDBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
- for {
- i7 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x0 := v_2
- if x0.Op != OpPPC64MOVBstore {
- break
- }
- i6 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- _ = x0.Args[2]
- if p != x0.Args[0] {
- break
- }
- x0_1 := x0.Args[1]
- if x0_1.Op != OpPPC64SRDconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
- break
- }
- x1 := x0.Args[2]
- if x1.Op != OpPPC64MOVBstore {
- break
- }
- i5 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpPPC64SRDconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpPPC64MOVBstore {
- break
- }
- i4 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if p != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpPPC64SRDconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] {
- break
- }
- x3 := x2.Args[2]
- if x3.Op != OpPPC64MOVBstore {
- break
- }
- i3 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- break
- }
- _ = x3.Args[2]
- if p != x3.Args[0] {
- break
- }
- x3_1 := x3.Args[1]
- if x3_1.Op != OpPPC64SRDconst || auxIntToInt64(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
- break
- }
- x4 := x3.Args[2]
- if x4.Op != OpPPC64MOVBstore {
- break
- }
- i2 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- break
- }
- _ = x4.Args[2]
- if p != x4.Args[0] {
- break
- }
- x4_1 := x4.Args[1]
- if x4_1.Op != OpPPC64SRDconst || auxIntToInt64(x4_1.AuxInt) != 40 || w != x4_1.Args[0] {
- break
- }
- x5 := x4.Args[2]
- if x5.Op != OpPPC64MOVBstore {
- break
- }
- i1 := auxIntToInt32(x5.AuxInt)
- if auxToSym(x5.Aux) != s {
- break
- }
- _ = x5.Args[2]
- if p != x5.Args[0] {
- break
- }
- x5_1 := x5.Args[1]
- if x5_1.Op != OpPPC64SRDconst || auxIntToInt64(x5_1.AuxInt) != 48 || w != x5_1.Args[0] {
- break
- }
- x6 := x5.Args[2]
- if x6.Op != OpPPC64MOVBstore {
- break
- }
- i0 := auxIntToInt32(x6.AuxInt)
- if auxToSym(x6.Aux) != s {
- break
- }
- mem := x6.Args[2]
- if p != x6.Args[0] {
- break
- }
- x6_1 := x6.Args[1]
- if x6_1.Op != OpPPC64SRDconst || auxIntToInt64(x6_1.AuxInt) != 56 || w != x6_1.Args[0] || !(!config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3, x4, x5, x6)) {
- break
- }
- v.reset(OpPPC64MOVDBRstore)
- v0 := b.NewValue0(x6.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg(p)
- v.AddArg3(v0, w, mem)
- return true
- }
return false
}
func rewriteValuePPC64_OpPPC64MOVBstoreidx(v *Value) bool {
@@ -8047,6 +7899,7 @@ func rewriteValuePPC64_OpPPC64MOVDstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
+ b := v.Block
// match: (MOVDstore [off] {sym} ptr (MFVSRD x) mem)
// result: (FMOVDstore [off] {sym} ptr x mem)
for {
@@ -8149,6 +8002,49 @@ func rewriteValuePPC64_OpPPC64MOVDstore(v *Value) bool {
v.AddArg4(ptr, idx, val, mem)
return true
}
+ // match: (MOVDstore [off] {sym} ptr r:(BRD val) mem)
+ // cond: r.Uses == 1
+ // result: (MOVDBRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
+ for {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ r := v_1
+ if r.Op != OpPPC64BRD {
+ break
+ }
+ val := r.Args[0]
+ mem := v_2
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpPPC64MOVDBRstore)
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg(ptr)
+ v.AddArg3(v0, val, mem)
+ return true
+ }
+ // match: (MOVDstore [off] {sym} ptr (Bswap64 val) mem)
+ // result: (MOVDBRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
+ for {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ if v_1.Op != OpBswap64 {
+ break
+ }
+ val := v_1.Args[0]
+ mem := v_2
+ v.reset(OpPPC64MOVDBRstore)
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg(ptr)
+ v.AddArg3(v0, val, mem)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpPPC64MOVDstoreidx(v *Value) bool {
@@ -8194,6 +8090,39 @@ func rewriteValuePPC64_OpPPC64MOVDstoreidx(v *Value) bool {
v.AddArg3(ptr, val, mem)
return true
}
+ // match: (MOVDstoreidx ptr idx r:(BRD val) mem)
+ // cond: r.Uses == 1
+ // result: (MOVDBRstoreidx ptr idx val mem)
+ for {
+ ptr := v_0
+ idx := v_1
+ r := v_2
+ if r.Op != OpPPC64BRD {
+ break
+ }
+ val := r.Args[0]
+ mem := v_3
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpPPC64MOVDBRstoreidx)
+ v.AddArg4(ptr, idx, val, mem)
+ return true
+ }
+ // match: (MOVDstoreidx ptr idx (Bswap64 val) mem)
+ // result: (MOVDBRstoreidx ptr idx val mem)
+ for {
+ ptr := v_0
+ idx := v_1
+ if v_2.Op != OpBswap64 {
+ break
+ }
+ val := v_2.Args[0]
+ mem := v_3
+ v.reset(OpPPC64MOVDBRstoreidx)
+ v.AddArg4(ptr, idx, val, mem)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value) bool {
@@ -8249,10 +8178,9 @@ func rewriteValuePPC64_OpPPC64MOVHBRstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (MOVHBRstore {sym} ptr (MOVHreg x) mem)
- // result: (MOVHBRstore {sym} ptr x mem)
+ // match: (MOVHBRstore ptr (MOVHreg x) mem)
+ // result: (MOVHBRstore ptr x mem)
for {
- sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpPPC64MOVHreg {
break
@@ -8260,14 +8188,12 @@ func rewriteValuePPC64_OpPPC64MOVHBRstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpPPC64MOVHBRstore)
- v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVHBRstore {sym} ptr (MOVHZreg x) mem)
- // result: (MOVHBRstore {sym} ptr x mem)
+ // match: (MOVHBRstore ptr (MOVHZreg x) mem)
+ // result: (MOVHBRstore ptr x mem)
for {
- sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpPPC64MOVHZreg {
break
@@ -8275,14 +8201,12 @@ func rewriteValuePPC64_OpPPC64MOVHBRstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpPPC64MOVHBRstore)
- v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVHBRstore {sym} ptr (MOVWreg x) mem)
- // result: (MOVHBRstore {sym} ptr x mem)
+ // match: (MOVHBRstore ptr (MOVWreg x) mem)
+ // result: (MOVHBRstore ptr x mem)
for {
- sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpPPC64MOVWreg {
break
@@ -8290,14 +8214,12 @@ func rewriteValuePPC64_OpPPC64MOVHBRstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpPPC64MOVHBRstore)
- v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVHBRstore {sym} ptr (MOVWZreg x) mem)
- // result: (MOVHBRstore {sym} ptr x mem)
+ // match: (MOVHBRstore ptr (MOVWZreg x) mem)
+ // result: (MOVHBRstore ptr x mem)
for {
- sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpPPC64MOVWZreg {
break
@@ -8305,7 +8227,6 @@ func rewriteValuePPC64_OpPPC64MOVHBRstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpPPC64MOVHBRstore)
- v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -9223,7 +9144,6 @@ func rewriteValuePPC64_OpPPC64MOVHstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
- config := b.Func.Config
// match: (MOVHstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(int64(off1)+off2)
// result: (MOVHstore [off1+int32(off2)] {sym} x val mem)
@@ -9377,62 +9297,47 @@ func rewriteValuePPC64_OpPPC64MOVHstore(v *Value) bool {
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVHstore [i1] {s} p (SRWconst w [16]) x0:(MOVHstore [i0] {s} p w mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+2 && clobber(x0)
- // result: (MOVWstore [i0] {s} p w mem)
+ // match: (MOVHstore [off] {sym} ptr r:(BRH val) mem)
+ // cond: r.Uses == 1
+ // result: (MOVHBRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRWconst || auxIntToInt64(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVHstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ r := v_1
+ if r.Op != OpPPC64BRH {
break
}
- mem := x0.Args[2]
- if p != x0.Args[0] || w != x0.Args[1] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+2 && clobber(x0)) {
+ val := r.Args[0]
+ mem := v_2
+ if !(r.Uses == 1) {
break
}
- v.reset(OpPPC64MOVWstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
+ v.reset(OpPPC64MOVHBRstore)
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg(ptr)
+ v.AddArg3(v0, val, mem)
return true
}
- // match: (MOVHstore [i1] {s} p (SRDconst w [16]) x0:(MOVHstore [i0] {s} p w mem))
- // cond: !config.BigEndian && x0.Uses == 1 && i1 == i0+2 && clobber(x0)
- // result: (MOVWstore [i0] {s} p w mem)
+ // match: (MOVHstore [off] {sym} ptr (Bswap16 val) mem)
+ // result: (MOVHBRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
for {
- i1 := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpPPC64SRDconst || auxIntToInt64(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x0 := v_2
- if x0.Op != OpPPC64MOVHstore {
- break
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- break
- }
- mem := x0.Args[2]
- if p != x0.Args[0] || w != x0.Args[1] || !(!config.BigEndian && x0.Uses == 1 && i1 == i0+2 && clobber(x0)) {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ if v_1.Op != OpBswap16 {
break
}
- v.reset(OpPPC64MOVWstore)
- v.AuxInt = int32ToAuxInt(i0)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
+ val := v_1.Args[0]
+ mem := v_2
+ v.reset(OpPPC64MOVHBRstore)
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg(ptr)
+ v.AddArg3(v0, val, mem)
return true
}
return false
@@ -9536,6 +9441,39 @@ func rewriteValuePPC64_OpPPC64MOVHstoreidx(v *Value) bool {
v.AddArg4(ptr, idx, x, mem)
return true
}
+ // match: (MOVHstoreidx ptr idx r:(BRH val) mem)
+ // cond: r.Uses == 1
+ // result: (MOVHBRstoreidx ptr idx val mem)
+ for {
+ ptr := v_0
+ idx := v_1
+ r := v_2
+ if r.Op != OpPPC64BRH {
+ break
+ }
+ val := r.Args[0]
+ mem := v_3
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpPPC64MOVHBRstoreidx)
+ v.AddArg4(ptr, idx, val, mem)
+ return true
+ }
+ // match: (MOVHstoreidx ptr idx (Bswap16 val) mem)
+ // result: (MOVHBRstoreidx ptr idx val mem)
+ for {
+ ptr := v_0
+ idx := v_1
+ if v_2.Op != OpBswap16 {
+ break
+ }
+ val := v_2.Args[0]
+ mem := v_3
+ v.reset(OpPPC64MOVHBRstoreidx)
+ v.AddArg4(ptr, idx, val, mem)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value) bool {
@@ -9591,10 +9529,9 @@ func rewriteValuePPC64_OpPPC64MOVWBRstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (MOVWBRstore {sym} ptr (MOVWreg x) mem)
- // result: (MOVWBRstore {sym} ptr x mem)
+ // match: (MOVWBRstore ptr (MOVWreg x) mem)
+ // result: (MOVWBRstore ptr x mem)
for {
- sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpPPC64MOVWreg {
break
@@ -9602,14 +9539,12 @@ func rewriteValuePPC64_OpPPC64MOVWBRstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpPPC64MOVWBRstore)
- v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
- // match: (MOVWBRstore {sym} ptr (MOVWZreg x) mem)
- // result: (MOVWBRstore {sym} ptr x mem)
+ // match: (MOVWBRstore ptr (MOVWZreg x) mem)
+ // result: (MOVWBRstore ptr x mem)
for {
- sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpPPC64MOVWZreg {
break
@@ -9617,7 +9552,6 @@ func rewriteValuePPC64_OpPPC64MOVWBRstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpPPC64MOVWBRstore)
- v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10580,6 +10514,7 @@ func rewriteValuePPC64_OpPPC64MOVWstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
+ b := v.Block
// match: (MOVWstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(int64(off1)+off2)
// result: (MOVWstore [off1+int32(off2)] {sym} x val mem)
@@ -10699,6 +10634,49 @@ func rewriteValuePPC64_OpPPC64MOVWstore(v *Value) bool {
v.AddArg3(ptr, x, mem)
return true
}
+ // match: (MOVWstore [off] {sym} ptr r:(BRW val) mem)
+ // cond: r.Uses == 1
+ // result: (MOVWBRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
+ for {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ r := v_1
+ if r.Op != OpPPC64BRW {
+ break
+ }
+ val := r.Args[0]
+ mem := v_2
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpPPC64MOVWBRstore)
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg(ptr)
+ v.AddArg3(v0, val, mem)
+ return true
+ }
+ // match: (MOVWstore [off] {sym} ptr (Bswap32 val) mem)
+ // result: (MOVWBRstore (MOVDaddr <ptr.Type> [off] {sym} ptr) val mem)
+ for {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ if v_1.Op != OpBswap32 {
+ break
+ }
+ val := v_1.Args[0]
+ mem := v_2
+ v.reset(OpPPC64MOVWBRstore)
+ v0 := b.NewValue0(v.Pos, OpPPC64MOVDaddr, ptr.Type)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg(ptr)
+ v.AddArg3(v0, val, mem)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpPPC64MOVWstoreidx(v *Value) bool {
@@ -10772,6 +10750,39 @@ func rewriteValuePPC64_OpPPC64MOVWstoreidx(v *Value) bool {
v.AddArg4(ptr, idx, x, mem)
return true
}
+ // match: (MOVWstoreidx ptr idx r:(BRW val) mem)
+ // cond: r.Uses == 1
+ // result: (MOVWBRstoreidx ptr idx val mem)
+ for {
+ ptr := v_0
+ idx := v_1
+ r := v_2
+ if r.Op != OpPPC64BRW {
+ break
+ }
+ val := r.Args[0]
+ mem := v_3
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpPPC64MOVWBRstoreidx)
+ v.AddArg4(ptr, idx, val, mem)
+ return true
+ }
+ // match: (MOVWstoreidx ptr idx (Bswap32 val) mem)
+ // result: (MOVWBRstoreidx ptr idx val mem)
+ for {
+ ptr := v_0
+ idx := v_1
+ if v_2.Op != OpBswap32 {
+ break
+ }
+ val := v_2.Args[0]
+ mem := v_3
+ v.reset(OpPPC64MOVWBRstoreidx)
+ v.AddArg4(ptr, idx, val, mem)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value) bool {
@@ -11056,9 +11067,6 @@ func rewriteValuePPC64_OpPPC64NotEqual(v *Value) bool {
func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- config := b.Func.Config
- typ := &b.Func.Config.Types
// match: (OR x (NOR y y))
// result: (ORN x y)
for {
@@ -11115,1293 +11123,6 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
}
break
}
- // match: (OR <t> x0:(MOVBZload [i0] {s} p mem) o1:(SLWconst x1:(MOVBZload [i1] {s} p mem) [8]))
- // cond: !config.BigEndian && i1 == i0+1 && x0.Uses ==1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)
- // result: @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o1 := v_1
- if o1.Op != OpPPC64SLWconst || auxIntToInt64(o1.AuxInt) != 8 {
- continue
- }
- x1 := o1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(!config.BigEndian && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpPPC64MOVHZload, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (OR <t> x0:(MOVBZload [i0] {s} p mem) o1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))
- // cond: !config.BigEndian && i1 == i0+1 && x0.Uses ==1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)
- // result: @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o1 := v_1
- if o1.Op != OpPPC64SLDconst || auxIntToInt64(o1.AuxInt) != 8 {
- continue
- }
- x1 := o1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(!config.BigEndian && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpPPC64MOVHZload, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (OR <t> x0:(MOVBZload [i1] {s} p mem) o1:(SLWconst x1:(MOVBZload [i0] {s} p mem) [8]))
- // cond: !config.BigEndian && i1 == i0+1 && x0.Uses ==1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)
- // result: @mergePoint(b,x0,x1) (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o1 := v_1
- if o1.Op != OpPPC64SLWconst || auxIntToInt64(o1.AuxInt) != 8 {
- continue
- }
- x1 := o1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(!config.BigEndian && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpPPC64MOVHBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- break
- }
- // match: (OR <t> x0:(MOVBZload [i1] {s} p mem) o1:(SLDconst x1:(MOVBZload [i0] {s} p mem) [8]))
- // cond: !config.BigEndian && i1 == i0+1 && x0.Uses ==1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)
- // result: @mergePoint(b,x0,x1) (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o1 := v_1
- if o1.Op != OpPPC64SLDconst || auxIntToInt64(o1.AuxInt) != 8 {
- continue
- }
- x1 := o1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(!config.BigEndian && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, o1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpPPC64MOVHBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- break
- }
- // match: (OR <t> s0:(SLWconst x0:(MOVBZload [i1] {s} p mem) [n1]) s1:(SLWconst x1:(MOVBZload [i0] {s} p mem) [n2]))
- // cond: !config.BigEndian && i1 == i0+1 && n1%8 == 0 && n2 == n1+8 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, s0, s1)
- // result: @mergePoint(b,x0,x1) (SLDconst <t> (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [n1])
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpPPC64SLWconst {
- continue
- }
- n1 := auxIntToInt64(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- s1 := v_1
- if s1.Op != OpPPC64SLWconst {
- continue
- }
- n2 := auxIntToInt64(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(!config.BigEndian && i1 == i0+1 && n1%8 == 0 && n2 == n1+8 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, s0, s1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpPPC64SLDconst, t)
- v.copyOf(v0)
- v0.AuxInt = int64ToAuxInt(n1)
- v1 := b.NewValue0(x1.Pos, OpPPC64MOVHBRload, t)
- v2 := b.NewValue0(x1.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR <t> s0:(SLDconst x0:(MOVBZload [i1] {s} p mem) [n1]) s1:(SLDconst x1:(MOVBZload [i0] {s} p mem) [n2]))
- // cond: !config.BigEndian && i1 == i0+1 && n1%8 == 0 && n2 == n1+8 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, s0, s1)
- // result: @mergePoint(b,x0,x1) (SLDconst <t> (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [n1])
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpPPC64SLDconst {
- continue
- }
- n1 := auxIntToInt64(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- s1 := v_1
- if s1.Op != OpPPC64SLDconst {
- continue
- }
- n2 := auxIntToInt64(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(!config.BigEndian && i1 == i0+1 && n1%8 == 0 && n2 == n1+8 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, s0, s1)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpPPC64SLDconst, t)
- v.copyOf(v0)
- v0.AuxInt = int64ToAuxInt(n1)
- v1 := b.NewValue0(x1.Pos, OpPPC64MOVHBRload, t)
- v2 := b.NewValue0(x1.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR <t> s1:(SLWconst x2:(MOVBZload [i3] {s} p mem) [24]) o0:(OR <t> s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [16]) x0:(MOVHZload [i0] {s} p mem)))
- // cond: !config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpPPC64SLWconst || auxIntToInt64(s1.AuxInt) != 24 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i3 := auxIntToInt32(x2.AuxInt)
- s := auxToSym(x2.Aux)
- mem := x2.Args[1]
- p := x2.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s0 := o0_0
- if s0.Op != OpPPC64SLWconst || auxIntToInt64(s0.AuxInt) != 16 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- x0 := o0_1
- if x0.Op != OpPPC64MOVHZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x0.Pos, OpPPC64MOVWZload, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> s1:(SLDconst x2:(MOVBZload [i3] {s} p mem) [24]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i2] {s} p mem) [16]) x0:(MOVHZload [i0] {s} p mem)))
- // cond: !config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpPPC64SLDconst || auxIntToInt64(s1.AuxInt) != 24 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i3 := auxIntToInt32(x2.AuxInt)
- s := auxToSym(x2.Aux)
- mem := x2.Args[1]
- p := x2.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s0 := o0_0
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 16 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- x0 := o0_1
- if x0.Op != OpPPC64MOVHZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x0.Pos, OpPPC64MOVWZload, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> s1:(SLWconst x2:(MOVBZload [i0] {s} p mem) [24]) o0:(OR <t> s0:(SLWconst x1:(MOVBZload [i1] {s} p mem) [16]) x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem)))
- // cond: !config.BigEndian && i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpPPC64SLWconst || auxIntToInt64(s1.AuxInt) != 24 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x2.AuxInt)
- s := auxToSym(x2.Aux)
- mem := x2.Args[1]
- p := x2.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s0 := o0_0
- if s0.Op != OpPPC64SLWconst || auxIntToInt64(s0.AuxInt) != 16 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- x0 := o0_1
- if x0.Op != OpPPC64MOVHBRload || x0.Type != t {
- continue
- }
- _ = x0.Args[1]
- x0_0 := x0.Args[0]
- if x0_0.Op != OpPPC64MOVDaddr || x0_0.Type != typ.Uintptr {
- continue
- }
- i2 := auxIntToInt32(x0_0.AuxInt)
- if auxToSym(x0_0.Aux) != s || p != x0_0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x0.Pos, OpPPC64MOVWBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> s1:(SLDconst x2:(MOVBZload [i0] {s} p mem) [24]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [16]) x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem)))
- // cond: !config.BigEndian && i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpPPC64SLDconst || auxIntToInt64(s1.AuxInt) != 24 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x2.AuxInt)
- s := auxToSym(x2.Aux)
- mem := x2.Args[1]
- p := x2.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s0 := o0_0
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 16 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- x0 := o0_1
- if x0.Op != OpPPC64MOVHBRload || x0.Type != t {
- continue
- }
- _ = x0.Args[1]
- x0_0 := x0.Args[0]
- if x0_0.Op != OpPPC64MOVDaddr || x0_0.Type != typ.Uintptr {
- continue
- }
- i2 := auxIntToInt32(x0_0.AuxInt)
- if auxToSym(x0_0.Aux) != s || p != x0_0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x0.Pos, OpPPC64MOVWBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> x0:(MOVBZload [i3] {s} p mem) o0:(OR <t> s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [8]) s1:(SLWconst x2:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [16])))
- // cond: !config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i3 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s0 := o0_0
- if s0.Op != OpPPC64SLWconst || auxIntToInt64(s0.AuxInt) != 8 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- s1 := o0_1
- if s1.Op != OpPPC64SLWconst || auxIntToInt64(s1.AuxInt) != 16 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != OpPPC64MOVHBRload || x2.Type != t {
- continue
- }
- _ = x2.Args[1]
- x2_0 := x2.Args[0]
- if x2_0.Op != OpPPC64MOVDaddr || x2_0.Type != typ.Uintptr {
- continue
- }
- i0 := auxIntToInt32(x2_0.AuxInt)
- if auxToSym(x2_0.Aux) != s || p != x2_0.Args[0] || mem != x2.Args[1] || !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, OpPPC64MOVWBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x2.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> x0:(MOVBZload [i3] {s} p mem) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i2] {s} p mem) [8]) s1:(SLDconst x2:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [16])))
- // cond: !config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)
- // result: @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i3 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s0 := o0_0
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 8 {
- continue
- }
- x1 := s0.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- s1 := o0_1
- if s1.Op != OpPPC64SLDconst || auxIntToInt64(s1.AuxInt) != 16 {
- continue
- }
- x2 := s1.Args[0]
- if x2.Op != OpPPC64MOVHBRload || x2.Type != t {
- continue
- }
- _ = x2.Args[1]
- x2_0 := x2.Args[0]
- if x2_0.Op != OpPPC64MOVDaddr || x2_0.Type != typ.Uintptr {
- continue
- }
- i0 := auxIntToInt32(x2_0.AuxInt)
- if auxToSym(x2_0.Aux) != s || p != x2_0.Args[0] || mem != x2.Args[1] || !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x2.Pos, OpPPC64MOVWBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x2.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- break
- }
- // match: (OR <t> s2:(SLDconst x2:(MOVBZload [i3] {s} p mem) [32]) o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i2] {s} p mem) [40]) s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [48])))
- // cond: !config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, s2, o0)
- // result: @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s2 := v_0
- if s2.Op != OpPPC64SLDconst || auxIntToInt64(s2.AuxInt) != 32 {
- continue
- }
- x2 := s2.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i3 := auxIntToInt32(x2.AuxInt)
- s := auxToSym(x2.Aux)
- mem := x2.Args[1]
- p := x2.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s1 := o0_0
- if s1.Op != OpPPC64SLDconst || auxIntToInt64(s1.AuxInt) != 40 {
- continue
- }
- x1 := s1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i2 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- s0 := o0_1
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 48 {
- continue
- }
- x0 := s0.Args[0]
- if x0.Op != OpPPC64MOVHBRload || x0.Type != t {
- continue
- }
- _ = x0.Args[1]
- x0_0 := x0.Args[0]
- if x0_0.Op != OpPPC64MOVDaddr || x0_0.Type != typ.Uintptr {
- continue
- }
- i0 := auxIntToInt32(x0_0.AuxInt)
- if auxToSym(x0_0.Aux) != s || p != x0_0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, s2, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x0.Pos, OpPPC64SLDconst, t)
- v.copyOf(v0)
- v0.AuxInt = int64ToAuxInt(32)
- v1 := b.NewValue0(x0.Pos, OpPPC64MOVWBRload, t)
- v2 := b.NewValue0(x0.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- }
- break
- }
- // match: (OR <t> s2:(SLDconst x2:(MOVBZload [i0] {s} p mem) [56]) o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48]) s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem) [32])))
- // cond: !config.BigEndian && i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, s2, o0)
- // result: @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s2 := v_0
- if s2.Op != OpPPC64SLDconst || auxIntToInt64(s2.AuxInt) != 56 {
- continue
- }
- x2 := s2.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x2.AuxInt)
- s := auxToSym(x2.Aux)
- mem := x2.Args[1]
- p := x2.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s1 := o0_0
- if s1.Op != OpPPC64SLDconst || auxIntToInt64(s1.AuxInt) != 48 {
- continue
- }
- x1 := s1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- s0 := o0_1
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 32 {
- continue
- }
- x0 := s0.Args[0]
- if x0.Op != OpPPC64MOVHBRload || x0.Type != t {
- continue
- }
- _ = x0.Args[1]
- x0_0 := x0.Args[0]
- if x0_0.Op != OpPPC64MOVDaddr || x0_0.Type != typ.Uintptr {
- continue
- }
- i2 := auxIntToInt32(x0_0.AuxInt)
- if auxToSym(x0_0.Aux) != s || p != x0_0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, s0, s1, s2, o0)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2)
- v0 := b.NewValue0(x0.Pos, OpPPC64SLDconst, t)
- v.copyOf(v0)
- v0.AuxInt = int64ToAuxInt(32)
- v1 := b.NewValue0(x0.Pos, OpPPC64MOVWBRload, t)
- v2 := b.NewValue0(x0.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg(p)
- v1.AddArg2(v2, mem)
- v0.AddArg(v1)
- return true
- }
- }
- break
- }
- // match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) x0:(MOVWZload {s} [i0] p mem)))))
- // cond: !config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x4, x5, x6, x7) != nil && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)
- // result: @mergePoint(b,x0,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s6 := v_0
- if s6.Op != OpPPC64SLDconst || auxIntToInt64(s6.AuxInt) != 56 {
- continue
- }
- x7 := s6.Args[0]
- if x7.Op != OpPPC64MOVBZload {
- continue
- }
- i7 := auxIntToInt32(x7.AuxInt)
- s := auxToSym(x7.Aux)
- mem := x7.Args[1]
- p := x7.Args[0]
- o5 := v_1
- if o5.Op != OpPPC64OR || o5.Type != t {
- continue
- }
- _ = o5.Args[1]
- o5_0 := o5.Args[0]
- o5_1 := o5.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o5_0, o5_1 = _i1+1, o5_1, o5_0 {
- s5 := o5_0
- if s5.Op != OpPPC64SLDconst || auxIntToInt64(s5.AuxInt) != 48 {
- continue
- }
- x6 := s5.Args[0]
- if x6.Op != OpPPC64MOVBZload {
- continue
- }
- i6 := auxIntToInt32(x6.AuxInt)
- if auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- if p != x6.Args[0] || mem != x6.Args[1] {
- continue
- }
- o4 := o5_1
- if o4.Op != OpPPC64OR || o4.Type != t {
- continue
- }
- _ = o4.Args[1]
- o4_0 := o4.Args[0]
- o4_1 := o4.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, o4_0, o4_1 = _i2+1, o4_1, o4_0 {
- s4 := o4_0
- if s4.Op != OpPPC64SLDconst || auxIntToInt64(s4.AuxInt) != 40 {
- continue
- }
- x5 := s4.Args[0]
- if x5.Op != OpPPC64MOVBZload {
- continue
- }
- i5 := auxIntToInt32(x5.AuxInt)
- if auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- o3 := o4_1
- if o3.Op != OpPPC64OR || o3.Type != t {
- continue
- }
- _ = o3.Args[1]
- o3_0 := o3.Args[0]
- o3_1 := o3.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, o3_0, o3_1 = _i3+1, o3_1, o3_0 {
- s3 := o3_0
- if s3.Op != OpPPC64SLDconst || auxIntToInt64(s3.AuxInt) != 32 {
- continue
- }
- x4 := s3.Args[0]
- if x4.Op != OpPPC64MOVBZload {
- continue
- }
- i4 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- x0 := o3_1
- if x0.Op != OpPPC64MOVWZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x4, x5, x6, x7) != nil && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)) {
- continue
- }
- b = mergePoint(b, x0, x4, x5, x6, x7)
- v0 := b.NewValue0(x0.Pos, OpPPC64MOVDload, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- }
- }
- }
- break
- }
- // match: (OR <t> s0:(SLDconst x0:(MOVBZload [i0] {s} p mem) [56]) o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48]) o1:(OR <t> s2:(SLDconst x2:(MOVBZload [i2] {s} p mem) [40]) o2:(OR <t> s3:(SLDconst x3:(MOVBZload [i3] {s} p mem) [32]) x4:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i4] p) mem)))))
- // cond: !config.BigEndian && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, o0, o1, o2, s0, s1, s2, s3)
- // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 56 {
- continue
- }
- x0 := s0.Args[0]
- if x0.Op != OpPPC64MOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- o0 := v_1
- if o0.Op != OpPPC64OR || o0.Type != t {
- continue
- }
- _ = o0.Args[1]
- o0_0 := o0.Args[0]
- o0_1 := o0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o0_0, o0_1 = _i1+1, o0_1, o0_0 {
- s1 := o0_0
- if s1.Op != OpPPC64SLDconst || auxIntToInt64(s1.AuxInt) != 48 {
- continue
- }
- x1 := s1.Args[0]
- if x1.Op != OpPPC64MOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- o1 := o0_1
- if o1.Op != OpPPC64OR || o1.Type != t {
- continue
- }
- _ = o1.Args[1]
- o1_0 := o1.Args[0]
- o1_1 := o1.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, o1_0, o1_1 = _i2+1, o1_1, o1_0 {
- s2 := o1_0
- if s2.Op != OpPPC64SLDconst || auxIntToInt64(s2.AuxInt) != 40 {
- continue
- }
- x2 := s2.Args[0]
- if x2.Op != OpPPC64MOVBZload {
- continue
- }
- i2 := auxIntToInt32(x2.AuxInt)
- if auxToSym(x2.Aux) != s {
- continue
- }
- _ = x2.Args[1]
- if p != x2.Args[0] || mem != x2.Args[1] {
- continue
- }
- o2 := o1_1
- if o2.Op != OpPPC64OR || o2.Type != t {
- continue
- }
- _ = o2.Args[1]
- o2_0 := o2.Args[0]
- o2_1 := o2.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, o2_0, o2_1 = _i3+1, o2_1, o2_0 {
- s3 := o2_0
- if s3.Op != OpPPC64SLDconst || auxIntToInt64(s3.AuxInt) != 32 {
- continue
- }
- x3 := s3.Args[0]
- if x3.Op != OpPPC64MOVBZload {
- continue
- }
- i3 := auxIntToInt32(x3.AuxInt)
- if auxToSym(x3.Aux) != s {
- continue
- }
- _ = x3.Args[1]
- if p != x3.Args[0] || mem != x3.Args[1] {
- continue
- }
- x4 := o2_1
- if x4.Op != OpPPC64MOVWBRload || x4.Type != t {
- continue
- }
- _ = x4.Args[1]
- x4_0 := x4.Args[0]
- if x4_0.Op != OpPPC64MOVDaddr || x4_0.Type != typ.Uintptr {
- continue
- }
- i4 := auxIntToInt32(x4_0.AuxInt)
- if p != x4_0.Args[0] || mem != x4.Args[1] || !(!config.BigEndian && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, o0, o1, o2, s0, s1, s2, s3)) {
- continue
- }
- b = mergePoint(b, x0, x1, x2, x3, x4)
- v0 := b.NewValue0(x4.Pos, OpPPC64MOVDBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x4.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- }
- }
- break
- }
- // match: (OR <t> x7:(MOVBZload [i7] {s} p mem) o5:(OR <t> s6:(SLDconst x6:(MOVBZload [i6] {s} p mem) [8]) o4:(OR <t> s5:(SLDconst x5:(MOVBZload [i5] {s} p mem) [16]) o3:(OR <t> s4:(SLDconst x4:(MOVBZload [i4] {s} p mem) [24]) s0:(SLWconst x3:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])))))
- // cond: !config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x3, x4, x5, x6, x7) != nil && clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)
- // result: @mergePoint(b,x3,x4,x5,x6,x7) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x7 := v_0
- if x7.Op != OpPPC64MOVBZload {
- continue
- }
- i7 := auxIntToInt32(x7.AuxInt)
- s := auxToSym(x7.Aux)
- mem := x7.Args[1]
- p := x7.Args[0]
- o5 := v_1
- if o5.Op != OpPPC64OR || o5.Type != t {
- continue
- }
- _ = o5.Args[1]
- o5_0 := o5.Args[0]
- o5_1 := o5.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o5_0, o5_1 = _i1+1, o5_1, o5_0 {
- s6 := o5_0
- if s6.Op != OpPPC64SLDconst || auxIntToInt64(s6.AuxInt) != 8 {
- continue
- }
- x6 := s6.Args[0]
- if x6.Op != OpPPC64MOVBZload {
- continue
- }
- i6 := auxIntToInt32(x6.AuxInt)
- if auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- if p != x6.Args[0] || mem != x6.Args[1] {
- continue
- }
- o4 := o5_1
- if o4.Op != OpPPC64OR || o4.Type != t {
- continue
- }
- _ = o4.Args[1]
- o4_0 := o4.Args[0]
- o4_1 := o4.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, o4_0, o4_1 = _i2+1, o4_1, o4_0 {
- s5 := o4_0
- if s5.Op != OpPPC64SLDconst || auxIntToInt64(s5.AuxInt) != 16 {
- continue
- }
- x5 := s5.Args[0]
- if x5.Op != OpPPC64MOVBZload {
- continue
- }
- i5 := auxIntToInt32(x5.AuxInt)
- if auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- o3 := o4_1
- if o3.Op != OpPPC64OR || o3.Type != t {
- continue
- }
- _ = o3.Args[1]
- o3_0 := o3.Args[0]
- o3_1 := o3.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, o3_0, o3_1 = _i3+1, o3_1, o3_0 {
- s4 := o3_0
- if s4.Op != OpPPC64SLDconst || auxIntToInt64(s4.AuxInt) != 24 {
- continue
- }
- x4 := s4.Args[0]
- if x4.Op != OpPPC64MOVBZload {
- continue
- }
- i4 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- s0 := o3_1
- if s0.Op != OpPPC64SLWconst || auxIntToInt64(s0.AuxInt) != 32 {
- continue
- }
- x3 := s0.Args[0]
- if x3.Op != OpPPC64MOVWBRload || x3.Type != t {
- continue
- }
- _ = x3.Args[1]
- x3_0 := x3.Args[0]
- if x3_0.Op != OpPPC64MOVDaddr || x3_0.Type != typ.Uintptr {
- continue
- }
- i0 := auxIntToInt32(x3_0.AuxInt)
- if auxToSym(x3_0.Aux) != s || p != x3_0.Args[0] || mem != x3.Args[1] || !(!config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x3, x4, x5, x6, x7) != nil && clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)) {
- continue
- }
- b = mergePoint(b, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(x3.Pos, OpPPC64MOVDBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x3.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- }
- }
- break
- }
- // match: (OR <t> x7:(MOVBZload [i7] {s} p mem) o5:(OR <t> s6:(SLDconst x6:(MOVBZload [i6] {s} p mem) [8]) o4:(OR <t> s5:(SLDconst x5:(MOVBZload [i5] {s} p mem) [16]) o3:(OR <t> s4:(SLDconst x4:(MOVBZload [i4] {s} p mem) [24]) s0:(SLDconst x3:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])))))
- // cond: !config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x3, x4, x5, x6, x7) != nil && clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)
- // result: @mergePoint(b,x3,x4,x5,x6,x7) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
- for {
- t := v.Type
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x7 := v_0
- if x7.Op != OpPPC64MOVBZload {
- continue
- }
- i7 := auxIntToInt32(x7.AuxInt)
- s := auxToSym(x7.Aux)
- mem := x7.Args[1]
- p := x7.Args[0]
- o5 := v_1
- if o5.Op != OpPPC64OR || o5.Type != t {
- continue
- }
- _ = o5.Args[1]
- o5_0 := o5.Args[0]
- o5_1 := o5.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, o5_0, o5_1 = _i1+1, o5_1, o5_0 {
- s6 := o5_0
- if s6.Op != OpPPC64SLDconst || auxIntToInt64(s6.AuxInt) != 8 {
- continue
- }
- x6 := s6.Args[0]
- if x6.Op != OpPPC64MOVBZload {
- continue
- }
- i6 := auxIntToInt32(x6.AuxInt)
- if auxToSym(x6.Aux) != s {
- continue
- }
- _ = x6.Args[1]
- if p != x6.Args[0] || mem != x6.Args[1] {
- continue
- }
- o4 := o5_1
- if o4.Op != OpPPC64OR || o4.Type != t {
- continue
- }
- _ = o4.Args[1]
- o4_0 := o4.Args[0]
- o4_1 := o4.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, o4_0, o4_1 = _i2+1, o4_1, o4_0 {
- s5 := o4_0
- if s5.Op != OpPPC64SLDconst || auxIntToInt64(s5.AuxInt) != 16 {
- continue
- }
- x5 := s5.Args[0]
- if x5.Op != OpPPC64MOVBZload {
- continue
- }
- i5 := auxIntToInt32(x5.AuxInt)
- if auxToSym(x5.Aux) != s {
- continue
- }
- _ = x5.Args[1]
- if p != x5.Args[0] || mem != x5.Args[1] {
- continue
- }
- o3 := o4_1
- if o3.Op != OpPPC64OR || o3.Type != t {
- continue
- }
- _ = o3.Args[1]
- o3_0 := o3.Args[0]
- o3_1 := o3.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, o3_0, o3_1 = _i3+1, o3_1, o3_0 {
- s4 := o3_0
- if s4.Op != OpPPC64SLDconst || auxIntToInt64(s4.AuxInt) != 24 {
- continue
- }
- x4 := s4.Args[0]
- if x4.Op != OpPPC64MOVBZload {
- continue
- }
- i4 := auxIntToInt32(x4.AuxInt)
- if auxToSym(x4.Aux) != s {
- continue
- }
- _ = x4.Args[1]
- if p != x4.Args[0] || mem != x4.Args[1] {
- continue
- }
- s0 := o3_1
- if s0.Op != OpPPC64SLDconst || auxIntToInt64(s0.AuxInt) != 32 {
- continue
- }
- x3 := s0.Args[0]
- if x3.Op != OpPPC64MOVWBRload || x3.Type != t {
- continue
- }
- _ = x3.Args[1]
- x3_0 := x3.Args[0]
- if x3_0.Op != OpPPC64MOVDaddr || x3_0.Type != typ.Uintptr {
- continue
- }
- i0 := auxIntToInt32(x3_0.AuxInt)
- if auxToSym(x3_0.Aux) != s || p != x3_0.Args[0] || mem != x3.Args[1] || !(!config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x3, x4, x5, x6, x7) != nil && clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)) {
- continue
- }
- b = mergePoint(b, x3, x4, x5, x6, x7)
- v0 := b.NewValue0(x3.Pos, OpPPC64MOVDBRload, t)
- v.copyOf(v0)
- v1 := b.NewValue0(x3.Pos, OpPPC64MOVDaddr, typ.Uintptr)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg(p)
- v0.AddArg2(v1, mem)
- return true
- }
- }
- }
- }
- break
- }
return false
}
func rewriteValuePPC64_OpPPC64ORN(v *Value) bool {
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index fdd15f31a4..a3d621898f 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -90,6 +90,8 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpAvg64u(v)
case OpBitLen64:
return rewriteValueS390X_OpBitLen64(v)
+ case OpBswap16:
+ return rewriteValueS390X_OpBswap16(v)
case OpBswap32:
v.Op = OpS390XMOVWBR
return true
@@ -630,6 +632,8 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpS390XMOVBstore(v)
case OpS390XMOVBstoreconst:
return rewriteValueS390X_OpS390XMOVBstoreconst(v)
+ case OpS390XMOVDBR:
+ return rewriteValueS390X_OpS390XMOVDBR(v)
case OpS390XMOVDaddridx:
return rewriteValueS390X_OpS390XMOVDaddridx(v)
case OpS390XMOVDload:
@@ -638,8 +642,8 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpS390XMOVDstore(v)
case OpS390XMOVDstoreconst:
return rewriteValueS390X_OpS390XMOVDstoreconst(v)
- case OpS390XMOVHBRstore:
- return rewriteValueS390X_OpS390XMOVHBRstore(v)
+ case OpS390XMOVDstoreidx:
+ return rewriteValueS390X_OpS390XMOVDstoreidx(v)
case OpS390XMOVHZload:
return rewriteValueS390X_OpS390XMOVHZload(v)
case OpS390XMOVHZreg:
@@ -652,8 +656,10 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpS390XMOVHstore(v)
case OpS390XMOVHstoreconst:
return rewriteValueS390X_OpS390XMOVHstoreconst(v)
- case OpS390XMOVWBRstore:
- return rewriteValueS390X_OpS390XMOVWBRstore(v)
+ case OpS390XMOVHstoreidx:
+ return rewriteValueS390X_OpS390XMOVHstoreidx(v)
+ case OpS390XMOVWBR:
+ return rewriteValueS390X_OpS390XMOVWBR(v)
case OpS390XMOVWZload:
return rewriteValueS390X_OpS390XMOVWZload(v)
case OpS390XMOVWZreg:
@@ -666,6 +672,8 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpS390XMOVWstore(v)
case OpS390XMOVWstoreconst:
return rewriteValueS390X_OpS390XMOVWstoreconst(v)
+ case OpS390XMOVWstoreidx:
+ return rewriteValueS390X_OpS390XMOVWstoreidx(v)
case OpS390XMULLD:
return rewriteValueS390X_OpS390XMULLD(v)
case OpS390XMULLDconst:
@@ -1270,6 +1278,55 @@ func rewriteValueS390X_OpBitLen64(v *Value) bool {
return true
}
}
+func rewriteValueS390X_OpBswap16(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (Bswap16 x:(MOVHZload [off] {sym} ptr mem))
+ // result: @x.Block (MOVHZreg (MOVHBRload [off] {sym} ptr mem))
+ for {
+ x := v_0
+ if x.Op != OpS390XMOVHZload {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpS390XMOVHZreg, typ.UInt64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpS390XMOVHBRload, typ.UInt16)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg2(ptr, mem)
+ v0.AddArg(v1)
+ return true
+ }
+ // match: (Bswap16 x:(MOVHZloadidx [off] {sym} ptr idx mem))
+ // result: @x.Block (MOVHZreg (MOVHBRloadidx [off] {sym} ptr idx mem))
+ for {
+ x := v_0
+ if x.Op != OpS390XMOVHZloadidx {
+ break
+ }
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(v.Pos, OpS390XMOVHBRloadidx, typ.Int16)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg3(ptr, idx, mem)
+ v0.AddArg(v1)
+ return true
+ }
+ return false
+}
func rewriteValueS390X_OpCeil(v *Value) bool {
v_0 := v.Args[0]
// match: (Ceil x)
@@ -8651,280 +8708,6 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRDconst [8] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w0:(SRDconst [j] w) x:(MOVBstore [i-1] {s} p (SRDconst [j+8] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w0 := v_1
- if w0.Op != OpS390XSRDconst {
- break
- }
- j := auxIntToUint8(w0.AuxInt)
- w := w0.Args[0]
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRWconst [8] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p w0:(SRWconst [j] w) x:(MOVBstore [i-1] {s} p (SRWconst [j+8] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w0 := v_1
- if w0.Op != OpS390XSRWconst {
- break
- }
- j := auxIntToUint8(w0.AuxInt)
- w := w0.Args[0]
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SRDconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHBRstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHBRstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SRDconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRDconst [j-8] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHBRstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst {
- break
- }
- j := auxIntToUint8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || auxIntToUint8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHBRstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHBRstore [i-1] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 8 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHBRstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVBstore [i] {s} p (SRWconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRWconst [j-8] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVHBRstore [i-1] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRWconst {
- break
- }
- j := auxIntToUint8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpS390XSRWconst || auxIntToUint8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVHBRstore)
- v.AuxInt = int32ToAuxInt(i - 1)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVBstore [7] {s} p1 (SRDconst w) x1:(MOVHBRstore [5] {s} p1 (SRDconst w) x2:(MOVWBRstore [1] {s} p1 (SRDconst w) x3:(MOVBstore [0] {s} p1 w mem))))
- // cond: x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)
- // result: (MOVDBRstore {s} p1 w mem)
- for {
- if auxIntToInt32(v.AuxInt) != 7 {
- break
- }
- s := auxToSym(v.Aux)
- p1 := v_0
- if v_1.Op != OpS390XSRDconst {
- break
- }
- w := v_1.Args[0]
- x1 := v_2
- if x1.Op != OpS390XMOVHBRstore || auxIntToInt32(x1.AuxInt) != 5 || auxToSym(x1.Aux) != s {
- break
- }
- _ = x1.Args[2]
- if p1 != x1.Args[0] {
- break
- }
- x1_1 := x1.Args[1]
- if x1_1.Op != OpS390XSRDconst || w != x1_1.Args[0] {
- break
- }
- x2 := x1.Args[2]
- if x2.Op != OpS390XMOVWBRstore || auxIntToInt32(x2.AuxInt) != 1 || auxToSym(x2.Aux) != s {
- break
- }
- _ = x2.Args[2]
- if p1 != x2.Args[0] {
- break
- }
- x2_1 := x2.Args[1]
- if x2_1.Op != OpS390XSRDconst || w != x2_1.Args[0] {
- break
- }
- x3 := x2.Args[2]
- if x3.Op != OpS390XMOVBstore || auxIntToInt32(x3.AuxInt) != 0 || auxToSym(x3.Aux) != s {
- break
- }
- mem := x3.Args[2]
- if p1 != x3.Args[0] || w != x3.Args[1] || !(x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)) {
- break
- }
- v.reset(OpS390XMOVDBRstore)
- v.Aux = symToAux(s)
- v.AddArg3(p1, w, mem)
- return true
- }
return false
}
func rewriteValueS390X_OpS390XMOVBstoreconst(v *Value) bool {
@@ -8973,29 +8756,57 @@ func rewriteValueS390X_OpS390XMOVBstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
- // cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
- // result: (MOVHstoreconst [makeValAndOff(c.Val()&0xff | a.Val()<<8, a.Off())] {s} p mem)
+ return false
+}
+func rewriteValueS390X_OpS390XMOVDBR(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (MOVDBR x:(MOVDload [off] {sym} ptr mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVDBRload [off] {sym} ptr mem)
for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != OpS390XMOVBstoreconst {
+ x := v_0
+ if x.Op != OpS390XMOVDload {
break
}
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ if !(x.Uses == 1) {
break
}
- mem := x.Args[1]
- if p != x.Args[0] || !(p.Op != OpSB && x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) {
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpS390XMOVDBRload, typ.UInt64)
+ v.copyOf(v0)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg2(ptr, mem)
+ return true
+ }
+ // match: (MOVDBR x:(MOVDloadidx [off] {sym} ptr idx mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVDBRloadidx [off] {sym} ptr idx mem)
+ for {
+ x := v_0
+ if x.Op != OpS390XMOVDloadidx {
break
}
- v.reset(OpS390XMOVHstoreconst)
- v.AuxInt = valAndOffToAuxInt(makeValAndOff(c.Val()&0xff|a.Val()<<8, a.Off()))
- v.Aux = symToAux(s)
- v.AddArg2(p, mem)
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[2]
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ if !(x.Uses == 1) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpS390XMOVDBRloadidx, typ.Int64)
+ v.copyOf(v0)
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
+ v0.AddArg3(ptr, idx, mem)
return true
}
return false
@@ -9329,6 +9140,28 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool {
v.AddArg6(p, w0, w1, w2, w3, mem)
return true
}
+ // match: (MOVDstore [off] {sym} ptr r:(MOVDBR x) mem)
+ // cond: r.Uses == 1
+ // result: (MOVDBRstore [off] {sym} ptr x mem)
+ for {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ r := v_1
+ if r.Op != OpS390XMOVDBR {
+ break
+ }
+ x := r.Args[0]
+ mem := v_2
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpS390XMOVDBRstore)
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
+ v.AddArg3(ptr, x, mem)
+ return true
+ }
return false
}
func rewriteValueS390X_OpS390XMOVDstoreconst(v *Value) bool {
@@ -9379,118 +9212,32 @@ func rewriteValueS390X_OpS390XMOVDstoreconst(v *Value) bool {
}
return false
}
-func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
+func rewriteValueS390X_OpS390XMOVDstoreidx(v *Value) bool {
+ v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (MOVHBRstore [i] {s} p (SRDconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVWBRstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVHBRstore [i] {s} p (SRDconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRDconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstore [i-2] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst {
- break
- }
- j := auxIntToUint8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || auxIntToUint8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVWBRstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVHBRstore [i] {s} p (SRWconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 16 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVWBRstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVHBRstore [i] {s} p (SRWconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRWconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstore [i-2] {s} p w0 mem)
+ // match: (MOVDstoreidx [off] {sym} ptr idx r:(MOVDBR x) mem)
+ // cond: r.Uses == 1
+ // result: (MOVDBRstoreidx [off] {sym} ptr idx x mem)
for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRWconst {
- break
- }
- j := auxIntToUint8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ idx := v_1
+ r := v_2
+ if r.Op != OpS390XMOVDBR {
break
}
- w0 := x.Args[1]
- if w0.Op != OpS390XSRWconst || auxIntToUint8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ x := r.Args[0]
+ mem := v_3
+ if !(r.Uses == 1) {
break
}
- v.reset(OpS390XMOVWBRstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
+ v.reset(OpS390XMOVDBRstoreidx)
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
+ v.AddArg4(ptr, idx, x, mem)
return true
}
return false
@@ -10114,118 +9861,21 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVHstore [i] {s} p w0:(SRDconst [j] w) x:(MOVHstore [i-2] {s} p (SRDconst [j+16] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-2] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w0 := v_1
- if w0.Op != OpS390XSRDconst {
- break
- }
- j := auxIntToUint8(w0.AuxInt)
- w := w0.Args[0]
- x := v_2
- if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
- // match: (MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRWconst [16] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-2] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w := v_1
- x := v_2
- if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVHstore [i] {s} p w0:(SRWconst [j] w) x:(MOVHstore [i-2] {s} p (SRWconst [j+16] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVWstore [i-2] {s} p w0 mem)
+ // match: (MOVHstore [off] {sym} ptr (Bswap16 val) mem)
+ // result: (MOVHBRstore [off] {sym} ptr val mem)
for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w0 := v_1
- if w0.Op != OpS390XSRWconst {
- break
- }
- j := auxIntToUint8(w0.AuxInt)
- w := w0.Args[0]
- x := v_2
- if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ if v_1.Op != OpBswap16 {
break
}
- v.reset(OpS390XMOVWstore)
- v.AuxInt = int32ToAuxInt(i - 2)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
+ val := v_1.Args[0]
+ mem := v_2
+ v.reset(OpS390XMOVHBRstore)
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
+ v.AddArg3(ptr, val, mem)
return true
}
return false
@@ -10233,8 +9883,6 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
func rewriteValueS390X_OpS390XMOVHstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem)
// cond: isU12Bit(sc.Off64()+int64(off))
// result: (MOVHstoreconst [sc.addOffset32(off)] {s} ptr mem)
@@ -10278,92 +9926,86 @@ func rewriteValueS390X_OpS390XMOVHstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
- // cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
- // result: (MOVWstore [a.Off()] {s} p (MOVDconst [int64(c.Val()&0xffff | a.Val()<<16)]) mem)
+ return false
+}
+func rewriteValueS390X_OpS390XMOVHstoreidx(v *Value) bool {
+ v_3 := v.Args[3]
+ v_2 := v.Args[2]
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (MOVHstoreidx [off] {sym} ptr idx (Bswap16 val) mem)
+ // result: (MOVHBRstoreidx [off] {sym} ptr idx val mem)
for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != OpS390XMOVHstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[1]
- if p != x.Args[0] || !(p.Op != OpSB && x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ idx := v_1
+ if v_2.Op != OpBswap16 {
break
}
- v.reset(OpS390XMOVWstore)
- v.AuxInt = int32ToAuxInt(a.Off())
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpS390XMOVDconst, typ.UInt64)
- v0.AuxInt = int64ToAuxInt(int64(c.Val()&0xffff | a.Val()<<16))
- v.AddArg3(p, v0, mem)
+ val := v_2.Args[0]
+ mem := v_3
+ v.reset(OpS390XMOVHBRstoreidx)
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
+ v.AddArg4(ptr, idx, val, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
+func rewriteValueS390X_OpS390XMOVWBR(v *Value) bool {
v_0 := v.Args[0]
- // match: (MOVWBRstore [i] {s} p (SRDconst [32] w) x:(MOVWBRstore [i-4] {s} p w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDBRstore [i-4] {s} p w mem)
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (MOVWBR x:(MOVWZload [off] {sym} ptr mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVWZreg (MOVWBRload [off] {sym} ptr mem))
for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 32 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVWBRstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
+ x := v_0
+ if x.Op != OpS390XMOVWZload {
break
}
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
+ mem := x.Args[1]
+ ptr := x.Args[0]
+ if !(x.Uses == 1) {
break
}
- v.reset(OpS390XMOVDBRstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpS390XMOVWZreg, typ.UInt64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(x.Pos, OpS390XMOVWBRload, typ.UInt32)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg2(ptr, mem)
+ v0.AddArg(v1)
return true
}
- // match: (MOVWBRstore [i] {s} p (SRDconst [j] w) x:(MOVWBRstore [i-4] {s} p w0:(SRDconst [j-32] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDBRstore [i-4] {s} p w0 mem)
+ // match: (MOVWBR x:(MOVWZloadidx [off] {sym} ptr idx mem))
+ // cond: x.Uses == 1
+ // result: @x.Block (MOVWZreg (MOVWBRloadidx [off] {sym} ptr idx mem))
for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst {
- break
- }
- j := auxIntToUint8(v_1.AuxInt)
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVWBRstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
+ x := v_0
+ if x.Op != OpS390XMOVWZloadidx {
break
}
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[2]
- if p != x.Args[0] {
+ ptr := x.Args[0]
+ idx := x.Args[1]
+ if !(x.Uses == 1) {
break
}
- w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || auxIntToUint8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVDBRstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpS390XMOVWZreg, typ.UInt64)
+ v.copyOf(v0)
+ v1 := b.NewValue0(v.Pos, OpS390XMOVWBRloadidx, typ.Int32)
+ v1.AuxInt = int32ToAuxInt(off)
+ v1.Aux = symToAux(sym)
+ v1.AddArg3(ptr, idx, mem)
+ v0.AddArg(v1)
return true
}
return false
@@ -10952,62 +10594,6 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVDstore [i-4] {s} p w mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 32 {
- break
- }
- w := v_1.Args[0]
- x := v_2
- if x.Op != OpS390XMOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] || w != x.Args[1] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVDstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(p, w, mem)
- return true
- }
- // match: (MOVWstore [i] {s} p w0:(SRDconst [j] w) x:(MOVWstore [i-4] {s} p (SRDconst [j+32] w) mem))
- // cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
- // result: (MOVDstore [i-4] {s} p w0 mem)
- for {
- i := auxIntToInt32(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- w0 := v_1
- if w0.Op != OpS390XSRDconst {
- break
- }
- j := auxIntToUint8(w0.AuxInt)
- w := w0.Args[0]
- x := v_2
- if x.Op != OpS390XMOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
- break
- }
- mem := x.Args[2]
- if p != x.Args[0] {
- break
- }
- x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != j+32 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
- break
- }
- v.reset(OpS390XMOVDstore)
- v.AuxInt = int32ToAuxInt(i - 4)
- v.Aux = symToAux(s)
- v.AddArg3(p, w0, mem)
- return true
- }
// match: (MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem))
// cond: p.Op != OpSB && x.Uses == 1 && is20Bit(int64(i)-4) && clobber(x)
// result: (STM2 [i-4] {s} p w0 w1 mem)
@@ -11089,13 +10675,33 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
v.AddArg6(p, w0, w1, w2, w3, mem)
return true
}
+ // match: (MOVWstore [off] {sym} ptr r:(MOVWBR x) mem)
+ // cond: r.Uses == 1
+ // result: (MOVWBRstore [off] {sym} ptr x mem)
+ for {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ r := v_1
+ if r.Op != OpS390XMOVWBR {
+ break
+ }
+ x := r.Args[0]
+ mem := v_2
+ if !(r.Uses == 1) {
+ break
+ }
+ v.reset(OpS390XMOVWBRstore)
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
+ v.AddArg3(ptr, x, mem)
+ return true
+ }
return false
}
func rewriteValueS390X_OpS390XMOVWstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem)
// cond: isU12Bit(sc.Off64()+int64(off))
// result: (MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem)
@@ -11139,31 +10745,34 @@ func rewriteValueS390X_OpS390XMOVWstoreconst(v *Value) bool {
v.AddArg2(ptr, mem)
return true
}
- // match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
- // cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
- // result: (MOVDstore [a.Off()] {s} p (MOVDconst [c.Val64()&0xffffffff | a.Val64()<<32]) mem)
+ return false
+}
+func rewriteValueS390X_OpS390XMOVWstoreidx(v *Value) bool {
+ v_3 := v.Args[3]
+ v_2 := v.Args[2]
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (MOVWstoreidx [off] {sym} ptr idx r:(MOVWBR x) mem)
+ // cond: r.Uses == 1
+ // result: (MOVWBRstoreidx [off] {sym} ptr idx x mem)
for {
- c := auxIntToValAndOff(v.AuxInt)
- s := auxToSym(v.Aux)
- p := v_0
- x := v_1
- if x.Op != OpS390XMOVWstoreconst {
- break
- }
- a := auxIntToValAndOff(x.AuxInt)
- if auxToSym(x.Aux) != s {
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
+ ptr := v_0
+ idx := v_1
+ r := v_2
+ if r.Op != OpS390XMOVWBR {
break
}
- mem := x.Args[1]
- if p != x.Args[0] || !(p.Op != OpSB && x.Uses == 1 && a.Off()+4 == c.Off() && clobber(x)) {
+ x := r.Args[0]
+ mem := v_3
+ if !(r.Uses == 1) {
break
}
- v.reset(OpS390XMOVDstore)
- v.AuxInt = int32ToAuxInt(a.Off())
- v.Aux = symToAux(s)
- v0 := b.NewValue0(x.Pos, OpS390XMOVDconst, typ.UInt64)
- v0.AuxInt = int64ToAuxInt(c.Val64()&0xffffffff | a.Val64()<<32)
- v.AddArg3(p, v0, mem)
+ v.reset(OpS390XMOVWBRstoreidx)
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
+ v.AddArg4(ptr, idx, x, mem)
return true
}
return false
@@ -11657,7 +11266,6 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
- typ := &b.Func.Config.Types
// match: (OR x (MOVDconst [c]))
// cond: isU32Bit(c)
// result: (ORconst [c] x)
@@ -11816,531 +11424,11 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
}
break
}
- // match: (OR x1:(MOVBZload [i1] {s} p mem) sh:(SLDconst [8] x0:(MOVBZload [i0] {s} p mem)))
- // cond: i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpS390XMOVHZload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (OR x1:(MOVHZload [i1] {s} p mem) sh:(SLDconst [16] x0:(MOVHZload [i0] {s} p mem)))
- // cond: i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVHZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 16 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVHZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpS390XMOVWZload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (OR x1:(MOVWZload [i1] {s} p mem) sh:(SLDconst [32] x0:(MOVWZload [i0] {s} p mem)))
- // cond: i1 == i0+4 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVDload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVWZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 32 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVWZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+4 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpS390XMOVDload, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (OR s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem)) or:(OR s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem)) y))
- // cond: i1 == i0+1 && j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := auxIntToUint8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := auxIntToUint8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = uint8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpS390XMOVHZload, typ.UInt16)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg2(p, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (OR s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem)) or:(OR s1:(SLDconst [j1] x1:(MOVHZload [i1] {s} p mem)) y))
- // cond: i1 == i0+2 && j1 == j0-16 && j1 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := auxIntToUint8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVHZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := auxIntToUint8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVHZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+2 && j1 == j0-16 && j1%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = uint8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpS390XMOVWZload, typ.UInt32)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg2(p, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (OR x0:(MOVBZload [i0] {s} p mem) sh:(SLDconst [8] x1:(MOVBZload [i1] {s} p mem)))
- // cond: p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpS390XMOVHZreg, typ.UInt64)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpS390XMOVHBRload, typ.UInt16)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)) sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r0 := v_0
- if r0.Op != OpS390XMOVHZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVHBRload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 16 {
- continue
- }
- r1 := sh.Args[0]
- if r1.Op != OpS390XMOVHZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVHBRload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpS390XMOVWZreg, typ.UInt64)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpS390XMOVWBRload, typ.UInt32)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (OR r0:(MOVWZreg x0:(MOVWBRload [i0] {s} p mem)) sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRload [i1] {s} p mem))))
- // cond: i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (MOVDBRload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r0 := v_0
- if r0.Op != OpS390XMOVWZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVWBRload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 32 {
- continue
- }
- r1 := sh.Args[0]
- if r1.Op != OpS390XMOVWZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVWBRload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpS390XMOVDBRload, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (OR s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem)) or:(OR s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem)) y))
- // cond: p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := auxIntToUint8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := auxIntToUint8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = uint8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpS390XMOVHZreg, typ.UInt64)
- v3 := b.NewValue0(x0.Pos, OpS390XMOVHBRload, typ.UInt16)
- v3.AuxInt = int32ToAuxInt(i0)
- v3.Aux = symToAux(s)
- v3.AddArg2(p, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (OR s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))) or:(OR s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))) y))
- // cond: i1 == i0+2 && j1 == j0+16 && j0 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := auxIntToUint8(s1.AuxInt)
- r1 := s1.Args[0]
- if r1.Op != OpS390XMOVHZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVHBRload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := auxIntToUint8(s0.AuxInt)
- r0 := s0.Args[0]
- if r0.Op != OpS390XMOVHZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVHBRload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+2 && j1 == j0+16 && j0%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = uint8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpS390XMOVWZreg, typ.UInt64)
- v3 := b.NewValue0(x0.Pos, OpS390XMOVWBRload, typ.UInt32)
- v3.AuxInt = int32ToAuxInt(i0)
- v3.Aux = symToAux(s)
- v3.AddArg2(p, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XORW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
// match: (ORW x (MOVDconst [c]))
// result: (ORWconst [int32(c)] x)
for {
@@ -12421,300 +11509,6 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
}
break
}
- // match: (ORW x1:(MOVBZload [i1] {s} p mem) sh:(SLWconst [8] x0:(MOVBZload [i0] {s} p mem)))
- // cond: i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpS390XMOVHZload, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORW x1:(MOVHZload [i1] {s} p mem) sh:(SLWconst [16] x0:(MOVHZload [i0] {s} p mem)))
- // cond: i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVHZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 16 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVHZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] || !(i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x0.Pos, OpS390XMOVWZload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORW s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem)) or:(ORW s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem)) y))
- // cond: i1 == i0+1 && j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpS390XSLWconst {
- continue
- }
- j0 := auxIntToUint8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- or := v_1
- if or.Op != OpS390XORW {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpS390XSLWconst {
- continue
- }
- j1 := auxIntToUint8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x1.Pos, OpS390XORW, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = uint8ToAuxInt(j1)
- v2 := b.NewValue0(x1.Pos, OpS390XMOVHZload, typ.UInt16)
- v2.AuxInt = int32ToAuxInt(i0)
- v2.Aux = symToAux(s)
- v2.AddArg2(p, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
- // match: (ORW x0:(MOVBZload [i0] {s} p mem) sh:(SLWconst [8] x1:(MOVBZload [i1] {s} p mem)))
- // cond: p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpS390XMOVHZreg, typ.UInt64)
- v.copyOf(v0)
- v1 := b.NewValue0(x1.Pos, OpS390XMOVHBRload, typ.UInt16)
- v1.AuxInt = int32ToAuxInt(i0)
- v1.Aux = symToAux(s)
- v1.AddArg2(p, mem)
- v0.AddArg(v1)
- return true
- }
- break
- }
- // match: (ORW r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)) sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWBRload [i0] {s} p mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r0 := v_0
- if r0.Op != OpS390XMOVHZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVHBRload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- s := auxToSym(x0.Aux)
- mem := x0.Args[1]
- p := x0.Args[0]
- sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 16 {
- continue
- }
- r1 := sh.Args[0]
- if r1.Op != OpS390XMOVHZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVHBRload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- if auxToSym(x1.Aux) != s {
- continue
- }
- _ = x1.Args[1]
- if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(x1.Pos, OpS390XMOVWBRload, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(i0)
- v0.Aux = symToAux(s)
- v0.AddArg2(p, mem)
- return true
- }
- break
- }
- // match: (ORW s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem)) or:(ORW s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem)) y))
- // cond: p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpS390XSLWconst {
- continue
- }
- j1 := auxIntToUint8(s1.AuxInt)
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZload {
- continue
- }
- i1 := auxIntToInt32(x1.AuxInt)
- s := auxToSym(x1.Aux)
- mem := x1.Args[1]
- p := x1.Args[0]
- or := v_1
- if or.Op != OpS390XORW {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, or_0, or_1 = _i1+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpS390XSLWconst {
- continue
- }
- j0 := auxIntToUint8(s0.AuxInt)
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZload {
- continue
- }
- i0 := auxIntToInt32(x0.AuxInt)
- if auxToSym(x0.Aux) != s {
- continue
- }
- _ = x0.Args[1]
- if p != x0.Args[0] || mem != x0.Args[1] {
- continue
- }
- y := or_1
- if !(p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(x0.Pos, OpS390XORW, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(x0.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = uint8ToAuxInt(j0)
- v2 := b.NewValue0(x0.Pos, OpS390XMOVHZreg, typ.UInt64)
- v3 := b.NewValue0(x0.Pos, OpS390XMOVHBRload, typ.UInt16)
- v3.AuxInt = int32ToAuxInt(i0)
- v3.Aux = symToAux(s)
- v3.AddArg2(p, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XORWconst(v *Value) bool {
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index 0567b3e214..6b0367a3dc 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -84,6 +84,13 @@ func (v *Value) AuxInt8() int8 {
return int8(v.AuxInt)
}
+func (v *Value) AuxUInt8() uint8 {
+ if opcodeTable[v.Op].auxType != auxUInt8 {
+ v.Fatalf("op %s doesn't have an uint8 aux field", v.Op)
+ }
+ return uint8(v.AuxInt)
+}
+
func (v *Value) AuxInt16() int16 {
if opcodeTable[v.Op].auxType != auxInt16 {
v.Fatalf("op %s doesn't have an int16 aux field", v.Op)
@@ -190,6 +197,8 @@ func (v *Value) auxString() string {
return fmt.Sprintf(" [%d]", v.AuxInt32())
case auxInt64, auxInt128:
return fmt.Sprintf(" [%d]", v.AuxInt)
+ case auxUInt8:
+ return fmt.Sprintf(" [%d]", v.AuxUInt8())
case auxARM64BitField:
lsb := v.AuxArm64BitField().getARM64BFlsb()
width := v.AuxArm64BitField().getARM64BFwidth()
@@ -202,6 +211,7 @@ func (v *Value) auxString() string {
if v.Aux != nil {
return fmt.Sprintf(" {%v}", v.Aux)
}
+ return ""
case auxSymOff, auxCallOff, auxTypSize, auxNameOffsetInt8:
s := ""
if v.Aux != nil {
@@ -223,8 +233,12 @@ func (v *Value) auxString() string {
return fmt.Sprintf(" {%v}", v.Aux)
case auxFlagConstant:
return fmt.Sprintf("[%s]", flagConstant(v.AuxInt))
+ case auxNone:
+ return ""
+ default:
+ // If you see this, add a case above instead.
+ return fmt.Sprintf("[auxtype=%d AuxInt=%d Aux=%v]", opcodeTable[v.Op].auxType, v.AuxInt, v.Aux)
}
- return ""
}
// If/when midstack inlining is enabled (-l=4), the compiler gets both larger and slower.
diff --git a/src/cmd/compile/internal/test/memcombine_test.go b/src/cmd/compile/internal/test/memcombine_test.go
new file mode 100644
index 0000000000..c7e7a208dd
--- /dev/null
+++ b/src/cmd/compile/internal/test/memcombine_test.go
@@ -0,0 +1,73 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+ "encoding/binary"
+ "testing"
+)
+
+var gv = [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8}
+
+//go:noinline
+func readGlobalUnaligned() uint64 {
+ return binary.LittleEndian.Uint64(gv[1:])
+}
+
+func TestUnalignedGlobal(t *testing.T) {
+ // Note: this is a test not so much of the result of the read, but of
+ // the correct compilation of that read. On s390x unaligned global
+ // accesses fail to compile.
+ if got, want := readGlobalUnaligned(), uint64(0x0807060504030201); got != want {
+ t.Errorf("read global %x, want %x", got, want)
+ }
+}
+
+func TestSpillOfExtendedEndianLoads(t *testing.T) {
+ b := []byte{0xaa, 0xbb, 0xcc, 0xdd}
+
+ var testCases = []struct {
+ fn func([]byte) uint64
+ want uint64
+ }{
+ {readUint16le, 0xbbaa},
+ {readUint16be, 0xaabb},
+ {readUint32le, 0xddccbbaa},
+ {readUint32be, 0xaabbccdd},
+ }
+ for _, test := range testCases {
+ if got := test.fn(b); got != test.want {
+ t.Errorf("got %x, want %x", got, test.want)
+ }
+ }
+}
+
+func readUint16le(b []byte) uint64 {
+ y := uint64(binary.LittleEndian.Uint16(b))
+ nop() // force spill
+ return y
+}
+
+func readUint16be(b []byte) uint64 {
+ y := uint64(binary.BigEndian.Uint16(b))
+ nop() // force spill
+ return y
+}
+
+func readUint32le(b []byte) uint64 {
+ y := uint64(binary.LittleEndian.Uint32(b))
+ nop() // force spill
+ return y
+}
+
+func readUint32be(b []byte) uint64 {
+ y := uint64(binary.BigEndian.Uint32(b))
+ nop() // force spill
+ return y
+}
+
+//go:noinline
+func nop() {
+}