mirror of https://github.com/golang/go.git
cmd/compile: fix ephemeral pointer problem on amd64
Make sure we don't use the rewrite ptr + (c + x) -> c + (ptr + x), as that may create an ephemeral out-of-bounds pointer. I have not seen an actual bug caused by this yet, but we've seen them in the 386 port so I'm fixing this issue for amd64 as well. The load-combining rules needed to be reworked somewhat to still work without the above broken rule. Update #37881 Change-Id: I8046d170e89e2035195f261535e34ca7d8aca68a Reviewed-on: https://go-review.googlesource.com/c/go/+/226437 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
5a31228879
commit
33b648c0e9
|
|
@ -1491,65 +1491,70 @@
|
|||
|
||||
// Little-endian loads
|
||||
|
||||
(ORL x0:(MOVBload [i0] {s} p0 mem)
|
||||
sh:(SHLLconst [8] x1:(MOVBload [i1] {s} p1 mem)))
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (MOVWload [i0] {s} p0 mem)
|
||||
-> @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
|
||||
|
||||
(ORQ x0:(MOVBload [i0] {s} p0 mem)
|
||||
sh:(SHLQconst [8] x1:(MOVBload [i1] {s} p1 mem)))
|
||||
&& i1 == i0+1
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (MOVWload [i0] {s} p0 mem)
|
||||
-> @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
|
||||
|
||||
(ORL x0:(MOVWload [i0] {s} p0 mem)
|
||||
sh:(SHLLconst [16] x1:(MOVWload [i1] {s} p1 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
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (MOVLload [i0] {s} p0 mem)
|
||||
-> @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem)
|
||||
|
||||
(ORQ x0:(MOVWload [i0] {s} p0 mem)
|
||||
sh:(SHLQconst [16] x1:(MOVWload [i1] {s} p1 mem)))
|
||||
&& i1 == i0+2
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 2)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (MOVLload [i0] {s} p0 mem)
|
||||
-> @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem)
|
||||
|
||||
(ORQ x0:(MOVLload [i0] {s} p0 mem)
|
||||
sh:(SHLQconst [32] x1:(MOVLload [i1] {s} p1 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
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (MOVQload [i0] {s} p0 mem)
|
||||
-> @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem)
|
||||
|
||||
(ORL
|
||||
s1:(SHLLconst [j1] x1:(MOVBload [i1] {s} p0 mem))
|
||||
or:(ORL
|
||||
s0:(SHLLconst [j0] x0:(MOVBload [i0] {s} p1 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
|
||||
|
|
@ -1559,17 +1564,15 @@
|
|||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0, x1, s0, s1, or)
|
||||
-> @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWload [i0] {s} p0 mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
|
||||
|
||||
(ORQ
|
||||
s1:(SHLQconst [j1] x1:(MOVBload [i1] {s} p0 mem))
|
||||
or:(ORQ
|
||||
s0:(SHLQconst [j0] x0:(MOVBload [i0] {s} p1 mem))
|
||||
(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))
|
||||
&& i1 == i0+1
|
||||
&& j1 == j0+8
|
||||
&& j0 % 16 == 0
|
||||
&& x0.Uses == 1
|
||||
|
|
@ -1577,15 +1580,15 @@
|
|||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 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] (MOVWload [i0] {s} p0 mem)) y)
|
||||
-> @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} p0 mem))
|
||||
s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem))
|
||||
or:(ORQ
|
||||
s0:(SHLQconst [j0] x0:(MOVWload [i0] {s} p1 mem))
|
||||
s0:(SHLQconst [j0] x0:(MOVWload [i0] {s} p mem))
|
||||
y))
|
||||
&& i1 == i0+2
|
||||
&& j1 == j0+16
|
||||
|
|
@ -1595,106 +1598,107 @@
|
|||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& same(p0, p1, 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} p0 mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
|
||||
|
||||
// Little-endian indexed loads
|
||||
|
||||
// Move constants offsets from LEAQx up into load. This lets the above combining
|
||||
// rules discover indexed load-combining instances.
|
||||
//TODO:remove! These rules are bad.
|
||||
(MOV(B|W|L|Q)load [i0] {s0} l:(LEAQ1 [i1] {s1} x y) mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)load [i0+i1] {s0} (LEAQ1 <l.Type> [0] {s1} x y) mem)
|
||||
(MOV(B|W|L|Q)load [i0] {s0} l:(LEAQ2 [i1] {s1} x y) mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)load [i0+i1] {s0} (LEAQ2 <l.Type> [0] {s1} x y) mem)
|
||||
(MOV(B|W|L|Q)load [i0] {s0} l:(LEAQ4 [i1] {s1} x y) mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)load [i0+i1] {s0} (LEAQ4 <l.Type> [0] {s1} x y) mem)
|
||||
(MOV(B|W|L|Q)load [i0] {s0} l:(LEAQ8 [i1] {s1} x y) mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)load [i0+i1] {s0} (LEAQ8 <l.Type> [0] {s1} x y) mem)
|
||||
|
||||
(MOV(B|W|L|Q)store [i0] {s0} l:(LEAQ1 [i1] {s1} x y) val mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)store [i0+i1] {s0} (LEAQ1 <l.Type> [0] {s1} x y) val mem)
|
||||
(MOV(B|W|L|Q)store [i0] {s0} l:(LEAQ2 [i1] {s1} x y) val mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)store [i0+i1] {s0} (LEAQ2 <l.Type> [0] {s1} x y) val mem)
|
||||
(MOV(B|W|L|Q)store [i0] {s0} l:(LEAQ4 [i1] {s1} x y) val mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)store [i0+i1] {s0} (LEAQ4 <l.Type> [0] {s1} x y) val mem)
|
||||
(MOV(B|W|L|Q)store [i0] {s0} l:(LEAQ8 [i1] {s1} x y) val mem) && i1 != 0 && is32Bit(i0+i1)
|
||||
-> (MOV(B|W|L|Q)store [i0+i1] {s0} (LEAQ8 <l.Type> [0] {s1} x y) val mem)
|
||||
(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
|
||||
|
||||
(ORL
|
||||
x1:(MOVBload [i1] {s} p0 mem)
|
||||
sh:(SHLLconst [8] x0:(MOVBload [i0] {s} p1 mem)))
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p0 mem))
|
||||
-> @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem))
|
||||
|
||||
(ORQ
|
||||
x1:(MOVBload [i1] {s} p0 mem)
|
||||
sh:(SHLQconst [8] x0:(MOVBload [i0] {s} p1 mem)))
|
||||
&& i1 == i0+1
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, sh)
|
||||
-> @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p0 mem))
|
||||
-> @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem))
|
||||
|
||||
(ORL
|
||||
r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p0 mem))
|
||||
sh:(SHLLconst [16] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p1 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
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, r0, r1, sh)
|
||||
-> @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p0 mem))
|
||||
-> @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem))
|
||||
|
||||
(ORQ
|
||||
r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p0 mem))
|
||||
sh:(SHLQconst [16] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p1 mem))))
|
||||
&& i1 == i0+2
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 2)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, r0, r1, sh)
|
||||
-> @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p0 mem))
|
||||
-> @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem))
|
||||
|
||||
(ORQ
|
||||
r1:(BSWAPL x1:(MOVLload [i1] {s} p0 mem))
|
||||
sh:(SHLQconst [32] r0:(BSWAPL x0:(MOVLload [i0] {s} p1 mem))))
|
||||
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
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& clobber(x0, x1, r0, r1, sh)
|
||||
-> @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p0 mem))
|
||||
-> @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem))
|
||||
|
||||
(ORL
|
||||
s0:(SHLLconst [j0] x0:(MOVBload [i0] {s} p0 mem))
|
||||
or:(ORL
|
||||
s1:(SHLLconst [j1] x1:(MOVBload [i1] {s} p1 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
|
||||
|
|
@ -1704,17 +1708,15 @@
|
|||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0, x1, s0, s1, or)
|
||||
-> @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p0 mem))) y)
|
||||
-> @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)
|
||||
|
||||
(ORQ
|
||||
s0:(SHLQconst [j0] x0:(MOVBload [i0] {s} p0 mem))
|
||||
or:(ORQ
|
||||
s1:(SHLQconst [j1] x1:(MOVBload [i1] {s} p1 mem))
|
||||
(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))
|
||||
&& i1 == i0+1
|
||||
&& j1 == j0-8
|
||||
&& j1 % 16 == 0
|
||||
&& x0.Uses == 1
|
||||
|
|
@ -1722,15 +1724,15 @@
|
|||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 1)
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0, x1, s0, s1, or)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p0 mem))) y)
|
||||
-> @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} p0 mem)))
|
||||
s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem)))
|
||||
or:(ORQ
|
||||
s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p1 mem)))
|
||||
s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)))
|
||||
y))
|
||||
&& i1 == i0+2
|
||||
&& j1 == j0-16
|
||||
|
|
@ -1742,41 +1744,73 @@
|
|||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& same(p0, p1, 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} p0 mem))) y)
|
||||
-> @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} p1 w
|
||||
x0:(MOVBstore [i-1] {s} p0 (SHRWconst [8] w) mem))
|
||||
(MOVBstore [i] {s} p w
|
||||
x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
|
||||
&& x0.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& clobber(x0)
|
||||
-> (MOVWstore [i-1] {s} p0 (ROLWconst <w.Type> [8] w) mem)
|
||||
-> (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [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 <w.Type> [8] w) mem)
|
||||
|
||||
// Combine stores + shifts into bswap and larger (unaligned) stores
|
||||
(MOVBstore [i] {s} p3 w
|
||||
x2:(MOVBstore [i-1] {s} p2 (SHRLconst [8] w)
|
||||
x1:(MOVBstore [i-2] {s} p1 (SHRLconst [16] w)
|
||||
x0:(MOVBstore [i-3] {s} p0 (SHRLconst [24] w) mem))))
|
||||
(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
|
||||
&& same(p0, p1, 1)
|
||||
&& same(p1, p2, 1)
|
||||
&& same(p2, p3, 1)
|
||||
&& clobber(x0, x1, x2)
|
||||
-> (MOVLstore [i-3] {s} p0 (BSWAPL <w.Type> w) mem)
|
||||
-> (MOVLstore [i-3] {s} p (BSWAPL <w.Type> 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 <w.Type> w) mem)
|
||||
|
||||
(MOVBstore [i] {s} p7 w
|
||||
x6:(MOVBstore [i-1] {s} p6 (SHRQconst [8] w)
|
||||
x5:(MOVBstore [i-2] {s} p5 (SHRQconst [16] w)
|
||||
x4:(MOVBstore [i-3] {s} p4 (SHRQconst [24] w)
|
||||
x3:(MOVBstore [i-4] {s} p3 (SHRQconst [32] w)
|
||||
x2:(MOVBstore [i-5] {s} p2 (SHRQconst [40] w)
|
||||
x1:(MOVBstore [i-6] {s} p1 (SHRQconst [48] w)
|
||||
x0:(MOVBstore [i-7] {s} p0 (SHRQconst [56] 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
|
||||
|
|
@ -1784,99 +1818,139 @@
|
|||
&& x4.Uses == 1
|
||||
&& x5.Uses == 1
|
||||
&& x6.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& same(p1, p2, 1)
|
||||
&& same(p2, p3, 1)
|
||||
&& same(p3, p4, 1)
|
||||
&& same(p4, p5, 1)
|
||||
&& same(p5, p6, 1)
|
||||
&& same(p6, p7, 1)
|
||||
&& clobber(x0, x1, x2, x3, x4, x5, x6)
|
||||
-> (MOVQstore [i-7] {s} p0 (BSWAPQ <w.Type> w) mem)
|
||||
-> (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> 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 <w.Type> w) mem)
|
||||
|
||||
// Combine constant stores into larger (unaligned) stores.
|
||||
(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
|
||||
(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(a).Off() + 1 == ValAndOff(c).Off()
|
||||
&& clobber(x)
|
||||
-> (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p0 mem)
|
||||
(MOVBstoreconst [a] {s} p1 x:(MOVBstoreconst [c] {s} p0 mem))
|
||||
-> (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p mem)
|
||||
(MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(a).Off() + 1 == ValAndOff(c).Off()
|
||||
&& clobber(x)
|
||||
-> (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p0 mem)
|
||||
(MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
|
||||
-> (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p mem)
|
||||
(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
|
||||
&& clobber(x)
|
||||
-> (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p0 mem)
|
||||
(MOVWstoreconst [a] {s} p1 x:(MOVWstoreconst [c] {s} p0 mem))
|
||||
-> (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p mem)
|
||||
(MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
|
||||
&& clobber(x)
|
||||
-> (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p0 mem)
|
||||
(MOVLstoreconst [c] {s} p1 x:(MOVLstoreconst [a] {s} p0 mem))
|
||||
-> (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p mem)
|
||||
(MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(a).Off() + 4 == ValAndOff(c).Off()
|
||||
&& clobber(x)
|
||||
-> (MOVQstore [ValAndOff(a).Off()] {s} p0 (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem)
|
||||
(MOVLstoreconst [a] {s} p1 x:(MOVLstoreconst [c] {s} p0 mem))
|
||||
-> (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem)
|
||||
(MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(a).Off() + 4 == ValAndOff(c).Off()
|
||||
&& clobber(x)
|
||||
-> (MOVQstore [ValAndOff(a).Off()] {s} p0 (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem)
|
||||
(MOVQstoreconst [c] {s} p1 x:(MOVQstoreconst [c2] {s} p0 mem))
|
||||
-> (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem)
|
||||
(MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem))
|
||||
&& config.useSSE
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& ValAndOff(c2).Off() + 8 == ValAndOff(c).Off()
|
||||
&& ValAndOff(c).Val() == 0
|
||||
&& ValAndOff(c2).Val() == 0
|
||||
&& clobber(x)
|
||||
-> (MOVOstore [ValAndOff(c2).Off()] {s} p0 (MOVOconst [0]) mem)
|
||||
-> (MOVOstore [ValAndOff(c2).Off()] {s} p (MOVOconst [0]) mem)
|
||||
|
||||
// Combine stores into larger (unaligned) stores.
|
||||
(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) x:(MOVBstore [i-1] {s} p0 w 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
|
||||
&& same(p0, p1, 1)
|
||||
&& clobber(x)
|
||||
-> (MOVWstore [i-1] {s} p0 w mem)
|
||||
(MOVBstore [i] {s} p1 w x:(MOVBstore [i+1] {s} p0 (SHR(W|L|Q)const [8] w) mem))
|
||||
-> (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
|
||||
&& same(p0, p1, 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} p1 (SHR(L|Q)const [j] w) x:(MOVBstore [i-1] {s} p0 w0:(SHR(L|Q)const [j-8] w) mem))
|
||||
(MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) mem))
|
||||
&& x.Uses == 1
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 1)
|
||||
&& clobber(x)
|
||||
-> (MOVWstore [i-1] {s} p0 w0 mem)
|
||||
(MOVWstore [i] {s} p1 (SHR(L|Q)const [16] w) x:(MOVWstore [i-2] {s} p0 w mem))
|
||||
-> (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
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 1)
|
||||
&& clobber(x)
|
||||
-> (MOVLstore [i-2] {s} p0 w mem)
|
||||
(MOVWstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVWstore [i-2] {s} p0 w0:(SHR(L|Q)const [j-16] w) mem))
|
||||
-> (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
|
||||
&& same(p0, p1, 1)
|
||||
&& clobber(x)
|
||||
-> (MOVLstore [i-2] {s} p0 w0 mem)
|
||||
(MOVLstore [i] {s} p1 (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p0 w mem))
|
||||
-> (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
|
||||
&& same(p0, p1, 1)
|
||||
&& clobber(x)
|
||||
-> (MOVQstore [i-4] {s} p0 w mem)
|
||||
(MOVLstore [i] {s} p1 (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p0 w0:(SHRQconst [j-32] w) mem))
|
||||
-> (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
|
||||
&& same(p0, p1, 1)
|
||||
&& sequentialAddresses(p0, p1, 2)
|
||||
&& clobber(x)
|
||||
-> (MOVQstore [i-4] {s} p0 w0 mem)
|
||||
-> (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 [i] {s} p
|
||||
x1:(MOVBload [j] {s2} p2 mem)
|
||||
|
|
|
|||
|
|
@ -1260,46 +1260,15 @@ func sequentialAddresses(x, y *Value, n int64) bool {
|
|||
x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
|
||||
return true
|
||||
}
|
||||
if x.Op == OpAMD64ADDQ && y.Op == OpAMD64LEAQ1 && y.AuxInt == n && y.Aux == nil &&
|
||||
(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
|
||||
x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
|
||||
return true
|
||||
}
|
||||
if x.Op == OpAMD64LEAQ1 && y.Op == OpAMD64LEAQ1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
|
||||
(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
|
||||
x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// same reports whether x and y are the same value.
|
||||
// It checks to a maximum depth of d, so it may report
|
||||
// a false negative.
|
||||
// TODO: remove when amd64 port is switched to using sequentialAddresses
|
||||
func same(x, y *Value, depth int) bool {
|
||||
if x == y {
|
||||
return true
|
||||
}
|
||||
if depth <= 0 {
|
||||
return false
|
||||
}
|
||||
if x.Op != y.Op || x.Aux != y.Aux || x.AuxInt != y.AuxInt {
|
||||
return false
|
||||
}
|
||||
if len(x.Args) != len(y.Args) {
|
||||
return false
|
||||
}
|
||||
if opcodeTable[x.Op].commutative {
|
||||
// Check exchanged ordering first.
|
||||
for i, a := range x.Args {
|
||||
j := i
|
||||
if j < 2 {
|
||||
j ^= 1
|
||||
}
|
||||
b := y.Args[j]
|
||||
if !same(a, b, depth-1) {
|
||||
goto checkNormalOrder
|
||||
}
|
||||
}
|
||||
return true
|
||||
checkNormalOrder:
|
||||
}
|
||||
for i, a := range x.Args {
|
||||
b := y.Args[i]
|
||||
if !same(a, b, depth-1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -160,14 +160,14 @@ func load_le_byte8_uint64_inv(s []byte) uint64 {
|
|||
|
||||
func load_be_byte2_uint16(s []byte) uint16 {
|
||||
// arm64:`MOVHU\t\(R[0-9]+\)`,`REV16W`,-`ORR`,-`MOVB`
|
||||
// amd64:`MOVWLZX\s\([A-Z]+\)`,-`MOVB`,-`OR`
|
||||
// amd64:`MOVWLZX\s\([A-Z]+\)`,`ROLW`,-`MOVB`,-`OR`
|
||||
// ppc64le:`MOVHBR\t\(R[0-9]+\)`,-`MOVBZ`
|
||||
return uint16(s[0])<<8 | uint16(s[1])
|
||||
}
|
||||
|
||||
func load_be_byte2_uint16_inv(s []byte) uint16 {
|
||||
// arm64:`MOVHU\t\(R[0-9]+\)`,`REV16W`,-`ORR`,-`MOVB`
|
||||
// amd64:`MOVWLZX\s\([A-Z]+\)`,-`MOVB`,-`OR`
|
||||
// amd64:`MOVWLZX\s\([A-Z]+\)`,`ROLW`,-`MOVB`,-`OR`
|
||||
// ppc64le:`MOVHBR\t\(R[0-9]+\)`,-`MOVBZ`
|
||||
return uint16(s[1]) | uint16(s[0])<<8
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ func load_be_byte4_uint32(s []byte) uint32 {
|
|||
|
||||
func load_be_byte4_uint32_inv(s []byte) uint32 {
|
||||
// arm64:`MOVWU\t\(R[0-9]+\)`,`REVW`,-`ORR`,-`REV16W`,-`MOV[BH]`
|
||||
// amd64:`MOVL\s\([A-Z]+\)`,-`MOV[BW]`,-`OR`
|
||||
// amd64:`MOVL\s\([A-Z]+\)`,`BSWAPL`,-`MOV[BW]`,-`OR`
|
||||
return uint32(s[3]) | uint32(s[2])<<8 | uint32(s[1])<<16 | uint32(s[0])<<24
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ func load_be_byte8_uint64(s []byte) uint64 {
|
|||
|
||||
func load_be_byte8_uint64_inv(s []byte) uint64 {
|
||||
// arm64:`MOVD\t\(R[0-9]+\)`,`REV`,-`ORR`,-`REVW`,-`REV16W`,-`MOV[BHW]`
|
||||
// amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]\t[^$]`,-`OR`
|
||||
// amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,`BSWAPQ`,-`MOV[BWL]\t[^$]`,-`OR`
|
||||
// ppc64le:`MOVDBR\t\(R[0-9]+\)`,-`MOV[BHW]Z`
|
||||
return uint64(s[7]) | uint64(s[6])<<8 | uint64(s[5])<<16 | uint64(s[4])<<24 | uint64(s[3])<<32 | uint64(s[2])<<40 | uint64(s[1])<<48 | uint64(s[0])<<56
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue