Commit a2f22a68 authored by Ben Shi's avatar Ben Shi Committed by Cherry Zhang

cmd/compile: optimize ARM with more efficient MOVB/MOVBU/MOVH/MOVHU

Like the indexed MOVW (MOVWloadidx/MOVWstoreidx) used in current
ARM backend, the indexed MOVB/MOVBU/MOVH/MOVHU can also be used to
generate further optimized ARM code.

My patch implements this optimization. Here are some contrast test
results against the original go compiler.

1. The total size of all .a files in pkg/ shrinks by 0.03%.

2. The compilecmp benchmark shows a little decline.
name        old time/op       new time/op       delta
Template          2.35s ± 1%        2.37s ± 3%  +0.94%  (p=0.006 n=19+19)
Unicode           1.33s ± 3%        1.33s ± 2%    ~     (p=0.158 n=20+18)
GoTypes           7.86s ± 2%        7.84s ± 1%    ~     (p=0.284 n=19+18)
Compiler          37.5s ± 1%        37.7s ± 2%    ~     (p=0.101 n=20+19)
SSA               83.4s ± 2%        83.6s ± 2%    ~     (p=0.231 n=20+20)
Flate             1.46s ± 2%        1.45s ± 1%    ~     (p=0.097 n=20+17)
GoParser          1.86s ± 2%        1.86s ± 4%    ~     (p=0.738 n=20+20)
Reflect           5.10s ± 1%        5.11s ± 1%    ~     (p=0.290 n=20+18)
Tar               1.78s ± 2%        1.77s ± 2%    ~     (p=0.166 n=19+20)
XML               2.61s ± 2%        2.61s ± 2%    ~     (p=0.665 n=19+19)
[Geo mean]        4.67s             4.68s       +0.16%

name        old user-time/op  new user-time/op  delta
Template          2.79s ± 3%        2.80s ± 2%    ~     (p=0.662 n=20+20)
Unicode           1.62s ± 3%        1.64s ± 4%    ~     (p=0.252 n=20+20)
GoTypes           9.58s ± 2%        9.62s ± 2%    ~     (p=0.250 n=20+20)
Compiler          46.2s ± 1%        46.2s ± 1%    ~     (p=0.602 n=20+19)
SSA                108s ± 1%         108s ± 2%    ~     (p=0.242 n=18+20)
Flate             1.69s ± 3%        1.69s ± 4%    ~     (p=0.470 n=20+20)
GoParser          2.16s ± 3%        2.20s ± 4%  +1.70%  (p=0.005 n=19+20)
Reflect           6.02s ± 2%        6.02s ± 2%    ~     (p=0.700 n=20+17)
Tar               2.11s ± 2%        2.11s ± 3%    ~     (p=0.480 n=18+20)
XML               3.07s ± 2%        3.11s ± 4%  +1.50%  (p=0.043 n=20+20)
[Geo mean]        5.61s             5.64s       +0.55%

name        old text-bytes    new text-bytes    delta
HelloSize         586kB ± 0%        586kB ± 0%    ~     (all equal)

name        old data-bytes    new data-bytes    delta
HelloSize        5.46kB ± 0%       5.46kB ± 0%    ~     (all equal)

name        old bss-bytes     new bss-bytes     delta
HelloSize        72.9kB ± 0%       72.9kB ± 0%    ~     (all equal)

name        old exe-bytes     new exe-bytes     delta
HelloSize        1.03MB ± 0%       1.03MB ± 0%    ~     (all equal)

3. The go1 benchmark shows improvement totally, and even more than 10%
improvement in the test case Revcomp. 
name                     old time/op    new time/op    delta
BinaryTree17-4              42.0s ± 1%     41.5s ± 1%   -1.32%  (p=0.000 n=39+40)
Fannkuch11-4                24.1s ± 1%     23.6s ± 0%   -2.38%  (p=0.000 n=40+40)
FmtFprintfEmpty-4           843ns ± 0%     839ns ± 1%   -0.46%  (p=0.000 n=33+40)
FmtFprintfString-4         1.44µs ± 1%    1.37µs ± 1%   -5.48%  (p=0.000 n=40+35)
FmtFprintfInt-4            1.44µs ± 1%    1.41µs ± 2%   -1.50%  (p=0.000 n=40+40)
FmtFprintfIntInt-4         2.07µs ± 1%    2.06µs ± 0%   -0.78%  (p=0.000 n=40+40)
FmtFprintfPrefixedInt-4    2.50µs ± 1%    2.33µs ± 1%   -6.85%  (p=0.000 n=40+40)
FmtFprintfFloat-4          4.36µs ± 1%    4.34µs ± 0%   -0.39%  (p=0.017 n=40+40)
FmtManyArgs-4              8.11µs ± 0%    8.00µs ± 0%   -1.37%  (p=0.000 n=40+40)
GobDecode-4                 105ms ± 2%     103ms ± 2%   -2.17%  (p=0.000 n=39+39)
GobEncode-4                90.1ms ± 2%    88.6ms ± 1%   -1.67%  (p=0.000 n=40+39)
Gzip-4                      4.18s ± 1%     4.09s ± 1%   -2.03%  (p=0.000 n=40+40)
Gunzip-4                    608ms ± 1%     603ms ± 1%   -0.86%  (p=0.000 n=40+34)
HTTPClientServer-4          674µs ± 3%     661µs ± 2%   -1.82%  (p=0.000 n=40+39)
JSONEncode-4                256ms ± 1%     243ms ± 0%   -5.11%  (p=0.000 n=39+31)
JSONDecode-4                915ms ± 1%     904ms ± 1%   -1.18%  (p=0.000 n=40+36)
Mandelbrot200-4            49.2ms ± 0%    49.3ms ± 0%     ~     (p=0.254 n=34+40)
GoParse-4                  46.9ms ± 2%    46.9ms ± 1%     ~     (p=0.737 n=40+39)
RegexpMatchEasy0_32-4      1.28µs ± 1%    1.27µs ± 1%   -0.71%  (p=0.000 n=40+40)
RegexpMatchEasy0_1K-4      7.86µs ± 4%    7.67µs ± 4%   -2.46%  (p=0.000 n=38+40)
RegexpMatchEasy1_32-4      1.28µs ± 1%    1.28µs ± 1%   -0.54%  (p=0.000 n=40+40)
RegexpMatchEasy1_1K-4      10.4µs ± 2%    10.3µs ± 2%   -0.88%  (p=0.003 n=40+39)
RegexpMatchMedium_32-4     2.05µs ± 0%    2.04µs ± 0%   -0.34%  (p=0.000 n=40+33)
RegexpMatchMedium_1K-4      541µs ± 1%     535µs ± 1%   -1.02%  (p=0.000 n=40+38)
RegexpMatchHard_32-4       29.3µs ± 1%    29.1µs ± 1%   -0.51%  (p=0.000 n=40+40)
RegexpMatchHard_1K-4        881µs ± 1%     871µs ± 1%   -1.15%  (p=0.000 n=40+40)
Revcomp-4                  81.7ms ± 2%    67.5ms ± 2%  -17.37%  (p=0.000 n=39+39)
Template-4                  1.05s ± 1%     1.08s ± 2%   +3.67%  (p=0.000 n=40+40)
TimeParse-4                7.24µs ± 1%    7.09µs ± 1%   -2.13%  (p=0.000 n=40+40)
TimeFormat-4               13.2µs ± 1%    13.1µs ± 0%   -0.31%  (p=0.007 n=40+31)
[Geo mean]                  733µs          718µs        -2.03%

name                     old speed      new speed      delta
GobDecode-4              7.28MB/s ± 2%  7.44MB/s ± 2%   +2.23%  (p=0.000 n=39+39)
GobEncode-4              8.52MB/s ± 2%  8.67MB/s ± 1%   +1.70%  (p=0.000 n=40+39)
Gzip-4                   4.65MB/s ± 1%  4.74MB/s ± 1%   +1.94%  (p=0.000 n=37+40)
Gunzip-4                 31.9MB/s ± 1%  32.2MB/s ± 1%   +0.90%  (p=0.000 n=40+36)
JSONEncode-4             7.57MB/s ± 1%  7.98MB/s ± 0%   +5.41%  (p=0.000 n=40+31)
JSONDecode-4             2.12MB/s ± 1%  2.15MB/s ± 1%   +1.23%  (p=0.000 n=40+40)
GoParse-4                1.23MB/s ± 1%  1.23MB/s ± 1%     ~     (p=0.769 n=39+40)
RegexpMatchEasy0_32-4    25.0MB/s ± 1%  25.2MB/s ± 1%   +0.71%  (p=0.000 n=40+40)
RegexpMatchEasy0_1K-4     130MB/s ± 5%   134MB/s ± 4%   +2.53%  (p=0.000 n=38+40)
RegexpMatchEasy1_32-4    24.9MB/s ± 1%  25.1MB/s ± 1%   +0.55%  (p=0.000 n=40+40)
RegexpMatchEasy1_1K-4    98.5MB/s ± 2%  99.4MB/s ± 2%   +0.88%  (p=0.003 n=40+39)
RegexpMatchMedium_32-4    490kB/s ± 0%   490kB/s ± 0%     ~     (all equal)
RegexpMatchMedium_1K-4   1.89MB/s ± 1%  1.91MB/s ± 1%   +1.02%  (p=0.000 n=40+38)
RegexpMatchHard_32-4     1.10MB/s ± 1%  1.10MB/s ± 0%   +0.41%  (p=0.000 n=40+33)
RegexpMatchHard_1K-4     1.16MB/s ± 1%  1.17MB/s ± 1%   +1.21%  (p=0.000 n=40+40)
Revcomp-4                31.1MB/s ± 2%  37.6MB/s ± 2%  +21.03%  (p=0.000 n=39+39)
Template-4               1.86MB/s ± 1%  1.79MB/s ± 1%   -3.51%  (p=0.000 n=40+38)
[Geo mean]               6.66MB/s       6.80MB/s        +2.13%

fixes #21492

Change-Id: Ia26e7ca393f0a5f31de240e8ff9a220453ca7e0d
Reviewed-on: https://go-review.googlesource.com/58450Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 1fe1512f
...@@ -516,7 +516,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -516,7 +516,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg() p.To.Reg = v.Args[0].Reg()
gc.AddAux(&p.To, v) gc.AddAux(&p.To, v)
case ssa.OpARMMOVWloadidx: case ssa.OpARMMOVWloadidx, ssa.OpARMMOVBUloadidx, ssa.OpARMMOVBloadidx, ssa.OpARMMOVHUloadidx, ssa.OpARMMOVHloadidx:
// this is just shift 0 bits // this is just shift 0 bits
fallthrough fallthrough
case ssa.OpARMMOVWloadshiftLL: case ssa.OpARMMOVWloadshiftLL:
...@@ -528,7 +528,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -528,7 +528,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpARMMOVWloadshiftRA: case ssa.OpARMMOVWloadshiftRA:
p := genshift(s, v.Op.Asm(), 0, v.Args[1].Reg(), v.Reg(), arm.SHIFT_AR, v.AuxInt) p := genshift(s, v.Op.Asm(), 0, v.Args[1].Reg(), v.Reg(), arm.SHIFT_AR, v.AuxInt)
p.From.Reg = v.Args[0].Reg() p.From.Reg = v.Args[0].Reg()
case ssa.OpARMMOVWstoreidx: case ssa.OpARMMOVWstoreidx, ssa.OpARMMOVBstoreidx, ssa.OpARMMOVHstoreidx:
// this is just shift 0 bits // this is just shift 0 bits
fallthrough fallthrough
case ssa.OpARMMOVWstoreshiftLL: case ssa.OpARMMOVWstoreshiftLL:
......
...@@ -499,6 +499,10 @@ ...@@ -499,6 +499,10 @@
(MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
(MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
(MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x (MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBUreg x)
(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBreg x)
(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHUreg x)
(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHreg x)
// fold constant into arithmatic ops // fold constant into arithmatic ops
(ADD x (MOVWconst [c])) -> (ADDconst [c] x) (ADD x (MOVWconst [c])) -> (ADDconst [c] x)
...@@ -1152,13 +1156,31 @@ ...@@ -1152,13 +1156,31 @@
(MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftLL ptr idx [c] val mem) (MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftLL ptr idx [c] val mem)
(MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRL ptr idx [c] val mem) (MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRL ptr idx [c] val mem)
(MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRA ptr idx [c] val mem) (MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRA ptr idx [c] val mem)
(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVBUloadidx ptr idx mem)
(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVBloadidx ptr idx mem)
(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVBstoreidx ptr idx val mem)
(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVHUloadidx ptr idx mem)
(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVHloadidx ptr idx mem)
(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVHstoreidx ptr idx val mem)
// constant folding in indexed loads and stores // constant folding in indexed loads and stores
(MOVWloadidx ptr (MOVWconst [c]) mem) -> (MOVWload [c] ptr mem) (MOVWloadidx ptr (MOVWconst [c]) mem) -> (MOVWload [c] ptr mem)
(MOVWloadidx (MOVWconst [c]) ptr mem) -> (MOVWload [c] ptr mem) (MOVWloadidx (MOVWconst [c]) ptr mem) -> (MOVWload [c] ptr mem)
(MOVBloadidx ptr (MOVWconst [c]) mem) -> (MOVBload [c] ptr mem)
(MOVBloadidx (MOVWconst [c]) ptr mem) -> (MOVBload [c] ptr mem)
(MOVBUloadidx ptr (MOVWconst [c]) mem) -> (MOVBUload [c] ptr mem)
(MOVBUloadidx (MOVWconst [c]) ptr mem) -> (MOVBUload [c] ptr mem)
(MOVHUloadidx ptr (MOVWconst [c]) mem) -> (MOVHUload [c] ptr mem)
(MOVHUloadidx (MOVWconst [c]) ptr mem) -> (MOVHUload [c] ptr mem)
(MOVHloadidx ptr (MOVWconst [c]) mem) -> (MOVHload [c] ptr mem)
(MOVHloadidx (MOVWconst [c]) ptr mem) -> (MOVHload [c] ptr mem)
(MOVWstoreidx ptr (MOVWconst [c]) val mem) -> (MOVWstore [c] ptr val mem) (MOVWstoreidx ptr (MOVWconst [c]) val mem) -> (MOVWstore [c] ptr val mem)
(MOVWstoreidx (MOVWconst [c]) ptr val mem) -> (MOVWstore [c] ptr val mem) (MOVWstoreidx (MOVWconst [c]) ptr val mem) -> (MOVWstore [c] ptr val mem)
(MOVBstoreidx ptr (MOVWconst [c]) val mem) -> (MOVBstore [c] ptr val mem)
(MOVBstoreidx (MOVWconst [c]) ptr val mem) -> (MOVBstore [c] ptr val mem)
(MOVHstoreidx ptr (MOVWconst [c]) val mem) -> (MOVHstore [c] ptr val mem)
(MOVHstoreidx (MOVWconst [c]) ptr val mem) -> (MOVHstore [c] ptr val mem)
(MOVWloadidx ptr (SLLconst idx [c]) mem) -> (MOVWloadshiftLL ptr idx [c] mem) (MOVWloadidx ptr (SLLconst idx [c]) mem) -> (MOVWloadshiftLL ptr idx [c] mem)
(MOVWloadidx (SLLconst idx [c]) ptr mem) -> (MOVWloadshiftLL ptr idx [c] mem) (MOVWloadidx (SLLconst idx [c]) ptr mem) -> (MOVWloadshiftLL ptr idx [c] mem)
......
...@@ -346,11 +346,17 @@ func init() { ...@@ -346,11 +346,17 @@ func init() {
{name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1<<auxInt. arg2=mem {name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1<<auxInt. arg2=mem
{name: "MOVWloadshiftRL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, unsigned shift. arg2=mem {name: "MOVWloadshiftRL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, unsigned shift. arg2=mem
{name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem {name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem
{name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU"}, // load from arg0 + arg1. arg2=mem
{name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB"}, // load from arg0 + arg1. arg2=mem
{name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU"}, // load from arg0 + arg1. arg2=mem
{name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH"}, // load from arg0 + arg1. arg2=mem
{name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW"}, // store arg2 to arg0 + arg1. arg3=mem {name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW"}, // store arg2 to arg0 + arg1. arg3=mem
{name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1<<auxInt. arg3=mem {name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1<<auxInt. arg3=mem
{name: "MOVWstoreshiftRL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, unsigned shift. arg3=mem {name: "MOVWstoreshiftRL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, unsigned shift. arg3=mem
{name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem {name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem
{name: "MOVBstoreidx", argLength: 4, reg: gp2store, asm: "MOVB"}, // store arg2 to arg0 + arg1. arg3=mem
{name: "MOVHstoreidx", argLength: 4, reg: gp2store, asm: "MOVH"}, // store arg2 to arg0 + arg1. arg3=mem
{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"}, // move from arg0, sign-extended from byte {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"}, // move from arg0, sign-extended from byte
{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
......
...@@ -847,10 +847,16 @@ const ( ...@@ -847,10 +847,16 @@ const (
OpARMMOVWloadshiftLL OpARMMOVWloadshiftLL
OpARMMOVWloadshiftRL OpARMMOVWloadshiftRL
OpARMMOVWloadshiftRA OpARMMOVWloadshiftRA
OpARMMOVBUloadidx
OpARMMOVBloadidx
OpARMMOVHUloadidx
OpARMMOVHloadidx
OpARMMOVWstoreidx OpARMMOVWstoreidx
OpARMMOVWstoreshiftLL OpARMMOVWstoreshiftLL
OpARMMOVWstoreshiftRL OpARMMOVWstoreshiftRL
OpARMMOVWstoreshiftRA OpARMMOVWstoreshiftRA
OpARMMOVBstoreidx
OpARMMOVHstoreidx
OpARMMOVBreg OpARMMOVBreg
OpARMMOVBUreg OpARMMOVBUreg
OpARMMOVHreg OpARMMOVHreg
...@@ -10651,6 +10657,62 @@ var opcodeTable = [...]opInfo{ ...@@ -10651,6 +10657,62 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "MOVBUloadidx",
argLen: 3,
asm: arm.AMOVBU,
reg: regInfo{
inputs: []inputInfo{
{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
},
outputs: []outputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
},
},
},
{
name: "MOVBloadidx",
argLen: 3,
asm: arm.AMOVB,
reg: regInfo{
inputs: []inputInfo{
{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
},
outputs: []outputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
},
},
},
{
name: "MOVHUloadidx",
argLen: 3,
asm: arm.AMOVHU,
reg: regInfo{
inputs: []inputInfo{
{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
},
outputs: []outputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
},
},
},
{
name: "MOVHloadidx",
argLen: 3,
asm: arm.AMOVH,
reg: regInfo{
inputs: []inputInfo{
{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
},
outputs: []outputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
},
},
},
{ {
name: "MOVWstoreidx", name: "MOVWstoreidx",
argLen: 4, argLen: 4,
...@@ -10702,6 +10764,30 @@ var opcodeTable = [...]opInfo{ ...@@ -10702,6 +10764,30 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "MOVBstoreidx",
argLen: 4,
asm: arm.AMOVB,
reg: regInfo{
inputs: []inputInfo{
{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{2, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
},
},
},
{
name: "MOVHstoreidx",
argLen: 4,
asm: arm.AMOVH,
reg: regInfo{
inputs: []inputInfo{
{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{2, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
},
},
},
{ {
name: "MOVBreg", name: "MOVBreg",
argLen: 1, argLen: 1,
......
...@@ -137,14 +137,20 @@ func rewriteValueARM(v *Value) bool { ...@@ -137,14 +137,20 @@ func rewriteValueARM(v *Value) bool {
return rewriteValueARM_OpARMLessThanU_0(v) return rewriteValueARM_OpARMLessThanU_0(v)
case OpARMMOVBUload: case OpARMMOVBUload:
return rewriteValueARM_OpARMMOVBUload_0(v) return rewriteValueARM_OpARMMOVBUload_0(v)
case OpARMMOVBUloadidx:
return rewriteValueARM_OpARMMOVBUloadidx_0(v)
case OpARMMOVBUreg: case OpARMMOVBUreg:
return rewriteValueARM_OpARMMOVBUreg_0(v) return rewriteValueARM_OpARMMOVBUreg_0(v)
case OpARMMOVBload: case OpARMMOVBload:
return rewriteValueARM_OpARMMOVBload_0(v) return rewriteValueARM_OpARMMOVBload_0(v)
case OpARMMOVBloadidx:
return rewriteValueARM_OpARMMOVBloadidx_0(v)
case OpARMMOVBreg: case OpARMMOVBreg:
return rewriteValueARM_OpARMMOVBreg_0(v) return rewriteValueARM_OpARMMOVBreg_0(v)
case OpARMMOVBstore: case OpARMMOVBstore:
return rewriteValueARM_OpARMMOVBstore_0(v) return rewriteValueARM_OpARMMOVBstore_0(v)
case OpARMMOVBstoreidx:
return rewriteValueARM_OpARMMOVBstoreidx_0(v)
case OpARMMOVDload: case OpARMMOVDload:
return rewriteValueARM_OpARMMOVDload_0(v) return rewriteValueARM_OpARMMOVDload_0(v)
case OpARMMOVDstore: case OpARMMOVDstore:
...@@ -155,14 +161,20 @@ func rewriteValueARM(v *Value) bool { ...@@ -155,14 +161,20 @@ func rewriteValueARM(v *Value) bool {
return rewriteValueARM_OpARMMOVFstore_0(v) return rewriteValueARM_OpARMMOVFstore_0(v)
case OpARMMOVHUload: case OpARMMOVHUload:
return rewriteValueARM_OpARMMOVHUload_0(v) return rewriteValueARM_OpARMMOVHUload_0(v)
case OpARMMOVHUloadidx:
return rewriteValueARM_OpARMMOVHUloadidx_0(v)
case OpARMMOVHUreg: case OpARMMOVHUreg:
return rewriteValueARM_OpARMMOVHUreg_0(v) return rewriteValueARM_OpARMMOVHUreg_0(v)
case OpARMMOVHload: case OpARMMOVHload:
return rewriteValueARM_OpARMMOVHload_0(v) return rewriteValueARM_OpARMMOVHload_0(v)
case OpARMMOVHloadidx:
return rewriteValueARM_OpARMMOVHloadidx_0(v)
case OpARMMOVHreg: case OpARMMOVHreg:
return rewriteValueARM_OpARMMOVHreg_0(v) return rewriteValueARM_OpARMMOVHreg_0(v)
case OpARMMOVHstore: case OpARMMOVHstore:
return rewriteValueARM_OpARMMOVHstore_0(v) return rewriteValueARM_OpARMMOVHstore_0(v)
case OpARMMOVHstoreidx:
return rewriteValueARM_OpARMMOVHstoreidx_0(v)
case OpARMMOVWload: case OpARMMOVWload:
return rewriteValueARM_OpARMMOVWload_0(v) return rewriteValueARM_OpARMMOVWload_0(v)
case OpARMMOVWloadidx: case OpARMMOVWloadidx:
...@@ -5755,6 +5767,10 @@ func rewriteValueARM_OpARMLessThanU_0(v *Value) bool { ...@@ -5755,6 +5767,10 @@ func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
return false return false
} }
func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool { func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
// match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: // cond:
// result: (MOVBUload [off1+off2] {sym} ptr mem) // result: (MOVBUload [off1+off2] {sym} ptr mem)
...@@ -5846,6 +5862,95 @@ func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool { ...@@ -5846,6 +5862,95 @@ func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (MOVBUload [0] {sym} (ADD ptr idx) mem)
// cond: sym == nil && !config.nacl
// result: (MOVBUloadidx ptr idx mem)
for {
if v.AuxInt != 0 {
break
}
sym := v.Aux
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpARMADD {
break
}
_ = v_0.Args[1]
ptr := v_0.Args[0]
idx := v_0.Args[1]
mem := v.Args[1]
if !(sym == nil && !config.nacl) {
break
}
v.reset(OpARMMOVBUloadidx)
v.AddArg(ptr)
v.AddArg(idx)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpARMMOVBUloadidx_0(v *Value) bool {
// match: (MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _))
// cond: isSamePtr(ptr, ptr2)
// result: (MOVBUreg x)
for {
_ = v.Args[2]
ptr := v.Args[0]
idx := v.Args[1]
v_2 := v.Args[2]
if v_2.Op != OpARMMOVBstoreidx {
break
}
_ = v_2.Args[3]
ptr2 := v_2.Args[0]
if idx != v_2.Args[1] {
break
}
x := v_2.Args[2]
if !(isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARMMOVBUreg)
v.AddArg(x)
return true
}
// match: (MOVBUloadidx ptr (MOVWconst [c]) mem)
// cond:
// result: (MOVBUload [c] ptr mem)
for {
_ = v.Args[2]
ptr := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpARMMOVWconst {
break
}
c := v_1.AuxInt
mem := v.Args[2]
v.reset(OpARMMOVBUload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
// match: (MOVBUloadidx (MOVWconst [c]) ptr mem)
// cond:
// result: (MOVBUload [c] ptr mem)
for {
_ = v.Args[2]
v_0 := v.Args[0]
if v_0.Op != OpARMMOVWconst {
break
}
c := v_0.AuxInt
ptr := v.Args[1]
mem := v.Args[2]
v.reset(OpARMMOVBUload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
return false return false
} }
func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool { func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
...@@ -5905,6 +6010,10 @@ func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool { ...@@ -5905,6 +6010,10 @@ func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
return false return false
} }
func rewriteValueARM_OpARMMOVBload_0(v *Value) bool { func rewriteValueARM_OpARMMOVBload_0(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) // match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: // cond:
// result: (MOVBload [off1+off2] {sym} ptr mem) // result: (MOVBload [off1+off2] {sym} ptr mem)
...@@ -5996,6 +6105,95 @@ func rewriteValueARM_OpARMMOVBload_0(v *Value) bool { ...@@ -5996,6 +6105,95 @@ func rewriteValueARM_OpARMMOVBload_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (MOVBload [0] {sym} (ADD ptr idx) mem)
// cond: sym == nil && !config.nacl
// result: (MOVBloadidx ptr idx mem)
for {
if v.AuxInt != 0 {
break
}
sym := v.Aux
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpARMADD {
break
}
_ = v_0.Args[1]
ptr := v_0.Args[0]
idx := v_0.Args[1]
mem := v.Args[1]
if !(sym == nil && !config.nacl) {
break
}
v.reset(OpARMMOVBloadidx)
v.AddArg(ptr)
v.AddArg(idx)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpARMMOVBloadidx_0(v *Value) bool {
// match: (MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _))
// cond: isSamePtr(ptr, ptr2)
// result: (MOVBreg x)
for {
_ = v.Args[2]
ptr := v.Args[0]
idx := v.Args[1]
v_2 := v.Args[2]
if v_2.Op != OpARMMOVBstoreidx {
break
}
_ = v_2.Args[3]
ptr2 := v_2.Args[0]
if idx != v_2.Args[1] {
break
}
x := v_2.Args[2]
if !(isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARMMOVBreg)
v.AddArg(x)
return true
}
// match: (MOVBloadidx ptr (MOVWconst [c]) mem)
// cond:
// result: (MOVBload [c] ptr mem)
for {
_ = v.Args[2]
ptr := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpARMMOVWconst {
break
}
c := v_1.AuxInt
mem := v.Args[2]
v.reset(OpARMMOVBload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
// match: (MOVBloadidx (MOVWconst [c]) ptr mem)
// cond:
// result: (MOVBload [c] ptr mem)
for {
_ = v.Args[2]
v_0 := v.Args[0]
if v_0.Op != OpARMMOVWconst {
break
}
c := v_0.AuxInt
ptr := v.Args[1]
mem := v.Args[2]
v.reset(OpARMMOVBload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
return false return false
} }
func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool { func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
...@@ -6058,6 +6256,10 @@ func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool { ...@@ -6058,6 +6256,10 @@ func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
return false return false
} }
func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool { func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) // match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: // cond:
// result: (MOVBstore [off1+off2] {sym} ptr val mem) // result: (MOVBstore [off1+off2] {sym} ptr val mem)
...@@ -6219,6 +6421,77 @@ func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool { ...@@ -6219,6 +6421,77 @@ func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
v.AddArg(mem) v.AddArg(mem)
return true return true
} }
// match: (MOVBstore [0] {sym} (ADD ptr idx) val mem)
// cond: sym == nil && !config.nacl
// result: (MOVBstoreidx ptr idx val mem)
for {
if v.AuxInt != 0 {
break
}
sym := v.Aux
_ = v.Args[2]
v_0 := v.Args[0]
if v_0.Op != OpARMADD {
break
}
_ = v_0.Args[1]
ptr := v_0.Args[0]
idx := v_0.Args[1]
val := v.Args[1]
mem := v.Args[2]
if !(sym == nil && !config.nacl) {
break
}
v.reset(OpARMMOVBstoreidx)
v.AddArg(ptr)
v.AddArg(idx)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpARMMOVBstoreidx_0(v *Value) bool {
// match: (MOVBstoreidx ptr (MOVWconst [c]) val mem)
// cond:
// result: (MOVBstore [c] ptr val mem)
for {
_ = v.Args[3]
ptr := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpARMMOVWconst {
break
}
c := v_1.AuxInt
val := v.Args[2]
mem := v.Args[3]
v.reset(OpARMMOVBstore)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
return true
}
// match: (MOVBstoreidx (MOVWconst [c]) ptr val mem)
// cond:
// result: (MOVBstore [c] ptr val mem)
for {
_ = v.Args[3]
v_0 := v.Args[0]
if v_0.Op != OpARMMOVWconst {
break
}
c := v_0.AuxInt
ptr := v.Args[1]
val := v.Args[2]
mem := v.Args[3]
v.reset(OpARMMOVBstore)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false return false
} }
func rewriteValueARM_OpARMMOVDload_0(v *Value) bool { func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
...@@ -6564,6 +6837,10 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool { ...@@ -6564,6 +6837,10 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
return false return false
} }
func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool { func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
// match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: // cond:
// result: (MOVHUload [off1+off2] {sym} ptr mem) // result: (MOVHUload [off1+off2] {sym} ptr mem)
...@@ -6655,6 +6932,95 @@ func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool { ...@@ -6655,6 +6932,95 @@ func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (MOVHUload [0] {sym} (ADD ptr idx) mem)
// cond: sym == nil && !config.nacl
// result: (MOVHUloadidx ptr idx mem)
for {
if v.AuxInt != 0 {
break
}
sym := v.Aux
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpARMADD {
break
}
_ = v_0.Args[1]
ptr := v_0.Args[0]
idx := v_0.Args[1]
mem := v.Args[1]
if !(sym == nil && !config.nacl) {
break
}
v.reset(OpARMMOVHUloadidx)
v.AddArg(ptr)
v.AddArg(idx)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpARMMOVHUloadidx_0(v *Value) bool {
// match: (MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
// cond: isSamePtr(ptr, ptr2)
// result: (MOVHUreg x)
for {
_ = v.Args[2]
ptr := v.Args[0]
idx := v.Args[1]
v_2 := v.Args[2]
if v_2.Op != OpARMMOVHstoreidx {
break
}
_ = v_2.Args[3]
ptr2 := v_2.Args[0]
if idx != v_2.Args[1] {
break
}
x := v_2.Args[2]
if !(isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARMMOVHUreg)
v.AddArg(x)
return true
}
// match: (MOVHUloadidx ptr (MOVWconst [c]) mem)
// cond:
// result: (MOVHUload [c] ptr mem)
for {
_ = v.Args[2]
ptr := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpARMMOVWconst {
break
}
c := v_1.AuxInt
mem := v.Args[2]
v.reset(OpARMMOVHUload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
// match: (MOVHUloadidx (MOVWconst [c]) ptr mem)
// cond:
// result: (MOVHUload [c] ptr mem)
for {
_ = v.Args[2]
v_0 := v.Args[0]
if v_0.Op != OpARMMOVWconst {
break
}
c := v_0.AuxInt
ptr := v.Args[1]
mem := v.Args[2]
v.reset(OpARMMOVHUload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
return false return false
} }
func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool { func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
...@@ -6739,6 +7105,10 @@ func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool { ...@@ -6739,6 +7105,10 @@ func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
return false return false
} }
func rewriteValueARM_OpARMMOVHload_0(v *Value) bool { func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: // cond:
// result: (MOVHload [off1+off2] {sym} ptr mem) // result: (MOVHload [off1+off2] {sym} ptr mem)
...@@ -6830,6 +7200,95 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool { ...@@ -6830,6 +7200,95 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (MOVHload [0] {sym} (ADD ptr idx) mem)
// cond: sym == nil && !config.nacl
// result: (MOVHloadidx ptr idx mem)
for {
if v.AuxInt != 0 {
break
}
sym := v.Aux
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpARMADD {
break
}
_ = v_0.Args[1]
ptr := v_0.Args[0]
idx := v_0.Args[1]
mem := v.Args[1]
if !(sym == nil && !config.nacl) {
break
}
v.reset(OpARMMOVHloadidx)
v.AddArg(ptr)
v.AddArg(idx)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
// match: (MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
// cond: isSamePtr(ptr, ptr2)
// result: (MOVHreg x)
for {
_ = v.Args[2]
ptr := v.Args[0]
idx := v.Args[1]
v_2 := v.Args[2]
if v_2.Op != OpARMMOVHstoreidx {
break
}
_ = v_2.Args[3]
ptr2 := v_2.Args[0]
if idx != v_2.Args[1] {
break
}
x := v_2.Args[2]
if !(isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARMMOVHreg)
v.AddArg(x)
return true
}
// match: (MOVHloadidx ptr (MOVWconst [c]) mem)
// cond:
// result: (MOVHload [c] ptr mem)
for {
_ = v.Args[2]
ptr := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpARMMOVWconst {
break
}
c := v_1.AuxInt
mem := v.Args[2]
v.reset(OpARMMOVHload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
// match: (MOVHloadidx (MOVWconst [c]) ptr mem)
// cond:
// result: (MOVHload [c] ptr mem)
for {
_ = v.Args[2]
v_0 := v.Args[0]
if v_0.Op != OpARMMOVWconst {
break
}
c := v_0.AuxInt
ptr := v.Args[1]
mem := v.Args[2]
v.reset(OpARMMOVHload)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(mem)
return true
}
return false return false
} }
func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool { func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
...@@ -6942,6 +7401,10 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool { ...@@ -6942,6 +7401,10 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
return false return false
} }
func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool { func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: // cond:
// result: (MOVHstore [off1+off2] {sym} ptr val mem) // result: (MOVHstore [off1+off2] {sym} ptr val mem)
...@@ -7059,6 +7522,77 @@ func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool { ...@@ -7059,6 +7522,77 @@ func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
v.AddArg(mem) v.AddArg(mem)
return true return true
} }
// match: (MOVHstore [0] {sym} (ADD ptr idx) val mem)
// cond: sym == nil && !config.nacl
// result: (MOVHstoreidx ptr idx val mem)
for {
if v.AuxInt != 0 {
break
}
sym := v.Aux
_ = v.Args[2]
v_0 := v.Args[0]
if v_0.Op != OpARMADD {
break
}
_ = v_0.Args[1]
ptr := v_0.Args[0]
idx := v_0.Args[1]
val := v.Args[1]
mem := v.Args[2]
if !(sym == nil && !config.nacl) {
break
}
v.reset(OpARMMOVHstoreidx)
v.AddArg(ptr)
v.AddArg(idx)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpARMMOVHstoreidx_0(v *Value) bool {
// match: (MOVHstoreidx ptr (MOVWconst [c]) val mem)
// cond:
// result: (MOVHstore [c] ptr val mem)
for {
_ = v.Args[3]
ptr := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpARMMOVWconst {
break
}
c := v_1.AuxInt
val := v.Args[2]
mem := v.Args[3]
v.reset(OpARMMOVHstore)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
return true
}
// match: (MOVHstoreidx (MOVWconst [c]) ptr val mem)
// cond:
// result: (MOVHstore [c] ptr val mem)
for {
_ = v.Args[3]
v_0 := v.Args[0]
if v_0.Op != OpARMMOVWconst {
break
}
c := v_0.AuxInt
ptr := v.Args[1]
val := v.Args[2]
mem := v.Args[3]
v.reset(OpARMMOVHstore)
v.AuxInt = c
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false return false
} }
func rewriteValueARM_OpARMMOVWload_0(v *Value) bool { func rewriteValueARM_OpARMMOVWload_0(v *Value) bool {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment