]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize ARM code with CMN/TST/TEQ
authorBen Shi <powerman1st@163.com>
Mon, 2 Oct 2017 03:09:28 +0000 (03:09 +0000)
committerCherry Zhang <cherryyz@google.com>
Wed, 11 Oct 2017 14:03:00 +0000 (14:03 +0000)
CMN/TST/TEQ were supported since ARMv4, which can be used to
simplify comparisons.

This patch implements the optimization and here are the benchmark
results.

1. A special test case got 18.21% improvement.
name                     old time/op    new time/op    delta
TSTTEQ-4                    806µs ± 1%     659µs ± 0%  -18.21%  (p=0.000 n=20+18)
(https://github.com/benshi001/ugo1/blob/master/tstteq_test.go)

2. There is no regression in the compilecmp benchmark.
name        old time/op       new time/op       delta
Template          2.31s ± 1%        2.30s ± 1%    ~     (p=0.661 n=10+9)
Unicode           1.32s ± 3%        1.32s ± 5%    ~     (p=0.280 n=10+10)
GoTypes           7.69s ± 1%        7.65s ± 0%  -0.52%  (p=0.027 n=10+8)
Compiler          36.5s ± 1%        36.4s ± 1%    ~     (p=0.546 n=9+9)
SSA               85.1s ± 2%        84.9s ± 1%    ~     (p=0.529 n=10+10)
Flate             1.43s ± 2%        1.43s ± 2%    ~     (p=0.661 n=10+9)
GoParser          1.81s ± 2%        1.81s ± 1%    ~     (p=0.796 n=10+10)
Reflect           5.10s ± 2%        5.09s ± 1%    ~     (p=0.853 n=10+10)
Tar               2.47s ± 1%        2.48s ± 1%    ~     (p=0.123 n=10+10)
XML               2.59s ± 1%        2.58s ± 1%    ~     (p=0.853 n=10+10)
[Geo mean]        4.78s             4.77s       -0.17%

name        old user-time/op  new user-time/op  delta
Template          2.72s ± 3%        2.73s ± 2%    ~     (p=0.928 n=10+10)
Unicode           1.58s ± 4%        1.60s ± 1%    ~     (p=0.087 n=10+9)
GoTypes           9.41s ± 2%        9.36s ± 1%    ~     (p=0.060 n=10+10)
Compiler          44.4s ± 2%        44.2s ± 2%    ~     (p=0.289 n=10+10)
SSA                110s ± 2%         110s ± 1%    ~     (p=0.739 n=10+10)
Flate             1.67s ± 2%        1.63s ± 3%    ~     (p=0.063 n=10+10)
GoParser          2.12s ± 1%        2.12s ± 2%    ~     (p=0.840 n=10+10)
Reflect           5.94s ± 1%        5.98s ± 1%    ~     (p=0.063 n=9+10)
Tar               3.01s ± 2%        3.02s ± 2%    ~     (p=0.584 n=10+10)
XML               3.04s ± 3%        3.02s ± 2%    ~     (p=0.696 n=10+10)
[Geo mean]        5.73s             5.72s       -0.20%

name        old text-bytes    new text-bytes    delta
HelloSize         579kB ± 0%        579kB ± 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.8kB ± 0%       72.8kB ± 0%    ~     (all equal)

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

3. There is little change in the go1 benchmark (excluding the noise).
name                     old time/op    new time/op     delta
BinaryTree17-4              40.3s ± 1%      40.6s ± 1%  +0.80%  (p=0.000 n=30+30)
Fannkuch11-4                24.2s ± 1%      24.1s ± 0%    ~     (p=0.093 n=30+30)
FmtFprintfEmpty-4           834ns ± 0%      826ns ± 0%  -0.93%  (p=0.000 n=29+24)
FmtFprintfString-4         1.39µs ± 1%     1.36µs ± 0%  -2.02%  (p=0.000 n=30+30)
FmtFprintfInt-4            1.43µs ± 1%     1.44µs ± 1%    ~     (p=0.155 n=30+29)
FmtFprintfIntInt-4         2.09µs ± 0%     2.11µs ± 0%  +1.16%  (p=0.000 n=28+30)
FmtFprintfPrefixedInt-4    2.33µs ± 1%     2.36µs ± 0%  +1.25%  (p=0.000 n=30+30)
FmtFprintfFloat-4          4.27µs ± 1%     4.32µs ± 1%  +1.27%  (p=0.000 n=30+30)
FmtManyArgs-4              8.18µs ± 0%     8.14µs ± 0%  -0.46%  (p=0.000 n=25+27)
GobDecode-4                 101ms ± 1%      101ms ± 1%    ~     (p=0.182 n=29+29)
GobEncode-4                89.6ms ± 1%     87.8ms ± 2%  -2.02%  (p=0.000 n=30+29)
Gzip-4                      4.07s ± 1%      4.08s ± 1%    ~     (p=0.173 n=30+27)
Gunzip-4                    602ms ± 1%      600ms ± 1%  -0.29%  (p=0.000 n=29+28)
HTTPClientServer-4          679µs ± 4%      683µs ± 3%    ~     (p=0.197 n=30+30)
JSONEncode-4                241ms ± 1%      239ms ± 1%  -0.84%  (p=0.000 n=30+30)
JSONDecode-4                903ms ± 1%      882ms ± 1%  -2.33%  (p=0.000 n=30+30)
Mandelbrot200-4            41.8ms ± 0%     41.8ms ± 0%    ~     (p=0.719 n=30+30)
GoParse-4                  45.5ms ± 1%     45.8ms ± 1%  +0.52%  (p=0.000 n=30+30)
RegexpMatchEasy0_32-4      1.27µs ± 1%     1.27µs ± 0%  -0.60%  (p=0.000 n=30+30)
RegexpMatchEasy0_1K-4      7.77µs ± 6%     7.69µs ± 4%  -0.96%  (p=0.040 n=30+30)
RegexpMatchEasy1_32-4      1.29µs ± 1%     1.28µs ± 1%  -0.54%  (p=0.000 n=30+30)
RegexpMatchEasy1_1K-4      10.3µs ± 6%     10.2µs ± 3%    ~     (p=0.453 n=30+27)
RegexpMatchMedium_32-4     1.98µs ± 1%     2.00µs ± 1%  +0.85%  (p=0.000 n=30+29)
RegexpMatchMedium_1K-4      503µs ± 0%      503µs ± 1%    ~     (p=0.752 n=30+30)
RegexpMatchHard_32-4       27.1µs ± 1%     26.5µs ± 0%  -1.96%  (p=0.000 n=30+24)
RegexpMatchHard_1K-4        809µs ± 1%      799µs ± 1%  -1.29%  (p=0.000 n=29+30)
Revcomp-4                  67.3ms ± 2%     67.2ms ± 1%    ~     (p=0.265 n=29+29)
Template-4                  1.08s ± 1%      1.07s ± 0%  -1.39%  (p=0.000 n=30+22)
TimeParse-4                6.93µs ± 1%     6.96µs ± 1%  +0.40%  (p=0.005 n=30+30)
TimeFormat-4               13.3µs ± 0%     13.3µs ± 1%    ~     (p=0.734 n=30+30)
[Geo mean]                  709µs           707µs       -0.32%

name                     old speed      new speed       delta
GobDecode-4              7.59MB/s ± 1%   7.57MB/s ± 1%    ~     (p=0.145 n=29+29)
GobEncode-4              8.56MB/s ± 1%   8.74MB/s ± 1%  +2.07%  (p=0.000 n=30+29)
Gzip-4                   4.76MB/s ± 1%   4.75MB/s ± 1%  -0.25%  (p=0.037 n=30+30)
Gunzip-4                 32.2MB/s ± 1%   32.3MB/s ± 1%  +0.29%  (p=0.000 n=29+28)
JSONEncode-4             8.04MB/s ± 1%   8.11MB/s ± 1%  +0.85%  (p=0.000 n=30+30)
JSONDecode-4             2.15MB/s ± 1%   2.20MB/s ± 1%  +2.29%  (p=0.000 n=30+30)
GoParse-4                1.27MB/s ± 1%   1.26MB/s ± 1%  -0.73%  (p=0.000 n=30+30)
RegexpMatchEasy0_32-4    25.1MB/s ± 1%   25.3MB/s ± 0%  +0.61%  (p=0.000 n=30+30)
RegexpMatchEasy0_1K-4     131MB/s ± 6%    133MB/s ± 4%  +1.35%  (p=0.009 n=28+30)
RegexpMatchEasy1_32-4    24.9MB/s ± 1%   25.0MB/s ± 1%  +0.54%  (p=0.000 n=30+30)
RegexpMatchEasy1_1K-4    99.2MB/s ± 6%  100.2MB/s ± 3%    ~     (p=0.448 n=30+27)
RegexpMatchMedium_32-4    503kB/s ± 1%    500kB/s ± 0%  -0.66%  (p=0.002 n=30+24)
RegexpMatchMedium_1K-4   2.04MB/s ± 0%   2.04MB/s ± 1%    ~     (p=0.358 n=30+30)
RegexpMatchHard_32-4     1.18MB/s ± 1%   1.20MB/s ± 1%  +1.75%  (p=0.000 n=30+30)
RegexpMatchHard_1K-4     1.26MB/s ± 1%   1.28MB/s ± 1%  +1.42%  (p=0.000 n=30+30)
Revcomp-4                37.8MB/s ± 2%   37.8MB/s ± 1%    ~     (p=0.266 n=29+29)
Template-4               1.80MB/s ± 1%   1.82MB/s ± 1%  +1.46%  (p=0.000 n=30+30)
[Geo mean]               6.91MB/s        6.96MB/s       +0.70%

fixes #21583

Change-Id: I24065a80588ccae7de3ad732a3cfb0026cf7e214
Reviewed-on: https://go-review.googlesource.com/67490
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARMOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteARM.go

index 41887753291bd64f4a19ba5f4261bea37fce4b9e..aee9ff3014efcfb18602ecdd5c101bfbb87fdb04 100644 (file)
@@ -473,17 +473,17 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p := s.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_REG
                p.From.Reg = v.Args[0].Reg()
-       case ssa.OpARMCMPshiftLL:
+       case ssa.OpARMCMPshiftLL, ssa.OpARMCMNshiftLL, ssa.OpARMTSTshiftLL, ssa.OpARMTEQshiftLL:
                genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm.SHIFT_LL, v.AuxInt)
-       case ssa.OpARMCMPshiftRL:
+       case ssa.OpARMCMPshiftRL, ssa.OpARMCMNshiftRL, ssa.OpARMTSTshiftRL, ssa.OpARMTEQshiftRL:
                genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm.SHIFT_LR, v.AuxInt)
-       case ssa.OpARMCMPshiftRA:
+       case ssa.OpARMCMPshiftRA, ssa.OpARMCMNshiftRA, ssa.OpARMTSTshiftRA, ssa.OpARMTEQshiftRA:
                genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm.SHIFT_AR, v.AuxInt)
-       case ssa.OpARMCMPshiftLLreg:
+       case ssa.OpARMCMPshiftLLreg, ssa.OpARMCMNshiftLLreg, ssa.OpARMTSTshiftLLreg, ssa.OpARMTEQshiftLLreg:
                genregshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg(), 0, arm.SHIFT_LL)
-       case ssa.OpARMCMPshiftRLreg:
+       case ssa.OpARMCMPshiftRLreg, ssa.OpARMCMNshiftRLreg, ssa.OpARMTSTshiftRLreg, ssa.OpARMTEQshiftRLreg:
                genregshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg(), 0, arm.SHIFT_LR)
-       case ssa.OpARMCMPshiftRAreg:
+       case ssa.OpARMCMPshiftRAreg, ssa.OpARMCMNshiftRAreg, ssa.OpARMTSTshiftRAreg, ssa.OpARMTEQshiftRAreg:
                genregshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg(), 0, arm.SHIFT_AR)
        case ssa.OpARMMOVWaddr:
                p := s.Prog(arm.AMOVW)
index 3378e4db8a6022cd0946bbcdfef17bc58f680552..a5e440336aea3cc47948aa39833156788647894f 100644 (file)
 
 (CMP x (MOVWconst [c])) -> (CMPconst [c] x)
 (CMP (MOVWconst [c]) x) -> (InvertFlags (CMPconst [c] x))
+(CMN x (MOVWconst [c])) -> (CMNconst [c] x)
+(TST x (MOVWconst [c])) -> (TSTconst [c] x)
+(TEQ x (MOVWconst [c])) -> (TEQconst [c] x)
 
 // don't extend after proper load
 // MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type.
 (CMPconst (MOVWconst [x]) [y]) && int32(x)<int32(y) && uint32(x)>uint32(y) -> (FlagLT_UGT)
 (CMPconst (MOVWconst [x]) [y]) && int32(x)>int32(y) && uint32(x)<uint32(y) -> (FlagGT_ULT)
 (CMPconst (MOVWconst [x]) [y]) && int32(x)>int32(y) && uint32(x)>uint32(y) -> (FlagGT_UGT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)==int32(-y) -> (FlagEQ)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)<int32(-y) && uint32(x)<uint32(-y) -> (FlagLT_ULT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)<int32(-y) && uint32(x)>uint32(-y) -> (FlagLT_UGT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)>int32(-y) && uint32(x)<uint32(-y) -> (FlagGT_ULT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)>int32(-y) && uint32(x)>uint32(-y) -> (FlagGT_UGT)
+(TSTconst (MOVWconst [x]) [y]) && int32(x&y)==0 -> (FlagEQ)
+(TSTconst (MOVWconst [x]) [y]) && int32(x&y)<0 -> (FlagLT_UGT)
+(TSTconst (MOVWconst [x]) [y]) && int32(x&y)>0 -> (FlagGT_UGT)
+(TEQconst (MOVWconst [x]) [y]) && int32(x^y)==0 -> (FlagEQ)
+(TEQconst (MOVWconst [x]) [y]) && int32(x^y)<0 -> (FlagLT_UGT)
+(TEQconst (MOVWconst [x]) [y]) && int32(x^y)>0 -> (FlagGT_UGT)
 
 // other known comparisons
 (CMPconst (MOVBUreg _) [c]) && 0xff < c -> (FlagLT_ULT)
 (CMP (SRL y z) x) -> (InvertFlags (CMPshiftRLreg x y z))
 (CMP x (SRA y z)) -> (CMPshiftRAreg x y z)
 (CMP (SRA y z) x) -> (InvertFlags (CMPshiftRAreg x y z))
+(TST x (SLLconst [c] y)) -> (TSTshiftLL x y [c])
+(TST x (SRLconst [c] y)) -> (TSTshiftRL x y [c])
+(TST x (SRAconst [c] y)) -> (TSTshiftRA x y [c])
+(TST x (SLL y z)) -> (TSTshiftLLreg x y z)
+(TST x (SRL y z)) -> (TSTshiftRLreg x y z)
+(TST x (SRA y z)) -> (TSTshiftRAreg x y z)
+(TEQ x (SLLconst [c] y)) -> (TEQshiftLL x y [c])
+(TEQ x (SRLconst [c] y)) -> (TEQshiftRL x y [c])
+(TEQ x (SRAconst [c] y)) -> (TEQshiftRA x y [c])
+(TEQ x (SLL y z)) -> (TEQshiftLLreg x y z)
+(TEQ x (SRL y z)) -> (TEQshiftRLreg x y z)
+(TEQ x (SRA y z)) -> (TEQshiftRAreg x y z)
+(CMN x (SLLconst [c] y)) -> (CMNshiftLL x y [c])
+(CMN x (SRLconst [c] y)) -> (CMNshiftRL x y [c])
+(CMN x (SRAconst [c] y)) -> (CMNshiftRA x y [c])
+(CMN x (SLL y z)) -> (CMNshiftLLreg x y z)
+(CMN x (SRL y z)) -> (CMNshiftRLreg x y z)
+(CMN x (SRA y z)) -> (CMNshiftRAreg x y z)
 
 // prefer *const ops to *shift ops
 (ADDshiftLL (MOVWconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d]))
 (CMPshiftLL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
 (CMPshiftRL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
 (CMPshiftRA (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
+(TSTshiftLL (MOVWconst [c]) x [d]) -> (TSTconst [c] (SLLconst <x.Type> x [d]))
+(TSTshiftRL (MOVWconst [c]) x [d]) -> (TSTconst [c] (SRLconst <x.Type> x [d]))
+(TSTshiftRA (MOVWconst [c]) x [d]) -> (TSTconst [c] (SRAconst <x.Type> x [d]))
+(TEQshiftLL (MOVWconst [c]) x [d]) -> (TEQconst [c] (SLLconst <x.Type> x [d]))
+(TEQshiftRL (MOVWconst [c]) x [d]) -> (TEQconst [c] (SRLconst <x.Type> x [d]))
+(TEQshiftRA (MOVWconst [c]) x [d]) -> (TEQconst [c] (SRAconst <x.Type> x [d]))
+(CMNshiftLL (MOVWconst [c]) x [d]) -> (CMNconst [c] (SLLconst <x.Type> x [d]))
+(CMNshiftRL (MOVWconst [c]) x [d]) -> (CMNconst [c] (SRLconst <x.Type> x [d]))
+(CMNshiftRA (MOVWconst [c]) x [d]) -> (CMNconst [c] (SRAconst <x.Type> x [d]))
 
 (ADDshiftLLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SLL <x.Type> x y))
 (ADDshiftRLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SRL <x.Type> x y))
 (CMPshiftLLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
 (CMPshiftRLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
 (CMPshiftRAreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
+(TSTshiftLLreg (MOVWconst [c]) x y) -> (TSTconst [c] (SLL <x.Type> x y))
+(TSTshiftRLreg (MOVWconst [c]) x y) -> (TSTconst [c] (SRL <x.Type> x y))
+(TSTshiftRAreg (MOVWconst [c]) x y) -> (TSTconst [c] (SRA <x.Type> x y))
+(TEQshiftLLreg (MOVWconst [c]) x y) -> (TEQconst [c] (SLL <x.Type> x y))
+(TEQshiftRLreg (MOVWconst [c]) x y) -> (TEQconst [c] (SRL <x.Type> x y))
+(TEQshiftRAreg (MOVWconst [c]) x y) -> (TEQconst [c] (SRA <x.Type> x y))
+(CMNshiftLLreg (MOVWconst [c]) x y) -> (CMNconst [c] (SLL <x.Type> x y))
+(CMNshiftRLreg (MOVWconst [c]) x y) -> (CMNconst [c] (SRL <x.Type> x y))
+(CMNshiftRAreg (MOVWconst [c]) x y) -> (CMNconst [c] (SRA <x.Type> x y))
 
 // constant folding in *shift ops
 (ADDshiftLL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(uint32(c)<<uint64(d))])
 (CMPshiftLL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(uint32(c)<<uint64(d))])
 (CMPshiftRL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(uint32(c)>>uint64(d))])
 (CMPshiftRA x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(c)>>uint64(d))])
+(TSTshiftLL x (MOVWconst [c]) [d]) -> (TSTconst x [int64(uint32(c)<<uint64(d))])
+(TSTshiftRL x (MOVWconst [c]) [d]) -> (TSTconst x [int64(uint32(c)>>uint64(d))])
+(TSTshiftRA x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(c)>>uint64(d))])
+(TEQshiftLL x (MOVWconst [c]) [d]) -> (TEQconst x [int64(uint32(c)<<uint64(d))])
+(TEQshiftRL x (MOVWconst [c]) [d]) -> (TEQconst x [int64(uint32(c)>>uint64(d))])
+(TEQshiftRA x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(c)>>uint64(d))])
+(CMNshiftLL x (MOVWconst [c]) [d]) -> (CMNconst x [int64(uint32(c)<<uint64(d))])
+(CMNshiftRL x (MOVWconst [c]) [d]) -> (CMNconst x [int64(uint32(c)>>uint64(d))])
+(CMNshiftRA x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(c)>>uint64(d))])
 
 (ADDshiftLLreg x y (MOVWconst [c])) -> (ADDshiftLL x y [c])
 (ADDshiftRLreg x y (MOVWconst [c])) -> (ADDshiftRL x y [c])
 (CMPshiftLLreg x y (MOVWconst [c])) -> (CMPshiftLL x y [c])
 (CMPshiftRLreg x y (MOVWconst [c])) -> (CMPshiftRL x y [c])
 (CMPshiftRAreg x y (MOVWconst [c])) -> (CMPshiftRA x y [c])
+(TSTshiftLLreg x y (MOVWconst [c])) -> (TSTshiftLL x y [c])
+(TSTshiftRLreg x y (MOVWconst [c])) -> (TSTshiftRL x y [c])
+(TSTshiftRAreg x y (MOVWconst [c])) -> (TSTshiftRA x y [c])
+(TEQshiftLLreg x y (MOVWconst [c])) -> (TEQshiftLL x y [c])
+(TEQshiftRLreg x y (MOVWconst [c])) -> (TEQshiftRL x y [c])
+(TEQshiftRAreg x y (MOVWconst [c])) -> (TEQshiftRA x y [c])
+(CMNshiftLLreg x y (MOVWconst [c])) -> (CMNshiftLL x y [c])
+(CMNshiftRLreg x y (MOVWconst [c])) -> (CMNshiftRL x y [c])
+(CMNshiftRAreg x y (MOVWconst [c])) -> (CMNshiftRA x y [c])
 
 // Generate rotates
 (ADDshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x)
 // bit extraction
 (SRAconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 -> (BFX [(d-c)|(32-d)<<8] x)
 (SRLconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 -> (BFXU [(d-c)|(32-d)<<8] x)
+
+// comparison simplification
+(CMP x (RSBconst [0] y)) -> (CMN x y)
+(CMN x (RSBconst [0] y)) -> (CMP x y)
+(EQ (CMPconst [0] (SUB x y)) yes no) -> (EQ (CMP x y) yes no)
+(EQ (CMPconst [0] (SUBconst [c] x)) yes no) -> (EQ (CMPconst [c] x) yes no)
+(EQ (CMPconst [0] (SUBshiftLL x y [c])) yes no) -> (EQ (CMPshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (SUBshiftRL x y [c])) yes no) -> (EQ (CMPshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (SUBshiftRA x y [c])) yes no) -> (EQ (CMPshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (SUBshiftLLreg x y z)) yes no) -> (EQ (CMPshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (SUBshiftRLreg x y z)) yes no) -> (EQ (CMPshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (SUBshiftRAreg x y z)) yes no) -> (EQ (CMPshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (SUB x y)) yes no) -> (NE (CMP x y) yes no)
+(NE (CMPconst [0] (SUBconst [c] x)) yes no) -> (NE (CMPconst [c] x) yes no)
+(NE (CMPconst [0] (SUBshiftLL x y [c])) yes no) -> (NE (CMPshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (SUBshiftRL x y [c])) yes no) -> (NE (CMPshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (SUBshiftRA x y [c])) yes no) -> (NE (CMPshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (SUBshiftLLreg x y z)) yes no) -> (NE (CMPshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (SUBshiftRLreg x y z)) yes no) -> (NE (CMPshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (SUBshiftRAreg x y z)) yes no) -> (NE (CMPshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] (ADD x y)) yes no) -> (EQ (CMN x y) yes no)
+(EQ (CMPconst [0] (ADDconst [c] x)) yes no) -> (EQ (CMNconst [c] x) yes no)
+(EQ (CMPconst [0] (ADDshiftLL x y [c])) yes no) -> (EQ (CMNshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (ADDshiftRL x y [c])) yes no) -> (EQ (CMNshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (ADDshiftRA x y [c])) yes no) -> (EQ (CMNshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (ADDshiftLLreg x y z)) yes no) -> (EQ (CMNshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (ADDshiftRLreg x y z)) yes no) -> (EQ (CMNshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (ADDshiftRAreg x y z)) yes no) -> (EQ (CMNshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (ADD x y)) yes no) -> (NE (CMN x y) yes no)
+(NE (CMPconst [0] (ADDconst [c] x)) yes no) -> (NE (CMNconst [c] x) yes no)
+(NE (CMPconst [0] (ADDshiftLL x y [c])) yes no) -> (NE (CMNshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (ADDshiftRL x y [c])) yes no) -> (NE (CMNshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (ADDshiftRA x y [c])) yes no) -> (NE (CMNshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (ADDshiftLLreg x y z)) yes no) -> (NE (CMNshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (ADDshiftRLreg x y z)) yes no) -> (NE (CMNshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (ADDshiftRAreg x y z)) yes no) -> (NE (CMNshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] (AND x y)) yes no) -> (EQ (TST x y) yes no)
+(EQ (CMPconst [0] (ANDconst [c] x)) yes no) -> (EQ (TSTconst [c] x) yes no)
+(EQ (CMPconst [0] (ANDshiftLL x y [c])) yes no) -> (EQ (TSTshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (ANDshiftRL x y [c])) yes no) -> (EQ (TSTshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (ANDshiftRA x y [c])) yes no) -> (EQ (TSTshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (ANDshiftLLreg x y z)) yes no) -> (EQ (TSTshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (ANDshiftRLreg x y z)) yes no) -> (EQ (TSTshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (ANDshiftRAreg x y z)) yes no) -> (EQ (TSTshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (AND x y)) yes no) -> (NE (TST x y) yes no)
+(NE (CMPconst [0] (ANDconst [c] x)) yes no) -> (NE (TSTconst [c] x) yes no)
+(NE (CMPconst [0] (ANDshiftLL x y [c])) yes no) -> (NE (TSTshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (ANDshiftRL x y [c])) yes no) -> (NE (TSTshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (ANDshiftRA x y [c])) yes no) -> (NE (TSTshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (ANDshiftLLreg x y z)) yes no) -> (NE (TSTshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (ANDshiftRLreg x y z)) yes no) -> (NE (TSTshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (ANDshiftRAreg x y z)) yes no) -> (NE (TSTshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] (XOR x y)) yes no) -> (EQ (TEQ x y) yes no)
+(EQ (CMPconst [0] (XORconst [c] x)) yes no) -> (EQ (TEQconst [c] x) yes no)
+(EQ (CMPconst [0] (XORshiftLL x y [c])) yes no) -> (EQ (TEQshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (XORshiftRL x y [c])) yes no) -> (EQ (TEQshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (XORshiftRA x y [c])) yes no) -> (EQ (TEQshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (XORshiftLLreg x y z)) yes no) -> (EQ (TEQshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (XORshiftRLreg x y z)) yes no) -> (EQ (TEQshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (XORshiftRAreg x y z)) yes no) -> (EQ (TEQshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (XOR x y)) yes no) -> (NE (TEQ x y) yes no)
+(NE (CMPconst [0] (XORconst [c] x)) yes no) -> (NE (TEQconst [c] x) yes no)
+(NE (CMPconst [0] (XORshiftLL x y [c])) yes no) -> (NE (TEQshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (XORshiftRL x y [c])) yes no) -> (NE (TEQshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (XORshiftRA x y [c])) yes no) -> (NE (TEQshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (XORshiftLLreg x y z)) yes no) -> (NE (TEQshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (XORshiftRLreg x y z)) yes no) -> (NE (TEQshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (XORshiftRAreg x y z)) yes no) -> (NE (TEQshiftRAreg x y z) yes no)
index 928236b73ce7b25a26afccf77f8a7d7b0304badb..d16675fddb2585cacff1393d3cc465c0f0ca4eb2 100644 (file)
@@ -314,7 +314,7 @@ func init() {
                // comparisons
                {name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                    // arg0 compare to arg1
                {name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt
-               {name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags"},                    // arg0 compare to -arg1
+               {name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1
                {name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt
                {name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
                {name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0
@@ -326,10 +326,28 @@ func init() {
                {name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1<<auxInt
                {name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift
                {name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift
+               {name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1<<auxInt)
+               {name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), unsigned shift
+               {name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), signed shift
+               {name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1<<auxInt) compare to 0
+               {name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, unsigned shift
+               {name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, signed shift
+               {name: "TEQshiftLL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1<<auxInt) compare to 0
+               {name: "TEQshiftRL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, unsigned shift
+               {name: "TEQshiftRA", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, signed shift
 
                {name: "CMPshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1<<arg2
                {name: "CMPshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, unsigned shift
                {name: "CMPshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, signed shift
+               {name: "CMNshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1<<arg2) compare to 0
+               {name: "CMNshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, unsigned shift
+               {name: "CMNshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, signed shift
+               {name: "TSTshiftLLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1<<arg2) compare to 0
+               {name: "TSTshiftRLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, unsigned shift
+               {name: "TSTshiftRAreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, signed shift
+               {name: "TEQshiftLLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1<<arg2) compare to 0
+               {name: "TEQshiftRLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, unsigned shift
+               {name: "TEQshiftRAreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, signed shift
 
                {name: "CMPF0", argLength: 1, reg: fp1flags, asm: "CMPF", typ: "Flags"}, // arg0 compare to 0, float32
                {name: "CMPD0", argLength: 1, reg: fp1flags, asm: "CMPD", typ: "Flags"}, // arg0 compare to 0, float64
index fccadf342d2df69238a923ff6fb96787e3bbfd39..9c289bacafb3a9ea0c418884500b19b557160532 100644 (file)
@@ -847,9 +847,27 @@ const (
        OpARMCMPshiftLL
        OpARMCMPshiftRL
        OpARMCMPshiftRA
+       OpARMCMNshiftLL
+       OpARMCMNshiftRL
+       OpARMCMNshiftRA
+       OpARMTSTshiftLL
+       OpARMTSTshiftRL
+       OpARMTSTshiftRA
+       OpARMTEQshiftLL
+       OpARMTEQshiftRL
+       OpARMTEQshiftRA
        OpARMCMPshiftLLreg
        OpARMCMPshiftRLreg
        OpARMCMPshiftRAreg
+       OpARMCMNshiftLLreg
+       OpARMCMNshiftRLreg
+       OpARMCMNshiftRAreg
+       OpARMTSTshiftLLreg
+       OpARMTSTshiftRLreg
+       OpARMTSTshiftRAreg
+       OpARMTEQshiftLLreg
+       OpARMTEQshiftRLreg
+       OpARMTEQshiftRAreg
        OpARMCMPF0
        OpARMCMPD0
        OpARMMOVWconst
@@ -10570,9 +10588,10 @@ var opcodeTable = [...]opInfo{
                },
        },
        {
-               name:   "CMN",
-               argLen: 2,
-               asm:    arm.ACMN,
+               name:        "CMN",
+               argLen:      2,
+               commutative: true,
+               asm:         arm.ACMN,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
@@ -10695,6 +10714,114 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:    "CMNshiftLL",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "CMNshiftRL",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "CMNshiftRA",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "TSTshiftLL",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "TSTshiftRL",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "TSTshiftRA",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "TEQshiftLL",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ATEQ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "TEQshiftRL",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ATEQ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
+       {
+               name:    "TEQshiftRA",
+               auxType: auxInt32,
+               argLen:  2,
+               asm:     arm.ATEQ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                       },
+               },
+       },
        {
                name:   "CMPshiftLLreg",
                argLen: 3,
@@ -10731,6 +10858,114 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "CMNshiftLLreg",
+               argLen: 3,
+               asm:    arm.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "CMNshiftRLreg",
+               argLen: 3,
+               asm:    arm.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "CMNshiftRAreg",
+               argLen: 3,
+               asm:    arm.ACMN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "TSTshiftLLreg",
+               argLen: 3,
+               asm:    arm.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "TSTshiftRLreg",
+               argLen: 3,
+               asm:    arm.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "TSTshiftRAreg",
+               argLen: 3,
+               asm:    arm.ATST,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "TEQshiftLLreg",
+               argLen: 3,
+               asm:    arm.ATEQ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "TEQshiftRLreg",
+               argLen: 3,
+               asm:    arm.ATEQ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "TEQshiftRAreg",
+               argLen: 3,
+               asm:    arm.ATEQ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                               {2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
        {
                name:   "CMPF0",
                argLen: 1,
index 3514886e8ef9c509d4e704f28c43cd92e8f329bb..fa22ff2502af4ad1aaedd230e392c45f290c4bad 100644 (file)
@@ -101,6 +101,22 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpARMBICshiftRL_0(v)
        case OpARMBICshiftRLreg:
                return rewriteValueARM_OpARMBICshiftRLreg_0(v)
+       case OpARMCMN:
+               return rewriteValueARM_OpARMCMN_0(v) || rewriteValueARM_OpARMCMN_10(v)
+       case OpARMCMNconst:
+               return rewriteValueARM_OpARMCMNconst_0(v)
+       case OpARMCMNshiftLL:
+               return rewriteValueARM_OpARMCMNshiftLL_0(v)
+       case OpARMCMNshiftLLreg:
+               return rewriteValueARM_OpARMCMNshiftLLreg_0(v)
+       case OpARMCMNshiftRA:
+               return rewriteValueARM_OpARMCMNshiftRA_0(v)
+       case OpARMCMNshiftRAreg:
+               return rewriteValueARM_OpARMCMNshiftRAreg_0(v)
+       case OpARMCMNshiftRL:
+               return rewriteValueARM_OpARMCMNshiftRL_0(v)
+       case OpARMCMNshiftRLreg:
+               return rewriteValueARM_OpARMCMNshiftRLreg_0(v)
        case OpARMCMOVWHSconst:
                return rewriteValueARM_OpARMCMOVWHSconst_0(v)
        case OpARMCMOVWLSconst:
@@ -361,6 +377,38 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpARMSUBshiftRL_0(v)
        case OpARMSUBshiftRLreg:
                return rewriteValueARM_OpARMSUBshiftRLreg_0(v)
+       case OpARMTEQ:
+               return rewriteValueARM_OpARMTEQ_0(v) || rewriteValueARM_OpARMTEQ_10(v)
+       case OpARMTEQconst:
+               return rewriteValueARM_OpARMTEQconst_0(v)
+       case OpARMTEQshiftLL:
+               return rewriteValueARM_OpARMTEQshiftLL_0(v)
+       case OpARMTEQshiftLLreg:
+               return rewriteValueARM_OpARMTEQshiftLLreg_0(v)
+       case OpARMTEQshiftRA:
+               return rewriteValueARM_OpARMTEQshiftRA_0(v)
+       case OpARMTEQshiftRAreg:
+               return rewriteValueARM_OpARMTEQshiftRAreg_0(v)
+       case OpARMTEQshiftRL:
+               return rewriteValueARM_OpARMTEQshiftRL_0(v)
+       case OpARMTEQshiftRLreg:
+               return rewriteValueARM_OpARMTEQshiftRLreg_0(v)
+       case OpARMTST:
+               return rewriteValueARM_OpARMTST_0(v) || rewriteValueARM_OpARMTST_10(v)
+       case OpARMTSTconst:
+               return rewriteValueARM_OpARMTSTconst_0(v)
+       case OpARMTSTshiftLL:
+               return rewriteValueARM_OpARMTSTshiftLL_0(v)
+       case OpARMTSTshiftLLreg:
+               return rewriteValueARM_OpARMTSTshiftLLreg_0(v)
+       case OpARMTSTshiftRA:
+               return rewriteValueARM_OpARMTSTshiftRA_0(v)
+       case OpARMTSTshiftRAreg:
+               return rewriteValueARM_OpARMTSTshiftRAreg_0(v)
+       case OpARMTSTshiftRL:
+               return rewriteValueARM_OpARMTSTshiftRL_0(v)
+       case OpARMTSTshiftRLreg:
+               return rewriteValueARM_OpARMTSTshiftRLreg_0(v)
        case OpARMXOR:
                return rewriteValueARM_OpARMXOR_0(v) || rewriteValueARM_OpARMXOR_10(v)
        case OpARMXORconst:
@@ -4410,663 +4458,851 @@ func rewriteValueARM_OpARMBICshiftRLreg_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMCMOVWHSconst_0(v *Value) bool {
-       // match: (CMOVWHSconst _ (FlagEQ) [c])
-       // cond:
-       // result: (MOVWconst [c])
-       for {
-               c := v.AuxInt
-               _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagEQ {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = c
-               return true
-       }
-       // match: (CMOVWHSconst x (FlagLT_ULT))
+func rewriteValueARM_OpARMCMN_0(v *Value) bool {
+       // match: (CMN x (MOVWconst [c]))
        // cond:
-       // result: x
+       // result: (CMNconst [c] x)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagLT_ULT {
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               c := v_1.AuxInt
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
                v.AddArg(x)
                return true
        }
-       // match: (CMOVWHSconst _ (FlagLT_UGT) [c])
+       // match: (CMN (MOVWconst [c]) x)
        // cond:
-       // result: (MOVWconst [c])
+       // result: (CMNconst [c] x)
        for {
-               c := v.AuxInt
                _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagLT_UGT {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMCMNconst)
                v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-       // match: (CMOVWHSconst x (FlagGT_ULT))
+       // match: (CMN x (SLLconst [c] y))
        // cond:
-       // result: x
+       // result: (CMNshiftLL x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagGT_ULT {
+               if v_1.Op != OpARMSLLconst {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMCMNshiftLL)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMOVWHSconst _ (FlagGT_UGT) [c])
+       // match: (CMN (SLLconst [c] y) x)
        // cond:
-       // result: (MOVWconst [c])
+       // result: (CMNshiftLL x y [c])
        for {
-               c := v.AuxInt
                _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagGT_UGT {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLLconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMCMNshiftLL)
                v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMOVWHSconst x (InvertFlags flags) [c])
+       // match: (CMN x (SRLconst [c] y))
        // cond:
-       // result: (CMOVWLSconst x flags [c])
+       // result: (CMNshiftRL x y [c])
        for {
-               c := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMInvertFlags {
+               if v_1.Op != OpARMSRLconst {
                        break
                }
-               flags := v_1.Args[0]
-               v.reset(OpARMCMOVWLSconst)
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMCMNshiftRL)
                v.AuxInt = c
                v.AddArg(x)
-               v.AddArg(flags)
-               return true
-       }
-       return false
-}
-func rewriteValueARM_OpARMCMOVWLSconst_0(v *Value) bool {
-       // match: (CMOVWLSconst _ (FlagEQ) [c])
-       // cond:
-       // result: (MOVWconst [c])
-       for {
-               c := v.AuxInt
-               _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagEQ {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = c
+               v.AddArg(y)
                return true
        }
-       // match: (CMOVWLSconst _ (FlagLT_ULT) [c])
+       // match: (CMN (SRLconst [c] y) x)
        // cond:
-       // result: (MOVWconst [c])
+       // result: (CMNshiftRL x y [c])
        for {
-               c := v.AuxInt
                _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagLT_ULT {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRLconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMCMNshiftRL)
                v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMOVWLSconst x (FlagLT_UGT))
+       // match: (CMN x (SRAconst [c] y))
        // cond:
-       // result: x
+       // result: (CMNshiftRA x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagLT_UGT {
+               if v_1.Op != OpARMSRAconst {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMCMNshiftRA)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMOVWLSconst _ (FlagGT_ULT) [c])
+       // match: (CMN (SRAconst [c] y) x)
        // cond:
-       // result: (MOVWconst [c])
+       // result: (CMNshiftRA x y [c])
        for {
-               c := v.AuxInt
                _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagGT_ULT {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRAconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMCMNshiftRA)
                v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMOVWLSconst x (FlagGT_UGT))
+       // match: (CMN x (SLL y z))
        // cond:
-       // result: x
+       // result: (CMNshiftLLreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMFlagGT_UGT {
+               if v_1.Op != OpARMSLL {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMCMNshiftLLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       // match: (CMOVWLSconst x (InvertFlags flags) [c])
+       // match: (CMN (SLL y z) x)
        // cond:
-       // result: (CMOVWHSconst x flags [c])
+       // result: (CMNshiftLLreg x y z)
        for {
-               c := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMInvertFlags {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLL {
                        break
                }
-               flags := v_1.Args[0]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = c
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMCMNshiftLLreg)
                v.AddArg(x)
-               v.AddArg(flags)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMCMP_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMP x (MOVWconst [c]))
+func rewriteValueARM_OpARMCMN_10(v *Value) bool {
+       // match: (CMN x (SRL y z))
        // cond:
-       // result: (CMPconst [c] x)
+       // result: (CMNshiftRLreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v_1.Op != OpARMSRL {
                        break
                }
-               c := v_1.AuxInt
-               v.reset(OpARMCMPconst)
-               v.AuxInt = c
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMCMNshiftRLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       // match: (CMP (MOVWconst [c]) x)
+       // match: (CMN (SRL y z) x)
        // cond:
-       // result: (InvertFlags (CMPconst [c] x))
+       // result: (CMNshiftRLreg x y z)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSRL {
                        break
                }
-               c := v_0.AuxInt
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v0.AuxInt = c
-               v0.AddArg(x)
-               v.AddArg(v0)
+               v.reset(OpARMCMNshiftRLreg)
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       // match: (CMP x (SLLconst [c] y))
+       // match: (CMN x (SRA y z))
        // cond:
-       // result: (CMPshiftLL x y [c])
+       // result: (CMNshiftRAreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMSLLconst {
+               if v_1.Op != OpARMSRA {
                        break
                }
-               c := v_1.AuxInt
+               _ = v_1.Args[1]
                y := v_1.Args[0]
-               v.reset(OpARMCMPshiftLL)
-               v.AuxInt = c
+               z := v_1.Args[1]
+               v.reset(OpARMCMNshiftRAreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       // match: (CMP (SLLconst [c] y) x)
+       // match: (CMN (SRA y z) x)
        // cond:
-       // result: (InvertFlags (CMPshiftLL x y [c]))
+       // result: (CMNshiftRAreg x y z)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSLLconst {
+               if v_0.Op != OpARMSRA {
                        break
                }
-               c := v_0.AuxInt
+               _ = v_0.Args[1]
                y := v_0.Args[0]
+               z := v_0.Args[1]
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
-               v0.AuxInt = c
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMCMNshiftRAreg)
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       // match: (CMP x (SRLconst [c] y))
+       // match: (CMN x (RSBconst [0] y))
        // cond:
-       // result: (CMPshiftRL x y [c])
+       // result: (CMP x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMSRLconst {
+               if v_1.Op != OpARMRSBconst {
+                       break
+               }
+               if v_1.AuxInt != 0 {
                        break
                }
-               c := v_1.AuxInt
                y := v_1.Args[0]
-               v.reset(OpARMCMPshiftRL)
-               v.AuxInt = c
+               v.reset(OpARMCMP)
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (CMP (SRLconst [c] y) x)
+       // match: (CMN (RSBconst [0] y) x)
        // cond:
-       // result: (InvertFlags (CMPshiftRL x y [c]))
+       // result: (CMP x y)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSRLconst {
+               if v_0.Op != OpARMRSBconst {
+                       break
+               }
+               if v_0.AuxInt != 0 {
                        break
                }
-               c := v_0.AuxInt
                y := v_0.Args[0]
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
-               v0.AuxInt = c
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMCMP)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMP x (SRAconst [c] y))
-       // cond:
-       // result: (CMPshiftRA x y [c])
+       return false
+}
+func rewriteValueARM_OpARMCMNconst_0(v *Value) bool {
+       // match: (CMNconst (MOVWconst [x]) [y])
+       // cond: int32(x)==int32(-y)
+       // result: (FlagEQ)
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSRAconst {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
-               v.reset(OpARMCMPshiftRA)
-               v.AuxInt = c
-               v.AddArg(x)
-               v.AddArg(y)
+               x := v_0.AuxInt
+               if !(int32(x) == int32(-y)) {
+                       break
+               }
+               v.reset(OpARMFlagEQ)
                return true
        }
-       // match: (CMP (SRAconst [c] y) x)
+       // match: (CMNconst (MOVWconst [x]) [y])
+       // cond: int32(x)<int32(-y) && uint32(x)<uint32(-y)
+       // result: (FlagLT_ULT)
+       for {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x) < int32(-y) && uint32(x) < uint32(-y)) {
+                       break
+               }
+               v.reset(OpARMFlagLT_ULT)
+               return true
+       }
+       // match: (CMNconst (MOVWconst [x]) [y])
+       // cond: int32(x)<int32(-y) && uint32(x)>uint32(-y)
+       // result: (FlagLT_UGT)
+       for {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x) < int32(-y) && uint32(x) > uint32(-y)) {
+                       break
+               }
+               v.reset(OpARMFlagLT_UGT)
+               return true
+       }
+       // match: (CMNconst (MOVWconst [x]) [y])
+       // cond: int32(x)>int32(-y) && uint32(x)<uint32(-y)
+       // result: (FlagGT_ULT)
+       for {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x) > int32(-y) && uint32(x) < uint32(-y)) {
+                       break
+               }
+               v.reset(OpARMFlagGT_ULT)
+               return true
+       }
+       // match: (CMNconst (MOVWconst [x]) [y])
+       // cond: int32(x)>int32(-y) && uint32(x)>uint32(-y)
+       // result: (FlagGT_UGT)
+       for {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x) > int32(-y) && uint32(x) > uint32(-y)) {
+                       break
+               }
+               v.reset(OpARMFlagGT_UGT)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMCMNshiftLL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftLL (MOVWconst [c]) x [d])
        // cond:
-       // result: (InvertFlags (CMPshiftRA x y [c]))
+       // result: (CMNconst [c] (SLLconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSRAconst {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
                c := v_0.AuxInt
-               y := v_0.Args[0]
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
-               v0.AuxInt = c
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+               v0.AuxInt = d
                v0.AddArg(x)
-               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-       // match: (CMP x (SLL y z))
+       // match: (CMNshiftLL x (MOVWconst [c]) [d])
        // cond:
-       // result: (CMPshiftLLreg x y z)
+       // result: (CMNconst x [int64(uint32(c)<<uint64(d))])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMSLL {
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               _ = v_1.Args[1]
-               y := v_1.Args[0]
-               z := v_1.Args[1]
-               v.reset(OpARMCMPshiftLLreg)
+               c := v_1.AuxInt
+               v.reset(OpARMCMNconst)
+               v.AuxInt = int64(uint32(c) << uint64(d))
                v.AddArg(x)
-               v.AddArg(y)
-               v.AddArg(z)
                return true
        }
-       // match: (CMP (SLL y z) x)
+       return false
+}
+func rewriteValueARM_OpARMCMNshiftLLreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftLLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (InvertFlags (CMPshiftLLreg x y z))
+       // result: (CMNconst [c] (SLL <x.Type> x y))
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSLL {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               _ = v_0.Args[1]
-               y := v_0.Args[0]
-               z := v_0.Args[1]
+               c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+               y := v.Args[2]
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
                v0.AddArg(y)
-               v0.AddArg(z)
                v.AddArg(v0)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMP_10(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMP x (SRL y z))
+       // match: (CMNshiftLLreg x y (MOVWconst [c]))
        // cond:
-       // result: (CMPshiftRLreg x y z)
+       // result: (CMNshiftLL x y [c])
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSRL {
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
                        break
                }
-               _ = v_1.Args[1]
-               y := v_1.Args[0]
-               z := v_1.Args[1]
-               v.reset(OpARMCMPshiftRLreg)
+               c := v_2.AuxInt
+               v.reset(OpARMCMNshiftLL)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
-               v.AddArg(z)
                return true
        }
-       // match: (CMP (SRL y z) x)
+       return false
+}
+func rewriteValueARM_OpARMCMNshiftRA_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftRA (MOVWconst [c]) x [d])
        // cond:
-       // result: (InvertFlags (CMPshiftRLreg x y z))
+       // result: (CMNconst [c] (SRAconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSRL {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               _ = v_0.Args[1]
-               y := v_0.Args[0]
-               z := v_0.Args[1]
+               c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+               v0.AuxInt = d
                v0.AddArg(x)
-               v0.AddArg(y)
-               v0.AddArg(z)
                v.AddArg(v0)
                return true
        }
-       // match: (CMP x (SRA y z))
+       // match: (CMNshiftRA x (MOVWconst [c]) [d])
        // cond:
-       // result: (CMPshiftRAreg x y z)
+       // result: (CMNconst x [int64(int32(c)>>uint64(d))])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMSRA {
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               _ = v_1.Args[1]
-               y := v_1.Args[0]
-               z := v_1.Args[1]
-               v.reset(OpARMCMPshiftRAreg)
+               c := v_1.AuxInt
+               v.reset(OpARMCMNconst)
+               v.AuxInt = int64(int32(c) >> uint64(d))
                v.AddArg(x)
-               v.AddArg(y)
-               v.AddArg(z)
                return true
        }
-       // match: (CMP (SRA y z) x)
+       return false
+}
+func rewriteValueARM_OpARMCMNshiftRAreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftRAreg (MOVWconst [c]) x y)
        // cond:
-       // result: (InvertFlags (CMPshiftRAreg x y z))
+       // result: (CMNconst [c] (SRA <x.Type> x y))
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSRA {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               _ = v_0.Args[1]
-               y := v_0.Args[0]
-               z := v_0.Args[1]
+               c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+               y := v.Args[2]
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
                v0.AddArg(x)
                v0.AddArg(y)
-               v0.AddArg(z)
                v.AddArg(v0)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMPD_0(v *Value) bool {
-       // match: (CMPD x (MOVDconst [0]))
+       // match: (CMNshiftRAreg x y (MOVWconst [c]))
        // cond:
-       // result: (CMPD0 x)
+       // result: (CMNshiftRA x y [c])
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVDconst {
-                       break
-               }
-               if v_1.AuxInt != 0 {
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMCMPD0)
+               c := v_2.AuxInt
+               v.reset(OpARMCMNshiftRA)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMCMPF_0(v *Value) bool {
-       // match: (CMPF x (MOVFconst [0]))
+func rewriteValueARM_OpARMCMNshiftRL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftRL (MOVWconst [c]) x [d])
        // cond:
-       // result: (CMPF0 x)
+       // result: (CMNconst [c] (SRLconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVFconst {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               if v_1.AuxInt != 0 {
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (CMNshiftRL x (MOVWconst [c]) [d])
+       // cond:
+       // result: (CMNconst x [int64(uint32(c)>>uint64(d))])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMCMPF0)
+               c := v_1.AuxInt
+               v.reset(OpARMCMNconst)
+               v.AuxInt = int64(uint32(c) >> uint64(d))
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMCMPconst_0(v *Value) bool {
-       // match: (CMPconst (MOVWconst [x]) [y])
-       // cond: int32(x)==int32(y)
-       // result: (FlagEQ)
+func rewriteValueARM_OpARMCMNshiftRLreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMNshiftRLreg (MOVWconst [c]) x y)
+       // cond:
+       // result: (CMNconst [c] (SRL <x.Type> x y))
        for {
-               y := v.AuxInt
+               _ = v.Args[2]
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWconst {
                        break
                }
-               x := v_0.AuxInt
-               if !(int32(x) == int32(y)) {
-                       break
-               }
-               v.reset(OpARMFlagEQ)
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMCMNconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
-       // match: (CMPconst (MOVWconst [x]) [y])
-       // cond: int32(x)<int32(y) && uint32(x)<uint32(y)
-       // result: (FlagLT_ULT)
+       // match: (CMNshiftRLreg x y (MOVWconst [c]))
+       // cond:
+       // result: (CMNshiftRL x y [c])
        for {
-               y := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
-                       break
-               }
-               x := v_0.AuxInt
-               if !(int32(x) < int32(y) && uint32(x) < uint32(y)) {
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMFlagLT_ULT)
+               c := v_2.AuxInt
+               v.reset(OpARMCMNshiftRL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (CMPconst (MOVWconst [x]) [y])
-       // cond: int32(x)<int32(y) && uint32(x)>uint32(y)
-       // result: (FlagLT_UGT)
+       return false
+}
+func rewriteValueARM_OpARMCMOVWHSconst_0(v *Value) bool {
+       // match: (CMOVWHSconst _ (FlagEQ) [c])
+       // cond:
+       // result: (MOVWconst [c])
        for {
-               y := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
-                       break
-               }
-               x := v_0.AuxInt
-               if !(int32(x) < int32(y) && uint32(x) > uint32(y)) {
+               c := v.AuxInt
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagEQ {
                        break
                }
-               v.reset(OpARMFlagLT_UGT)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c
                return true
        }
-       // match: (CMPconst (MOVWconst [x]) [y])
-       // cond: int32(x)>int32(y) && uint32(x)<uint32(y)
-       // result: (FlagGT_ULT)
+       // match: (CMOVWHSconst x (FlagLT_ULT))
+       // cond:
+       // result: x
        for {
-               y := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
-                       break
-               }
-               x := v_0.AuxInt
-               if !(int32(x) > int32(y) && uint32(x) < uint32(y)) {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagLT_ULT {
                        break
                }
-               v.reset(OpARMFlagGT_ULT)
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
                return true
        }
-       // match: (CMPconst (MOVWconst [x]) [y])
-       // cond: int32(x)>int32(y) && uint32(x)>uint32(y)
-       // result: (FlagGT_UGT)
+       // match: (CMOVWHSconst _ (FlagLT_UGT) [c])
+       // cond:
+       // result: (MOVWconst [c])
        for {
-               y := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               c := v.AuxInt
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagLT_UGT {
                        break
                }
-               x := v_0.AuxInt
-               if !(int32(x) > int32(y) && uint32(x) > uint32(y)) {
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c
+               return true
+       }
+       // match: (CMOVWHSconst x (FlagGT_ULT))
+       // cond:
+       // result: x
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagGT_ULT {
                        break
                }
-               v.reset(OpARMFlagGT_UGT)
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
                return true
        }
-       // match: (CMPconst (MOVBUreg _) [c])
-       // cond: 0xff < c
-       // result: (FlagLT_ULT)
+       // match: (CMOVWHSconst _ (FlagGT_UGT) [c])
+       // cond:
+       // result: (MOVWconst [c])
        for {
                c := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVBUreg {
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagGT_UGT {
                        break
                }
-               if !(0xff < c) {
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c
+               return true
+       }
+       // match: (CMOVWHSconst x (InvertFlags flags) [c])
+       // cond:
+       // result: (CMOVWLSconst x flags [c])
+       for {
+               c := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMInvertFlags {
                        break
                }
-               v.reset(OpARMFlagLT_ULT)
+               flags := v_1.Args[0]
+               v.reset(OpARMCMOVWLSconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(flags)
                return true
        }
-       // match: (CMPconst (MOVHUreg _) [c])
-       // cond: 0xffff < c
-       // result: (FlagLT_ULT)
+       return false
+}
+func rewriteValueARM_OpARMCMOVWLSconst_0(v *Value) bool {
+       // match: (CMOVWLSconst _ (FlagEQ) [c])
+       // cond:
+       // result: (MOVWconst [c])
        for {
                c := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVHUreg {
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagEQ {
                        break
                }
-               if !(0xffff < c) {
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c
+               return true
+       }
+       // match: (CMOVWLSconst _ (FlagLT_ULT) [c])
+       // cond:
+       // result: (MOVWconst [c])
+       for {
+               c := v.AuxInt
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagLT_ULT {
                        break
                }
-               v.reset(OpARMFlagLT_ULT)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c
                return true
        }
-       // match: (CMPconst (ANDconst _ [m]) [n])
-       // cond: 0 <= int32(m) && int32(m) < int32(n)
-       // result: (FlagLT_ULT)
+       // match: (CMOVWLSconst x (FlagLT_UGT))
+       // cond:
+       // result: x
        for {
-               n := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMANDconst {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagLT_UGT {
                        break
                }
-               m := v_0.AuxInt
-               if !(0 <= int32(m) && int32(m) < int32(n)) {
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMOVWLSconst _ (FlagGT_ULT) [c])
+       // cond:
+       // result: (MOVWconst [c])
+       for {
+               c := v.AuxInt
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagGT_ULT {
                        break
                }
-               v.reset(OpARMFlagLT_ULT)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c
                return true
        }
-       // match: (CMPconst (SRLconst _ [c]) [n])
-       // cond: 0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n)
-       // result: (FlagLT_ULT)
+       // match: (CMOVWLSconst x (FlagGT_UGT))
+       // cond:
+       // result: x
        for {
-               n := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMSRLconst {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMFlagGT_UGT {
                        break
                }
-               c := v_0.AuxInt
-               if !(0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n)) {
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMOVWLSconst x (InvertFlags flags) [c])
+       // cond:
+       // result: (CMOVWHSconst x flags [c])
+       for {
+               c := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMInvertFlags {
                        break
                }
-               v.reset(OpARMFlagLT_ULT)
+               flags := v_1.Args[0]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(flags)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMCMPshiftLL_0(v *Value) bool {
+func rewriteValueARM_OpARMCMP_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (CMPshiftLL (MOVWconst [c]) x [d])
+       // match: (CMP x (MOVWconst [c]))
        // cond:
-       // result: (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
+       // result: (CMPconst [c] x)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMCMPconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMP (MOVWconst [c]) x)
+       // cond:
+       // result: (InvertFlags (CMPconst [c] x))
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWconst {
@@ -5077,637 +5313,724 @@ func rewriteValueARM_OpARMCMPshiftLL_0(v *Value) bool {
                v.reset(OpARMInvertFlags)
                v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
                v0.AuxInt = c
-               v1 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
-               v1.AuxInt = d
-               v1.AddArg(x)
-               v0.AddArg(v1)
+               v0.AddArg(x)
                v.AddArg(v0)
                return true
        }
-       // match: (CMPshiftLL x (MOVWconst [c]) [d])
+       // match: (CMP x (SLLconst [c] y))
        // cond:
-       // result: (CMPconst x [int64(uint32(c)<<uint64(d))])
+       // result: (CMPshiftLL x y [c])
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v_1.Op != OpARMSLLconst {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMCMPconst)
-               v.AuxInt = int64(uint32(c) << uint64(d))
+               y := v_1.Args[0]
+               v.reset(OpARMCMPshiftLL)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMPshiftLLreg_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMPshiftLLreg (MOVWconst [c]) x y)
+       // match: (CMP (SLLconst [c] y) x)
        // cond:
-       // result: (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
+       // result: (InvertFlags (CMPshiftLL x y [c]))
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSLLconst {
                        break
                }
                c := v_0.AuxInt
+               y := v_0.Args[0]
                x := v.Args[1]
-               y := v.Args[2]
                v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
                v0.AuxInt = c
-               v1 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
-               v1.AddArg(x)
-               v1.AddArg(y)
-               v0.AddArg(v1)
+               v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-       // match: (CMPshiftLLreg x y (MOVWconst [c]))
+       // match: (CMP x (SRLconst [c] y))
        // cond:
-       // result: (CMPshiftLL x y [c])
+       // result: (CMPshiftRL x y [c])
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v_2 := v.Args[2]
-               if v_2.Op != OpARMMOVWconst {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRLconst {
                        break
                }
-               c := v_2.AuxInt
-               v.reset(OpARMCMPshiftLL)
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMCMPshiftRL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMPshiftRA_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMPshiftRA (MOVWconst [c]) x [d])
+       // match: (CMP (SRLconst [c] y) x)
        // cond:
-       // result: (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
+       // result: (InvertFlags (CMPshiftRL x y [c]))
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSRLconst {
                        break
                }
                c := v_0.AuxInt
+               y := v_0.Args[0]
                x := v.Args[1]
                v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
                v0.AuxInt = c
-               v1 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
-               v1.AuxInt = d
-               v1.AddArg(x)
-               v0.AddArg(v1)
+               v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-       // match: (CMPshiftRA x (MOVWconst [c]) [d])
+       // match: (CMP x (SRAconst [c] y))
        // cond:
-       // result: (CMPconst x [int64(int32(c)>>uint64(d))])
+       // result: (CMPshiftRA x y [c])
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v_1.Op != OpARMSRAconst {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMCMPconst)
-               v.AuxInt = int64(int32(c) >> uint64(d))
+               y := v_1.Args[0]
+               v.reset(OpARMCMPshiftRA)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMPshiftRAreg_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMPshiftRAreg (MOVWconst [c]) x y)
+       // match: (CMP (SRAconst [c] y) x)
        // cond:
-       // result: (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
+       // result: (InvertFlags (CMPshiftRA x y [c]))
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSRAconst {
                        break
                }
                c := v_0.AuxInt
+               y := v_0.Args[0]
                x := v.Args[1]
-               y := v.Args[2]
                v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
                v0.AuxInt = c
-               v1 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
-               v1.AddArg(x)
-               v1.AddArg(y)
-               v0.AddArg(v1)
+               v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-       // match: (CMPshiftRAreg x y (MOVWconst [c]))
+       // match: (CMP x (SLL y z))
        // cond:
-       // result: (CMPshiftRA x y [c])
+       // result: (CMPshiftLLreg x y z)
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v_2 := v.Args[2]
-               if v_2.Op != OpARMMOVWconst {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSLL {
                        break
                }
-               c := v_2.AuxInt
-               v.reset(OpARMCMPshiftRA)
-               v.AuxInt = c
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMCMPshiftLLreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMPshiftRL_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMPshiftRL (MOVWconst [c]) x [d])
+       // match: (CMP (SLL y z) x)
        // cond:
-       // result: (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
+       // result: (InvertFlags (CMPshiftLLreg x y z))
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSLL {
                        break
                }
-               c := v_0.AuxInt
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
                x := v.Args[1]
                v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v0.AuxInt = c
-               v1 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
-               v1.AuxInt = d
-               v1.AddArg(x)
-               v0.AddArg(v1)
+               v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v0.AddArg(z)
                v.AddArg(v0)
                return true
        }
-       // match: (CMPshiftRL x (MOVWconst [c]) [d])
+       return false
+}
+func rewriteValueARM_OpARMCMP_10(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMP x (SRL y z))
        // cond:
-       // result: (CMPconst x [int64(uint32(c)>>uint64(d))])
+       // result: (CMPshiftRLreg x y z)
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v_1.Op != OpARMSRL {
                        break
                }
-               c := v_1.AuxInt
-               v.reset(OpARMCMPconst)
-               v.AuxInt = int64(uint32(c) >> uint64(d))
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMCMPshiftRLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMCMPshiftRLreg_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (CMPshiftRLreg (MOVWconst [c]) x y)
+       // match: (CMP (SRL y z) x)
        // cond:
-       // result: (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
+       // result: (InvertFlags (CMPshiftRLreg x y z))
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSRL {
                        break
                }
-               c := v_0.AuxInt
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
                x := v.Args[1]
-               y := v.Args[2]
                v.reset(OpARMInvertFlags)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v0.AuxInt = c
-               v1 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
-               v1.AddArg(x)
-               v1.AddArg(y)
-               v0.AddArg(v1)
+               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v0.AddArg(z)
                v.AddArg(v0)
                return true
        }
-       // match: (CMPshiftRLreg x y (MOVWconst [c]))
+       // match: (CMP x (SRA y z))
        // cond:
-       // result: (CMPshiftRL x y [c])
+       // result: (CMPshiftRAreg x y z)
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v_2 := v.Args[2]
-               if v_2.Op != OpARMMOVWconst {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRA {
                        break
                }
-               c := v_2.AuxInt
-               v.reset(OpARMCMPshiftRL)
-               v.AuxInt = c
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMCMPshiftRAreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMEqual_0(v *Value) bool {
-       // match: (Equal (FlagEQ))
+       // match: (CMP (SRA y z) x)
        // cond:
-       // result: (MOVWconst [1])
+       // result: (InvertFlags (CMPshiftRAreg x y z))
        for {
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagEQ {
+               if v_0.Op != OpARMSRA {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v0.AddArg(z)
+               v.AddArg(v0)
                return true
        }
-       // match: (Equal (FlagLT_ULT))
+       // match: (CMP x (RSBconst [0] y))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (CMN x y)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_ULT {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMRSBconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
-       // match: (Equal (FlagLT_UGT))
-       // cond:
-       // result: (MOVWconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_UGT {
+               if v_1.AuxInt != 0 {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               y := v_1.Args[0]
+               v.reset(OpARMCMN)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (Equal (FlagGT_ULT))
+       return false
+}
+func rewriteValueARM_OpARMCMPD_0(v *Value) bool {
+       // match: (CMPD x (MOVDconst [0]))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (CMPD0 x)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_ULT {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVDconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
-       // match: (Equal (FlagGT_UGT))
-       // cond:
-       // result: (MOVWconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_UGT {
+               if v_1.AuxInt != 0 {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.reset(OpARMCMPD0)
+               v.AddArg(x)
                return true
        }
-       // match: (Equal (InvertFlags x))
+       return false
+}
+func rewriteValueARM_OpARMCMPF_0(v *Value) bool {
+       // match: (CMPF x (MOVFconst [0]))
        // cond:
-       // result: (Equal x)
+       // result: (CMPF0 x)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMInvertFlags {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVFconst {
                        break
                }
-               x := v_0.Args[0]
-               v.reset(OpARMEqual)
+               if v_1.AuxInt != 0 {
+                       break
+               }
+               v.reset(OpARMCMPF0)
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMGreaterEqual_0(v *Value) bool {
-       // match: (GreaterEqual (FlagEQ))
-       // cond:
-       // result: (MOVWconst [1])
+func rewriteValueARM_OpARMCMPconst_0(v *Value) bool {
+       // match: (CMPconst (MOVWconst [x]) [y])
+       // cond: int32(x)==int32(y)
+       // result: (FlagEQ)
        for {
+               y := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagEQ {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
-               return true
-       }
-       // match: (GreaterEqual (FlagLT_ULT))
-       // cond:
-       // result: (MOVWconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_ULT {
+               x := v_0.AuxInt
+               if !(int32(x) == int32(y)) {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.reset(OpARMFlagEQ)
                return true
        }
-       // match: (GreaterEqual (FlagLT_UGT))
-       // cond:
-       // result: (MOVWconst [0])
+       // match: (CMPconst (MOVWconst [x]) [y])
+       // cond: int32(x)<int32(y) && uint32(x)<uint32(y)
+       // result: (FlagLT_ULT)
        for {
+               y := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_UGT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               x := v_0.AuxInt
+               if !(int32(x) < int32(y) && uint32(x) < uint32(y)) {
+                       break
+               }
+               v.reset(OpARMFlagLT_ULT)
                return true
        }
-       // match: (GreaterEqual (FlagGT_ULT))
-       // cond:
-       // result: (MOVWconst [1])
+       // match: (CMPconst (MOVWconst [x]) [y])
+       // cond: int32(x)<int32(y) && uint32(x)>uint32(y)
+       // result: (FlagLT_UGT)
        for {
+               y := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_ULT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               x := v_0.AuxInt
+               if !(int32(x) < int32(y) && uint32(x) > uint32(y)) {
+                       break
+               }
+               v.reset(OpARMFlagLT_UGT)
                return true
        }
-       // match: (GreaterEqual (FlagGT_UGT))
-       // cond:
-       // result: (MOVWconst [1])
+       // match: (CMPconst (MOVWconst [x]) [y])
+       // cond: int32(x)>int32(y) && uint32(x)<uint32(y)
+       // result: (FlagGT_ULT)
        for {
+               y := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_UGT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               x := v_0.AuxInt
+               if !(int32(x) > int32(y) && uint32(x) < uint32(y)) {
+                       break
+               }
+               v.reset(OpARMFlagGT_ULT)
                return true
        }
-       // match: (GreaterEqual (InvertFlags x))
-       // cond:
-       // result: (LessEqual x)
+       // match: (CMPconst (MOVWconst [x]) [y])
+       // cond: int32(x)>int32(y) && uint32(x)>uint32(y)
+       // result: (FlagGT_UGT)
        for {
+               y := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMInvertFlags {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               x := v_0.Args[0]
-               v.reset(OpARMLessEqual)
-               v.AddArg(x)
+               x := v_0.AuxInt
+               if !(int32(x) > int32(y) && uint32(x) > uint32(y)) {
+                       break
+               }
+               v.reset(OpARMFlagGT_UGT)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMGreaterEqualU_0(v *Value) bool {
-       // match: (GreaterEqualU (FlagEQ))
-       // cond:
-       // result: (MOVWconst [1])
+       // match: (CMPconst (MOVBUreg _) [c])
+       // cond: 0xff < c
+       // result: (FlagLT_ULT)
        for {
+               c := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagEQ {
+               if v_0.Op != OpARMMOVBUreg {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               if !(0xff < c) {
+                       break
+               }
+               v.reset(OpARMFlagLT_ULT)
                return true
        }
-       // match: (GreaterEqualU (FlagLT_ULT))
-       // cond:
-       // result: (MOVWconst [0])
+       // match: (CMPconst (MOVHUreg _) [c])
+       // cond: 0xffff < c
+       // result: (FlagLT_ULT)
        for {
+               c := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_ULT {
+               if v_0.Op != OpARMMOVHUreg {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               if !(0xffff < c) {
+                       break
+               }
+               v.reset(OpARMFlagLT_ULT)
                return true
        }
-       // match: (GreaterEqualU (FlagLT_UGT))
-       // cond:
-       // result: (MOVWconst [1])
+       // match: (CMPconst (ANDconst _ [m]) [n])
+       // cond: 0 <= int32(m) && int32(m) < int32(n)
+       // result: (FlagLT_ULT)
        for {
+               n := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_UGT {
+               if v_0.Op != OpARMANDconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               m := v_0.AuxInt
+               if !(0 <= int32(m) && int32(m) < int32(n)) {
+                       break
+               }
+               v.reset(OpARMFlagLT_ULT)
                return true
        }
-       // match: (GreaterEqualU (FlagGT_ULT))
-       // cond:
-       // result: (MOVWconst [0])
+       // match: (CMPconst (SRLconst _ [c]) [n])
+       // cond: 0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n)
+       // result: (FlagLT_ULT)
        for {
+               n := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_ULT {
+               if v_0.Op != OpARMSRLconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               c := v_0.AuxInt
+               if !(0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n)) {
+                       break
+               }
+               v.reset(OpARMFlagLT_ULT)
                return true
        }
-       // match: (GreaterEqualU (FlagGT_UGT))
+       return false
+}
+func rewriteValueARM_OpARMCMPshiftLL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMPshiftLL (MOVWconst [c]) x [d])
        // cond:
-       // result: (MOVWconst [1])
+       // result: (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
        for {
+               d := v.AuxInt
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_UGT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = c
+               v1 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+               v1.AuxInt = d
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                return true
        }
-       // match: (GreaterEqualU (InvertFlags x))
+       // match: (CMPshiftLL x (MOVWconst [c]) [d])
        // cond:
-       // result: (LessEqualU x)
+       // result: (CMPconst x [int64(uint32(c)<<uint64(d))])
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMInvertFlags {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               x := v_0.Args[0]
-               v.reset(OpARMLessEqualU)
+               c := v_1.AuxInt
+               v.reset(OpARMCMPconst)
+               v.AuxInt = int64(uint32(c) << uint64(d))
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMGreaterThan_0(v *Value) bool {
-       // match: (GreaterThan (FlagEQ))
+func rewriteValueARM_OpARMCMPshiftLLreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMPshiftLLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (MOVWconst [0])
+       // result: (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
        for {
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagEQ {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
-       // match: (GreaterThan (FlagLT_ULT))
-       // cond:
-       // result: (MOVWconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_ULT {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
-       // match: (GreaterThan (FlagLT_UGT))
-       // cond:
-       // result: (MOVWconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_UGT {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = c
+               v1 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v1.AddArg(x)
+               v1.AddArg(y)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                return true
        }
-       // match: (GreaterThan (FlagGT_ULT))
+       // match: (CMPshiftLLreg x y (MOVWconst [c]))
        // cond:
-       // result: (MOVWconst [1])
+       // result: (CMPshiftLL x y [c])
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_ULT {
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               c := v_2.AuxInt
+               v.reset(OpARMCMPshiftLL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (GreaterThan (FlagGT_UGT))
+       return false
+}
+func rewriteValueARM_OpARMCMPshiftRA_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMPshiftRA (MOVWconst [c]) x [d])
        // cond:
-       // result: (MOVWconst [1])
+       // result: (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
        for {
+               d := v.AuxInt
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_UGT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = c
+               v1 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+               v1.AuxInt = d
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                return true
        }
-       // match: (GreaterThan (InvertFlags x))
+       // match: (CMPshiftRA x (MOVWconst [c]) [d])
        // cond:
-       // result: (LessThan x)
+       // result: (CMPconst x [int64(int32(c)>>uint64(d))])
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMInvertFlags {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               x := v_0.Args[0]
-               v.reset(OpARMLessThan)
+               c := v_1.AuxInt
+               v.reset(OpARMCMPconst)
+               v.AuxInt = int64(int32(c) >> uint64(d))
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMGreaterThanU_0(v *Value) bool {
-       // match: (GreaterThanU (FlagEQ))
+func rewriteValueARM_OpARMCMPshiftRAreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMPshiftRAreg (MOVWconst [c]) x y)
        // cond:
-       // result: (MOVWconst [0])
+       // result: (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
        for {
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagEQ {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = c
+               v1 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
+               v1.AddArg(x)
+               v1.AddArg(y)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                return true
        }
-       // match: (GreaterThanU (FlagLT_ULT))
+       // match: (CMPshiftRAreg x y (MOVWconst [c]))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (CMPshiftRA x y [c])
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_ULT {
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               c := v_2.AuxInt
+               v.reset(OpARMCMPshiftRA)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (GreaterThanU (FlagLT_UGT))
+       return false
+}
+func rewriteValueARM_OpARMCMPshiftRL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMPshiftRL (MOVWconst [c]) x [d])
        // cond:
-       // result: (MOVWconst [1])
+       // result: (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
        for {
+               d := v.AuxInt
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagLT_UGT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = c
+               v1 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+               v1.AuxInt = d
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                return true
        }
-       // match: (GreaterThanU (FlagGT_ULT))
+       // match: (CMPshiftRL x (MOVWconst [c]) [d])
        // cond:
-       // result: (MOVWconst [0])
+       // result: (CMPconst x [int64(uint32(c)>>uint64(d))])
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_ULT {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               c := v_1.AuxInt
+               v.reset(OpARMCMPconst)
+               v.AuxInt = int64(uint32(c) >> uint64(d))
+               v.AddArg(x)
                return true
        }
-       // match: (GreaterThanU (FlagGT_UGT))
+       return false
+}
+func rewriteValueARM_OpARMCMPshiftRLreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (CMPshiftRLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (MOVWconst [1])
+       // result: (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
        for {
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMFlagGT_UGT {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMInvertFlags)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = c
+               v1 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v1.AddArg(x)
+               v1.AddArg(y)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                return true
        }
-       // match: (GreaterThanU (InvertFlags x))
+       // match: (CMPshiftRLreg x y (MOVWconst [c]))
        // cond:
-       // result: (LessThanU x)
+       // result: (CMPshiftRL x y [c])
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMInvertFlags {
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
                        break
                }
-               x := v_0.Args[0]
-               v.reset(OpARMLessThanU)
+               c := v_2.AuxInt
+               v.reset(OpARMCMPshiftRL)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMLessEqual_0(v *Value) bool {
-       // match: (LessEqual (FlagEQ))
+func rewriteValueARM_OpARMEqual_0(v *Value) bool {
+       // match: (Equal (FlagEQ))
        // cond:
        // result: (MOVWconst [1])
        for {
@@ -5719,31 +6042,31 @@ func rewriteValueARM_OpARMLessEqual_0(v *Value) bool {
                v.AuxInt = 1
                return true
        }
-       // match: (LessEqual (FlagLT_ULT))
+       // match: (Equal (FlagLT_ULT))
        // cond:
-       // result: (MOVWconst [1])
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               v.AuxInt = 0
                return true
        }
-       // match: (LessEqual (FlagLT_UGT))
+       // match: (Equal (FlagLT_UGT))
        // cond:
-       // result: (MOVWconst [1])
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagLT_UGT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               v.AuxInt = 0
                return true
        }
-       // match: (LessEqual (FlagGT_ULT))
+       // match: (Equal (FlagGT_ULT))
        // cond:
        // result: (MOVWconst [0])
        for {
@@ -5755,7 +6078,7 @@ func rewriteValueARM_OpARMLessEqual_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (LessEqual (FlagGT_UGT))
+       // match: (Equal (FlagGT_UGT))
        // cond:
        // result: (MOVWconst [0])
        for {
@@ -5767,23 +6090,23 @@ func rewriteValueARM_OpARMLessEqual_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (LessEqual (InvertFlags x))
+       // match: (Equal (InvertFlags x))
        // cond:
-       // result: (GreaterEqual x)
+       // result: (Equal x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMInvertFlags {
                        break
                }
                x := v_0.Args[0]
-               v.reset(OpARMGreaterEqual)
+               v.reset(OpARMEqual)
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMLessEqualU_0(v *Value) bool {
-       // match: (LessEqualU (FlagEQ))
+func rewriteValueARM_OpARMGreaterEqual_0(v *Value) bool {
+       // match: (GreaterEqual (FlagEQ))
        // cond:
        // result: (MOVWconst [1])
        for {
@@ -5795,19 +6118,19 @@ func rewriteValueARM_OpARMLessEqualU_0(v *Value) bool {
                v.AuxInt = 1
                return true
        }
-       // match: (LessEqualU (FlagLT_ULT))
+       // match: (GreaterEqual (FlagLT_ULT))
        // cond:
-       // result: (MOVWconst [1])
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               v.AuxInt = 0
                return true
        }
-       // match: (LessEqualU (FlagLT_UGT))
+       // match: (GreaterEqual (FlagLT_UGT))
        // cond:
        // result: (MOVWconst [0])
        for {
@@ -5819,7 +6142,7 @@ func rewriteValueARM_OpARMLessEqualU_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (LessEqualU (FlagGT_ULT))
+       // match: (GreaterEqual (FlagGT_ULT))
        // cond:
        // result: (MOVWconst [1])
        for {
@@ -5831,59 +6154,59 @@ func rewriteValueARM_OpARMLessEqualU_0(v *Value) bool {
                v.AuxInt = 1
                return true
        }
-       // match: (LessEqualU (FlagGT_UGT))
+       // match: (GreaterEqual (FlagGT_UGT))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (MOVWconst [1])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.AuxInt = 1
                return true
        }
-       // match: (LessEqualU (InvertFlags x))
+       // match: (GreaterEqual (InvertFlags x))
        // cond:
-       // result: (GreaterEqualU x)
+       // result: (LessEqual x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMInvertFlags {
                        break
                }
                x := v_0.Args[0]
-               v.reset(OpARMGreaterEqualU)
+               v.reset(OpARMLessEqual)
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMLessThan_0(v *Value) bool {
-       // match: (LessThan (FlagEQ))
+func rewriteValueARM_OpARMGreaterEqualU_0(v *Value) bool {
+       // match: (GreaterEqualU (FlagEQ))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (MOVWconst [1])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagEQ {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.AuxInt = 1
                return true
        }
-       // match: (LessThan (FlagLT_ULT))
+       // match: (GreaterEqualU (FlagLT_ULT))
        // cond:
-       // result: (MOVWconst [1])
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               v.AuxInt = 0
                return true
        }
-       // match: (LessThan (FlagLT_UGT))
+       // match: (GreaterEqualU (FlagLT_UGT))
        // cond:
        // result: (MOVWconst [1])
        for {
@@ -5895,7 +6218,7 @@ func rewriteValueARM_OpARMLessThan_0(v *Value) bool {
                v.AuxInt = 1
                return true
        }
-       // match: (LessThan (FlagGT_ULT))
+       // match: (GreaterEqualU (FlagGT_ULT))
        // cond:
        // result: (MOVWconst [0])
        for {
@@ -5907,35 +6230,35 @@ func rewriteValueARM_OpARMLessThan_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (LessThan (FlagGT_UGT))
+       // match: (GreaterEqualU (FlagGT_UGT))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (MOVWconst [1])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.AuxInt = 1
                return true
        }
-       // match: (LessThan (InvertFlags x))
+       // match: (GreaterEqualU (InvertFlags x))
        // cond:
-       // result: (GreaterThan x)
+       // result: (LessEqualU x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMInvertFlags {
                        break
                }
                x := v_0.Args[0]
-               v.reset(OpARMGreaterThan)
+               v.reset(OpARMLessEqualU)
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
-       // match: (LessThanU (FlagEQ))
+func rewriteValueARM_OpARMGreaterThan_0(v *Value) bool {
+       // match: (GreaterThan (FlagEQ))
        // cond:
        // result: (MOVWconst [0])
        for {
@@ -5947,19 +6270,19 @@ func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (LessThanU (FlagLT_ULT))
+       // match: (GreaterThan (FlagLT_ULT))
        // cond:
-       // result: (MOVWconst [1])
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 1
+               v.AuxInt = 0
                return true
        }
-       // match: (LessThanU (FlagLT_UGT))
+       // match: (GreaterThan (FlagLT_UGT))
        // cond:
        // result: (MOVWconst [0])
        for {
@@ -5971,7 +6294,7 @@ func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (LessThanU (FlagGT_ULT))
+       // match: (GreaterThan (FlagGT_ULT))
        // cond:
        // result: (MOVWconst [1])
        for {
@@ -5983,580 +6306,467 @@ func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
                v.AuxInt = 1
                return true
        }
-       // match: (LessThanU (FlagGT_UGT))
+       // match: (GreaterThan (FlagGT_UGT))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (MOVWconst [1])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
                v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.AuxInt = 1
                return true
        }
-       // match: (LessThanU (InvertFlags x))
+       // match: (GreaterThan (InvertFlags x))
        // cond:
-       // result: (GreaterThanU x)
+       // result: (LessThan x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMInvertFlags {
                        break
                }
                x := v_0.Args[0]
-               v.reset(OpARMGreaterThanU)
+               v.reset(OpARMLessThan)
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       config := b.Func.Config
-       _ = config
-       // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
+func rewriteValueARM_OpARMGreaterThanU_0(v *Value) bool {
+       // match: (GreaterThanU (FlagEQ))
        // cond:
-       // result: (MOVBUload [off1+off2] {sym} ptr mem)
+       // result: (MOVWconst [0])
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADDconst {
+               if v_0.Op != OpARMFlagEQ {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBUload)
-               v.AuxInt = off1 + off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // match: (GreaterThanU (FlagLT_ULT))
        // cond:
-       // result: (MOVBUload [off1-off2] {sym} ptr mem)
+       // result: (MOVWconst [0])
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSUBconst {
+               if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBUload)
-               v.AuxInt = off1 - off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2)
-       // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // match: (GreaterThanU (FlagLT_UGT))
+       // cond:
+       // result: (MOVWconst [1])
        for {
-               off1 := v.AuxInt
-               sym1 := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWaddr {
-                       break
-               }
-               off2 := v_0.AuxInt
-               sym2 := v_0.Aux
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               if !(canMergeSym(sym1, sym2)) {
+               if v_0.Op != OpARMFlagLT_UGT {
                        break
                }
-               v.reset(OpARMMOVBUload)
-               v.AuxInt = off1 + off2
-               v.Aux = mergeSym(sym1, sym2)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       // match: (MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
-       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: (MOVBUreg x)
+       // match: (GreaterThanU (FlagGT_ULT))
+       // cond:
+       // result: (MOVWconst [0])
        for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVBstore {
-                       break
-               }
-               off2 := v_1.AuxInt
-               sym2 := v_1.Aux
-               _ = v_1.Args[2]
-               ptr2 := v_1.Args[0]
-               x := v_1.Args[1]
-               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagGT_ULT {
                        break
                }
-               v.reset(OpARMMOVBUreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBUload [0] {sym} (ADD ptr idx) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVBUloadidx ptr idx mem)
+       // match: (GreaterThanU (FlagGT_UGT))
+       // cond:
+       // result: (MOVWconst [1])
        for {
-               if v.AuxInt != 0 {
-                       break
-               }
-               sym := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADD {
+               if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
-               _ = v_0.Args[1]
-               ptr := v_0.Args[0]
-               idx := v_0.Args[1]
-               mem := v.Args[1]
-               if !(sym == nil && !config.nacl) {
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
+               return true
+       }
+       // match: (GreaterThanU (InvertFlags x))
+       // cond:
+       // result: (LessThanU x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMInvertFlags {
                        break
                }
-               v.reset(OpARMMOVBUloadidx)
-               v.AddArg(ptr)
-               v.AddArg(idx)
-               v.AddArg(mem)
+               x := v_0.Args[0]
+               v.reset(OpARMLessThanU)
+               v.AddArg(x)
                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)
+func rewriteValueARM_OpARMLessEqual_0(v *Value) bool {
+       // match: (LessEqual (FlagEQ))
+       // cond:
+       // result: (MOVWconst [1])
        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)) {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagEQ {
                        break
                }
-               v.reset(OpARMMOVBUreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       // match: (MOVBUloadidx ptr (MOVWconst [c]) mem)
+       // match: (LessEqual (FlagLT_ULT))
        // cond:
-       // result: (MOVBUload [c] ptr mem)
+       // result: (MOVWconst [1])
        for {
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
-               c := v_1.AuxInt
-               mem := v.Args[2]
-               v.reset(OpARMMOVBUload)
-               v.AuxInt = c
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       // match: (MOVBUloadidx (MOVWconst [c]) ptr mem)
+       // match: (LessEqual (FlagLT_UGT))
        // cond:
-       // result: (MOVBUload [c] ptr mem)
+       // result: (MOVWconst [1])
        for {
-               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMFlagLT_UGT {
                        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)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
-       // match: (MOVBUreg x:(MOVBUload _ _))
+       // match: (LessEqual (FlagGT_ULT))
        // cond:
-       // result: (MOVWreg x)
+       // result: (MOVWconst [0])
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBUload {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagGT_ULT {
                        break
                }
-               _ = x.Args[1]
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBUreg (ANDconst [c] x))
+       // match: (LessEqual (FlagGT_UGT))
        // cond:
-       // result: (ANDconst [c&0xff] x)
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpARMANDconst {
+               if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
-               c := v_0.AuxInt
-               x := v_0.Args[0]
-               v.reset(OpARMANDconst)
-               v.AuxInt = c & 0xff
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBUreg x:(MOVBUreg _))
+       // match: (LessEqual (InvertFlags x))
        // cond:
-       // result: (MOVWreg x)
+       // result: (GreaterEqual x)
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBUreg {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMInvertFlags {
                        break
                }
-               v.reset(OpARMMOVWreg)
+               x := v_0.Args[0]
+               v.reset(OpARMGreaterEqual)
                v.AddArg(x)
                return true
        }
-       // match: (MOVBUreg (MOVWconst [c]))
+       return false
+}
+func rewriteValueARM_OpARMLessEqualU_0(v *Value) bool {
+       // match: (LessEqualU (FlagEQ))
        // cond:
-       // result: (MOVWconst [int64(uint8(c))])
+       // result: (MOVWconst [1])
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMFlagEQ {
                        break
                }
-               c := v_0.AuxInt
                v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(uint8(c))
+               v.AuxInt = 1
                return true
        }
-       return false
-}
-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: (LessEqualU (FlagLT_ULT))
        // cond:
-       // result: (MOVBload [off1+off2] {sym} ptr mem)
+       // result: (MOVWconst [1])
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADDconst {
+               if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBload)
-               v.AuxInt = off1 + off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       // match: (MOVBload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // match: (LessEqualU (FlagLT_UGT))
        // cond:
-       // result: (MOVBload [off1-off2] {sym} ptr mem)
+       // result: (MOVWconst [0])
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSUBconst {
+               if v_0.Op != OpARMFlagLT_UGT {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBload)
-               v.AuxInt = off1 - off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2)
-       // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // match: (LessEqualU (FlagGT_ULT))
+       // cond:
+       // result: (MOVWconst [1])
        for {
-               off1 := v.AuxInt
-               sym1 := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWaddr {
-                       break
-               }
-               off2 := v_0.AuxInt
-               sym2 := v_0.Aux
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               if !(canMergeSym(sym1, sym2)) {
+               if v_0.Op != OpARMFlagGT_ULT {
                        break
                }
-               v.reset(OpARMMOVBload)
-               v.AuxInt = off1 + off2
-               v.Aux = mergeSym(sym1, sym2)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       // match: (MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
-       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: (MOVBreg x)
+       // match: (LessEqualU (FlagGT_UGT))
+       // cond:
+       // result: (MOVWconst [0])
        for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVBstore {
-                       break
-               }
-               off2 := v_1.AuxInt
-               sym2 := v_1.Aux
-               _ = v_1.Args[2]
-               ptr2 := v_1.Args[0]
-               x := v_1.Args[1]
-               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
-               v.reset(OpARMMOVBreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBload [0] {sym} (ADD ptr idx) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVBloadidx ptr idx mem)
+       // match: (LessEqualU (InvertFlags x))
+       // cond:
+       // result: (GreaterEqualU x)
        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) {
+               if v_0.Op != OpARMInvertFlags {
                        break
                }
-               v.reset(OpARMMOVBloadidx)
-               v.AddArg(ptr)
-               v.AddArg(idx)
-               v.AddArg(mem)
+               x := v_0.Args[0]
+               v.reset(OpARMGreaterEqualU)
+               v.AddArg(x)
                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)
+func rewriteValueARM_OpARMLessThan_0(v *Value) bool {
+       // match: (LessThan (FlagEQ))
+       // cond:
+       // result: (MOVWconst [0])
        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)) {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagEQ {
                        break
                }
-               v.reset(OpARMMOVBreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBloadidx ptr (MOVWconst [c]) mem)
+       // match: (LessThan (FlagLT_ULT))
        // cond:
-       // result: (MOVBload [c] ptr mem)
+       // result: (MOVWconst [1])
        for {
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
-               c := v_1.AuxInt
-               mem := v.Args[2]
-               v.reset(OpARMMOVBload)
-               v.AuxInt = c
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       // match: (MOVBloadidx (MOVWconst [c]) ptr mem)
+       // match: (LessThan (FlagLT_UGT))
        // cond:
-       // result: (MOVBload [c] ptr mem)
+       // result: (MOVWconst [1])
        for {
-               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMFlagLT_UGT {
                        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)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
-       // match: (MOVBreg x:(MOVBload _ _))
+       // match: (LessThan (FlagGT_ULT))
        // cond:
-       // result: (MOVWreg x)
+       // result: (MOVWconst [0])
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBload {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagGT_ULT {
                        break
                }
-               _ = x.Args[1]
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBreg (ANDconst [c] x))
-       // cond: c & 0x80 == 0
-       // result: (ANDconst [c&0x7f] x)
+       // match: (LessThan (FlagGT_UGT))
+       // cond:
+       // result: (MOVWconst [0])
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpARMANDconst {
+               if v_0.Op != OpARMFlagGT_UGT {
                        break
                }
-               c := v_0.AuxInt
-               x := v_0.Args[0]
-               if !(c&0x80 == 0) {
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
+               return true
+       }
+       // match: (LessThan (InvertFlags x))
+       // cond:
+       // result: (GreaterThan x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMInvertFlags {
                        break
                }
-               v.reset(OpARMANDconst)
-               v.AuxInt = c & 0x7f
+               x := v_0.Args[0]
+               v.reset(OpARMGreaterThan)
                v.AddArg(x)
                return true
        }
-       // match: (MOVBreg x:(MOVBreg _))
+       return false
+}
+func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
+       // match: (LessThanU (FlagEQ))
        // cond:
-       // result: (MOVWreg x)
+       // result: (MOVWconst [0])
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBreg {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagEQ {
                        break
                }
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
-       // match: (MOVBreg (MOVWconst [c]))
+       // match: (LessThanU (FlagLT_ULT))
        // cond:
-       // result: (MOVWconst [int64(int8(c))])
+       // result: (MOVWconst [1])
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMFlagLT_ULT {
                        break
                }
-               c := v_0.AuxInt
                v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(int8(c))
+               v.AuxInt = 1
+               return true
+       }
+       // match: (LessThanU (FlagLT_UGT))
+       // cond:
+       // result: (MOVWconst [0])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagLT_UGT {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
+               return true
+       }
+       // match: (LessThanU (FlagGT_ULT))
+       // cond:
+       // result: (MOVWconst [1])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagGT_ULT {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 1
+               return true
+       }
+       // match: (LessThanU (FlagGT_UGT))
+       // cond:
+       // result: (MOVWconst [0])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMFlagGT_UGT {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
+               return true
+       }
+       // match: (LessThanU (InvertFlags x))
+       // cond:
+       // result: (GreaterThanU x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMInvertFlags {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpARMGreaterThanU)
+               v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
+func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
        b := v.Block
        _ = b
        config := b.Func.Config
        _ = config
-       // match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
+       // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
-       // result: (MOVBstore [off1+off2] {sym} ptr val mem)
+       // result: (MOVBUload [off1+off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMADDconst {
                        break
                }
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
+               mem := v.Args[1]
+               v.reset(OpARMMOVBUload)
                v.AuxInt = off1 + off2
                v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem)
+       // match: (MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem)
        // cond:
-       // result: (MOVBstore [off1-off2] {sym} ptr val mem)
+       // result: (MOVBUload [off1-off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMSUBconst {
                        break
                }
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
+               mem := v.Args[1]
+               v.reset(OpARMMOVBUload)
                v.AuxInt = off1 - off2
                v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
+       // match: (MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
        // cond: canMergeSym(sym1,sym2)
-       // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := v.AuxInt
                sym1 := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWaddr {
                        break
@@ -6564,116 +6774,50 @@ func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
                off2 := v_0.AuxInt
                sym2 := v_0.Aux
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
+               mem := v.Args[1]
                if !(canMergeSym(sym1, sym2)) {
                        break
                }
-               v.reset(OpARMMOVBstore)
+               v.reset(OpARMMOVBUload)
                v.AuxInt = off1 + off2
                v.Aux = mergeSym(sym1, sym2)
                v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem)
-       // cond:
-       // result: (MOVBstore [off] {sym} ptr x mem)
-       for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVBreg {
-                       break
-               }
-               x := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = off
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem)
-       // cond:
-       // result: (MOVBstore [off] {sym} ptr x mem)
-       for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVBUreg {
-                       break
-               }
-               x := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = off
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(x)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem)
-       // cond:
-       // result: (MOVBstore [off] {sym} ptr x mem)
+       // match: (MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
+       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+       // result: (MOVBUreg x)
        for {
                off := v.AuxInt
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVHreg {
+               if v_1.Op != OpARMMOVBstore {
                        break
                }
-               x := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = off
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem)
-       // cond:
-       // result: (MOVBstore [off] {sym} ptr x mem)
-       for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVHUreg {
+               off2 := v_1.AuxInt
+               sym2 := v_1.Aux
+               _ = v_1.Args[2]
+               ptr2 := v_1.Args[0]
+               x := v_1.Args[1]
+               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
                        break
                }
-               x := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = off
-               v.Aux = sym
-               v.AddArg(ptr)
+               v.reset(OpARMMOVBUreg)
                v.AddArg(x)
-               v.AddArg(mem)
                return true
        }
-       // match: (MOVBstore [0] {sym} (ADD ptr idx) val mem)
+       // match: (MOVBUload [0] {sym} (ADD ptr idx) mem)
        // cond: sym == nil && !config.nacl
-       // result: (MOVBstoreidx ptr idx val mem)
+       // result: (MOVBUloadidx ptr idx mem)
        for {
                if v.AuxInt != 0 {
                        break
                }
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMADD {
                        break
@@ -6681,67 +6825,145 @@ func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
                _ = v_0.Args[1]
                ptr := v_0.Args[0]
                idx := v_0.Args[1]
-               val := v.Args[1]
-               mem := v.Args[2]
+               mem := v.Args[1]
                if !(sym == nil && !config.nacl) {
                        break
                }
-               v.reset(OpARMMOVBstoreidx)
+               v.reset(OpARMMOVBUloadidx)
                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)
+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[3]
+               _ = v.Args[2]
                ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               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
-               val := v.Args[2]
-               mem := v.Args[3]
-               v.reset(OpARMMOVBstore)
+               mem := v.Args[2]
+               v.reset(OpARMMOVBUload)
                v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVBstoreidx (MOVWconst [c]) ptr val mem)
+       // match: (MOVBUloadidx (MOVWconst [c]) ptr mem)
        // cond:
-       // result: (MOVBstore [c] ptr val mem)
+       // result: (MOVBUload [c] ptr mem)
        for {
-               _ = v.Args[3]
+               _ = v.Args[2]
                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)
+               mem := v.Args[2]
+               v.reset(OpARMMOVBUload)
                v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
-       // match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
+func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
+       // match: (MOVBUreg x:(MOVBUload _ _))
        // cond:
-       // result: (MOVDload [off1+off2] {sym} ptr mem)
+       // result: (MOVWreg x)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBUload {
+                       break
+               }
+               _ = x.Args[1]
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVBUreg (ANDconst [c] x))
+       // cond:
+       // result: (ANDconst [c&0xff] x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMANDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v_0.Args[0]
+               v.reset(OpARMANDconst)
+               v.AuxInt = c & 0xff
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVBUreg x:(MOVBUreg _))
+       // cond:
+       // result: (MOVWreg x)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBUreg {
+                       break
+               }
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVBUreg (MOVWconst [c]))
+       // cond:
+       // result: (MOVWconst [int64(uint8(c))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(uint8(c))
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVBload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
+       // match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
+       // cond:
+       // result: (MOVBload [off1+off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
@@ -6753,16 +6975,16 @@ func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
                mem := v.Args[1]
-               v.reset(OpARMMOVDload)
+               v.reset(OpARMMOVBload)
                v.AuxInt = off1 + off2
                v.Aux = sym
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVDload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // match: (MOVBload [off1] {sym} (SUBconst [off2] ptr) mem)
        // cond:
-       // result: (MOVDload [off1-off2] {sym} ptr mem)
+       // result: (MOVBload [off1-off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
@@ -6774,16 +6996,16 @@ func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
                mem := v.Args[1]
-               v.reset(OpARMMOVDload)
+               v.reset(OpARMMOVBload)
                v.AuxInt = off1 - off2
                v.Aux = sym
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
+       // match: (MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
        // cond: canMergeSym(sym1,sym2)
-       // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := v.AuxInt
                sym1 := v.Aux
@@ -6799,23 +7021,23 @@ func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
                if !(canMergeSym(sym1, sym2)) {
                        break
                }
-               v.reset(OpARMMOVDload)
+               v.reset(OpARMMOVBload)
                v.AuxInt = off1 + off2
                v.Aux = mergeSym(sym1, sym2)
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _))
+       // match: (MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
        // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: x
+       // result: (MOVBreg x)
        for {
                off := v.AuxInt
                sym := v.Aux
                _ = v.Args[1]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVDstore {
+               if v_1.Op != OpARMMOVBstore {
                        break
                }
                off2 := v_1.AuxInt
@@ -6826,188 +7048,168 @@ func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
                if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               v.reset(OpARMMOVBreg)
                v.AddArg(x)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMMOVDstore_0(v *Value) bool {
-       // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond:
-       // result: (MOVDstore [off1+off2] {sym} ptr val mem)
+       // match: (MOVBload [0] {sym} (ADD ptr idx) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVBloadidx ptr idx mem)
        for {
-               off1 := v.AuxInt
+               if v.AuxInt != 0 {
+                       break
+               }
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADDconst {
+               if v_0.Op != OpARMADD {
                        break
                }
-               off2 := v_0.AuxInt
+               _ = v_0.Args[1]
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVDstore)
-               v.AuxInt = off1 + off2
-               v.Aux = sym
+               idx := v_0.Args[1]
+               mem := v.Args[1]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVBloadidx)
                v.AddArg(ptr)
-               v.AddArg(val)
+               v.AddArg(idx)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem)
+       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: (MOVDstore [off1-off2] {sym} ptr val mem)
+       // result: (MOVBload [c] ptr mem)
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
                _ = v.Args[2]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMSUBconst {
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               val := v.Args[1]
+               c := v_1.AuxInt
                mem := v.Args[2]
-               v.reset(OpARMMOVDstore)
-               v.AuxInt = off1 - off2
-               v.Aux = sym
+               v.reset(OpARMMOVBload)
+               v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2)
-       // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       // match: (MOVBloadidx (MOVWconst [c]) ptr mem)
+       // cond:
+       // result: (MOVBload [c] ptr mem)
        for {
-               off1 := v.AuxInt
-               sym1 := v.Aux
                _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWaddr {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               off2 := v_0.AuxInt
-               sym2 := v_0.Aux
-               ptr := v_0.Args[0]
-               val := v.Args[1]
+               c := v_0.AuxInt
+               ptr := v.Args[1]
                mem := v.Args[2]
-               if !(canMergeSym(sym1, sym2)) {
-                       break
-               }
-               v.reset(OpARMMOVDstore)
-               v.AuxInt = off1 + off2
-               v.Aux = mergeSym(sym1, sym2)
+               v.reset(OpARMMOVBload)
+               v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVFload_0(v *Value) bool {
-       // match: (MOVFload [off1] {sym} (ADDconst [off2] ptr) mem)
+func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
+       // match: (MOVBreg x:(MOVBload _ _))
        // cond:
-       // result: (MOVFload [off1+off2] {sym} ptr mem)
+       // result: (MOVWreg x)
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMADDconst {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBload {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVFload)
-               v.AuxInt = off1 + off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               _ = x.Args[1]
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
                return true
        }
-       // match: (MOVFload [off1] {sym} (SUBconst [off2] ptr) mem)
-       // cond:
-       // result: (MOVFload [off1-off2] {sym} ptr mem)
+       // match: (MOVBreg (ANDconst [c] x))
+       // cond: c & 0x80 == 0
+       // result: (ANDconst [c&0x7f] x)
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSUBconst {
+               if v_0.Op != OpARMANDconst {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVFload)
-               v.AuxInt = off1 - off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               c := v_0.AuxInt
+               x := v_0.Args[0]
+               if !(c&0x80 == 0) {
+                       break
+               }
+               v.reset(OpARMANDconst)
+               v.AuxInt = c & 0x7f
+               v.AddArg(x)
                return true
        }
-       // match: (MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2)
-       // result: (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // match: (MOVBreg x:(MOVBreg _))
+       // cond:
+       // result: (MOVWreg x)
        for {
-               off1 := v.AuxInt
-               sym1 := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWaddr {
-                       break
-               }
-               off2 := v_0.AuxInt
-               sym2 := v_0.Aux
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               if !(canMergeSym(sym1, sym2)) {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBreg {
                        break
                }
-               v.reset(OpARMMOVFload)
-               v.AuxInt = off1 + off2
-               v.Aux = mergeSym(sym1, sym2)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
                return true
        }
-       // match: (MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _))
-       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: x
+       // match: (MOVBreg (MOVWconst [c]))
+       // cond:
+       // result: (MOVWconst [int64(int8(c))])
        for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVFstore {
-                       break
-               }
-               off2 := v_1.AuxInt
-               sym2 := v_1.Aux
-               _ = v_1.Args[2]
-               ptr2 := v_1.Args[0]
-               x := v_1.Args[1]
-               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               c := v_0.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(int8(c))
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
-       // match: (MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem)
+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)
        // cond:
-       // result: (MOVFstore [off1+off2] {sym} ptr val mem)
+       // result: (MOVBstore [off1+off2] {sym} ptr val mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
@@ -7020,7 +7222,7 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
                ptr := v_0.Args[0]
                val := v.Args[1]
                mem := v.Args[2]
-               v.reset(OpARMMOVFstore)
+               v.reset(OpARMMOVBstore)
                v.AuxInt = off1 + off2
                v.Aux = sym
                v.AddArg(ptr)
@@ -7028,9 +7230,9 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
                v.AddArg(mem)
                return true
        }
-       // match: (MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem)
+       // match: (MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem)
        // cond:
-       // result: (MOVFstore [off1-off2] {sym} ptr val mem)
+       // result: (MOVBstore [off1-off2] {sym} ptr val mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
@@ -7043,7 +7245,7 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
                ptr := v_0.Args[0]
                val := v.Args[1]
                mem := v.Args[2]
-               v.reset(OpARMMOVFstore)
+               v.reset(OpARMMOVBstore)
                v.AuxInt = off1 - off2
                v.Aux = sym
                v.AddArg(ptr)
@@ -7051,9 +7253,9 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
                v.AddArg(mem)
                return true
        }
-       // match: (MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
+       // match: (MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
        // cond: canMergeSym(sym1,sym2)
-       // result: (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := v.AuxInt
                sym1 := v.Aux
@@ -7070,7 +7272,7 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
                if !(canMergeSym(sym1, sym2)) {
                        break
                }
-               v.reset(OpARMMOVFstore)
+               v.reset(OpARMMOVBstore)
                v.AuxInt = off1 + off2
                v.Aux = mergeSym(sym1, sym2)
                v.AddArg(ptr)
@@ -7078,113 +7280,103 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
                v.AddArg(mem)
                return true
        }
-       return false
-}
-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: (MOVBstore [off] {sym} ptr (MOVBreg x) mem)
        // cond:
-       // result: (MOVHUload [off1+off2] {sym} ptr mem)
+       // result: (MOVBstore [off] {sym} ptr x mem)
        for {
-               off1 := v.AuxInt
+               off := v.AuxInt
                sym := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMADDconst {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVBreg {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVHUload)
-               v.AuxInt = off1 + off2
+               x := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = off
                v.Aux = sym
                v.AddArg(ptr)
+               v.AddArg(x)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem)
        // cond:
-       // result: (MOVHUload [off1-off2] {sym} ptr mem)
+       // result: (MOVBstore [off] {sym} ptr x mem)
        for {
-               off1 := v.AuxInt
+               off := v.AuxInt
                sym := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMSUBconst {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVBUreg {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVHUload)
-               v.AuxInt = off1 - off2
+               x := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = off
                v.Aux = sym
                v.AddArg(ptr)
+               v.AddArg(x)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2)
-       // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem)
+       // cond:
+       // result: (MOVBstore [off] {sym} ptr x mem)
        for {
-               off1 := v.AuxInt
-               sym1 := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWaddr {
-                       break
-               }
-               off2 := v_0.AuxInt
-               sym2 := v_0.Aux
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               if !(canMergeSym(sym1, sym2)) {
+               off := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVHreg {
                        break
                }
-               v.reset(OpARMMOVHUload)
-               v.AuxInt = off1 + off2
-               v.Aux = mergeSym(sym1, sym2)
+               x := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = off
+               v.Aux = sym
                v.AddArg(ptr)
+               v.AddArg(x)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
-       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: (MOVHUreg x)
+       // match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem)
+       // cond:
+       // result: (MOVBstore [off] {sym} ptr x mem)
        for {
                off := v.AuxInt
                sym := v.Aux
-               _ = v.Args[1]
+               _ = v.Args[2]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVHstore {
-                       break
-               }
-               off2 := v_1.AuxInt
-               sym2 := v_1.Aux
-               _ = v_1.Args[2]
-               ptr2 := v_1.Args[0]
-               x := v_1.Args[1]
-               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+               if v_1.Op != OpARMMOVHUreg {
                        break
                }
-               v.reset(OpARMMOVHUreg)
+               x := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = off
+               v.Aux = sym
+               v.AddArg(ptr)
                v.AddArg(x)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVHUload [0] {sym} (ADD ptr idx) mem)
+       // match: (MOVBstore [0] {sym} (ADD ptr idx) val mem)
        // cond: sym == nil && !config.nacl
-       // result: (MOVHUloadidx ptr idx mem)
+       // result: (MOVBstoreidx ptr idx val mem)
        for {
                if v.AuxInt != 0 {
                        break
                }
                sym := v.Aux
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
                if v_0.Op != OpARMADD {
                        break
@@ -7192,170 +7384,238 @@ func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
                _ = v_0.Args[1]
                ptr := v_0.Args[0]
                idx := v_0.Args[1]
-               mem := v.Args[1]
+               val := v.Args[1]
+               mem := v.Args[2]
                if !(sym == nil && !config.nacl) {
                        break
                }
-               v.reset(OpARMMOVHUloadidx)
+               v.reset(OpARMMOVBstoreidx)
                v.AddArg(ptr)
                v.AddArg(idx)
+               v.AddArg(val)
                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)
+func rewriteValueARM_OpARMMOVBstoreidx_0(v *Value) bool {
+       // match: (MOVBstoreidx ptr (MOVWconst [c]) val mem)
+       // cond:
+       // result: (MOVBstore [c] ptr val mem)
        for {
-               _ = v.Args[2]
+               _ = v.Args[3]
                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 {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
                c := v_1.AuxInt
-               mem := v.Args[2]
-               v.reset(OpARMMOVHUload)
+               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: (MOVHUloadidx (MOVWconst [c]) ptr mem)
+       // match: (MOVBstoreidx (MOVWconst [c]) ptr val mem)
        // cond:
-       // result: (MOVHUload [c] ptr mem)
+       // result: (MOVBstore [c] ptr val mem)
        for {
-               _ = v.Args[2]
+               _ = v.Args[3]
                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)
+               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
 }
-func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
-       // match: (MOVHUreg x:(MOVBUload _ _))
+func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
+       // match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
-       // result: (MOVWreg x)
+       // result: (MOVDload [off1+off2] {sym} ptr mem)
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBUload {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
                        break
                }
-               _ = x.Args[1]
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVHUreg x:(MOVHUload _ _))
+       // match: (MOVDload [off1] {sym} (SUBconst [off2] ptr) mem)
        // cond:
-       // result: (MOVWreg x)
+       // result: (MOVDload [off1-off2] {sym} ptr mem)
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVHUload {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSUBconst {
                        break
                }
-               _ = x.Args[1]
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVDload)
+               v.AuxInt = off1 - off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVHUreg (ANDconst [c] x))
-       // cond:
-       // result: (ANDconst [c&0xffff] x)
+       // match: (MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMANDconst {
+               if v_0.Op != OpARMMOVWaddr {
                        break
                }
-               c := v_0.AuxInt
-               x := v_0.Args[0]
-               v.reset(OpARMANDconst)
-               v.AuxInt = c & 0xffff
-               v.AddArg(x)
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVHUreg x:(MOVBUreg _))
-       // cond:
-       // result: (MOVWreg x)
+       // match: (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _))
+       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+       // result: x
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBUreg {
+               off := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVDstore {
                        break
                }
-               v.reset(OpARMMOVWreg)
+               off2 := v_1.AuxInt
+               sym2 := v_1.Aux
+               _ = v_1.Args[2]
+               ptr2 := v_1.Args[0]
+               x := v_1.Args[1]
+               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
                v.AddArg(x)
                return true
        }
-       // match: (MOVHUreg x:(MOVHUreg _))
+       return false
+}
+func rewriteValueARM_OpARMMOVDstore_0(v *Value) bool {
+       // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
        // cond:
-       // result: (MOVWreg x)
+       // result: (MOVDstore [off1+off2] {sym} ptr val mem)
        for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVHUreg {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
                        break
                }
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVDstore)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVHUreg (MOVWconst [c]))
+       // match: (MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem)
        // cond:
-       // result: (MOVWconst [int64(uint16(c))])
+       // result: (MOVDstore [off1-off2] {sym} ptr val mem)
        for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
+               if v_0.Op != OpARMSUBconst {
                        break
                }
-               c := v_0.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(uint16(c))
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVDstore)
+               v.AuxInt = off1 - off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVDstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       config := b.Func.Config
-       _ = config
-       // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
+func rewriteValueARM_OpARMMOVFload_0(v *Value) bool {
+       // match: (MOVFload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
-       // result: (MOVHload [off1+off2] {sym} ptr mem)
+       // result: (MOVFload [off1+off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
@@ -7367,16 +7627,16 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
                mem := v.Args[1]
-               v.reset(OpARMMOVHload)
+               v.reset(OpARMMOVFload)
                v.AuxInt = off1 + off2
                v.Aux = sym
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // match: (MOVFload [off1] {sym} (SUBconst [off2] ptr) mem)
        // cond:
-       // result: (MOVHload [off1-off2] {sym} ptr mem)
+       // result: (MOVFload [off1-off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
@@ -7388,16 +7648,16 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
                mem := v.Args[1]
-               v.reset(OpARMMOVHload)
+               v.reset(OpARMMOVFload)
                v.AuxInt = off1 - off2
                v.Aux = sym
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
+       // match: (MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
        // cond: canMergeSym(sym1,sym2)
-       // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // result: (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := v.AuxInt
                sym1 := v.Aux
@@ -7413,23 +7673,23 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
                if !(canMergeSym(sym1, sym2)) {
                        break
                }
-               v.reset(OpARMMOVHload)
+               v.reset(OpARMMOVFload)
                v.AuxInt = off1 + off2
                v.Aux = mergeSym(sym1, sym2)
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
+       // match: (MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _))
        // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: (MOVHreg x)
+       // result: x
        for {
                off := v.AuxInt
                sym := v.Aux
                _ = v.Args[1]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVHstore {
+               if v_1.Op != OpARMMOVFstore {
                        break
                }
                off2 := v_1.AuxInt
@@ -7440,21 +7700,196 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
                if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
                        break
                }
-               v.reset(OpARMMOVHreg)
+               v.reset(OpCopy)
+               v.Type = x.Type
                v.AddArg(x)
                return true
        }
-       // match: (MOVHload [0] {sym} (ADD ptr idx) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVHloadidx ptr idx mem)
+       return false
+}
+func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
+       // match: (MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem)
+       // cond:
+       // result: (MOVFstore [off1+off2] {sym} ptr val mem)
        for {
-               if v.AuxInt != 0 {
-                       break
-               }
+               off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADD {
+               if v_0.Op != OpARMADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVFstore)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem)
+       // cond:
+       // result: (MOVFstore [off1-off2] {sym} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSUBconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVFstore)
+               v.AuxInt = off1 - off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVFstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
+       // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
+       // cond:
+       // result: (MOVHUload [off1+off2] {sym} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVHUload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // cond:
+       // result: (MOVHUload [off1-off2] {sym} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSUBconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVHUload)
+               v.AuxInt = off1 - off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVHUload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
+       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+       // result: (MOVHUreg x)
+       for {
+               off := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVHstore {
+                       break
+               }
+               off2 := v_1.AuxInt
+               sym2 := v_1.Aux
+               _ = v_1.Args[2]
+               ptr2 := v_1.Args[0]
+               x := v_1.Args[1]
+               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpARMMOVHUreg)
+               v.AddArg(x)
+               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]
@@ -7464,7 +7899,7 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
                if !(sym == nil && !config.nacl) {
                        break
                }
-               v.reset(OpARMMOVHloadidx)
+               v.reset(OpARMMOVHUloadidx)
                v.AddArg(ptr)
                v.AddArg(idx)
                v.AddArg(mem)
@@ -7472,10 +7907,10 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
-       // match: (MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
+func rewriteValueARM_OpARMMOVHUloadidx_0(v *Value) bool {
+       // match: (MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
        // cond: isSamePtr(ptr, ptr2)
-       // result: (MOVHreg x)
+       // result: (MOVHUreg x)
        for {
                _ = v.Args[2]
                ptr := v.Args[0]
@@ -7493,13 +7928,13 @@ func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
                if !(isSamePtr(ptr, ptr2)) {
                        break
                }
-               v.reset(OpARMMOVHreg)
+               v.reset(OpARMMOVHUreg)
                v.AddArg(x)
                return true
        }
-       // match: (MOVHloadidx ptr (MOVWconst [c]) mem)
+       // match: (MOVHUloadidx ptr (MOVWconst [c]) mem)
        // cond:
-       // result: (MOVHload [c] ptr mem)
+       // result: (MOVHUload [c] ptr mem)
        for {
                _ = v.Args[2]
                ptr := v.Args[0]
@@ -7509,15 +7944,15 @@ func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
                }
                c := v_1.AuxInt
                mem := v.Args[2]
-               v.reset(OpARMMOVHload)
+               v.reset(OpARMMOVHUload)
                v.AuxInt = c
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHloadidx (MOVWconst [c]) ptr mem)
+       // match: (MOVHUloadidx (MOVWconst [c]) ptr mem)
        // cond:
-       // result: (MOVHload [c] ptr mem)
+       // result: (MOVHUload [c] ptr mem)
        for {
                _ = v.Args[2]
                v_0 := v.Args[0]
@@ -7527,7 +7962,7 @@ func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
                c := v_0.AuxInt
                ptr := v.Args[1]
                mem := v.Args[2]
-               v.reset(OpARMMOVHload)
+               v.reset(OpARMMOVHUload)
                v.AuxInt = c
                v.AddArg(ptr)
                v.AddArg(mem)
@@ -7535,21 +7970,8 @@ func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
-       // match: (MOVHreg x:(MOVBload _ _))
-       // cond:
-       // result: (MOVWreg x)
-       for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBload {
-                       break
-               }
-               _ = x.Args[1]
-               v.reset(OpARMMOVWreg)
-               v.AddArg(x)
-               return true
-       }
-       // match: (MOVHreg x:(MOVBUload _ _))
+func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
+       // match: (MOVHUreg x:(MOVBUload _ _))
        // cond:
        // result: (MOVWreg x)
        for {
@@ -7562,12 +7984,12 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (MOVHreg x:(MOVHload _ _))
+       // match: (MOVHUreg x:(MOVHUload _ _))
        // cond:
        // result: (MOVWreg x)
        for {
                x := v.Args[0]
-               if x.Op != OpARMMOVHload {
+               if x.Op != OpARMMOVHUload {
                        break
                }
                _ = x.Args[1]
@@ -7575,9 +7997,9 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (MOVHreg (ANDconst [c] x))
-       // cond: c & 0x8000 == 0
-       // result: (ANDconst [c&0x7fff] x)
+       // match: (MOVHUreg (ANDconst [c] x))
+       // cond:
+       // result: (ANDconst [c&0xffff] x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMANDconst {
@@ -7585,27 +8007,12 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
                }
                c := v_0.AuxInt
                x := v_0.Args[0]
-               if !(c&0x8000 == 0) {
-                       break
-               }
                v.reset(OpARMANDconst)
-               v.AuxInt = c & 0x7fff
-               v.AddArg(x)
-               return true
-       }
-       // match: (MOVHreg x:(MOVBreg _))
-       // cond:
-       // result: (MOVWreg x)
-       for {
-               x := v.Args[0]
-               if x.Op != OpARMMOVBreg {
-                       break
-               }
-               v.reset(OpARMMOVWreg)
+               v.AuxInt = c & 0xffff
                v.AddArg(x)
                return true
        }
-       // match: (MOVHreg x:(MOVBUreg _))
+       // match: (MOVHUreg x:(MOVBUreg _))
        // cond:
        // result: (MOVWreg x)
        for {
@@ -7617,21 +8024,21 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (MOVHreg x:(MOVHreg _))
+       // match: (MOVHUreg x:(MOVHUreg _))
        // cond:
        // result: (MOVWreg x)
        for {
                x := v.Args[0]
-               if x.Op != OpARMMOVHreg {
+               if x.Op != OpARMMOVHUreg {
                        break
                }
                v.reset(OpARMMOVWreg)
                v.AddArg(x)
                return true
        }
-       // match: (MOVHreg (MOVWconst [c]))
+       // match: (MOVHUreg (MOVWconst [c]))
        // cond:
-       // result: (MOVWconst [int64(int16(c))])
+       // result: (MOVWconst [int64(uint16(c))])
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWconst {
@@ -7639,69 +8046,65 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
                }
                c := v_0.AuxInt
                v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(int16(c))
+               v.AuxInt = int64(uint16(c))
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
+func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
        b := v.Block
        _ = b
        config := b.Func.Config
        _ = config
-       // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
+       // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
-       // result: (MOVHstore [off1+off2] {sym} ptr val mem)
+       // result: (MOVHload [off1+off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMADDconst {
                        break
                }
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVHstore)
+               mem := v.Args[1]
+               v.reset(OpARMMOVHload)
                v.AuxInt = off1 + off2
                v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem)
+       // match: (MOVHload [off1] {sym} (SUBconst [off2] ptr) mem)
        // cond:
-       // result: (MOVHstore [off1-off2] {sym} ptr val mem)
+       // result: (MOVHload [off1-off2] {sym} ptr mem)
        for {
                off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMSUBconst {
                        break
                }
                off2 := v_0.AuxInt
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVHstore)
+               mem := v.Args[1]
+               v.reset(OpARMMOVHload)
                v.AuxInt = off1 - off2
                v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
+       // match: (MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
        // cond: canMergeSym(sym1,sym2)
-       // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := v.AuxInt
                sym1 := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWaddr {
                        break
@@ -7709,72 +8112,50 @@ func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
                off2 := v_0.AuxInt
                sym2 := v_0.Aux
                ptr := v_0.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
+               mem := v.Args[1]
                if !(canMergeSym(sym1, sym2)) {
                        break
                }
-               v.reset(OpARMMOVHstore)
+               v.reset(OpARMMOVHload)
                v.AuxInt = off1 + off2
                v.Aux = mergeSym(sym1, sym2)
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem)
-       // cond:
-       // result: (MOVHstore [off] {sym} ptr x mem)
+       // match: (MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
+       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+       // result: (MOVHreg x)
        for {
                off := v.AuxInt
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVHreg {
+               if v_1.Op != OpARMMOVHstore {
                        break
                }
-               x := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVHstore)
-               v.AuxInt = off
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem)
-       // cond:
-       // result: (MOVHstore [off] {sym} ptr x mem)
-       for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVHUreg {
+               off2 := v_1.AuxInt
+               sym2 := v_1.Aux
+               _ = v_1.Args[2]
+               ptr2 := v_1.Args[0]
+               x := v_1.Args[1]
+               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
                        break
                }
-               x := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVHstore)
-               v.AuxInt = off
-               v.Aux = sym
-               v.AddArg(ptr)
+               v.reset(OpARMMOVHreg)
                v.AddArg(x)
-               v.AddArg(mem)
                return true
        }
-       // match: (MOVHstore [0] {sym} (ADD ptr idx) val mem)
+       // match: (MOVHload [0] {sym} (ADD ptr idx) mem)
        // cond: sym == nil && !config.nacl
-       // result: (MOVHstoreidx ptr idx val mem)
+       // result: (MOVHloadidx ptr idx mem)
        for {
                if v.AuxInt != 0 {
                        break
                }
                sym := v.Aux
-               _ = v.Args[2]
+               _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMADD {
                        break
@@ -7782,526 +8163,613 @@ func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
                _ = v_0.Args[1]
                ptr := v_0.Args[0]
                idx := v_0.Args[1]
-               val := v.Args[1]
-               mem := v.Args[2]
+               mem := v.Args[1]
                if !(sym == nil && !config.nacl) {
                        break
                }
-               v.reset(OpARMMOVHstoreidx)
+               v.reset(OpARMMOVHloadidx)
                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)
+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: (MOVHstore [c] ptr val mem)
+       // result: (MOVHload [c] ptr mem)
        for {
-               _ = v.Args[3]
+               _ = v.Args[2]
                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)
+               mem := v.Args[2]
+               v.reset(OpARMMOVHload)
                v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVHstoreidx (MOVWconst [c]) ptr val mem)
+       // match: (MOVHloadidx (MOVWconst [c]) ptr mem)
        // cond:
-       // result: (MOVHstore [c] ptr val mem)
+       // result: (MOVHload [c] ptr mem)
        for {
-               _ = v.Args[3]
+               _ = v.Args[2]
                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)
+               mem := v.Args[2]
+               v.reset(OpARMMOVHload)
                v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVWload_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       config := b.Func.Config
-       _ = config
-       // match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
+func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
+       // match: (MOVHreg x:(MOVBload _ _))
        // cond:
-       // result: (MOVWload [off1+off2] {sym} ptr mem)
+       // result: (MOVWreg x)
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMADDconst {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBload {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVWload)
-               v.AuxInt = off1 + off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               _ = x.Args[1]
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
                return true
        }
-       // match: (MOVWload [off1] {sym} (SUBconst [off2] ptr) mem)
+       // match: (MOVHreg x:(MOVBUload _ _))
        // cond:
-       // result: (MOVWload [off1-off2] {sym} ptr mem)
+       // result: (MOVWreg x)
        for {
-               off1 := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMSUBconst {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBUload {
                        break
                }
-               off2 := v_0.AuxInt
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVWload)
-               v.AuxInt = off1 - off2
-               v.Aux = sym
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               _ = x.Args[1]
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
                return true
        }
-       // match: (MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2)
-       // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       // match: (MOVHreg x:(MOVHload _ _))
+       // cond:
+       // result: (MOVWreg x)
        for {
-               off1 := v.AuxInt
-               sym1 := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWaddr {
-                       break
-               }
-               off2 := v_0.AuxInt
-               sym2 := v_0.Aux
-               ptr := v_0.Args[0]
-               mem := v.Args[1]
-               if !(canMergeSym(sym1, sym2)) {
+               x := v.Args[0]
+               if x.Op != OpARMMOVHload {
                        break
                }
-               v.reset(OpARMMOVWload)
-               v.AuxInt = off1 + off2
-               v.Aux = mergeSym(sym1, sym2)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               _ = x.Args[1]
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
                return true
        }
-       // match: (MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _))
-       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
-       // result: x
+       // match: (MOVHreg (ANDconst [c] x))
+       // cond: c & 0x8000 == 0
+       // result: (ANDconst [c&0x7fff] x)
        for {
-               off := v.AuxInt
-               sym := v.Aux
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWstore {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMANDconst {
                        break
                }
-               off2 := v_1.AuxInt
-               sym2 := v_1.Aux
-               _ = v_1.Args[2]
-               ptr2 := v_1.Args[0]
-               x := v_1.Args[1]
-               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+               c := v_0.AuxInt
+               x := v_0.Args[0]
+               if !(c&0x8000 == 0) {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               v.reset(OpARMANDconst)
+               v.AuxInt = c & 0x7fff
                v.AddArg(x)
                return true
        }
-       // match: (MOVWload [0] {sym} (ADD ptr idx) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVWloadidx ptr idx mem)
+       // match: (MOVHreg x:(MOVBreg _))
+       // cond:
+       // result: (MOVWreg x)
        for {
-               if v.AuxInt != 0 {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBreg {
                        break
                }
-               sym := v.Aux
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMADD {
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVHreg x:(MOVBUreg _))
+       // cond:
+       // result: (MOVWreg x)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARMMOVBUreg {
                        break
                }
-               _ = v_0.Args[1]
-               ptr := v_0.Args[0]
-               idx := v_0.Args[1]
-               mem := v.Args[1]
-               if !(sym == nil && !config.nacl) {
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVHreg x:(MOVHreg _))
+       // cond:
+       // result: (MOVWreg x)
+       for {
+               x := v.Args[0]
+               if x.Op != OpARMMOVHreg {
                        break
                }
-               v.reset(OpARMMOVWloadidx)
-               v.AddArg(ptr)
-               v.AddArg(idx)
-               v.AddArg(mem)
+               v.reset(OpARMMOVWreg)
+               v.AddArg(x)
                return true
        }
-       // match: (MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVWloadshiftLL ptr idx [c] mem)
+       // match: (MOVHreg (MOVWconst [c]))
+       // cond:
+       // result: (MOVWconst [int64(int16(c))])
        for {
-               if v.AuxInt != 0 {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
+               c := v_0.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(int16(c))
+               return true
+       }
+       return false
+}
+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)
+       // cond:
+       // result: (MOVHstore [off1+off2] {sym} ptr val mem)
+       for {
+               off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADDshiftLL {
+               if v_0.Op != OpARMADDconst {
                        break
                }
-               c := v_0.AuxInt
-               _ = v_0.Args[1]
+               off2 := v_0.AuxInt
                ptr := v_0.Args[0]
-               idx := v_0.Args[1]
-               mem := v.Args[1]
-               if !(sym == nil && !config.nacl) {
-                       break
-               }
-               v.reset(OpARMMOVWloadshiftLL)
-               v.AuxInt = c
+               val := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(idx)
+               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVWloadshiftRL ptr idx [c] mem)
+       // match: (MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem)
+       // cond:
+       // result: (MOVHstore [off1-off2] {sym} ptr val mem)
        for {
-               if v.AuxInt != 0 {
-                       break
-               }
+               off1 := v.AuxInt
                sym := v.Aux
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADDshiftRL {
+               if v_0.Op != OpARMSUBconst {
                        break
                }
-               c := v_0.AuxInt
-               _ = v_0.Args[1]
+               off2 := v_0.AuxInt
                ptr := v_0.Args[0]
-               idx := v_0.Args[1]
-               mem := v.Args[1]
-               if !(sym == nil && !config.nacl) {
-                       break
-               }
-               v.reset(OpARMMOVWloadshiftRL)
-               v.AuxInt = c
+               val := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = off1 - off2
+               v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(idx)
+               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem)
-       // cond: sym == nil && !config.nacl
-       // result: (MOVWloadshiftRA ptr idx [c] mem)
+       // match: (MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
-               if v.AuxInt != 0 {
-                       break
-               }
-               sym := v.Aux
-               _ = v.Args[1]
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMADDshiftRA {
+               if v_0.Op != OpARMMOVWaddr {
                        break
                }
-               c := v_0.AuxInt
-               _ = v_0.Args[1]
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
                ptr := v_0.Args[0]
-               idx := v_0.Args[1]
-               mem := v.Args[1]
-               if !(sym == nil && !config.nacl) {
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
                        break
                }
-               v.reset(OpARMMOVWloadshiftRA)
-               v.AuxInt = c
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
                v.AddArg(ptr)
-               v.AddArg(idx)
+               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMMOVWloadidx_0(v *Value) bool {
-       // match: (MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _))
-       // cond: isSamePtr(ptr, ptr2)
-       // result: x
+       // match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem)
+       // cond:
+       // result: (MOVHstore [off] {sym} ptr x mem)
        for {
+               off := v.AuxInt
+               sym := v.Aux
                _ = v.Args[2]
                ptr := v.Args[0]
-               idx := v.Args[1]
-               v_2 := v.Args[2]
-               if v_2.Op != OpARMMOVWstoreidx {
-                       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)) {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVHreg {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               x := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = off
+               v.Aux = sym
+               v.AddArg(ptr)
                v.AddArg(x)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx ptr (MOVWconst [c]) mem)
+       // match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem)
        // cond:
-       // result: (MOVWload [c] ptr mem)
+       // result: (MOVHstore [off] {sym} ptr x mem)
        for {
+               off := v.AuxInt
+               sym := v.Aux
                _ = v.Args[2]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v_1.Op != OpARMMOVHUreg {
                        break
                }
-               c := v_1.AuxInt
+               x := v_1.Args[0]
                mem := v.Args[2]
-               v.reset(OpARMMOVWload)
-               v.AuxInt = c
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = off
+               v.Aux = sym
                v.AddArg(ptr)
+               v.AddArg(x)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx (MOVWconst [c]) ptr mem)
-       // cond:
-       // result: (MOVWload [c] ptr mem)
+       // 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 != OpARMMOVWconst {
+               if v_0.Op != OpARMADD {
                        break
                }
-               c := v_0.AuxInt
-               ptr := v.Args[1]
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               val := v.Args[1]
                mem := v.Args[2]
-               v.reset(OpARMMOVWload)
-               v.AuxInt = c
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVHstoreidx)
                v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx ptr (SLLconst idx [c]) mem)
+       return false
+}
+func rewriteValueARM_OpARMMOVHstoreidx_0(v *Value) bool {
+       // match: (MOVHstoreidx ptr (MOVWconst [c]) val mem)
        // cond:
-       // result: (MOVWloadshiftLL ptr idx [c] mem)
+       // result: (MOVHstore [c] ptr val mem)
        for {
-               _ = v.Args[2]
+               _ = v.Args[3]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMSLLconst {
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
                c := v_1.AuxInt
-               idx := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVWloadshiftLL)
+               val := v.Args[2]
+               mem := v.Args[3]
+               v.reset(OpARMMOVHstore)
                v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(idx)
+               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx (SLLconst idx [c]) ptr mem)
+       // match: (MOVHstoreidx (MOVWconst [c]) ptr val mem)
        // cond:
-       // result: (MOVWloadshiftLL ptr idx [c] mem)
+       // result: (MOVHstore [c] ptr val mem)
        for {
-               _ = v.Args[2]
+               _ = v.Args[3]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSLLconst {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
                c := v_0.AuxInt
-               idx := v_0.Args[0]
                ptr := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVWloadshiftLL)
+               val := v.Args[2]
+               mem := v.Args[3]
+               v.reset(OpARMMOVHstore)
                v.AuxInt = c
                v.AddArg(ptr)
-               v.AddArg(idx)
+               v.AddArg(val)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx ptr (SRLconst idx [c]) mem)
+       return false
+}
+func rewriteValueARM_OpARMMOVWload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
+       // match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
-       // result: (MOVWloadshiftRL ptr idx [c] mem)
+       // result: (MOVWload [off1+off2] {sym} ptr mem)
        for {
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSRLconst {
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
                        break
                }
-               c := v_1.AuxInt
-               idx := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVWloadshiftRL)
-               v.AuxInt = c
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVWload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(idx)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx (SRLconst idx [c]) ptr mem)
+       // match: (MOVWload [off1] {sym} (SUBconst [off2] ptr) mem)
        // cond:
-       // result: (MOVWloadshiftRL ptr idx [c] mem)
+       // result: (MOVWload [off1-off2] {sym} ptr mem)
        for {
-               _ = v.Args[2]
+               off1 := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSRLconst {
+               if v_0.Op != OpARMSUBconst {
                        break
                }
-               c := v_0.AuxInt
-               idx := v_0.Args[0]
-               ptr := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVWloadshiftRL)
-               v.AuxInt = c
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVWload)
+               v.AuxInt = off1 - off2
+               v.Aux = sym
                v.AddArg(ptr)
-               v.AddArg(idx)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx ptr (SRAconst idx [c]) mem)
-       // cond:
-       // result: (MOVWloadshiftRA ptr idx [c] mem)
+       // match: (MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
-               _ = v.Args[2]
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVWload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _))
+       // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+       // result: x
+       for {
+               off := v.AuxInt
+               sym := v.Aux
+               _ = v.Args[1]
                ptr := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMSRAconst {
+               if v_1.Op != OpARMMOVWstore {
                        break
                }
-               c := v_1.AuxInt
-               idx := v_1.Args[0]
-               mem := v.Args[2]
-               v.reset(OpARMMOVWloadshiftRA)
-               v.AuxInt = c
+               off2 := v_1.AuxInt
+               sym2 := v_1.Aux
+               _ = v_1.Args[2]
+               ptr2 := v_1.Args[0]
+               x := v_1.Args[1]
+               if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVWload [0] {sym} (ADD ptr idx) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVWloadidx 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(OpARMMOVWloadidx)
                v.AddArg(ptr)
                v.AddArg(idx)
                v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadidx (SRAconst idx [c]) ptr mem)
-       // cond:
-       // result: (MOVWloadshiftRA ptr idx [c] mem)
+       // match: (MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVWloadshiftLL ptr idx [c] mem)
        for {
-               _ = v.Args[2]
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[1]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSRAconst {
+               if v_0.Op != OpARMADDshiftLL {
                        break
                }
                c := v_0.AuxInt
-               idx := v_0.Args[0]
-               ptr := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVWloadshiftRA)
+               _ = 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(OpARMMOVWloadshiftLL)
                v.AuxInt = c
                v.AddArg(ptr)
                v.AddArg(idx)
                v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMMOVWloadshiftLL_0(v *Value) bool {
-       // match: (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _))
-       // cond: c==d && isSamePtr(ptr, ptr2)
-       // result: x
+       // match: (MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVWloadshiftRL ptr idx [c] mem)
        for {
-               c := v.AuxInt
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               idx := v.Args[1]
-               v_2 := v.Args[2]
-               if v_2.Op != OpARMMOVWstoreshiftLL {
+               if v.AuxInt != 0 {
                        break
                }
-               d := v_2.AuxInt
-               _ = v_2.Args[3]
-               ptr2 := v_2.Args[0]
-               if idx != v_2.Args[1] {
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDshiftRL {
                        break
                }
-               x := v_2.Args[2]
-               if !(c == d && isSamePtr(ptr, ptr2)) {
+               c := v_0.AuxInt
+               _ = 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(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               v.reset(OpARMMOVWloadshiftRL)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
                return true
        }
-       // match: (MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem)
-       // cond:
-       // result: (MOVWload [int64(uint32(c)<<uint64(d))] ptr mem)
+       // match: (MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVWloadshiftRA ptr idx [c] mem)
        for {
-               d := v.AuxInt
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v.AuxInt != 0 {
                        break
                }
-               c := v_1.AuxInt
-               mem := v.Args[2]
-               v.reset(OpARMMOVWload)
-               v.AuxInt = int64(uint32(c) << uint64(d))
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDshiftRA {
+                       break
+               }
+               c := v_0.AuxInt
+               _ = 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(OpARMMOVWloadshiftRA)
+               v.AuxInt = c
                v.AddArg(ptr)
+               v.AddArg(idx)
                v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMMOVWloadshiftRA_0(v *Value) bool {
-       // match: (MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _))
-       // cond: c==d && isSamePtr(ptr, ptr2)
+func rewriteValueARM_OpARMMOVWloadidx_0(v *Value) bool {
+       // match: (MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _))
+       // cond: isSamePtr(ptr, ptr2)
        // result: x
        for {
-               c := v.AuxInt
                _ = v.Args[2]
                ptr := v.Args[0]
                idx := v.Args[1]
                v_2 := v.Args[2]
-               if v_2.Op != OpARMMOVWstoreshiftRA {
+               if v_2.Op != OpARMMOVWstoreidx {
                        break
                }
-               d := v_2.AuxInt
                _ = v_2.Args[3]
                ptr2 := v_2.Args[0]
                if idx != v_2.Args[1] {
                        break
                }
                x := v_2.Args[2]
-               if !(c == d && isSamePtr(ptr, ptr2)) {
+               if !(isSamePtr(ptr, ptr2)) {
                        break
                }
                v.reset(OpCopy)
@@ -8309,11 +8777,10 @@ func rewriteValueARM_OpARMMOVWloadshiftRA_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem)
+       // match: (MOVWloadidx ptr (MOVWconst [c]) mem)
        // cond:
-       // result: (MOVWload [int64(int32(c)>>uint64(d))] ptr mem)
+       // result: (MOVWload [c] ptr mem)
        for {
-               d := v.AuxInt
                _ = v.Args[2]
                ptr := v.Args[0]
                v_1 := v.Args[1]
@@ -8323,19 +8790,255 @@ func rewriteValueARM_OpARMMOVWloadshiftRA_0(v *Value) bool {
                c := v_1.AuxInt
                mem := v.Args[2]
                v.reset(OpARMMOVWload)
-               v.AuxInt = int64(int32(c) >> uint64(d))
+               v.AuxInt = c
                v.AddArg(ptr)
                v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMMOVWloadshiftRL_0(v *Value) bool {
-       // match: (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _))
-       // cond: c==d && isSamePtr(ptr, ptr2)
-       // result: x
-       for {
-               c := v.AuxInt
+       // match: (MOVWloadidx (MOVWconst [c]) ptr mem)
+       // cond:
+       // result: (MOVWload [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(OpARMMOVWload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWloadidx ptr (SLLconst idx [c]) mem)
+       // cond:
+       // result: (MOVWloadshiftLL ptr idx [c] mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSLLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               idx := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVWloadshiftLL)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWloadidx (SLLconst idx [c]) ptr mem)
+       // cond:
+       // result: (MOVWloadshiftLL ptr idx [c] mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLLconst {
+                       break
+               }
+               c := v_0.AuxInt
+               idx := v_0.Args[0]
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVWloadshiftLL)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWloadidx ptr (SRLconst idx [c]) mem)
+       // cond:
+       // result: (MOVWloadshiftRL ptr idx [c] mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               idx := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVWloadshiftRL)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWloadidx (SRLconst idx [c]) ptr mem)
+       // cond:
+       // result: (MOVWloadshiftRL ptr idx [c] mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_0.AuxInt
+               idx := v_0.Args[0]
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVWloadshiftRL)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWloadidx ptr (SRAconst idx [c]) mem)
+       // cond:
+       // result: (MOVWloadshiftRA ptr idx [c] mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRAconst {
+                       break
+               }
+               c := v_1.AuxInt
+               idx := v_1.Args[0]
+               mem := v.Args[2]
+               v.reset(OpARMMOVWloadshiftRA)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWloadidx (SRAconst idx [c]) ptr mem)
+       // cond:
+       // result: (MOVWloadshiftRA ptr idx [c] mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRAconst {
+                       break
+               }
+               c := v_0.AuxInt
+               idx := v_0.Args[0]
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVWloadshiftRA)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVWloadshiftLL_0(v *Value) bool {
+       // match: (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _))
+       // cond: c==d && isSamePtr(ptr, ptr2)
+       // result: x
+       for {
+               c := v.AuxInt
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               idx := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWstoreshiftLL {
+                       break
+               }
+               d := v_2.AuxInt
+               _ = v_2.Args[3]
+               ptr2 := v_2.Args[0]
+               if idx != v_2.Args[1] {
+                       break
+               }
+               x := v_2.Args[2]
+               if !(c == d && isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem)
+       // cond:
+       // result: (MOVWload [int64(uint32(c)<<uint64(d))] ptr mem)
+       for {
+               d := v.AuxInt
+               _ = 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(OpARMMOVWload)
+               v.AuxInt = int64(uint32(c) << uint64(d))
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVWloadshiftRA_0(v *Value) bool {
+       // match: (MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _))
+       // cond: c==d && isSamePtr(ptr, ptr2)
+       // result: x
+       for {
+               c := v.AuxInt
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               idx := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWstoreshiftRA {
+                       break
+               }
+               d := v_2.AuxInt
+               _ = v_2.Args[3]
+               ptr2 := v_2.Args[0]
+               if idx != v_2.Args[1] {
+                       break
+               }
+               x := v_2.Args[2]
+               if !(c == d && isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem)
+       // cond:
+       // result: (MOVWload [int64(int32(c)>>uint64(d))] ptr mem)
+       for {
+               d := v.AuxInt
+               _ = 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(OpARMMOVWload)
+               v.AuxInt = int64(int32(c) >> uint64(d))
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVWloadshiftRL_0(v *Value) bool {
+       // match: (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _))
+       // cond: c==d && isSamePtr(ptr, ptr2)
+       // result: x
+       for {
+               c := v.AuxInt
                _ = v.Args[2]
                ptr := v.Args[0]
                idx := v.Args[1]
@@ -14919,10 +15622,10 @@ func rewriteValueARM_OpARMSUBshiftRLreg_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMXOR_0(v *Value) bool {
-       // match: (XOR x (MOVWconst [c]))
+func rewriteValueARM_OpARMTEQ_0(v *Value) bool {
+       // match: (TEQ x (MOVWconst [c]))
        // cond:
-       // result: (XORconst [c] x)
+       // result: (TEQconst [c] x)
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -14931,14 +15634,14 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v.AddArg(x)
                return true
        }
-       // match: (XOR (MOVWconst [c]) x)
+       // match: (TEQ (MOVWconst [c]) x)
        // cond:
-       // result: (XORconst [c] x)
+       // result: (TEQconst [c] x)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -14947,14 +15650,14 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                }
                c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v.AddArg(x)
                return true
        }
-       // match: (XOR x (SLLconst [c] y))
+       // match: (TEQ x (SLLconst [c] y))
        // cond:
-       // result: (XORshiftLL x y [c])
+       // result: (TEQshiftLL x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -14964,15 +15667,15 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                }
                c := v_1.AuxInt
                y := v_1.Args[0]
-               v.reset(OpARMXORshiftLL)
+               v.reset(OpARMTEQshiftLL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (XOR (SLLconst [c] y) x)
+       // match: (TEQ (SLLconst [c] y) x)
        // cond:
-       // result: (XORshiftLL x y [c])
+       // result: (TEQshiftLL x y [c])
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -14982,15 +15685,15 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                c := v_0.AuxInt
                y := v_0.Args[0]
                x := v.Args[1]
-               v.reset(OpARMXORshiftLL)
+               v.reset(OpARMTEQshiftLL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (XOR x (SRLconst [c] y))
+       // match: (TEQ x (SRLconst [c] y))
        // cond:
-       // result: (XORshiftRL x y [c])
+       // result: (TEQshiftRL x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -15000,15 +15703,15 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                }
                c := v_1.AuxInt
                y := v_1.Args[0]
-               v.reset(OpARMXORshiftRL)
+               v.reset(OpARMTEQshiftRL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (XOR (SRLconst [c] y) x)
+       // match: (TEQ (SRLconst [c] y) x)
        // cond:
-       // result: (XORshiftRL x y [c])
+       // result: (TEQshiftRL x y [c])
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -15018,15 +15721,15 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                c := v_0.AuxInt
                y := v_0.Args[0]
                x := v.Args[1]
-               v.reset(OpARMXORshiftRL)
+               v.reset(OpARMTEQshiftRL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (XOR x (SRAconst [c] y))
+       // match: (TEQ x (SRAconst [c] y))
        // cond:
-       // result: (XORshiftRA x y [c])
+       // result: (TEQshiftRA x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -15036,15 +15739,15 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                }
                c := v_1.AuxInt
                y := v_1.Args[0]
-               v.reset(OpARMXORshiftRA)
+               v.reset(OpARMTEQshiftRA)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (XOR (SRAconst [c] y) x)
+       // match: (TEQ (SRAconst [c] y) x)
        // cond:
-       // result: (XORshiftRA x y [c])
+       // result: (TEQshiftRA x y [c])
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -15054,54 +15757,15 @@ func rewriteValueARM_OpARMXOR_0(v *Value) bool {
                c := v_0.AuxInt
                y := v_0.Args[0]
                x := v.Args[1]
-               v.reset(OpARMXORshiftRA)
-               v.AuxInt = c
-               v.AddArg(x)
-               v.AddArg(y)
-               return true
-       }
-       // match: (XOR x (SRRconst [c] y))
-       // cond:
-       // result: (XORshiftRR x y [c])
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSRRconst {
-                       break
-               }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
-               v.reset(OpARMXORshiftRR)
-               v.AuxInt = c
-               v.AddArg(x)
-               v.AddArg(y)
-               return true
-       }
-       // match: (XOR (SRRconst [c] y) x)
-       // cond:
-       // result: (XORshiftRR x y [c])
-       for {
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMSRRconst {
-                       break
-               }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
-               v.reset(OpARMXORshiftRR)
+               v.reset(OpARMTEQshiftRA)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpARMXOR_10(v *Value) bool {
-       // match: (XOR x (SLL y z))
+       // match: (TEQ x (SLL y z))
        // cond:
-       // result: (XORshiftLLreg x y z)
+       // result: (TEQshiftLLreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -15112,15 +15776,15 @@ func rewriteValueARM_OpARMXOR_10(v *Value) bool {
                _ = v_1.Args[1]
                y := v_1.Args[0]
                z := v_1.Args[1]
-               v.reset(OpARMXORshiftLLreg)
+               v.reset(OpARMTEQshiftLLreg)
                v.AddArg(x)
                v.AddArg(y)
                v.AddArg(z)
                return true
        }
-       // match: (XOR (SLL y z) x)
+       // match: (TEQ (SLL y z) x)
        // cond:
-       // result: (XORshiftLLreg x y z)
+       // result: (TEQshiftLLreg x y z)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -15131,15 +15795,18 @@ func rewriteValueARM_OpARMXOR_10(v *Value) bool {
                y := v_0.Args[0]
                z := v_0.Args[1]
                x := v.Args[1]
-               v.reset(OpARMXORshiftLLreg)
+               v.reset(OpARMTEQshiftLLreg)
                v.AddArg(x)
                v.AddArg(y)
                v.AddArg(z)
                return true
        }
-       // match: (XOR x (SRL y z))
+       return false
+}
+func rewriteValueARM_OpARMTEQ_10(v *Value) bool {
+       // match: (TEQ x (SRL y z))
        // cond:
-       // result: (XORshiftRLreg x y z)
+       // result: (TEQshiftRLreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -15150,15 +15817,15 @@ func rewriteValueARM_OpARMXOR_10(v *Value) bool {
                _ = v_1.Args[1]
                y := v_1.Args[0]
                z := v_1.Args[1]
-               v.reset(OpARMXORshiftRLreg)
+               v.reset(OpARMTEQshiftRLreg)
                v.AddArg(x)
                v.AddArg(y)
                v.AddArg(z)
                return true
        }
-       // match: (XOR (SRL y z) x)
+       // match: (TEQ (SRL y z) x)
        // cond:
-       // result: (XORshiftRLreg x y z)
+       // result: (TEQshiftRLreg x y z)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -15169,15 +15836,15 @@ func rewriteValueARM_OpARMXOR_10(v *Value) bool {
                y := v_0.Args[0]
                z := v_0.Args[1]
                x := v.Args[1]
-               v.reset(OpARMXORshiftRLreg)
+               v.reset(OpARMTEQshiftRLreg)
                v.AddArg(x)
                v.AddArg(y)
                v.AddArg(z)
                return true
        }
-       // match: (XOR x (SRA y z))
+       // match: (TEQ x (SRA y z))
        // cond:
-       // result: (XORshiftRAreg x y z)
+       // result: (TEQshiftRAreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -15188,15 +15855,15 @@ func rewriteValueARM_OpARMXOR_10(v *Value) bool {
                _ = v_1.Args[1]
                y := v_1.Args[0]
                z := v_1.Args[1]
-               v.reset(OpARMXORshiftRAreg)
+               v.reset(OpARMTEQshiftRAreg)
                v.AddArg(x)
                v.AddArg(y)
                v.AddArg(z)
                return true
        }
-       // match: (XOR (SRA y z) x)
+       // match: (TEQ (SRA y z) x)
        // cond:
-       // result: (XORshiftRAreg x y z)
+       // result: (TEQshiftRAreg x y z)
        for {
                _ = v.Args[1]
                v_0 := v.Args[0]
@@ -15207,79 +15874,71 @@ func rewriteValueARM_OpARMXOR_10(v *Value) bool {
                y := v_0.Args[0]
                z := v_0.Args[1]
                x := v.Args[1]
-               v.reset(OpARMXORshiftRAreg)
+               v.reset(OpARMTEQshiftRAreg)
                v.AddArg(x)
                v.AddArg(y)
                v.AddArg(z)
                return true
        }
-       // match: (XOR x x)
-       // cond:
-       // result: (MOVWconst [0])
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               if x != v.Args[1] {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
        return false
 }
-func rewriteValueARM_OpARMXORconst_0(v *Value) bool {
-       // match: (XORconst [0] x)
-       // cond:
-       // result: x
+func rewriteValueARM_OpARMTEQconst_0(v *Value) bool {
+       // match: (TEQconst (MOVWconst [x]) [y])
+       // cond: int32(x^y)==0
+       // result: (FlagEQ)
        for {
-               if v.AuxInt != 0 {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               x := v.Args[0]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               x := v_0.AuxInt
+               if !(int32(x^y) == 0) {
+                       break
+               }
+               v.reset(OpARMFlagEQ)
                return true
        }
-       // match: (XORconst [c] (MOVWconst [d]))
-       // cond:
-       // result: (MOVWconst [c^d])
+       // match: (TEQconst (MOVWconst [x]) [y])
+       // cond: int32(x^y)<0
+       // result: (FlagLT_UGT)
        for {
-               c := v.AuxInt
+               y := v.AuxInt
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWconst {
                        break
                }
-               d := v_0.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = c ^ d
+               x := v_0.AuxInt
+               if !(int32(x^y) < 0) {
+                       break
+               }
+               v.reset(OpARMFlagLT_UGT)
                return true
        }
-       // match: (XORconst [c] (XORconst [d] x))
-       // cond:
-       // result: (XORconst [c^d] x)
+       // match: (TEQconst (MOVWconst [x]) [y])
+       // cond: int32(x^y)>0
+       // result: (FlagGT_UGT)
        for {
-               c := v.AuxInt
+               y := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpARMXORconst {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               d := v_0.AuxInt
-               x := v_0.Args[0]
-               v.reset(OpARMXORconst)
-               v.AuxInt = c ^ d
-               v.AddArg(x)
+               x := v_0.AuxInt
+               if !(int32(x^y) > 0) {
+                       break
+               }
+               v.reset(OpARMFlagGT_UGT)
                return true
        }
        return false
 }
-func rewriteValueARM_OpARMXORshiftLL_0(v *Value) bool {
+func rewriteValueARM_OpARMTEQshiftLL_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (XORshiftLL (MOVWconst [c]) x [d])
+       // match: (TEQshiftLL (MOVWconst [c]) x [d])
        // cond:
-       // result: (XORconst [c] (SLLconst <x.Type> x [d]))
+       // result: (TEQconst [c] (SLLconst <x.Type> x [d]))
        for {
                d := v.AuxInt
                _ = v.Args[1]
@@ -15289,7 +15948,7 @@ func rewriteValueARM_OpARMXORshiftLL_0(v *Value) bool {
                }
                c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
                v0.AuxInt = d
@@ -15297,9 +15956,9 @@ func rewriteValueARM_OpARMXORshiftLL_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (XORshiftLL x (MOVWconst [c]) [d])
+       // match: (TEQshiftLL x (MOVWconst [c]) [d])
        // cond:
-       // result: (XORconst x [int64(uint32(c)<<uint64(d))])
+       // result: (TEQconst x [int64(uint32(c)<<uint64(d))])
        for {
                d := v.AuxInt
                _ = v.Args[1]
@@ -15309,63 +15968,19 @@ func rewriteValueARM_OpARMXORshiftLL_0(v *Value) bool {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = int64(uint32(c) << uint64(d))
                v.AddArg(x)
                return true
        }
-       // match: (XORshiftLL [c] (SRLconst x [32-c]) x)
-       // cond:
-       // result: (SRRconst [32-c] x)
-       for {
-               c := v.AuxInt
-               _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMSRLconst {
-                       break
-               }
-               if v_0.AuxInt != 32-c {
-                       break
-               }
-               x := v_0.Args[0]
-               if x != v.Args[1] {
-                       break
-               }
-               v.reset(OpARMSRRconst)
-               v.AuxInt = 32 - c
-               v.AddArg(x)
-               return true
-       }
-       // match: (XORshiftLL x (SLLconst x [c]) [d])
-       // cond: c==d
-       // result: (MOVWconst [0])
-       for {
-               d := v.AuxInt
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSLLconst {
-                       break
-               }
-               c := v_1.AuxInt
-               if x != v_1.Args[0] {
-                       break
-               }
-               if !(c == d) {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
        return false
 }
-func rewriteValueARM_OpARMXORshiftLLreg_0(v *Value) bool {
+func rewriteValueARM_OpARMTEQshiftLLreg_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (XORshiftLLreg (MOVWconst [c]) x y)
+       // match: (TEQshiftLLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (XORconst [c] (SLL <x.Type> x y))
+       // result: (TEQconst [c] (SLL <x.Type> x y))
        for {
                _ = v.Args[2]
                v_0 := v.Args[0]
@@ -15375,7 +15990,7 @@ func rewriteValueARM_OpARMXORshiftLLreg_0(v *Value) bool {
                c := v_0.AuxInt
                x := v.Args[1]
                y := v.Args[2]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
@@ -15383,9 +15998,9 @@ func rewriteValueARM_OpARMXORshiftLLreg_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (XORshiftLLreg x y (MOVWconst [c]))
+       // match: (TEQshiftLLreg x y (MOVWconst [c]))
        // cond:
-       // result: (XORshiftLL x y [c])
+       // result: (TEQshiftLL x y [c])
        for {
                _ = v.Args[2]
                x := v.Args[0]
@@ -15395,7 +16010,7 @@ func rewriteValueARM_OpARMXORshiftLLreg_0(v *Value) bool {
                        break
                }
                c := v_2.AuxInt
-               v.reset(OpARMXORshiftLL)
+               v.reset(OpARMTEQshiftLL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
@@ -15403,12 +16018,12 @@ func rewriteValueARM_OpARMXORshiftLLreg_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMXORshiftRA_0(v *Value) bool {
+func rewriteValueARM_OpARMTEQshiftRA_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (XORshiftRA (MOVWconst [c]) x [d])
+       // match: (TEQshiftRA (MOVWconst [c]) x [d])
        // cond:
-       // result: (XORconst [c] (SRAconst <x.Type> x [d]))
+       // result: (TEQconst [c] (SRAconst <x.Type> x [d]))
        for {
                d := v.AuxInt
                _ = v.Args[1]
@@ -15418,7 +16033,7 @@ func rewriteValueARM_OpARMXORshiftRA_0(v *Value) bool {
                }
                c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
                v0.AuxInt = d
@@ -15426,9 +16041,9 @@ func rewriteValueARM_OpARMXORshiftRA_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (XORshiftRA x (MOVWconst [c]) [d])
+       // match: (TEQshiftRA x (MOVWconst [c]) [d])
        // cond:
-       // result: (XORconst x [int64(int32(c)>>uint64(d))])
+       // result: (TEQconst x [int64(int32(c)>>uint64(d))])
        for {
                d := v.AuxInt
                _ = v.Args[1]
@@ -15438,41 +16053,19 @@ func rewriteValueARM_OpARMXORshiftRA_0(v *Value) bool {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = int64(int32(c) >> uint64(d))
                v.AddArg(x)
                return true
        }
-       // match: (XORshiftRA x (SRAconst x [c]) [d])
-       // cond: c==d
-       // result: (MOVWconst [0])
-       for {
-               d := v.AuxInt
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSRAconst {
-                       break
-               }
-               c := v_1.AuxInt
-               if x != v_1.Args[0] {
-                       break
-               }
-               if !(c == d) {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
        return false
 }
-func rewriteValueARM_OpARMXORshiftRAreg_0(v *Value) bool {
+func rewriteValueARM_OpARMTEQshiftRAreg_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (XORshiftRAreg (MOVWconst [c]) x y)
+       // match: (TEQshiftRAreg (MOVWconst [c]) x y)
        // cond:
-       // result: (XORconst [c] (SRA <x.Type> x y))
+       // result: (TEQconst [c] (SRA <x.Type> x y))
        for {
                _ = v.Args[2]
                v_0 := v.Args[0]
@@ -15482,7 +16075,7 @@ func rewriteValueARM_OpARMXORshiftRAreg_0(v *Value) bool {
                c := v_0.AuxInt
                x := v.Args[1]
                y := v.Args[2]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
                v0.AddArg(x)
@@ -15490,9 +16083,9 @@ func rewriteValueARM_OpARMXORshiftRAreg_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (XORshiftRAreg x y (MOVWconst [c]))
+       // match: (TEQshiftRAreg x y (MOVWconst [c]))
        // cond:
-       // result: (XORshiftRA x y [c])
+       // result: (TEQshiftRA x y [c])
        for {
                _ = v.Args[2]
                x := v.Args[0]
@@ -15502,7 +16095,7 @@ func rewriteValueARM_OpARMXORshiftRAreg_0(v *Value) bool {
                        break
                }
                c := v_2.AuxInt
-               v.reset(OpARMXORshiftRA)
+               v.reset(OpARMTEQshiftRA)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
@@ -15510,12 +16103,12 @@ func rewriteValueARM_OpARMXORshiftRAreg_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMXORshiftRL_0(v *Value) bool {
+func rewriteValueARM_OpARMTEQshiftRL_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (XORshiftRL (MOVWconst [c]) x [d])
+       // match: (TEQshiftRL (MOVWconst [c]) x [d])
        // cond:
-       // result: (XORconst [c] (SRLconst <x.Type> x [d]))
+       // result: (TEQconst [c] (SRLconst <x.Type> x [d]))
        for {
                d := v.AuxInt
                _ = v.Args[1]
@@ -15525,7 +16118,7 @@ func rewriteValueARM_OpARMXORshiftRL_0(v *Value) bool {
                }
                c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
                v0.AuxInt = d
@@ -15533,9 +16126,9 @@ func rewriteValueARM_OpARMXORshiftRL_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (XORshiftRL x (MOVWconst [c]) [d])
+       // match: (TEQshiftRL x (MOVWconst [c]) [d])
        // cond:
-       // result: (XORconst x [int64(uint32(c)>>uint64(d))])
+       // result: (TEQconst x [int64(uint32(c)>>uint64(d))])
        for {
                d := v.AuxInt
                _ = v.Args[1]
@@ -15545,73 +16138,29 @@ func rewriteValueARM_OpARMXORshiftRL_0(v *Value) bool {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTEQconst)
                v.AuxInt = int64(uint32(c) >> uint64(d))
                v.AddArg(x)
                return true
        }
-       // match: (XORshiftRL [c] (SLLconst x [32-c]) x)
+       return false
+}
+func rewriteValueARM_OpARMTEQshiftRLreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TEQshiftRLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (SRRconst [   c] x)
+       // result: (TEQconst [c] (SRL <x.Type> x y))
        for {
-               c := v.AuxInt
-               _ = v.Args[1]
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARMSLLconst {
-                       break
-               }
-               if v_0.AuxInt != 32-c {
-                       break
-               }
-               x := v_0.Args[0]
-               if x != v.Args[1] {
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMSRRconst)
-               v.AuxInt = c
-               v.AddArg(x)
-               return true
-       }
-       // match: (XORshiftRL x (SRLconst x [c]) [d])
-       // cond: c==d
-       // result: (MOVWconst [0])
-       for {
-               d := v.AuxInt
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMSRLconst {
-                       break
-               }
-               c := v_1.AuxInt
-               if x != v_1.Args[0] {
-                       break
-               }
-               if !(c == d) {
-                       break
-               }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
-               return true
-       }
-       return false
-}
-func rewriteValueARM_OpARMXORshiftRLreg_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (XORshiftRLreg (MOVWconst [c]) x y)
-       // cond:
-       // result: (XORconst [c] (SRL <x.Type> x y))
-       for {
-               _ = v.Args[2]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
-                       break
-               }
-               c := v_0.AuxInt
-               x := v.Args[1]
-               y := v.Args[2]
-               v.reset(OpARMXORconst)
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMTEQconst)
                v.AuxInt = c
                v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
                v0.AddArg(x)
@@ -15619,9 +16168,9 @@ func rewriteValueARM_OpARMXORshiftRLreg_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (XORshiftRLreg x y (MOVWconst [c]))
+       // match: (TEQshiftRLreg x y (MOVWconst [c]))
        // cond:
-       // result: (XORshiftRL x y [c])
+       // result: (TEQshiftRL x y [c])
        for {
                _ = v.Args[2]
                x := v.Args[0]
@@ -15631,7 +16180,7 @@ func rewriteValueARM_OpARMXORshiftRLreg_0(v *Value) bool {
                        break
                }
                c := v_2.AuxInt
-               v.reset(OpARMXORshiftRL)
+               v.reset(OpARMTEQshiftRL)
                v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
@@ -15639,14 +16188,27 @@ func rewriteValueARM_OpARMXORshiftRLreg_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpARMXORshiftRR_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (XORshiftRR (MOVWconst [c]) x [d])
+func rewriteValueARM_OpARMTST_0(v *Value) bool {
+       // match: (TST x (MOVWconst [c]))
        // cond:
-       // result: (XORconst [c] (SRRconst <x.Type> x [d]))
+       // result: (TSTconst [c] x)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (TST (MOVWconst [c]) x)
+       // cond:
+       // result: (TSTconst [c] x)
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                v_0 := v.Args[0]
                if v_0.Op != OpARMMOVWconst {
@@ -15654,2780 +16216,2694 @@ func rewriteValueARM_OpARMXORshiftRR_0(v *Value) bool {
                }
                c := v_0.AuxInt
                x := v.Args[1]
-               v.reset(OpARMXORconst)
+               v.reset(OpARMTSTconst)
                v.AuxInt = c
-               v0 := b.NewValue0(v.Pos, OpARMSRRconst, x.Type)
-               v0.AuxInt = d
-               v0.AddArg(x)
-               v.AddArg(v0)
+               v.AddArg(x)
                return true
        }
-       // match: (XORshiftRR x (MOVWconst [c]) [d])
+       // match: (TST x (SLLconst [c] y))
        // cond:
-       // result: (XORconst x [int64(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
+       // result: (TSTshiftLL x y [c])
        for {
-               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
+               if v_1.Op != OpARMSLLconst {
                        break
                }
                c := v_1.AuxInt
-               v.reset(OpARMXORconst)
-               v.AuxInt = int64(uint32(c)>>uint64(d) | uint32(c)<<uint64(32-d))
+               y := v_1.Args[0]
+               v.reset(OpARMTSTshiftLL)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpAdd16_0(v *Value) bool {
-       // match: (Add16 x y)
+       // match: (TST (SLLconst [c] y) x)
        // cond:
-       // result: (ADD x y)
+       // result: (TSTshiftLL x y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADD)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLLconst {
+                       break
+               }
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMTSTshiftLL)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpAdd32_0(v *Value) bool {
-       // match: (Add32 x y)
+       // match: (TST x (SRLconst [c] y))
        // cond:
-       // result: (ADD x y)
+       // result: (TSTshiftRL x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADD)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMTSTshiftRL)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpAdd32F_0(v *Value) bool {
-       // match: (Add32F x y)
+       // match: (TST (SRLconst [c] y) x)
        // cond:
-       // result: (ADDF x y)
+       // result: (TSTshiftRL x y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADDF)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMTSTshiftRL)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpAdd32carry_0(v *Value) bool {
-       // match: (Add32carry x y)
+       // match: (TST x (SRAconst [c] y))
        // cond:
-       // result: (ADDS x y)
+       // result: (TSTshiftRA x y [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADDS)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRAconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMTSTshiftRA)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpAdd32withcarry_0(v *Value) bool {
-       // match: (Add32withcarry x y c)
+       // match: (TST (SRAconst [c] y) x)
        // cond:
-       // result: (ADC x y c)
+       // result: (TSTshiftRA x y [c])
        for {
-               _ = v.Args[2]
-               x := v.Args[0]
-               y := v.Args[1]
-               c := v.Args[2]
-               v.reset(OpARMADC)
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRAconst {
+                       break
+               }
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMTSTshiftRA)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
-               v.AddArg(c)
                return true
        }
-}
-func rewriteValueARM_OpAdd64F_0(v *Value) bool {
-       // match: (Add64F x y)
+       // match: (TST x (SLL y z))
        // cond:
-       // result: (ADDD x y)
+       // result: (TSTshiftLLreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADDD)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSLL {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMTSTshiftLLreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpAdd8_0(v *Value) bool {
-       // match: (Add8 x y)
+       // match: (TST (SLL y z) x)
        // cond:
-       // result: (ADD x y)
+       // result: (TSTshiftLLreg x y z)
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADD)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLL {
+                       break
+               }
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMTSTshiftLLreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpAddPtr_0(v *Value) bool {
-       // match: (AddPtr x y)
+func rewriteValueARM_OpARMTST_10(v *Value) bool {
+       // match: (TST x (SRL y z))
        // cond:
-       // result: (ADD x y)
+       // result: (TSTshiftRLreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADD)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRL {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMTSTshiftRLreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpAddr_0(v *Value) bool {
-       // match: (Addr {sym} base)
+       // match: (TST (SRL y z) x)
        // cond:
-       // result: (MOVWaddr {sym} base)
+       // result: (TSTshiftRLreg x y z)
        for {
-               sym := v.Aux
-               base := v.Args[0]
-               v.reset(OpARMMOVWaddr)
-               v.Aux = sym
-               v.AddArg(base)
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRL {
+                       break
+               }
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMTSTshiftRLreg)
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpAnd16_0(v *Value) bool {
-       // match: (And16 x y)
+       // match: (TST x (SRA y z))
        // cond:
-       // result: (AND x y)
+       // result: (TSTshiftRAreg x y z)
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMAND)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRA {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMTSTshiftRAreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpAnd32_0(v *Value) bool {
-       // match: (And32 x y)
+       // match: (TST (SRA y z) x)
        // cond:
-       // result: (AND x y)
+       // result: (TSTshiftRAreg x y z)
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMAND)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRA {
+                       break
+               }
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMTSTshiftRAreg)
                v.AddArg(x)
                v.AddArg(y)
+               v.AddArg(z)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpAnd8_0(v *Value) bool {
-       // match: (And8 x y)
-       // cond:
-       // result: (AND x y)
+func rewriteValueARM_OpARMTSTconst_0(v *Value) bool {
+       // match: (TSTconst (MOVWconst [x]) [y])
+       // cond: int32(x&y)==0
+       // result: (FlagEQ)
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMAND)
-               v.AddArg(x)
-               v.AddArg(y)
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x&y) == 0) {
+                       break
+               }
+               v.reset(OpARMFlagEQ)
                return true
        }
-}
-func rewriteValueARM_OpAndB_0(v *Value) bool {
-       // match: (AndB x y)
-       // cond:
-       // result: (AND x y)
+       // match: (TSTconst (MOVWconst [x]) [y])
+       // cond: int32(x&y)<0
+       // result: (FlagLT_UGT)
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMAND)
-               v.AddArg(x)
-               v.AddArg(y)
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x&y) < 0) {
+                       break
+               }
+               v.reset(OpARMFlagLT_UGT)
+               return true
+       }
+       // match: (TSTconst (MOVWconst [x]) [y])
+       // cond: int32(x&y)>0
+       // result: (FlagGT_UGT)
+       for {
+               y := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               x := v_0.AuxInt
+               if !(int32(x&y) > 0) {
+                       break
+               }
+               v.reset(OpARMFlagGT_UGT)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpAvg32u_0(v *Value) bool {
+func rewriteValueARM_OpARMTSTshiftLL_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Avg32u <t> x y)
+       // match: (TSTshiftLL (MOVWconst [c]) x [d])
        // cond:
-       // result: (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
+       // result: (TSTconst [c] (SLLconst <x.Type> x [d]))
        for {
-               t := v.Type
+               d := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMADD)
-               v0 := b.NewValue0(v.Pos, OpARMSRLconst, t)
-               v0.AuxInt = 1
-               v1 := b.NewValue0(v.Pos, OpARMSUB, t)
-               v1.AddArg(x)
-               v1.AddArg(y)
-               v0.AddArg(v1)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
                v.AddArg(v0)
-               v.AddArg(y)
                return true
        }
+       // match: (TSTshiftLL x (MOVWconst [c]) [d])
+       // cond:
+       // result: (TSTconst x [int64(uint32(c)<<uint64(d))])
+       for {
+               d := v.AuxInt
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMTSTconst)
+               v.AuxInt = int64(uint32(c) << uint64(d))
+               v.AddArg(x)
+               return true
+       }
+       return false
 }
-func rewriteValueARM_OpBitLen32_0(v *Value) bool {
+func rewriteValueARM_OpARMTSTshiftLLreg_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (BitLen32 <t> x)
+       // match: (TSTshiftLLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (RSBconst [32] (CLZ <t> x))
+       // result: (TSTconst [c] (SLL <x.Type> x y))
        for {
-               t := v.Type
-               x := v.Args[0]
-               v.reset(OpARMRSBconst)
-               v.AuxInt = 32
-               v0 := b.NewValue0(v.Pos, OpARMCLZ, t)
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
+       // match: (TSTshiftLLreg x y (MOVWconst [c]))
+       // cond:
+       // result: (TSTshiftLL x y [c])
+       for {
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_2.AuxInt
+               v.reset(OpARMTSTshiftLL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
 }
-func rewriteValueARM_OpBswap32_0(v *Value) bool {
+func rewriteValueARM_OpARMTSTshiftRA_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Bswap32 <t> x)
-       // cond: objabi.GOARM==5
-       // result: (XOR <t>             (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])          (SRRconst <t> x [8]))
+       // match: (TSTshiftRA (MOVWconst [c]) x [d])
+       // cond:
+       // result: (TSTconst [c] (SRAconst <x.Type> x [d]))
        for {
-               t := v.Type
-               x := v.Args[0]
-               if !(objabi.GOARM == 5) {
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMXOR)
-               v.Type = t
-               v0 := b.NewValue0(v.Pos, OpARMSRLconst, t)
-               v0.AuxInt = 8
-               v1 := b.NewValue0(v.Pos, OpARMBICconst, t)
-               v1.AuxInt = 0xff0000
-               v2 := b.NewValue0(v.Pos, OpARMXOR, t)
-               v2.AddArg(x)
-               v3 := b.NewValue0(v.Pos, OpARMSRRconst, t)
-               v3.AuxInt = 16
-               v3.AddArg(x)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
-               v0.AddArg(v1)
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
                v.AddArg(v0)
-               v4 := b.NewValue0(v.Pos, OpARMSRRconst, t)
-               v4.AuxInt = 8
-               v4.AddArg(x)
-               v.AddArg(v4)
                return true
        }
-       // match: (Bswap32 x)
-       // cond: objabi.GOARM>=6
-       // result: (REV x)
+       // match: (TSTshiftRA x (MOVWconst [c]) [d])
+       // cond:
+       // result: (TSTconst x [int64(int32(c)>>uint64(d))])
        for {
+               d := v.AuxInt
+               _ = v.Args[1]
                x := v.Args[0]
-               if !(objabi.GOARM >= 6) {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
                        break
                }
-               v.reset(OpARMREV)
+               c := v_1.AuxInt
+               v.reset(OpARMTSTconst)
+               v.AuxInt = int64(int32(c) >> uint64(d))
                v.AddArg(x)
                return true
        }
        return false
 }
-func rewriteValueARM_OpClosureCall_0(v *Value) bool {
-       // match: (ClosureCall [argwid] entry closure mem)
+func rewriteValueARM_OpARMTSTshiftRAreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TSTshiftRAreg (MOVWconst [c]) x y)
        // cond:
-       // result: (CALLclosure [argwid] entry closure mem)
+       // result: (TSTconst [c] (SRA <x.Type> x y))
        for {
-               argwid := v.AuxInt
                _ = v.Args[2]
-               entry := v.Args[0]
-               closure := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMCALLclosure)
-               v.AuxInt = argwid
-               v.AddArg(entry)
-               v.AddArg(closure)
-               v.AddArg(mem)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpCom16_0(v *Value) bool {
-       // match: (Com16 x)
+       // match: (TSTshiftRAreg x y (MOVWconst [c]))
        // cond:
-       // result: (MVN x)
+       // result: (TSTshiftRA x y [c])
        for {
+               _ = v.Args[2]
                x := v.Args[0]
-               v.reset(OpARMMVN)
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_2.AuxInt
+               v.reset(OpARMTSTshiftRA)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpCom32_0(v *Value) bool {
-       // match: (Com32 x)
+func rewriteValueARM_OpARMTSTshiftRL_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TSTshiftRL (MOVWconst [c]) x [d])
        // cond:
-       // result: (MVN x)
+       // result: (TSTconst [c] (SRLconst <x.Type> x [d]))
        for {
-               x := v.Args[0]
-               v.reset(OpARMMVN)
-               v.AddArg(x)
+               d := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
+               v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpCom8_0(v *Value) bool {
-       // match: (Com8 x)
+       // match: (TSTshiftRL x (MOVWconst [c]) [d])
        // cond:
-       // result: (MVN x)
+       // result: (TSTconst x [int64(uint32(c)>>uint64(d))])
        for {
+               d := v.AuxInt
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMVN)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMTSTconst)
+               v.AuxInt = int64(uint32(c) >> uint64(d))
                v.AddArg(x)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpConst16_0(v *Value) bool {
-       // match: (Const16 [val])
+func rewriteValueARM_OpARMTSTshiftRLreg_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (TSTshiftRLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (MOVWconst [val])
+       // result: (TSTconst [c] (SRL <x.Type> x y))
        for {
-               val := v.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = val
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMTSTconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpConst32_0(v *Value) bool {
-       // match: (Const32 [val])
+       // match: (TSTshiftRLreg x y (MOVWconst [c]))
        // cond:
-       // result: (MOVWconst [val])
+       // result: (TSTshiftRL x y [c])
        for {
-               val := v.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = val
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_2.AuxInt
+               v.reset(OpARMTSTshiftRL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpConst32F_0(v *Value) bool {
-       // match: (Const32F [val])
+func rewriteValueARM_OpARMXOR_0(v *Value) bool {
+       // match: (XOR x (MOVWconst [c]))
        // cond:
-       // result: (MOVFconst [val])
+       // result: (XORconst [c] x)
        for {
-               val := v.AuxInt
-               v.reset(OpARMMOVFconst)
-               v.AuxInt = val
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-}
-func rewriteValueARM_OpConst64F_0(v *Value) bool {
-       // match: (Const64F [val])
+       // match: (XOR (MOVWconst [c]) x)
        // cond:
-       // result: (MOVDconst [val])
+       // result: (XORconst [c] x)
        for {
-               val := v.AuxInt
-               v.reset(OpARMMOVDconst)
-               v.AuxInt = val
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-}
-func rewriteValueARM_OpConst8_0(v *Value) bool {
-       // match: (Const8 [val])
+       // match: (XOR x (SLLconst [c] y))
        // cond:
-       // result: (MOVWconst [val])
+       // result: (XORshiftLL x y [c])
        for {
-               val := v.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = val
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSLLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMXORshiftLL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpConstBool_0(v *Value) bool {
-       // match: (ConstBool [b])
+       // match: (XOR (SLLconst [c] y) x)
        // cond:
-       // result: (MOVWconst [b])
+       // result: (XORshiftLL x y [c])
        for {
-               b := v.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = b
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLLconst {
+                       break
+               }
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftLL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpConstNil_0(v *Value) bool {
-       // match: (ConstNil)
+       // match: (XOR x (SRLconst [c] y))
        // cond:
-       // result: (MOVWconst [0])
+       // result: (XORshiftRL x y [c])
        for {
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMXORshiftRL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpConvert_0(v *Value) bool {
-       // match: (Convert x mem)
+       // match: (XOR (SRLconst [c] y) x)
        // cond:
-       // result: (MOVWconvert x mem)
+       // result: (XORshiftRL x y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVWconvert)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftRL)
+               v.AuxInt = c
                v.AddArg(x)
-               v.AddArg(mem)
+               v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpCtz32_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Ctz32 <t> x)
-       // cond: objabi.GOARM<=6
-       // result: (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
+       // match: (XOR x (SRAconst [c] y))
+       // cond:
+       // result: (XORshiftRA x y [c])
        for {
-               t := v.Type
+               _ = v.Args[1]
                x := v.Args[0]
-               if !(objabi.GOARM <= 6) {
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRAconst {
                        break
                }
-               v.reset(OpARMRSBconst)
-               v.AuxInt = 32
-               v0 := b.NewValue0(v.Pos, OpARMCLZ, t)
-               v1 := b.NewValue0(v.Pos, OpARMSUBconst, t)
-               v1.AuxInt = 1
-               v2 := b.NewValue0(v.Pos, OpARMAND, t)
-               v2.AddArg(x)
-               v3 := b.NewValue0(v.Pos, OpARMRSBconst, t)
-               v3.AuxInt = 0
-               v3.AddArg(x)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
-               v0.AddArg(v1)
-               v.AddArg(v0)
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMXORshiftRA)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (Ctz32 <t> x)
-       // cond: objabi.GOARM==7
-       // result: (CLZ <t> (RBIT <t> x))
+       // match: (XOR (SRAconst [c] y) x)
+       // cond:
+       // result: (XORshiftRA x y [c])
        for {
-               t := v.Type
-               x := v.Args[0]
-               if !(objabi.GOARM == 7) {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRAconst {
                        break
                }
-               v.reset(OpARMCLZ)
-               v.Type = t
-               v0 := b.NewValue0(v.Pos, OpARMRBIT, t)
-               v0.AddArg(x)
-               v.AddArg(v0)
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftRA)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpCvt32Fto32_0(v *Value) bool {
-       // match: (Cvt32Fto32 x)
+       // match: (XOR x (SRRconst [c] y))
        // cond:
-       // result: (MOVFW x)
+       // result: (XORshiftRR x y [c])
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVFW)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRRconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               v.reset(OpARMXORshiftRR)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-}
-func rewriteValueARM_OpCvt32Fto32U_0(v *Value) bool {
-       // match: (Cvt32Fto32U x)
+       // match: (XOR (SRRconst [c] y) x)
        // cond:
-       // result: (MOVFWU x)
+       // result: (XORshiftRR x y [c])
        for {
-               x := v.Args[0]
-               v.reset(OpARMMOVFWU)
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRRconst {
+                       break
+               }
+               c := v_0.AuxInt
+               y := v_0.Args[0]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftRR)
+               v.AuxInt = c
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpCvt32Fto64F_0(v *Value) bool {
-       // match: (Cvt32Fto64F x)
+func rewriteValueARM_OpARMXOR_10(v *Value) bool {
+       // match: (XOR x (SLL y z))
        // cond:
-       // result: (MOVFD x)
+       // result: (XORshiftLLreg x y z)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVFD)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSLL {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMXORshiftLLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpCvt32Uto32F_0(v *Value) bool {
-       // match: (Cvt32Uto32F x)
+       // match: (XOR (SLL y z) x)
        // cond:
-       // result: (MOVWUF x)
+       // result: (XORshiftLLreg x y z)
        for {
-               x := v.Args[0]
-               v.reset(OpARMMOVWUF)
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLL {
+                       break
+               }
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftLLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpCvt32Uto64F_0(v *Value) bool {
-       // match: (Cvt32Uto64F x)
+       // match: (XOR x (SRL y z))
        // cond:
-       // result: (MOVWUD x)
+       // result: (XORshiftRLreg x y z)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVWUD)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRL {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMXORshiftRLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpCvt32to32F_0(v *Value) bool {
-       // match: (Cvt32to32F x)
+       // match: (XOR (SRL y z) x)
        // cond:
-       // result: (MOVWF x)
+       // result: (XORshiftRLreg x y z)
        for {
-               x := v.Args[0]
-               v.reset(OpARMMOVWF)
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRL {
+                       break
+               }
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftRLreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpCvt32to64F_0(v *Value) bool {
-       // match: (Cvt32to64F x)
+       // match: (XOR x (SRA y z))
        // cond:
-       // result: (MOVWD x)
+       // result: (XORshiftRAreg x y z)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVWD)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRA {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               z := v_1.Args[1]
+               v.reset(OpARMXORshiftRAreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpCvt64Fto32_0(v *Value) bool {
-       // match: (Cvt64Fto32 x)
+       // match: (XOR (SRA y z) x)
        // cond:
-       // result: (MOVDW x)
+       // result: (XORshiftRAreg x y z)
        for {
-               x := v.Args[0]
-               v.reset(OpARMMOVDW)
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRA {
+                       break
+               }
+               _ = v_0.Args[1]
+               y := v_0.Args[0]
+               z := v_0.Args[1]
+               x := v.Args[1]
+               v.reset(OpARMXORshiftRAreg)
                v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(z)
                return true
        }
-}
-func rewriteValueARM_OpCvt64Fto32F_0(v *Value) bool {
-       // match: (Cvt64Fto32F x)
+       // match: (XOR x x)
        // cond:
-       // result: (MOVDF x)
+       // result: (MOVWconst [0])
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVDF)
-               v.AddArg(x)
+               if x != v.Args[1] {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
+       return false
 }
-func rewriteValueARM_OpCvt64Fto32U_0(v *Value) bool {
-       // match: (Cvt64Fto32U x)
+func rewriteValueARM_OpARMXORconst_0(v *Value) bool {
+       // match: (XORconst [0] x)
        // cond:
-       // result: (MOVDWU x)
+       // result: x
        for {
+               if v.AuxInt != 0 {
+                       break
+               }
                x := v.Args[0]
-               v.reset(OpARMMOVDWU)
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (XORconst [c] (MOVWconst [d]))
+       // cond:
+       // result: (MOVWconst [c^d])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               d := v_0.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = c ^ d
+               return true
+       }
+       // match: (XORconst [c] (XORconst [d] x))
+       // cond:
+       // result: (XORconst [c^d] x)
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMXORconst {
+                       break
+               }
+               d := v_0.AuxInt
+               x := v_0.Args[0]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c ^ d
                v.AddArg(x)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpDiv16_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftLL_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Div16 x y)
+       // match: (XORshiftLL (MOVWconst [c]) x [d])
        // cond:
-       // result: (Div32 (SignExt16to32 x) (SignExt16to32 y))
+       // result: (XORconst [c] (SLLconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpDiv32)
-               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+               v0.AuxInt = d
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
-}
-func rewriteValueARM_OpDiv16u_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Div16u x y)
+       // match: (XORshiftLL x (MOVWconst [c]) [d])
        // cond:
-       // result: (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+       // result: (XORconst x [int64(uint32(c)<<uint64(d))])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpDiv32u)
-               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v0.AddArg(x)
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMXORconst)
+               v.AuxInt = int64(uint32(c) << uint64(d))
+               v.AddArg(x)
                return true
        }
-}
-func rewriteValueARM_OpDiv32_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Div32 x y)
+       // match: (XORshiftLL [c] (SRLconst x [32-c]) x)
        // cond:
-       // result: (SUB (XOR <typ.UInt32>               (Select0 <typ.UInt32> (CALLudiv                         (SUB <typ.UInt32> (XOR x <typ.UInt32> (Signmask x)) (Signmask x))                       (SUB <typ.UInt32> (XOR y <typ.UInt32> (Signmask y)) (Signmask y))))             (Signmask (XOR <typ.UInt32> x y))) (Signmask (XOR <typ.UInt32> x y)))
+       // result: (SRRconst [32-c] x)
+       for {
+               c := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSRLconst {
+                       break
+               }
+               if v_0.AuxInt != 32-c {
+                       break
+               }
+               x := v_0.Args[0]
+               if x != v.Args[1] {
+                       break
+               }
+               v.reset(OpARMSRRconst)
+               v.AuxInt = 32 - c
+               v.AddArg(x)
+               return true
+       }
+       // match: (XORshiftLL x (SLLconst x [c]) [d])
+       // cond: c==d
+       // result: (MOVWconst [0])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMSUB)
-               v0 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v1 := b.NewValue0(v.Pos, OpSelect0, typ.UInt32)
-               v2 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
-               v3 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
-               v4 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v4.AddArg(x)
-               v5 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v5.AddArg(x)
-               v4.AddArg(v5)
-               v3.AddArg(v4)
-               v6 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v6.AddArg(x)
-               v3.AddArg(v6)
-               v2.AddArg(v3)
-               v7 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
-               v8 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v8.AddArg(y)
-               v9 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v9.AddArg(y)
-               v8.AddArg(v9)
-               v7.AddArg(v8)
-               v10 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v10.AddArg(y)
-               v7.AddArg(v10)
-               v2.AddArg(v7)
-               v1.AddArg(v2)
-               v0.AddArg(v1)
-               v11 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v12 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v12.AddArg(x)
-               v12.AddArg(y)
-               v11.AddArg(v12)
-               v0.AddArg(v11)
-               v.AddArg(v0)
-               v13 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v14 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v14.AddArg(x)
-               v14.AddArg(y)
-               v13.AddArg(v14)
-               v.AddArg(v13)
-               return true
-       }
-}
-func rewriteValueARM_OpDiv32F_0(v *Value) bool {
-       // match: (Div32F x y)
-       // cond:
-       // result: (DIVF x y)
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMDIVF)
-               v.AddArg(x)
-               v.AddArg(y)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSLLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               if x != v_1.Args[0] {
+                       break
+               }
+               if !(c == d) {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
+       return false
 }
-func rewriteValueARM_OpDiv32u_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftLLreg_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Div32u x y)
+       // match: (XORshiftLLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (Select0 <typ.UInt32> (CALLudiv x y))
+       // result: (XORconst [c] (SLL <x.Type> x y))
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpSelect0)
-               v.Type = typ.UInt32
-               v0 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpDiv64F_0(v *Value) bool {
-       // match: (Div64F x y)
+       // match: (XORshiftLLreg x y (MOVWconst [c]))
        // cond:
-       // result: (DIVD x y)
+       // result: (XORshiftLL x y [c])
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIVD)
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_2.AuxInt
+               v.reset(OpARMXORshiftLL)
+               v.AuxInt = c
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpDiv8_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftRA_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Div8 x y)
+       // match: (XORshiftRA (MOVWconst [c]) x [d])
        // cond:
-       // result: (Div32 (SignExt8to32 x) (SignExt8to32 y))
+       // result: (XORconst [c] (SRAconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpDiv32)
-               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+               v0.AuxInt = d
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
-}
-func rewriteValueARM_OpDiv8u_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Div8u x y)
+       // match: (XORshiftRA x (MOVWconst [c]) [d])
        // cond:
-       // result: (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
+       // result: (XORconst x [int64(int32(c)>>uint64(d))])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpDiv32u)
-               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v0.AddArg(x)
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMXORconst)
+               v.AuxInt = int64(int32(c) >> uint64(d))
+               v.AddArg(x)
                return true
        }
-}
-func rewriteValueARM_OpEq16_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Eq16 x y)
-       // cond:
-       // result: (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+       // match: (XORshiftRA x (SRAconst x [c]) [d])
+       // cond: c==d
+       // result: (MOVWconst [0])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRAconst {
+                       break
+               }
+               c := v_1.AuxInt
+               if x != v_1.Args[0] {
+                       break
+               }
+               if !(c == d) {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
+       return false
 }
-func rewriteValueARM_OpEq32_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftRAreg_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Eq32 x y)
+       // match: (XORshiftRAreg (MOVWconst [c]) x y)
        // cond:
-       // result: (Equal (CMP x y))
+       // result: (XORconst [c] (SRA <x.Type> x y))
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpEq32F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Eq32F x y)
+       // match: (XORshiftRAreg x y (MOVWconst [c]))
        // cond:
-       // result: (Equal (CMPF x y))
+       // result: (XORshiftRA x y [c])
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_2.AuxInt
+               v.reset(OpARMXORshiftRA)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpEq64F_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftRL_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Eq64F x y)
+       // match: (XORshiftRL (MOVWconst [c]) x [d])
        // cond:
-       // result: (Equal (CMPD x y))
+       // result: (XORconst [c] (SRLconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+               v0.AuxInt = d
                v0.AddArg(x)
-               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpEq8_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Eq8 x y)
+       // match: (XORshiftRL x (MOVWconst [c]) [d])
        // cond:
-       // result: (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+       // result: (XORconst x [int64(uint32(c)>>uint64(d))])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMXORconst)
+               v.AuxInt = int64(uint32(c) >> uint64(d))
+               v.AddArg(x)
                return true
        }
-}
-func rewriteValueARM_OpEqB_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (EqB x y)
+       // match: (XORshiftRL [c] (SLLconst x [32-c]) x)
        // cond:
-       // result: (XORconst [1] (XOR <typ.Bool> x y))
+       // result: (SRRconst [   c] x)
+       for {
+               c := v.AuxInt
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMSLLconst {
+                       break
+               }
+               if v_0.AuxInt != 32-c {
+                       break
+               }
+               x := v_0.Args[0]
+               if x != v.Args[1] {
+                       break
+               }
+               v.reset(OpARMSRRconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (XORshiftRL x (SRLconst x [c]) [d])
+       // cond: c==d
+       // result: (MOVWconst [0])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMXORconst)
-               v.AuxInt = 1
-               v0 := b.NewValue0(v.Pos, OpARMXOR, typ.Bool)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMSRLconst {
+                       break
+               }
+               c := v_1.AuxInt
+               if x != v_1.Args[0] {
+                       break
+               }
+               if !(c == d) {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
+       return false
 }
-func rewriteValueARM_OpEqPtr_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftRLreg_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (EqPtr x y)
+       // match: (XORshiftRLreg (MOVWconst [c]) x y)
        // cond:
-       // result: (Equal (CMP x y))
+       // result: (XORconst [c] (SRL <x.Type> x y))
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               y := v.Args[2]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpGeq16_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Geq16 x y)
+       // match: (XORshiftRLreg x y (MOVWconst [c]))
        // cond:
-       // result: (GreaterEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
+       // result: (XORshiftRL x y [c])
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_2.AuxInt
+               v.reset(OpARMXORshiftRL)
+               v.AuxInt = c
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpGeq16U_0(v *Value) bool {
+func rewriteValueARM_OpARMXORshiftRR_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Geq16U x y)
+       // match: (XORshiftRR (MOVWconst [c]) x [d])
        // cond:
-       // result: (GreaterEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+       // result: (XORconst [c] (SRRconst <x.Type> x [d]))
        for {
+               d := v.AuxInt
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMGreaterEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               v.reset(OpARMXORconst)
+               v.AuxInt = c
+               v0 := b.NewValue0(v.Pos, OpARMSRRconst, x.Type)
+               v0.AuxInt = d
+               v0.AddArg(x)
                v.AddArg(v0)
                return true
        }
-}
-func rewriteValueARM_OpGeq32_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Geq32 x y)
+       // match: (XORshiftRR x (MOVWconst [c]) [d])
        // cond:
-       // result: (GreaterEqual (CMP x y))
+       // result: (XORconst x [int64(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
        for {
+               d := v.AuxInt
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               v.reset(OpARMXORconst)
+               v.AuxInt = int64(uint32(c)>>uint64(d) | uint32(c)<<uint64(32-d))
+               v.AddArg(x)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpGeq32F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Geq32F x y)
+func rewriteValueARM_OpAdd16_0(v *Value) bool {
+       // match: (Add16 x y)
        // cond:
-       // result: (GreaterEqual (CMPF x y))
+       // result: (ADD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMADD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGeq32U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Geq32U x y)
+func rewriteValueARM_OpAdd32_0(v *Value) bool {
+       // match: (Add32 x y)
        // cond:
-       // result: (GreaterEqualU (CMP x y))
+       // result: (ADD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMADD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGeq64F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Geq64F x y)
+func rewriteValueARM_OpAdd32F_0(v *Value) bool {
+       // match: (Add32F x y)
        // cond:
-       // result: (GreaterEqual (CMPD x y))
+       // result: (ADDF x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMADDF)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGeq8_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Geq8 x y)
+func rewriteValueARM_OpAdd32carry_0(v *Value) bool {
+       // match: (Add32carry x y)
        // cond:
-       // result: (GreaterEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
+       // result: (ADDS x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v.reset(OpARMADDS)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGeq8U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Geq8U x y)
+func rewriteValueARM_OpAdd32withcarry_0(v *Value) bool {
+       // match: (Add32withcarry x y c)
        // cond:
-       // result: (GreaterEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+       // result: (ADC x y c)
        for {
-               _ = v.Args[1]
+               _ = v.Args[2]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
-               return true
-       }
-}
-func rewriteValueARM_OpGetCallerSP_0(v *Value) bool {
-       // match: (GetCallerSP)
-       // cond:
-       // result: (LoweredGetCallerSP)
-       for {
-               v.reset(OpARMLoweredGetCallerSP)
+               c := v.Args[2]
+               v.reset(OpARMADC)
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(c)
                return true
        }
 }
-func rewriteValueARM_OpGetClosurePtr_0(v *Value) bool {
-       // match: (GetClosurePtr)
+func rewriteValueARM_OpAdd64F_0(v *Value) bool {
+       // match: (Add64F x y)
        // cond:
-       // result: (LoweredGetClosurePtr)
+       // result: (ADDD x y)
        for {
-               v.reset(OpARMLoweredGetClosurePtr)
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMADDD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater16_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Greater16 x y)
+func rewriteValueARM_OpAdd8_0(v *Value) bool {
+       // match: (Add8 x y)
        // cond:
-       // result: (GreaterThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
+       // result: (ADD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v.reset(OpARMADD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater16U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Greater16U x y)
+func rewriteValueARM_OpAddPtr_0(v *Value) bool {
+       // match: (AddPtr x y)
        // cond:
-       // result: (GreaterThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+       // result: (ADD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v.reset(OpARMADD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater32_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Greater32 x y)
+func rewriteValueARM_OpAddr_0(v *Value) bool {
+       // match: (Addr {sym} base)
        // cond:
-       // result: (GreaterThan (CMP x y))
+       // result: (MOVWaddr {sym} base)
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               sym := v.Aux
+               base := v.Args[0]
+               v.reset(OpARMMOVWaddr)
+               v.Aux = sym
+               v.AddArg(base)
                return true
        }
 }
-func rewriteValueARM_OpGreater32F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Greater32F x y)
+func rewriteValueARM_OpAnd16_0(v *Value) bool {
+       // match: (And16 x y)
        // cond:
-       // result: (GreaterThan (CMPF x y))
+       // result: (AND x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMAND)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater32U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Greater32U x y)
+func rewriteValueARM_OpAnd32_0(v *Value) bool {
+       // match: (And32 x y)
        // cond:
-       // result: (GreaterThanU (CMP x y))
+       // result: (AND x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMAND)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater64F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Greater64F x y)
+func rewriteValueARM_OpAnd8_0(v *Value) bool {
+       // match: (And8 x y)
        // cond:
-       // result: (GreaterThan (CMPD x y))
+       // result: (AND x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMAND)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater8_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Greater8 x y)
+func rewriteValueARM_OpAndB_0(v *Value) bool {
+       // match: (AndB x y)
        // cond:
-       // result: (GreaterThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
+       // result: (AND x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v.reset(OpARMAND)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpGreater8U_0(v *Value) bool {
+func rewriteValueARM_OpAvg32u_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Greater8U x y)
+       // match: (Avg32u <t> x y)
        // cond:
-       // result: (GreaterThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+       // result: (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
        for {
+               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v.reset(OpARMADD)
+               v0 := b.NewValue0(v.Pos, OpARMSRLconst, t)
+               v0.AuxInt = 1
+               v1 := b.NewValue0(v.Pos, OpARMSUB, t)
                v1.AddArg(x)
+               v1.AddArg(y)
                v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
                v.AddArg(v0)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpHmul32_0(v *Value) bool {
-       // match: (Hmul32 x y)
+func rewriteValueARM_OpBitLen32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (BitLen32 <t> x)
        // cond:
-       // result: (HMUL x y)
+       // result: (RSBconst [32] (CLZ <t> x))
        for {
-               _ = v.Args[1]
+               t := v.Type
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMHMUL)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMRSBconst)
+               v.AuxInt = 32
+               v0 := b.NewValue0(v.Pos, OpARMCLZ, t)
+               v0.AddArg(x)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpHmul32u_0(v *Value) bool {
-       // match: (Hmul32u x y)
-       // cond:
-       // result: (HMULU x y)
+func rewriteValueARM_OpBswap32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Bswap32 <t> x)
+       // cond: objabi.GOARM==5
+       // result: (XOR <t>             (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])          (SRRconst <t> x [8]))
        for {
-               _ = v.Args[1]
+               t := v.Type
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMHMULU)
-               v.AddArg(x)
-               v.AddArg(y)
+               if !(objabi.GOARM == 5) {
+                       break
+               }
+               v.reset(OpARMXOR)
+               v.Type = t
+               v0 := b.NewValue0(v.Pos, OpARMSRLconst, t)
+               v0.AuxInt = 8
+               v1 := b.NewValue0(v.Pos, OpARMBICconst, t)
+               v1.AuxInt = 0xff0000
+               v2 := b.NewValue0(v.Pos, OpARMXOR, t)
+               v2.AddArg(x)
+               v3 := b.NewValue0(v.Pos, OpARMSRRconst, t)
+               v3.AuxInt = 16
+               v3.AddArg(x)
+               v2.AddArg(v3)
+               v1.AddArg(v2)
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v4 := b.NewValue0(v.Pos, OpARMSRRconst, t)
+               v4.AuxInt = 8
+               v4.AddArg(x)
+               v.AddArg(v4)
+               return true
+       }
+       // match: (Bswap32 x)
+       // cond: objabi.GOARM>=6
+       // result: (REV x)
+       for {
+               x := v.Args[0]
+               if !(objabi.GOARM >= 6) {
+                       break
+               }
+               v.reset(OpARMREV)
+               v.AddArg(x)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpInterCall_0(v *Value) bool {
-       // match: (InterCall [argwid] entry mem)
+func rewriteValueARM_OpClosureCall_0(v *Value) bool {
+       // match: (ClosureCall [argwid] entry closure mem)
        // cond:
-       // result: (CALLinter [argwid] entry mem)
+       // result: (CALLclosure [argwid] entry closure mem)
        for {
                argwid := v.AuxInt
-               _ = v.Args[1]
+               _ = v.Args[2]
                entry := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMCALLinter)
+               closure := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMCALLclosure)
                v.AuxInt = argwid
                v.AddArg(entry)
+               v.AddArg(closure)
                v.AddArg(mem)
                return true
        }
 }
-func rewriteValueARM_OpIsInBounds_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (IsInBounds idx len)
+func rewriteValueARM_OpCom16_0(v *Value) bool {
+       // match: (Com16 x)
        // cond:
-       // result: (LessThanU (CMP idx len))
+       // result: (MVN x)
        for {
-               _ = v.Args[1]
-               idx := v.Args[0]
-               len := v.Args[1]
-               v.reset(OpARMLessThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(idx)
-               v0.AddArg(len)
-               v.AddArg(v0)
+               x := v.Args[0]
+               v.reset(OpARMMVN)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpIsNonNil_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (IsNonNil ptr)
+func rewriteValueARM_OpCom32_0(v *Value) bool {
+       // match: (Com32 x)
        // cond:
-       // result: (NotEqual (CMPconst [0] ptr))
+       // result: (MVN x)
        for {
-               ptr := v.Args[0]
-               v.reset(OpARMNotEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v0.AuxInt = 0
-               v0.AddArg(ptr)
-               v.AddArg(v0)
+               x := v.Args[0]
+               v.reset(OpARMMVN)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpIsSliceInBounds_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (IsSliceInBounds idx len)
+func rewriteValueARM_OpCom8_0(v *Value) bool {
+       // match: (Com8 x)
        // cond:
-       // result: (LessEqualU (CMP idx len))
+       // result: (MVN x)
        for {
-               _ = v.Args[1]
-               idx := v.Args[0]
-               len := v.Args[1]
-               v.reset(OpARMLessEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(idx)
-               v0.AddArg(len)
-               v.AddArg(v0)
+               x := v.Args[0]
+               v.reset(OpARMMVN)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpLeq16_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Leq16 x y)
+func rewriteValueARM_OpConst16_0(v *Value) bool {
+       // match: (Const16 [val])
        // cond:
-       // result: (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
+       // result: (MOVWconst [val])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               val := v.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = val
                return true
        }
 }
-func rewriteValueARM_OpLeq16U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Leq16U x y)
+func rewriteValueARM_OpConst32_0(v *Value) bool {
+       // match: (Const32 [val])
        // cond:
-       // result: (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+       // result: (MOVWconst [val])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               val := v.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = val
                return true
        }
 }
-func rewriteValueARM_OpLeq32_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Leq32 x y)
+func rewriteValueARM_OpConst32F_0(v *Value) bool {
+       // match: (Const32F [val])
        // cond:
-       // result: (LessEqual (CMP x y))
+       // result: (MOVFconst [val])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               val := v.AuxInt
+               v.reset(OpARMMOVFconst)
+               v.AuxInt = val
                return true
        }
 }
-func rewriteValueARM_OpLeq32F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Leq32F x y)
+func rewriteValueARM_OpConst64F_0(v *Value) bool {
+       // match: (Const64F [val])
        // cond:
-       // result: (GreaterEqual (CMPF y x))
+       // result: (MOVDconst [val])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
-               v0.AddArg(y)
-               v0.AddArg(x)
-               v.AddArg(v0)
+               val := v.AuxInt
+               v.reset(OpARMMOVDconst)
+               v.AuxInt = val
                return true
        }
 }
-func rewriteValueARM_OpLeq32U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Leq32U x y)
+func rewriteValueARM_OpConst8_0(v *Value) bool {
+       // match: (Const8 [val])
        // cond:
-       // result: (LessEqualU (CMP x y))
+       // result: (MOVWconst [val])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               val := v.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = val
                return true
        }
 }
-func rewriteValueARM_OpLeq64F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Leq64F x y)
+func rewriteValueARM_OpConstBool_0(v *Value) bool {
+       // match: (ConstBool [b])
        // cond:
-       // result: (GreaterEqual (CMPD y x))
+       // result: (MOVWconst [b])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMGreaterEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
-               v0.AddArg(y)
-               v0.AddArg(x)
-               v.AddArg(v0)
+               b := v.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = b
                return true
        }
 }
-func rewriteValueARM_OpLeq8_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Leq8 x y)
+func rewriteValueARM_OpConstNil_0(v *Value) bool {
+       // match: (ConstNil)
        // cond:
-       // result: (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
+       // result: (MOVWconst [0])
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessEqual)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
                return true
        }
 }
-func rewriteValueARM_OpLeq8U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Leq8U x y)
+func rewriteValueARM_OpConvert_0(v *Value) bool {
+       // match: (Convert x mem)
        // cond:
-       // result: (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+       // result: (MOVWconvert x mem)
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessEqualU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               mem := v.Args[1]
+               v.reset(OpARMMOVWconvert)
+               v.AddArg(x)
+               v.AddArg(mem)
                return true
        }
 }
-func rewriteValueARM_OpLess16_0(v *Value) bool {
+func rewriteValueARM_OpCtz32_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Less16 x y)
-       // cond:
-       // result: (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
+       // match: (Ctz32 <t> x)
+       // cond: objabi.GOARM<=6
+       // result: (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
        for {
-               _ = v.Args[1]
+               t := v.Type
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v1.AddArg(x)
+               if !(objabi.GOARM <= 6) {
+                       break
+               }
+               v.reset(OpARMRSBconst)
+               v.AuxInt = 32
+               v0 := b.NewValue0(v.Pos, OpARMCLZ, t)
+               v1 := b.NewValue0(v.Pos, OpARMSUBconst, t)
+               v1.AuxInt = 1
+               v2 := b.NewValue0(v.Pos, OpARMAND, t)
+               v2.AddArg(x)
+               v3 := b.NewValue0(v.Pos, OpARMRSBconst, t)
+               v3.AuxInt = 0
+               v3.AddArg(x)
+               v2.AddArg(v3)
+               v1.AddArg(v2)
                v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
+       // match: (Ctz32 <t> x)
+       // cond: objabi.GOARM==7
+       // result: (CLZ <t> (RBIT <t> x))
+       for {
+               t := v.Type
+               x := v.Args[0]
+               if !(objabi.GOARM == 7) {
+                       break
+               }
+               v.reset(OpARMCLZ)
+               v.Type = t
+               v0 := b.NewValue0(v.Pos, OpARMRBIT, t)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       return false
 }
-func rewriteValueARM_OpLess16U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Less16U x y)
+func rewriteValueARM_OpCvt32Fto32_0(v *Value) bool {
+       // match: (Cvt32Fto32 x)
        // cond:
-       // result: (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+       // result: (MOVFW x)
        for {
-               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
-               v.AddArg(v0)
+               v.reset(OpARMMOVFW)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpLess32_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Less32 x y)
+func rewriteValueARM_OpCvt32Fto32U_0(v *Value) bool {
+       // match: (Cvt32Fto32U x)
        // cond:
-       // result: (LessThan (CMP x y))
+       // result: (MOVFWU x)
        for {
-               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMMOVFWU)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpLess32F_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Less32F x y)
+func rewriteValueARM_OpCvt32Fto64F_0(v *Value) bool {
+       // match: (Cvt32Fto64F x)
        // cond:
-       // result: (GreaterThan (CMPF y x))
+       // result: (MOVFD x)
        for {
-               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
-               v0.AddArg(y)
-               v0.AddArg(x)
-               v.AddArg(v0)
+               v.reset(OpARMMOVFD)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpLess32U_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Less32U x y)
+func rewriteValueARM_OpCvt32Uto32F_0(v *Value) bool {
+       // match: (Cvt32Uto32F x)
        // cond:
-       // result: (LessThanU (CMP x y))
+       // result: (MOVWUF x)
        for {
-               _ = v.Args[1]
                x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMLessThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
-               v.AddArg(v0)
+               v.reset(OpARMMOVWUF)
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpLess64F_0(v *Value) bool {
+func rewriteValueARM_OpCvt32Uto64F_0(v *Value) bool {
+       // match: (Cvt32Uto64F x)
+       // cond:
+       // result: (MOVWUD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWUD)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32to32F_0(v *Value) bool {
+       // match: (Cvt32to32F x)
+       // cond:
+       // result: (MOVWF x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWF)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32to64F_0(v *Value) bool {
+       // match: (Cvt32to64F x)
+       // cond:
+       // result: (MOVWD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWD)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt64Fto32_0(v *Value) bool {
+       // match: (Cvt64Fto32 x)
+       // cond:
+       // result: (MOVDW x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVDW)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt64Fto32F_0(v *Value) bool {
+       // match: (Cvt64Fto32F x)
+       // cond:
+       // result: (MOVDF x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVDF)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt64Fto32U_0(v *Value) bool {
+       // match: (Cvt64Fto32U x)
+       // cond:
+       // result: (MOVDWU x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVDWU)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpDiv16_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Less64F x y)
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Div16 x y)
        // cond:
-       // result: (GreaterThan (CMPD y x))
+       // result: (Div32 (SignExt16to32 x) (SignExt16to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMGreaterThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
-               v0.AddArg(y)
+               v.reset(OpDiv32)
+               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
                v0.AddArg(x)
                v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpLess8_0(v *Value) bool {
+func rewriteValueARM_OpDiv16u_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Less8 x y)
+       // match: (Div16u x y)
        // cond:
-       // result: (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
+       // result: (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMLessThan)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
+               v.reset(OpDiv32u)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v0.AddArg(x)
                v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpLess8U_0(v *Value) bool {
+func rewriteValueARM_OpDiv32_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Less8U x y)
+       // match: (Div32 x y)
        // cond:
-       // result: (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+       // result: (SUB (XOR <typ.UInt32>               (Select0 <typ.UInt32> (CALLudiv                         (SUB <typ.UInt32> (XOR x <typ.UInt32> (Signmask x)) (Signmask x))                       (SUB <typ.UInt32> (XOR y <typ.UInt32> (Signmask y)) (Signmask y))))             (Signmask (XOR <typ.UInt32> x y))) (Signmask (XOR <typ.UInt32> x y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMLessThanU)
-               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(x)
+               v.reset(OpARMSUB)
+               v0 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v1 := b.NewValue0(v.Pos, OpSelect0, typ.UInt32)
+               v2 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
+               v3 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
+               v4 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v4.AddArg(x)
+               v5 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v5.AddArg(x)
+               v4.AddArg(v5)
+               v3.AddArg(v4)
+               v6 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v6.AddArg(x)
+               v3.AddArg(v6)
+               v2.AddArg(v3)
+               v7 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
+               v8 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v8.AddArg(y)
+               v9 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v9.AddArg(y)
+               v8.AddArg(v9)
+               v7.AddArg(v8)
+               v10 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v10.AddArg(y)
+               v7.AddArg(v10)
+               v2.AddArg(v7)
+               v1.AddArg(v2)
                v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
+               v11 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v12 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v12.AddArg(x)
+               v12.AddArg(y)
+               v11.AddArg(v12)
+               v0.AddArg(v11)
                v.AddArg(v0)
+               v13 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v14 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v14.AddArg(x)
+               v14.AddArg(y)
+               v13.AddArg(v14)
+               v.AddArg(v13)
                return true
        }
 }
-func rewriteValueARM_OpLoad_0(v *Value) bool {
-       // match: (Load <t> ptr mem)
-       // cond: t.IsBoolean()
-       // result: (MOVBUload ptr mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(t.IsBoolean()) {
-                       break
-               }
-               v.reset(OpARMMOVBUload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Load <t> ptr mem)
-       // cond: (is8BitInt(t) && isSigned(t))
-       // result: (MOVBload ptr mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is8BitInt(t) && isSigned(t)) {
-                       break
-               }
-               v.reset(OpARMMOVBload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Load <t> ptr mem)
-       // cond: (is8BitInt(t) && !isSigned(t))
-       // result: (MOVBUload ptr mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is8BitInt(t) && !isSigned(t)) {
-                       break
-               }
-               v.reset(OpARMMOVBUload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Load <t> ptr mem)
-       // cond: (is16BitInt(t) && isSigned(t))
-       // result: (MOVHload ptr mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is16BitInt(t) && isSigned(t)) {
-                       break
-               }
-               v.reset(OpARMMOVHload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Load <t> ptr mem)
-       // cond: (is16BitInt(t) && !isSigned(t))
-       // result: (MOVHUload ptr mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is16BitInt(t) && !isSigned(t)) {
-                       break
-               }
-               v.reset(OpARMMOVHUload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Load <t> ptr mem)
-       // cond: (is32BitInt(t) || isPtr(t))
-       // result: (MOVWload ptr mem)
+func rewriteValueARM_OpDiv32F_0(v *Value) bool {
+       // match: (Div32F x y)
+       // cond:
+       // result: (DIVF x y)
        for {
-               t := v.Type
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is32BitInt(t) || isPtr(t)) {
-                       break
-               }
-               v.reset(OpARMMOVWload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMDIVF)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (Load <t> ptr mem)
-       // cond: is32BitFloat(t)
-       // result: (MOVFload ptr mem)
+}
+func rewriteValueARM_OpDiv32u_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Div32u x y)
+       // cond:
+       // result: (Select0 <typ.UInt32> (CALLudiv x y))
        for {
-               t := v.Type
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is32BitFloat(t)) {
-                       break
-               }
-               v.reset(OpARMMOVFload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpSelect0)
+               v.Type = typ.UInt32
+               v0 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
-       // match: (Load <t> ptr mem)
-       // cond: is64BitFloat(t)
-       // result: (MOVDload ptr mem)
+}
+func rewriteValueARM_OpDiv64F_0(v *Value) bool {
+       // match: (Div64F x y)
+       // cond:
+       // result: (DIVD x y)
        for {
-               t := v.Type
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(is64BitFloat(t)) {
-                       break
-               }
-               v.reset(OpARMMOVDload)
-               v.AddArg(ptr)
-               v.AddArg(mem)
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMDIVD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       return false
 }
-func rewriteValueARM_OpLsh16x16_0(v *Value) bool {
+func rewriteValueARM_OpDiv8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Lsh16x16 x y)
+       // match: (Div8 x y)
        // cond:
-       // result: (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       // result: (Div32 (SignExt8to32 x) (SignExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v.reset(OpDiv32)
+               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v0.AddArg(x)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(y)
-               v0.AddArg(v1)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v2.AuxInt = 256
-               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpLsh16x32_0(v *Value) bool {
+func rewriteValueARM_OpDiv8u_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Lsh16x32 x y)
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Div8u x y)
        // cond:
-       // result: (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
+       // result: (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v.reset(OpDiv32u)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v0.AddArg(x)
-               v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v1.AuxInt = 256
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v1.AddArg(y)
                v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpLsh16x64_0(v *Value) bool {
-       // match: (Lsh16x64 x (Const64 [c]))
-       // cond: uint64(c) < 16
-       // result: (SLLconst x [c])
+func rewriteValueARM_OpEq16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Eq16 x y)
+       // cond:
+       // result: (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) < 16) {
-                       break
-               }
-               v.reset(OpARMSLLconst)
-               v.AuxInt = c
-               v.AddArg(x)
-               return true
-       }
-       // match: (Lsh16x64 _ (Const64 [c]))
-       // cond: uint64(c) >= 16
-       // result: (Const16 [0])
-       for {
-               _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) >= 16) {
-                       break
-               }
-               v.reset(OpConst16)
-               v.AuxInt = 0
+               y := v.Args[1]
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
-       return false
 }
-func rewriteValueARM_OpLsh16x8_0(v *Value) bool {
+func rewriteValueARM_OpEq32_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Lsh16x8 x y)
+       // match: (Eq32 x y)
        // cond:
-       // result: (SLL x (ZeroExt8to32 y))
+       // result: (Equal (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSLL)
-               v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpLsh32x16_0(v *Value) bool {
+func rewriteValueARM_OpEq32F_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Lsh32x16 x y)
+       // match: (Eq32F x y)
        // cond:
-       // result: (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       // result: (Equal (CMPF x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
                v0.AddArg(x)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(y)
-               v0.AddArg(v1)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v2.AuxInt = 256
-               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
                return true
        }
 }
-func rewriteValueARM_OpLsh32x32_0(v *Value) bool {
+func rewriteValueARM_OpEq64F_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Lsh32x32 x y)
+       // match: (Eq64F x y)
        // cond:
-       // result: (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
+       // result: (Equal (CMPD x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v1.AuxInt = 256
-               v1.AddArg(y)
-               v.AddArg(v1)
-               return true
-       }
-}
-func rewriteValueARM_OpLsh32x64_0(v *Value) bool {
-       // match: (Lsh32x64 x (Const64 [c]))
-       // cond: uint64(c) < 32
-       // result: (SLLconst x [c])
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) < 32) {
-                       break
-               }
-               v.reset(OpARMSLLconst)
-               v.AuxInt = c
-               v.AddArg(x)
-               return true
-       }
-       // match: (Lsh32x64 _ (Const64 [c]))
-       // cond: uint64(c) >= 32
-       // result: (Const32 [0])
-       for {
-               _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) >= 32) {
-                       break
-               }
-               v.reset(OpConst32)
-               v.AuxInt = 0
                return true
        }
-       return false
 }
-func rewriteValueARM_OpLsh32x8_0(v *Value) bool {
+func rewriteValueARM_OpEq8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Lsh32x8 x y)
+       // match: (Eq8 x y)
        // cond:
-       // result: (SLL x (ZeroExt8to32 y))
+       // result: (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSLL)
-               v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v0.AddArg(y)
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpLsh8x16_0(v *Value) bool {
+func rewriteValueARM_OpEqB_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Lsh8x16 x y)
+       // match: (EqB x y)
        // cond:
-       // result: (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       // result: (XORconst [1] (XOR <typ.Bool> x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v.reset(OpARMXORconst)
+               v.AuxInt = 1
+               v0 := b.NewValue0(v.Pos, OpARMXOR, typ.Bool)
                v0.AddArg(x)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(y)
-               v0.AddArg(v1)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v2.AuxInt = 256
-               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
                return true
        }
 }
-func rewriteValueARM_OpLsh8x32_0(v *Value) bool {
+func rewriteValueARM_OpEqPtr_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Lsh8x32 x y)
+       // match: (EqPtr x y)
        // cond:
-       // result: (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
+       // result: (Equal (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v1.AuxInt = 256
-               v1.AddArg(y)
-               v.AddArg(v1)
-               return true
-       }
-}
-func rewriteValueARM_OpLsh8x64_0(v *Value) bool {
-       // match: (Lsh8x64 x (Const64 [c]))
-       // cond: uint64(c) < 8
-       // result: (SLLconst x [c])
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) < 8) {
-                       break
-               }
-               v.reset(OpARMSLLconst)
-               v.AuxInt = c
-               v.AddArg(x)
-               return true
-       }
-       // match: (Lsh8x64 _ (Const64 [c]))
-       // cond: uint64(c) >= 8
-       // result: (Const8 [0])
-       for {
-               _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) >= 8) {
-                       break
-               }
-               v.reset(OpConst8)
-               v.AuxInt = 0
                return true
        }
-       return false
 }
-func rewriteValueARM_OpLsh8x8_0(v *Value) bool {
+func rewriteValueARM_OpGeq16_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Lsh8x8 x y)
+       // match: (Geq16 x y)
        // cond:
-       // result: (SLL x (ZeroExt8to32 y))
+       // result: (GreaterEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSLL)
-               v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v0.AddArg(y)
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMod16_0(v *Value) bool {
+func rewriteValueARM_OpGeq16U_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Mod16 x y)
+       // match: (Geq16U x y)
        // cond:
-       // result: (Mod32 (SignExt16to32 x) (SignExt16to32 y))
+       // result: (GreaterEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpMod32)
-               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v0.AddArg(x)
+               v.reset(OpARMGreaterEqualU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpMod16u_0(v *Value) bool {
+func rewriteValueARM_OpGeq32_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Mod16u x y)
+       // match: (Geq32 x y)
        // cond:
-       // result: (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+       // result: (GreaterEqual (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpMod32u)
-               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
                v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpMod32_0(v *Value) bool {
+func rewriteValueARM_OpGeq32F_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Mod32 x y)
+       // match: (Geq32F x y)
        // cond:
-       // result: (SUB (XOR <typ.UInt32>               (Select1 <typ.UInt32> (CALLudiv                         (SUB <typ.UInt32> (XOR <typ.UInt32> x (Signmask x)) (Signmask x))                       (SUB <typ.UInt32> (XOR <typ.UInt32> y (Signmask y)) (Signmask y))))             (Signmask x)) (Signmask x))
+       // result: (GreaterEqual (CMPF x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUB)
-               v0 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v1 := b.NewValue0(v.Pos, OpSelect1, typ.UInt32)
-               v2 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
-               v3 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
-               v4 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v4.AddArg(x)
-               v5 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v5.AddArg(x)
-               v4.AddArg(v5)
-               v3.AddArg(v4)
-               v6 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v6.AddArg(x)
-               v3.AddArg(v6)
-               v2.AddArg(v3)
-               v7 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
-               v8 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
-               v8.AddArg(y)
-               v9 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v9.AddArg(y)
-               v8.AddArg(v9)
-               v7.AddArg(v8)
-               v10 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v10.AddArg(y)
-               v7.AddArg(v10)
-               v2.AddArg(v7)
-               v1.AddArg(v2)
-               v0.AddArg(v1)
-               v11 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v11.AddArg(x)
-               v0.AddArg(v11)
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v12 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
-               v12.AddArg(x)
-               v.AddArg(v12)
                return true
        }
 }
-func rewriteValueARM_OpMod32u_0(v *Value) bool {
+func rewriteValueARM_OpGeq32U_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Mod32u x y)
+       // match: (Geq32U x y)
        // cond:
-       // result: (Select1 <typ.UInt32> (CALLudiv x y))
+       // result: (GreaterEqualU (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpSelect1)
-               v.Type = typ.UInt32
-               v0 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
+               v.reset(OpARMGreaterEqualU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMod8_0(v *Value) bool {
+func rewriteValueARM_OpGeq64F_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Mod8 x y)
+       // match: (Geq64F x y)
        // cond:
-       // result: (Mod32 (SignExt8to32 x) (SignExt8to32 y))
+       // result: (GreaterEqual (CMPD x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpMod32)
-               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
                v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpMod8u_0(v *Value) bool {
+func rewriteValueARM_OpGeq8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Mod8u x y)
+       // match: (Geq8 x y)
        // cond:
-       // result: (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
+       // result: (GreaterEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpMod32u)
-               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v0.AddArg(x)
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpMove_0(v *Value) bool {
+func rewriteValueARM_OpGeq8U_0(v *Value) bool {
        b := v.Block
        _ = b
-       config := b.Func.Config
-       _ = config
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Move [0] _ _ mem)
+       // match: (Geq8U x y)
        // cond:
-       // result: mem
+       // result: (GreaterEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
        for {
-               if v.AuxInt != 0 {
-                       break
-               }
-               _ = v.Args[2]
-               mem := v.Args[2]
-               v.reset(OpCopy)
-               v.Type = mem.Type
-               v.AddArg(mem)
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterEqualU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
-       // match: (Move [1] dst src mem)
+}
+func rewriteValueARM_OpGetCallerSP_0(v *Value) bool {
+       // match: (GetCallerSP)
        // cond:
-       // result: (MOVBstore dst (MOVBUload src mem) mem)
+       // result: (LoweredGetCallerSP)
        for {
-               if v.AuxInt != 1 {
-                       break
-               }
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v0.AddArg(src)
-               v0.AddArg(mem)
-               v.AddArg(v0)
-               v.AddArg(mem)
+               v.reset(OpARMLoweredGetCallerSP)
                return true
        }
-       // match: (Move [2] {t} dst src mem)
-       // cond: t.(*types.Type).Alignment()%2 == 0
-       // result: (MOVHstore dst (MOVHUload src mem) mem)
+}
+func rewriteValueARM_OpGetClosurePtr_0(v *Value) bool {
+       // match: (GetClosurePtr)
+       // cond:
+       // result: (LoweredGetClosurePtr)
        for {
-               if v.AuxInt != 2 {
-                       break
-               }
-               t := v.Aux
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Alignment()%2 == 0) {
-                       break
-               }
-               v.reset(OpARMMOVHstore)
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16)
-               v0.AddArg(src)
-               v0.AddArg(mem)
-               v.AddArg(v0)
-               v.AddArg(mem)
+               v.reset(OpARMLoweredGetClosurePtr)
                return true
        }
-       // match: (Move [2] dst src mem)
+}
+func rewriteValueARM_OpGreater16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Greater16 x y)
        // cond:
-       // result: (MOVBstore [1] dst (MOVBUload [1] src mem)           (MOVBstore dst (MOVBUload src mem) mem))
+       // result: (GreaterThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
        for {
-               if v.AuxInt != 2 {
-                       break
-               }
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = 1
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v0.AuxInt = 1
-               v0.AddArg(src)
-               v0.AddArg(mem)
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v1.AddArg(dst)
-               v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v2.AddArg(src)
-               v2.AddArg(mem)
-               v1.AddArg(v2)
-               v1.AddArg(mem)
-               v.AddArg(v1)
                return true
        }
-       // match: (Move [4] {t} dst src mem)
-       // cond: t.(*types.Type).Alignment()%4 == 0
-       // result: (MOVWstore dst (MOVWload src mem) mem)
+}
+func rewriteValueARM_OpGreater16U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Greater16U x y)
+       // cond:
+       // result: (GreaterThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
        for {
-               if v.AuxInt != 4 {
-                       break
-               }
-               t := v.Aux
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Alignment()%4 == 0) {
-                       break
-               }
-               v.reset(OpARMMOVWstore)
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWload, typ.UInt32)
-               v0.AddArg(src)
-               v0.AddArg(mem)
-               v.AddArg(v0)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Move [4] {t} dst src mem)
-       // cond: t.(*types.Type).Alignment()%2 == 0
-       // result: (MOVHstore [2] dst (MOVHUload [2] src mem)           (MOVHstore dst (MOVHUload src mem) mem))
-       for {
-               if v.AuxInt != 4 {
-                       break
-               }
-               t := v.Aux
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Alignment()%2 == 0) {
-                       break
-               }
-               v.reset(OpARMMOVHstore)
-               v.AuxInt = 2
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16)
-               v0.AuxInt = 2
-               v0.AddArg(src)
-               v0.AddArg(mem)
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVHstore, types.TypeMem)
-               v1.AddArg(dst)
-               v2 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16)
-               v2.AddArg(src)
-               v2.AddArg(mem)
-               v1.AddArg(v2)
-               v1.AddArg(mem)
-               v.AddArg(v1)
-               return true
-       }
-       // match: (Move [4] dst src mem)
-       // cond:
-       // result: (MOVBstore [3] dst (MOVBUload [3] src mem)           (MOVBstore [2] dst (MOVBUload [2] src mem)                      (MOVBstore [1] dst (MOVBUload [1] src mem)                              (MOVBstore dst (MOVBUload src mem) mem))))
-       for {
-               if v.AuxInt != 4 {
-                       break
-               }
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = 3
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v0.AuxInt = 3
-               v0.AddArg(src)
-               v0.AddArg(mem)
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v1.AuxInt = 2
-               v1.AddArg(dst)
-               v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v2.AuxInt = 2
-               v2.AddArg(src)
-               v2.AddArg(mem)
-               v1.AddArg(v2)
-               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v3.AuxInt = 1
-               v3.AddArg(dst)
-               v4 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v4.AuxInt = 1
-               v4.AddArg(src)
-               v4.AddArg(mem)
-               v3.AddArg(v4)
-               v5 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v5.AddArg(dst)
-               v6 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v6.AddArg(src)
-               v6.AddArg(mem)
-               v5.AddArg(v6)
-               v5.AddArg(mem)
-               v3.AddArg(v5)
-               v1.AddArg(v3)
-               v.AddArg(v1)
-               return true
-       }
-       // match: (Move [3] dst src mem)
-       // cond:
-       // result: (MOVBstore [2] dst (MOVBUload [2] src mem)           (MOVBstore [1] dst (MOVBUload [1] src mem)                      (MOVBstore dst (MOVBUload src mem) mem)))
-       for {
-               if v.AuxInt != 3 {
-                       break
-               }
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = 2
-               v.AddArg(dst)
-               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v0.AuxInt = 2
-               v0.AddArg(src)
-               v0.AddArg(mem)
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v1.AuxInt = 1
-               v1.AddArg(dst)
-               v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v2.AuxInt = 1
-               v2.AddArg(src)
-               v2.AddArg(mem)
-               v1.AddArg(v2)
-               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v3.AddArg(dst)
-               v4 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
-               v4.AddArg(src)
-               v4.AddArg(mem)
-               v3.AddArg(v4)
-               v3.AddArg(mem)
-               v1.AddArg(v3)
-               v.AddArg(v1)
-               return true
-       }
-       // match: (Move [s] {t} dst src mem)
-       // cond: s%4 == 0 && s > 4 && s <= 512  && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice
-       // result: (DUFFCOPY [8 * (128 - int64(s/4))] dst src mem)
-       for {
-               s := v.AuxInt
-               t := v.Aux
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               if !(s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice) {
-                       break
-               }
-               v.reset(OpARMDUFFCOPY)
-               v.AuxInt = 8 * (128 - int64(s/4))
-               v.AddArg(dst)
-               v.AddArg(src)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Move [s] {t} dst src mem)
-       // cond: (s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0
-       // result: (LoweredMove [t.(*types.Type).Alignment()]           dst             src             (ADDconst <src.Type> src [s-moveSize(t.(*types.Type).Alignment(), config)])             mem)
-       for {
-               s := v.AuxInt
-               t := v.Aux
-               _ = v.Args[2]
-               dst := v.Args[0]
-               src := v.Args[1]
-               mem := v.Args[2]
-               if !((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) {
-                       break
-               }
-               v.reset(OpARMLoweredMove)
-               v.AuxInt = t.(*types.Type).Alignment()
-               v.AddArg(dst)
-               v.AddArg(src)
-               v0 := b.NewValue0(v.Pos, OpARMADDconst, src.Type)
-               v0.AuxInt = s - moveSize(t.(*types.Type).Alignment(), config)
-               v0.AddArg(src)
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
-               v.AddArg(mem)
                return true
        }
-       return false
 }
-func rewriteValueARM_OpMul16_0(v *Value) bool {
-       // match: (Mul16 x y)
+func rewriteValueARM_OpGreater32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Greater32 x y)
        // cond:
-       // result: (MUL x y)
+       // result: (GreaterThan (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMUL)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMul32_0(v *Value) bool {
-       // match: (Mul32 x y)
+func rewriteValueARM_OpGreater32F_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Greater32F x y)
        // cond:
-       // result: (MUL x y)
+       // result: (GreaterThan (CMPF x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMUL)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMul32F_0(v *Value) bool {
-       // match: (Mul32F x y)
+func rewriteValueARM_OpGreater32U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Greater32U x y)
        // cond:
-       // result: (MULF x y)
+       // result: (GreaterThanU (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMULF)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMul32uhilo_0(v *Value) bool {
-       // match: (Mul32uhilo x y)
+func rewriteValueARM_OpGreater64F_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Greater64F x y)
        // cond:
-       // result: (MULLU x y)
+       // result: (GreaterThan (CMPD x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMULLU)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMul64F_0(v *Value) bool {
-       // match: (Mul64F x y)
+func rewriteValueARM_OpGreater8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Greater8 x y)
        // cond:
-       // result: (MULD x y)
+       // result: (GreaterThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMULD)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpMul8_0(v *Value) bool {
-       // match: (Mul8 x y)
+func rewriteValueARM_OpGreater8U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Greater8U x y)
        // cond:
-       // result: (MUL x y)
+       // result: (GreaterThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMUL)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeg16_0(v *Value) bool {
-       // match: (Neg16 x)
+func rewriteValueARM_OpHmul32_0(v *Value) bool {
+       // match: (Hmul32 x y)
        // cond:
-       // result: (RSBconst [0] x)
+       // result: (HMUL x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMRSBconst)
-               v.AuxInt = 0
+               y := v.Args[1]
+               v.reset(OpARMHMUL)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpNeg32_0(v *Value) bool {
-       // match: (Neg32 x)
+func rewriteValueARM_OpHmul32u_0(v *Value) bool {
+       // match: (Hmul32u x y)
        // cond:
-       // result: (RSBconst [0] x)
+       // result: (HMULU x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMRSBconst)
-               v.AuxInt = 0
+               y := v.Args[1]
+               v.reset(OpARMHMULU)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpNeg32F_0(v *Value) bool {
-       // match: (Neg32F x)
+func rewriteValueARM_OpInterCall_0(v *Value) bool {
+       // match: (InterCall [argwid] entry mem)
        // cond:
-       // result: (NEGF x)
+       // result: (CALLinter [argwid] entry mem)
        for {
-               x := v.Args[0]
-               v.reset(OpARMNEGF)
-               v.AddArg(x)
+               argwid := v.AuxInt
+               _ = v.Args[1]
+               entry := v.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMCALLinter)
+               v.AuxInt = argwid
+               v.AddArg(entry)
+               v.AddArg(mem)
                return true
        }
 }
-func rewriteValueARM_OpNeg64F_0(v *Value) bool {
-       // match: (Neg64F x)
+func rewriteValueARM_OpIsInBounds_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (IsInBounds idx len)
        // cond:
-       // result: (NEGD x)
+       // result: (LessThanU (CMP idx len))
        for {
-               x := v.Args[0]
-               v.reset(OpARMNEGD)
-               v.AddArg(x)
+               _ = v.Args[1]
+               idx := v.Args[0]
+               len := v.Args[1]
+               v.reset(OpARMLessThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(idx)
+               v0.AddArg(len)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeg8_0(v *Value) bool {
-       // match: (Neg8 x)
+func rewriteValueARM_OpIsNonNil_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (IsNonNil ptr)
        // cond:
-       // result: (RSBconst [0] x)
+       // result: (NotEqual (CMPconst [0] ptr))
+       for {
+               ptr := v.Args[0]
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = 0
+               v0.AddArg(ptr)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpIsSliceInBounds_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (IsSliceInBounds idx len)
+       // cond:
+       // result: (LessEqualU (CMP idx len))
+       for {
+               _ = v.Args[1]
+               idx := v.Args[0]
+               len := v.Args[1]
+               v.reset(OpARMLessEqualU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(idx)
+               v0.AddArg(len)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpLeq16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Leq16 x y)
+       // cond:
+       // result: (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMRSBconst)
-               v.AuxInt = 0
-               v.AddArg(x)
+               y := v.Args[1]
+               v.reset(OpARMLessEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeq16_0(v *Value) bool {
+func rewriteValueARM_OpLeq16U_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Neq16 x y)
+       // match: (Leq16U x y)
        // cond:
-       // result: (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+       // result: (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMNotEqual)
+               v.reset(OpARMLessEqualU)
                v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
                v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
                v1.AddArg(x)
@@ -18439,17 +18915,17 @@ func rewriteValueARM_OpNeq16_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpNeq32_0(v *Value) bool {
+func rewriteValueARM_OpLeq32_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Neq32 x y)
+       // match: (Leq32 x y)
        // cond:
-       // result: (NotEqual (CMP x y))
+       // result: (LessEqual (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMNotEqual)
+               v.reset(OpARMLessEqual)
                v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
                v0.AddArg(x)
                v0.AddArg(y)
@@ -18457,376 +18933,427 @@ func rewriteValueARM_OpNeq32_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpNeq32F_0(v *Value) bool {
+func rewriteValueARM_OpLeq32F_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Neq32F x y)
+       // match: (Leq32F x y)
        // cond:
-       // result: (NotEqual (CMPF x y))
+       // result: (GreaterEqual (CMPF y x))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMNotEqual)
+               v.reset(OpARMGreaterEqual)
                v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpLeq32U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Leq32U x y)
+       // cond:
+       // result: (LessEqualU (CMP x y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMLessEqualU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeq64F_0(v *Value) bool {
+func rewriteValueARM_OpLeq64F_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Neq64F x y)
+       // match: (Leq64F x y)
        // cond:
-       // result: (NotEqual (CMPD x y))
+       // result: (GreaterEqual (CMPD y x))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMNotEqual)
+               v.reset(OpARMGreaterEqual)
                v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
-               v0.AddArg(x)
                v0.AddArg(y)
+               v0.AddArg(x)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeq8_0(v *Value) bool {
+func rewriteValueARM_OpLeq8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Neq8 x y)
+       // match: (Leq8 x y)
        // cond:
-       // result: (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+       // result: (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMNotEqual)
+               v.reset(OpARMLessEqual)
                v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v1.AddArg(x)
                v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v2.AddArg(y)
                v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeqB_0(v *Value) bool {
-       // match: (NeqB x y)
+func rewriteValueARM_OpLeq8U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Leq8U x y)
        // cond:
-       // result: (XOR x y)
+       // result: (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMXOR)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMLessEqualU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNeqPtr_0(v *Value) bool {
+func rewriteValueARM_OpLess16_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (NeqPtr x y)
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Less16 x y)
        // cond:
-       // result: (NotEqual (CMP x y))
+       // result: (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMNotEqual)
+               v.reset(OpARMLessThan)
                v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
-               v0.AddArg(x)
-               v0.AddArg(y)
+               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpNilCheck_0(v *Value) bool {
-       // match: (NilCheck ptr mem)
-       // cond:
-       // result: (LoweredNilCheck ptr mem)
-       for {
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMLoweredNilCheck)
-               v.AddArg(ptr)
-               v.AddArg(mem)
-               return true
-       }
-}
-func rewriteValueARM_OpNot_0(v *Value) bool {
-       // match: (Not x)
-       // cond:
-       // result: (XORconst [1] x)
-       for {
-               x := v.Args[0]
-               v.reset(OpARMXORconst)
-               v.AuxInt = 1
-               v.AddArg(x)
-               return true
-       }
-}
-func rewriteValueARM_OpOffPtr_0(v *Value) bool {
-       // match: (OffPtr [off] ptr:(SP))
-       // cond:
-       // result: (MOVWaddr [off] ptr)
-       for {
-               off := v.AuxInt
-               ptr := v.Args[0]
-               if ptr.Op != OpSP {
-                       break
-               }
-               v.reset(OpARMMOVWaddr)
-               v.AuxInt = off
-               v.AddArg(ptr)
-               return true
-       }
-       // match: (OffPtr [off] ptr)
-       // cond:
-       // result: (ADDconst [off] ptr)
-       for {
-               off := v.AuxInt
-               ptr := v.Args[0]
-               v.reset(OpARMADDconst)
-               v.AuxInt = off
-               v.AddArg(ptr)
-               return true
-       }
-}
-func rewriteValueARM_OpOr16_0(v *Value) bool {
-       // match: (Or16 x y)
+func rewriteValueARM_OpLess16U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Less16U x y)
        // cond:
-       // result: (OR x y)
+       // result: (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMOR)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMLessThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpOr32_0(v *Value) bool {
-       // match: (Or32 x y)
+func rewriteValueARM_OpLess32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Less32 x y)
        // cond:
-       // result: (OR x y)
+       // result: (LessThan (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMOR)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMLessThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpOr8_0(v *Value) bool {
-       // match: (Or8 x y)
+func rewriteValueARM_OpLess32F_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Less32F x y)
        // cond:
-       // result: (OR x y)
+       // result: (GreaterThan (CMPF y x))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMOR)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpOrB_0(v *Value) bool {
-       // match: (OrB x y)
+func rewriteValueARM_OpLess32U_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Less32U x y)
        // cond:
-       // result: (OR x y)
+       // result: (LessThanU (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMOR)
-               v.AddArg(x)
-               v.AddArg(y)
-               return true
-       }
-}
-func rewriteValueARM_OpRound32F_0(v *Value) bool {
-       // match: (Round32F x)
-       // cond:
-       // result: x
-       for {
-               x := v.Args[0]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               v.reset(OpARMLessThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpRound64F_0(v *Value) bool {
-       // match: (Round64F x)
+func rewriteValueARM_OpLess64F_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Less64F x y)
        // cond:
-       // result: x
+       // result: (GreaterThan (CMPD y x))
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               y := v.Args[1]
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpRsh16Ux16_0(v *Value) bool {
+func rewriteValueARM_OpLess8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16Ux16 x y)
+       // match: (Less8 x y)
        // cond:
-       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       // result: (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v.reset(OpARMLessThan)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v1.AddArg(x)
                v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v2.AddArg(y)
                v0.AddArg(v2)
                v.AddArg(v0)
-               v3 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v3.AuxInt = 256
-               v4 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v.AddArg(v3)
                return true
        }
 }
-func rewriteValueARM_OpRsh16Ux32_0(v *Value) bool {
+func rewriteValueARM_OpLess8U_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16Ux32 x y)
+       // match: (Less8U x y)
        // cond:
-       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0])
+       // result: (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v.reset(OpARMLessThanU)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v1.AddArg(x)
                v0.AddArg(v1)
-               v0.AddArg(y)
-               v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v2.AuxInt = 256
+               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v2.AddArg(y)
-               v.AddArg(v2)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpRsh16Ux64_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Rsh16Ux64 x (Const64 [c]))
-       // cond: uint64(c) < 16
-       // result: (SRLconst (SLLconst <typ.UInt32> x [16]) [c+16])
+func rewriteValueARM_OpLoad_0(v *Value) bool {
+       // match: (Load <t> ptr mem)
+       // cond: t.IsBoolean()
+       // result: (MOVBUload ptr mem)
        for {
+               t := v.Type
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) < 16) {
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(t.IsBoolean()) {
                        break
                }
-               v.reset(OpARMSRLconst)
-               v.AuxInt = c + 16
-               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
-               v0.AuxInt = 16
-               v0.AddArg(x)
-               v.AddArg(v0)
+               v.reset(OpARMMOVBUload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
-       // match: (Rsh16Ux64 _ (Const64 [c]))
-       // cond: uint64(c) >= 16
-       // result: (Const16 [0])
+       // match: (Load <t> ptr mem)
+       // cond: (is8BitInt(t) && isSigned(t))
+       // result: (MOVBload ptr mem)
        for {
+               t := v.Type
                _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) >= 16) {
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is8BitInt(t) && isSigned(t)) {
                        break
                }
-               v.reset(OpConst16)
-               v.AuxInt = 0
+               v.reset(OpARMMOVBload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpRsh16Ux8_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Rsh16Ux8 x y)
-       // cond:
-       // result: (SRL (ZeroExt16to32 x) (ZeroExt8to32 y))
-       for {
+       // match: (Load <t> ptr mem)
+       // cond: (is8BitInt(t) && !isSigned(t))
+       // result: (MOVBUload ptr mem)
+       for {
+               t := v.Type
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMSRL)
-               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v0.AddArg(x)
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is8BitInt(t) && !isSigned(t)) {
+                       break
+               }
+               v.reset(OpARMMOVBUload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Load <t> ptr mem)
+       // cond: (is16BitInt(t) && isSigned(t))
+       // result: (MOVHload ptr mem)
+       for {
+               t := v.Type
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is16BitInt(t) && isSigned(t)) {
+                       break
+               }
+               v.reset(OpARMMOVHload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Load <t> ptr mem)
+       // cond: (is16BitInt(t) && !isSigned(t))
+       // result: (MOVHUload ptr mem)
+       for {
+               t := v.Type
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is16BitInt(t) && !isSigned(t)) {
+                       break
+               }
+               v.reset(OpARMMOVHUload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Load <t> ptr mem)
+       // cond: (is32BitInt(t) || isPtr(t))
+       // result: (MOVWload ptr mem)
+       for {
+               t := v.Type
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is32BitInt(t) || isPtr(t)) {
+                       break
+               }
+               v.reset(OpARMMOVWload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Load <t> ptr mem)
+       // cond: is32BitFloat(t)
+       // result: (MOVFload ptr mem)
+       for {
+               t := v.Type
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is32BitFloat(t)) {
+                       break
+               }
+               v.reset(OpARMMOVFload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Load <t> ptr mem)
+       // cond: is64BitFloat(t)
+       // result: (MOVDload ptr mem)
+       for {
+               t := v.Type
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is64BitFloat(t)) {
+                       break
+               }
+               v.reset(OpARMMOVDload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
+       return false
 }
-func rewriteValueARM_OpRsh16x16_0(v *Value) bool {
+func rewriteValueARM_OpLsh16x16_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16x16 x y)
+       // match: (Lsh16x16 x y)
        // cond:
-       // result: (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+       // result: (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRAcond)
-               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
-               v.AddArg(v0)
                v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
                v1.AddArg(y)
-               v.AddArg(v1)
+               v0.AddArg(v1)
+               v.AddArg(v0)
                v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
                v2.AuxInt = 256
                v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
@@ -18836,23 +19363,22 @@ func rewriteValueARM_OpRsh16x16_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpRsh16x32_0(v *Value) bool {
+func rewriteValueARM_OpLsh16x32_0(v *Value) bool {
        b := v.Block
        _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Rsh16x32 x y)
+       // match: (Lsh16x32 x y)
        // cond:
-       // result: (SRAcond (SignExt16to32 x) y (CMPconst [256] y))
+       // result: (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRAcond)
-               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v.AddArg(y)
                v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
                v1.AuxInt = 256
                v1.AddArg(y)
@@ -18860,14 +19386,10 @@ func rewriteValueARM_OpRsh16x32_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpRsh16x64_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Rsh16x64 x (Const64 [c]))
+func rewriteValueARM_OpLsh16x64_0(v *Value) bool {
+       // match: (Lsh16x64 x (Const64 [c]))
        // cond: uint64(c) < 16
-       // result: (SRAconst (SLLconst <typ.UInt32> x [16]) [c+16])
+       // result: (SLLconst x [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -18879,20 +19401,16 @@ func rewriteValueARM_OpRsh16x64_0(v *Value) bool {
                if !(uint64(c) < 16) {
                        break
                }
-               v.reset(OpARMSRAconst)
-               v.AuxInt = c + 16
-               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
-               v0.AuxInt = 16
-               v0.AddArg(x)
-               v.AddArg(v0)
+               v.reset(OpARMSLLconst)
+               v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-       // match: (Rsh16x64 x (Const64 [c]))
+       // match: (Lsh16x64 _ (Const64 [c]))
        // cond: uint64(c) >= 16
-       // result: (SRAconst (SLLconst <typ.UInt32> x [16]) [31])
+       // result: (Const16 [0])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
                v_1 := v.Args[1]
                if v_1.Op != OpConst64 {
                        break
@@ -18901,53 +19419,47 @@ func rewriteValueARM_OpRsh16x64_0(v *Value) bool {
                if !(uint64(c) >= 16) {
                        break
                }
-               v.reset(OpARMSRAconst)
-               v.AuxInt = 31
-               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
-               v0.AuxInt = 16
-               v0.AddArg(x)
-               v.AddArg(v0)
+               v.reset(OpConst16)
+               v.AuxInt = 0
                return true
        }
        return false
 }
-func rewriteValueARM_OpRsh16x8_0(v *Value) bool {
+func rewriteValueARM_OpLsh16x8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16x8 x y)
+       // match: (Lsh16x8 x y)
        // cond:
-       // result: (SRA (SignExt16to32 x) (ZeroExt8to32 y))
+       // result: (SLL x (ZeroExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRA)
-               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-               v0.AddArg(x)
+               v.reset(OpARMSLL)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpRsh32Ux16_0(v *Value) bool {
+func rewriteValueARM_OpLsh32x16_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh32Ux16 x y)
+       // match: (Lsh32x16 x y)
        // cond:
-       // result: (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       // result: (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpARMCMOVWHSconst)
                v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
                v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
                v1.AddArg(y)
@@ -18962,19 +19474,19 @@ func rewriteValueARM_OpRsh32Ux16_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpRsh32Ux32_0(v *Value) bool {
+func rewriteValueARM_OpLsh32x32_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Rsh32Ux32 x y)
+       // match: (Lsh32x32 x y)
        // cond:
-       // result: (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0])
+       // result: (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpARMCMOVWHSconst)
                v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
@@ -18985,10 +19497,10 @@ func rewriteValueARM_OpRsh32Ux32_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpRsh32Ux64_0(v *Value) bool {
-       // match: (Rsh32Ux64 x (Const64 [c]))
+func rewriteValueARM_OpLsh32x64_0(v *Value) bool {
+       // match: (Lsh32x64 x (Const64 [c]))
        // cond: uint64(c) < 32
-       // result: (SRLconst x [c])
+       // result: (SLLconst x [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -19000,12 +19512,12 @@ func rewriteValueARM_OpRsh32Ux64_0(v *Value) bool {
                if !(uint64(c) < 32) {
                        break
                }
-               v.reset(OpARMSRLconst)
+               v.reset(OpARMSLLconst)
                v.AuxInt = c
                v.AddArg(x)
                return true
        }
-       // match: (Rsh32Ux64 _ (Const64 [c]))
+       // match: (Lsh32x64 _ (Const64 [c]))
        // cond: uint64(c) >= 32
        // result: (Const32 [0])
        for {
@@ -19024,19 +19536,19 @@ func rewriteValueARM_OpRsh32Ux64_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueARM_OpRsh32Ux8_0(v *Value) bool {
+func rewriteValueARM_OpLsh32x8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh32Ux8 x y)
+       // match: (Lsh32x8 x y)
        // cond:
-       // result: (SRL x (ZeroExt8to32 y))
+       // result: (SLL x (ZeroExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRL)
+               v.reset(OpARMSLL)
                v.AddArg(x)
                v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v0.AddArg(y)
@@ -19044,56 +19556,62 @@ func rewriteValueARM_OpRsh32Ux8_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpRsh32x16_0(v *Value) bool {
+func rewriteValueARM_OpLsh8x16_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh32x16 x y)
+       // match: (Lsh8x16 x y)
        // cond:
-       // result: (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+       // result: (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRAcond)
-               v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v0.AddArg(y)
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(y)
+               v0.AddArg(v1)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v1.AuxInt = 256
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v2.AuxInt = 256
+               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v.AddArg(v2)
                return true
        }
 }
-func rewriteValueARM_OpRsh32x32_0(v *Value) bool {
+func rewriteValueARM_OpLsh8x32_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Rsh32x32 x y)
+       // match: (Lsh8x32 x y)
        // cond:
-       // result: (SRAcond x y (CMPconst [256] y))
+       // result: (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRAcond)
-               v.AddArg(x)
-               v.AddArg(y)
-               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v0.AuxInt = 256
-               v0.AddArg(y)
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+               v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v1.AuxInt = 256
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpRsh32x64_0(v *Value) bool {
-       // match: (Rsh32x64 x (Const64 [c]))
-       // cond: uint64(c) < 32
-       // result: (SRAconst x [c])
+func rewriteValueARM_OpLsh8x64_0(v *Value) bool {
+       // match: (Lsh8x64 x (Const64 [c]))
+       // cond: uint64(c) < 8
+       // result: (SLLconst x [c])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -19102,48 +19620,46 @@ func rewriteValueARM_OpRsh32x64_0(v *Value) bool {
                        break
                }
                c := v_1.AuxInt
-               if !(uint64(c) < 32) {
+               if !(uint64(c) < 8) {
                        break
                }
-               v.reset(OpARMSRAconst)
+               v.reset(OpARMSLLconst)
                v.AuxInt = c
                v.AddArg(x)
                return true
        }
-       // match: (Rsh32x64 x (Const64 [c]))
-       // cond: uint64(c) >= 32
-       // result: (SRAconst x [31])
+       // match: (Lsh8x64 _ (Const64 [c]))
+       // cond: uint64(c) >= 8
+       // result: (Const8 [0])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
                v_1 := v.Args[1]
                if v_1.Op != OpConst64 {
                        break
                }
                c := v_1.AuxInt
-               if !(uint64(c) >= 32) {
+               if !(uint64(c) >= 8) {
                        break
                }
-               v.reset(OpARMSRAconst)
-               v.AuxInt = 31
-               v.AddArg(x)
+               v.reset(OpConst8)
+               v.AuxInt = 0
                return true
        }
        return false
 }
-func rewriteValueARM_OpRsh32x8_0(v *Value) bool {
+func rewriteValueARM_OpLsh8x8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh32x8 x y)
+       // match: (Lsh8x8 x y)
        // cond:
-       // result: (SRA x (ZeroExt8to32 y))
+       // result: (SLL x (ZeroExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRA)
+               v.reset(OpARMSLL)
                v.AddArg(x)
                v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v0.AddArg(y)
@@ -19151,1092 +19667,2411 @@ func rewriteValueARM_OpRsh32x8_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpRsh8Ux16_0(v *Value) bool {
+func rewriteValueARM_OpMod16_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8Ux16 x y)
+       // match: (Mod16 x y)
        // cond:
-       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       // result: (Mod32 (SignExt16to32 x) (SignExt16to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v2.AddArg(y)
-               v0.AddArg(v2)
+               v.reset(OpMod32)
+               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v0.AddArg(x)
                v.AddArg(v0)
-               v3 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v3.AuxInt = 256
-               v4 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v.AddArg(v3)
+               v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpRsh8Ux32_0(v *Value) bool {
+func rewriteValueARM_OpMod16u_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8Ux32 x y)
+       // match: (Mod16u x y)
        // cond:
-       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0])
+       // result: (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMCMOVWHSconst)
-               v.AuxInt = 0
-               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(x)
-               v0.AddArg(v1)
-               v0.AddArg(y)
+               v.reset(OpMod32u)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v0.AddArg(x)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v2.AuxInt = 256
-               v2.AddArg(y)
-               v.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpRsh8Ux64_0(v *Value) bool {
+func rewriteValueARM_OpMod32_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8Ux64 x (Const64 [c]))
-       // cond: uint64(c) < 8
-       // result: (SRLconst (SLLconst <typ.UInt32> x [24]) [c+24])
+       // match: (Mod32 x y)
+       // cond:
+       // result: (SUB (XOR <typ.UInt32>               (Select1 <typ.UInt32> (CALLudiv                         (SUB <typ.UInt32> (XOR <typ.UInt32> x (Signmask x)) (Signmask x))                       (SUB <typ.UInt32> (XOR <typ.UInt32> y (Signmask y)) (Signmask y))))             (Signmask x)) (Signmask x))
        for {
                _ = v.Args[1]
                x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) < 8) {
-                       break
-               }
-               v.reset(OpARMSRLconst)
-               v.AuxInt = c + 24
-               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
-               v0.AuxInt = 24
-               v0.AddArg(x)
+               y := v.Args[1]
+               v.reset(OpARMSUB)
+               v0 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v1 := b.NewValue0(v.Pos, OpSelect1, typ.UInt32)
+               v2 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
+               v3 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
+               v4 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v4.AddArg(x)
+               v5 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v5.AddArg(x)
+               v4.AddArg(v5)
+               v3.AddArg(v4)
+               v6 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v6.AddArg(x)
+               v3.AddArg(v6)
+               v2.AddArg(v3)
+               v7 := b.NewValue0(v.Pos, OpARMSUB, typ.UInt32)
+               v8 := b.NewValue0(v.Pos, OpARMXOR, typ.UInt32)
+               v8.AddArg(y)
+               v9 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v9.AddArg(y)
+               v8.AddArg(v9)
+               v7.AddArg(v8)
+               v10 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v10.AddArg(y)
+               v7.AddArg(v10)
+               v2.AddArg(v7)
+               v1.AddArg(v2)
+               v0.AddArg(v1)
+               v11 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v11.AddArg(x)
+               v0.AddArg(v11)
                v.AddArg(v0)
+               v12 := b.NewValue0(v.Pos, OpSignmask, typ.Int32)
+               v12.AddArg(x)
+               v.AddArg(v12)
                return true
        }
-       // match: (Rsh8Ux64 _ (Const64 [c]))
-       // cond: uint64(c) >= 8
-       // result: (Const8 [0])
-       for {
-               _ = v.Args[1]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) >= 8) {
-                       break
-               }
-               v.reset(OpConst8)
-               v.AuxInt = 0
-               return true
-       }
-       return false
 }
-func rewriteValueARM_OpRsh8Ux8_0(v *Value) bool {
+func rewriteValueARM_OpMod32u_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8Ux8 x y)
+       // match: (Mod32u x y)
        // cond:
-       // result: (SRL (ZeroExt8to32 x) (ZeroExt8to32 y))
+       // result: (Select1 <typ.UInt32> (CALLudiv x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRL)
-               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v.reset(OpSelect1)
+               v.Type = typ.UInt32
+               v0 := b.NewValue0(v.Pos, OpARMCALLudiv, types.NewTuple(typ.UInt32, typ.UInt32))
                v0.AddArg(x)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpRsh8x16_0(v *Value) bool {
+func rewriteValueARM_OpMod8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x16 x y)
+       // match: (Mod8 x y)
        // cond:
-       // result: (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+       // result: (Mod32 (SignExt8to32 x) (SignExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRAcond)
+               v.reset(OpMod32)
                v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
                v1.AddArg(y)
                v.AddArg(v1)
-               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v2.AuxInt = 256
-               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
                return true
        }
 }
-func rewriteValueARM_OpRsh8x32_0(v *Value) bool {
+func rewriteValueARM_OpMod8u_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x32 x y)
+       // match: (Mod8u x y)
        // cond:
-       // result: (SRAcond (SignExt8to32 x) y (CMPconst [256] y))
+       // result: (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSRAcond)
-               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v.reset(OpMod32u)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v0.AddArg(x)
                v.AddArg(v0)
-               v.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-               v1.AuxInt = 256
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
                v1.AddArg(y)
                v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpRsh8x64_0(v *Value) bool {
+func rewriteValueARM_OpMove_0(v *Value) bool {
        b := v.Block
        _ = b
+       config := b.Func.Config
+       _ = config
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x64 x (Const64 [c]))
-       // cond: uint64(c) < 8
-       // result: (SRAconst (SLLconst <typ.UInt32> x [24]) [c+24])
+       // match: (Move [0] _ _ mem)
+       // cond:
+       // result: mem
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(uint64(c) < 8) {
+               if v.AuxInt != 0 {
                        break
                }
-               v.reset(OpARMSRAconst)
-               v.AuxInt = c + 24
-               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
-               v0.AuxInt = 24
-               v0.AddArg(x)
-               v.AddArg(v0)
+               _ = v.Args[2]
+               mem := v.Args[2]
+               v.reset(OpCopy)
+               v.Type = mem.Type
+               v.AddArg(mem)
                return true
        }
-       // match: (Rsh8x64 x (Const64 [c]))
-       // cond: uint64(c) >= 8
-       // result: (SRAconst (SLLconst <typ.UInt32> x [24]) [31])
+       // match: (Move [1] dst src mem)
+       // cond:
+       // result: (MOVBstore dst (MOVBUload src mem) mem)
        for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
+               if v.AuxInt != 1 {
                        break
                }
-               c := v_1.AuxInt
-               if !(uint64(c) >= 8) {
-                       break
-               }
-               v.reset(OpARMSRAconst)
-               v.AuxInt = 31
-               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
-               v0.AuxInt = 24
-               v0.AddArg(x)
-               v.AddArg(v0)
-               return true
-       }
-       return false
-}
-func rewriteValueARM_OpRsh8x8_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Rsh8x8 x y)
-       // cond:
-       // result: (SRA (SignExt8to32 x) (ZeroExt8to32 y))
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMSRA)
-               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-               v0.AddArg(x)
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v0.AddArg(src)
+               v0.AddArg(mem)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-               v1.AddArg(y)
-               v.AddArg(v1)
+               v.AddArg(mem)
                return true
        }
-}
-func rewriteValueARM_OpSelect0_0(v *Value) bool {
-       // match: (Select0 (CALLudiv x (MOVWconst [1])))
-       // cond:
-       // result: x
+       // match: (Move [2] {t} dst src mem)
+       // cond: t.(*types.Type).Alignment()%2 == 0
+       // result: (MOVHstore dst (MOVHUload src mem) mem)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMCALLudiv {
-                       break
-               }
-               _ = v_0.Args[1]
-               x := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               if v_0_1.Op != OpARMMOVWconst {
+               if v.AuxInt != 2 {
                        break
                }
-               if v_0_1.AuxInt != 1 {
+               t := v.Aux
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Alignment()%2 == 0) {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               v.reset(OpARMMOVHstore)
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16)
+               v0.AddArg(src)
+               v0.AddArg(mem)
+               v.AddArg(v0)
+               v.AddArg(mem)
                return true
        }
-       // match: (Select0 (CALLudiv x (MOVWconst [c])))
-       // cond: isPowerOfTwo(c)
-       // result: (SRLconst [log2(c)] x)
+       // match: (Move [2] dst src mem)
+       // cond:
+       // result: (MOVBstore [1] dst (MOVBUload [1] src mem)           (MOVBstore dst (MOVBUload src mem) mem))
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMCALLudiv {
-                       break
-               }
-               _ = v_0.Args[1]
-               x := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               if v_0_1.Op != OpARMMOVWconst {
-                       break
-               }
-               c := v_0_1.AuxInt
-               if !(isPowerOfTwo(c)) {
+               if v.AuxInt != 2 {
                        break
                }
-               v.reset(OpARMSRLconst)
-               v.AuxInt = log2(c)
-               v.AddArg(x)
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = 1
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v0.AuxInt = 1
+               v0.AddArg(src)
+               v0.AddArg(mem)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v1.AddArg(dst)
+               v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v2.AddArg(src)
+               v2.AddArg(mem)
+               v1.AddArg(v2)
+               v1.AddArg(mem)
+               v.AddArg(v1)
                return true
        }
-       // match: (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
-       // cond:
-       // result: (MOVWconst [int64(uint32(c)/uint32(d))])
+       // match: (Move [4] {t} dst src mem)
+       // cond: t.(*types.Type).Alignment()%4 == 0
+       // result: (MOVWstore dst (MOVWload src mem) mem)
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMCALLudiv {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               if v_0_0.Op != OpARMMOVWconst {
+               if v.AuxInt != 4 {
                        break
                }
-               c := v_0_0.AuxInt
-               v_0_1 := v_0.Args[1]
-               if v_0_1.Op != OpARMMOVWconst {
+               t := v.Aux
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Alignment()%4 == 0) {
                        break
                }
-               d := v_0_1.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(uint32(c) / uint32(d))
+               v.reset(OpARMMOVWstore)
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWload, typ.UInt32)
+               v0.AddArg(src)
+               v0.AddArg(mem)
+               v.AddArg(v0)
+               v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM_OpSelect1_0(v *Value) bool {
-       // match: (Select1 (CALLudiv _ (MOVWconst [1])))
-       // cond:
-       // result: (MOVWconst [0])
+       // match: (Move [4] {t} dst src mem)
+       // cond: t.(*types.Type).Alignment()%2 == 0
+       // result: (MOVHstore [2] dst (MOVHUload [2] src mem)           (MOVHstore dst (MOVHUload src mem) mem))
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMCALLudiv {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_1 := v_0.Args[1]
-               if v_0_1.Op != OpARMMOVWconst {
+               if v.AuxInt != 4 {
                        break
                }
-               if v_0_1.AuxInt != 1 {
+               t := v.Aux
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Alignment()%2 == 0) {
                        break
                }
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = 0
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = 2
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16)
+               v0.AuxInt = 2
+               v0.AddArg(src)
+               v0.AddArg(mem)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVHstore, types.TypeMem)
+               v1.AddArg(dst)
+               v2 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16)
+               v2.AddArg(src)
+               v2.AddArg(mem)
+               v1.AddArg(v2)
+               v1.AddArg(mem)
+               v.AddArg(v1)
                return true
        }
-       // match: (Select1 (CALLudiv x (MOVWconst [c])))
-       // cond: isPowerOfTwo(c)
-       // result: (ANDconst [c-1] x)
+       // match: (Move [4] dst src mem)
+       // cond:
+       // result: (MOVBstore [3] dst (MOVBUload [3] src mem)           (MOVBstore [2] dst (MOVBUload [2] src mem)                      (MOVBstore [1] dst (MOVBUload [1] src mem)                              (MOVBstore dst (MOVBUload src mem) mem))))
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMCALLudiv {
-                       break
-               }
-               _ = v_0.Args[1]
-               x := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               if v_0_1.Op != OpARMMOVWconst {
-                       break
-               }
-               c := v_0_1.AuxInt
-               if !(isPowerOfTwo(c)) {
+               if v.AuxInt != 4 {
                        break
                }
-               v.reset(OpARMANDconst)
-               v.AuxInt = c - 1
-               v.AddArg(x)
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = 3
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v0.AuxInt = 3
+               v0.AddArg(src)
+               v0.AddArg(mem)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v1.AuxInt = 2
+               v1.AddArg(dst)
+               v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v2.AuxInt = 2
+               v2.AddArg(src)
+               v2.AddArg(mem)
+               v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v3.AuxInt = 1
+               v3.AddArg(dst)
+               v4 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v4.AuxInt = 1
+               v4.AddArg(src)
+               v4.AddArg(mem)
+               v3.AddArg(v4)
+               v5 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v5.AddArg(dst)
+               v6 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v6.AddArg(src)
+               v6.AddArg(mem)
+               v5.AddArg(v6)
+               v5.AddArg(mem)
+               v3.AddArg(v5)
+               v1.AddArg(v3)
+               v.AddArg(v1)
                return true
        }
-       // match: (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
+       // match: (Move [3] dst src mem)
        // cond:
-       // result: (MOVWconst [int64(uint32(c)%uint32(d))])
+       // result: (MOVBstore [2] dst (MOVBUload [2] src mem)           (MOVBstore [1] dst (MOVBUload [1] src mem)                      (MOVBstore dst (MOVBUload src mem) mem)))
        for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMCALLudiv {
+               if v.AuxInt != 3 {
                        break
                }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               if v_0_0.Op != OpARMMOVWconst {
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = 2
+               v.AddArg(dst)
+               v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v0.AuxInt = 2
+               v0.AddArg(src)
+               v0.AddArg(mem)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v1.AuxInt = 1
+               v1.AddArg(dst)
+               v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v2.AuxInt = 1
+               v2.AddArg(src)
+               v2.AddArg(mem)
+               v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v3.AddArg(dst)
+               v4 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8)
+               v4.AddArg(src)
+               v4.AddArg(mem)
+               v3.AddArg(v4)
+               v3.AddArg(mem)
+               v1.AddArg(v3)
+               v.AddArg(v1)
+               return true
+       }
+       // match: (Move [s] {t} dst src mem)
+       // cond: s%4 == 0 && s > 4 && s <= 512  && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice
+       // result: (DUFFCOPY [8 * (128 - int64(s/4))] dst src mem)
+       for {
+               s := v.AuxInt
+               t := v.Aux
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               if !(s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice) {
                        break
                }
-               c := v_0_0.AuxInt
-               v_0_1 := v_0.Args[1]
-               if v_0_1.Op != OpARMMOVWconst {
+               v.reset(OpARMDUFFCOPY)
+               v.AuxInt = 8 * (128 - int64(s/4))
+               v.AddArg(dst)
+               v.AddArg(src)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Move [s] {t} dst src mem)
+       // cond: (s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0
+       // result: (LoweredMove [t.(*types.Type).Alignment()]           dst             src             (ADDconst <src.Type> src [s-moveSize(t.(*types.Type).Alignment(), config)])             mem)
+       for {
+               s := v.AuxInt
+               t := v.Aux
+               _ = v.Args[2]
+               dst := v.Args[0]
+               src := v.Args[1]
+               mem := v.Args[2]
+               if !((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) {
                        break
                }
-               d := v_0_1.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(uint32(c) % uint32(d))
+               v.reset(OpARMLoweredMove)
+               v.AuxInt = t.(*types.Type).Alignment()
+               v.AddArg(dst)
+               v.AddArg(src)
+               v0 := b.NewValue0(v.Pos, OpARMADDconst, src.Type)
+               v0.AuxInt = s - moveSize(t.(*types.Type).Alignment(), config)
+               v0.AddArg(src)
+               v.AddArg(v0)
+               v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpSignExt16to32_0(v *Value) bool {
-       // match: (SignExt16to32 x)
+func rewriteValueARM_OpMul16_0(v *Value) bool {
+       // match: (Mul16 x y)
        // cond:
-       // result: (MOVHreg x)
+       // result: (MUL x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVHreg)
+               y := v.Args[1]
+               v.reset(OpARMMUL)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpSignExt8to16_0(v *Value) bool {
-       // match: (SignExt8to16 x)
+func rewriteValueARM_OpMul32_0(v *Value) bool {
+       // match: (Mul32 x y)
        // cond:
-       // result: (MOVBreg x)
+       // result: (MUL x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVBreg)
+               y := v.Args[1]
+               v.reset(OpARMMUL)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpSignExt8to32_0(v *Value) bool {
-       // match: (SignExt8to32 x)
+func rewriteValueARM_OpMul32F_0(v *Value) bool {
+       // match: (Mul32F x y)
        // cond:
-       // result: (MOVBreg x)
+       // result: (MULF x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVBreg)
+               y := v.Args[1]
+               v.reset(OpARMMULF)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpSignmask_0(v *Value) bool {
-       // match: (Signmask x)
+func rewriteValueARM_OpMul32uhilo_0(v *Value) bool {
+       // match: (Mul32uhilo x y)
        // cond:
-       // result: (SRAconst x [31])
+       // result: (MULLU x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMSRAconst)
-               v.AuxInt = 31
+               y := v.Args[1]
+               v.reset(OpARMMULLU)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpSlicemask_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       // match: (Slicemask <t> x)
+func rewriteValueARM_OpMul64F_0(v *Value) bool {
+       // match: (Mul64F x y)
        // cond:
-       // result: (SRAconst (RSBconst <t> [0] x) [31])
+       // result: (MULD x y)
        for {
-               t := v.Type
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMSRAconst)
-               v.AuxInt = 31
-               v0 := b.NewValue0(v.Pos, OpARMRSBconst, t)
-               v0.AuxInt = 0
-               v0.AddArg(x)
-               v.AddArg(v0)
+               y := v.Args[1]
+               v.reset(OpARMMULD)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpSqrt_0(v *Value) bool {
-       // match: (Sqrt x)
+func rewriteValueARM_OpMul8_0(v *Value) bool {
+       // match: (Mul8 x y)
        // cond:
-       // result: (SQRTD x)
+       // result: (MUL x y)
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMSQRTD)
+               y := v.Args[1]
+               v.reset(OpARMMUL)
                v.AddArg(x)
+               v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpStaticCall_0(v *Value) bool {
-       // match: (StaticCall [argwid] {target} mem)
+func rewriteValueARM_OpNeg16_0(v *Value) bool {
+       // match: (Neg16 x)
        // cond:
-       // result: (CALLstatic [argwid] {target} mem)
+       // result: (RSBconst [0] x)
        for {
-               argwid := v.AuxInt
-               target := v.Aux
-               mem := v.Args[0]
-               v.reset(OpARMCALLstatic)
-               v.AuxInt = argwid
-               v.Aux = target
-               v.AddArg(mem)
+               x := v.Args[0]
+               v.reset(OpARMRSBconst)
+               v.AuxInt = 0
+               v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpStore_0(v *Value) bool {
-       // match: (Store {t} ptr val mem)
-       // cond: t.(*types.Type).Size() == 1
-       // result: (MOVBstore ptr val mem)
+func rewriteValueARM_OpNeg32_0(v *Value) bool {
+       // match: (Neg32 x)
+       // cond:
+       // result: (RSBconst [0] x)
        for {
-               t := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Size() == 1) {
-                       break
-               }
-               v.reset(OpARMMOVBstore)
-               v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
+               x := v.Args[0]
+               v.reset(OpARMRSBconst)
+               v.AuxInt = 0
+               v.AddArg(x)
                return true
        }
-       // match: (Store {t} ptr val mem)
-       // cond: t.(*types.Type).Size() == 2
-       // result: (MOVHstore ptr val mem)
+}
+func rewriteValueARM_OpNeg32F_0(v *Value) bool {
+       // match: (Neg32F x)
+       // cond:
+       // result: (NEGF x)
        for {
-               t := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Size() == 2) {
-                       break
-               }
-               v.reset(OpARMMOVHstore)
-               v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
+               x := v.Args[0]
+               v.reset(OpARMNEGF)
+               v.AddArg(x)
                return true
        }
-       // match: (Store {t} ptr val mem)
-       // cond: t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type)
-       // result: (MOVWstore ptr val mem)
+}
+func rewriteValueARM_OpNeg64F_0(v *Value) bool {
+       // match: (Neg64F x)
+       // cond:
+       // result: (NEGD x)
        for {
-               t := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type)) {
-                       break
-               }
-               v.reset(OpARMMOVWstore)
-               v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
+               x := v.Args[0]
+               v.reset(OpARMNEGD)
+               v.AddArg(x)
                return true
        }
-       // match: (Store {t} ptr val mem)
-       // cond: t.(*types.Type).Size() == 4 && is32BitFloat(val.Type)
-       // result: (MOVFstore ptr val mem)
+}
+func rewriteValueARM_OpNeg8_0(v *Value) bool {
+       // match: (Neg8 x)
+       // cond:
+       // result: (RSBconst [0] x)
        for {
-               t := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Size() == 4 && is32BitFloat(val.Type)) {
-                       break
-               }
-               v.reset(OpARMMOVFstore)
-               v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Store {t} ptr val mem)
-       // cond: t.(*types.Type).Size() == 8 && is64BitFloat(val.Type)
-       // result: (MOVDstore ptr val mem)
-       for {
-               t := v.Aux
-               _ = v.Args[2]
-               ptr := v.Args[0]
-               val := v.Args[1]
-               mem := v.Args[2]
-               if !(t.(*types.Type).Size() == 8 && is64BitFloat(val.Type)) {
-                       break
-               }
-               v.reset(OpARMMOVDstore)
-               v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
+               x := v.Args[0]
+               v.reset(OpARMRSBconst)
+               v.AuxInt = 0
+               v.AddArg(x)
                return true
        }
-       return false
 }
-func rewriteValueARM_OpSub16_0(v *Value) bool {
-       // match: (Sub16 x y)
+func rewriteValueARM_OpNeq16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Neq16 x y)
        // cond:
-       // result: (SUB x y)
+       // result: (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUB)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpSub32_0(v *Value) bool {
-       // match: (Sub32 x y)
+func rewriteValueARM_OpNeq32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Neq32 x y)
        // cond:
-       // result: (SUB x y)
+       // result: (NotEqual (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUB)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpSub32F_0(v *Value) bool {
-       // match: (Sub32F x y)
+func rewriteValueARM_OpNeq32F_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Neq32F x y)
        // cond:
-       // result: (SUBF x y)
+       // result: (NotEqual (CMPF x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUBF)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPF, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpSub32carry_0(v *Value) bool {
-       // match: (Sub32carry x y)
+func rewriteValueARM_OpNeq64F_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Neq64F x y)
        // cond:
-       // result: (SUBS x y)
+       // result: (NotEqual (CMPD x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUBS)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMPD, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpSub32withcarry_0(v *Value) bool {
-       // match: (Sub32withcarry x y c)
+func rewriteValueARM_OpNeq8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Neq8 x y)
        // cond:
-       // result: (SBC x y c)
+       // result: (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
        for {
-               _ = v.Args[2]
+               _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               c := v.Args[2]
-               v.reset(OpARMSBC)
-               v.AddArg(x)
-               v.AddArg(y)
-               v.AddArg(c)
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpSub64F_0(v *Value) bool {
-       // match: (Sub64F x y)
+func rewriteValueARM_OpNeqB_0(v *Value) bool {
+       // match: (NeqB x y)
        // cond:
-       // result: (SUBD x y)
+       // result: (XOR x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUBD)
+               v.reset(OpARMXOR)
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpSub8_0(v *Value) bool {
-       // match: (Sub8 x y)
+func rewriteValueARM_OpNeqPtr_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (NeqPtr x y)
        // cond:
-       // result: (SUB x y)
+       // result: (NotEqual (CMP x y))
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMSUB)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
-func rewriteValueARM_OpSubPtr_0(v *Value) bool {
-       // match: (SubPtr x y)
+func rewriteValueARM_OpNilCheck_0(v *Value) bool {
+       // match: (NilCheck ptr mem)
        // cond:
-       // result: (SUB x y)
+       // result: (LoweredNilCheck ptr mem)
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               y := v.Args[1]
-               v.reset(OpARMSUB)
-               v.AddArg(x)
-               v.AddArg(y)
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMLoweredNilCheck)
+               v.AddArg(ptr)
+               v.AddArg(mem)
                return true
        }
 }
-func rewriteValueARM_OpTrunc16to8_0(v *Value) bool {
-       // match: (Trunc16to8 x)
+func rewriteValueARM_OpNot_0(v *Value) bool {
+       // match: (Not x)
        // cond:
-       // result: x
+       // result: (XORconst [1] x)
        for {
                x := v.Args[0]
-               v.reset(OpCopy)
-               v.Type = x.Type
+               v.reset(OpARMXORconst)
+               v.AuxInt = 1
                v.AddArg(x)
                return true
        }
 }
-func rewriteValueARM_OpTrunc32to16_0(v *Value) bool {
-       // match: (Trunc32to16 x)
+func rewriteValueARM_OpOffPtr_0(v *Value) bool {
+       // match: (OffPtr [off] ptr:(SP))
        // cond:
-       // result: x
+       // result: (MOVWaddr [off] ptr)
        for {
-               x := v.Args[0]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               off := v.AuxInt
+               ptr := v.Args[0]
+               if ptr.Op != OpSP {
+                       break
+               }
+               v.reset(OpARMMOVWaddr)
+               v.AuxInt = off
+               v.AddArg(ptr)
                return true
        }
-}
-func rewriteValueARM_OpTrunc32to8_0(v *Value) bool {
-       // match: (Trunc32to8 x)
+       // match: (OffPtr [off] ptr)
        // cond:
-       // result: x
+       // result: (ADDconst [off] ptr)
        for {
-               x := v.Args[0]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               off := v.AuxInt
+               ptr := v.Args[0]
+               v.reset(OpARMADDconst)
+               v.AuxInt = off
+               v.AddArg(ptr)
                return true
        }
 }
-func rewriteValueARM_OpXor16_0(v *Value) bool {
-       // match: (Xor16 x y)
+func rewriteValueARM_OpOr16_0(v *Value) bool {
+       // match: (Or16 x y)
        // cond:
-       // result: (XOR x y)
+       // result: (OR x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMXOR)
+               v.reset(OpARMOR)
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpXor32_0(v *Value) bool {
-       // match: (Xor32 x y)
+func rewriteValueARM_OpOr32_0(v *Value) bool {
+       // match: (Or32 x y)
        // cond:
-       // result: (XOR x y)
+       // result: (OR x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMXOR)
+               v.reset(OpARMOR)
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpXor8_0(v *Value) bool {
-       // match: (Xor8 x y)
+func rewriteValueARM_OpOr8_0(v *Value) bool {
+       // match: (Or8 x y)
        // cond:
-       // result: (XOR x y)
+       // result: (OR x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMXOR)
+               v.reset(OpARMOR)
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
 }
-func rewriteValueARM_OpZero_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       config := b.Func.Config
-       _ = config
-       typ := &b.Func.Config.Types
-       _ = typ
-       // match: (Zero [0] _ mem)
+func rewriteValueARM_OpOrB_0(v *Value) bool {
+       // match: (OrB x y)
        // cond:
-       // result: mem
+       // result: (OR x y)
        for {
-               if v.AuxInt != 0 {
-                       break
-               }
                _ = v.Args[1]
-               mem := v.Args[1]
-               v.reset(OpCopy)
-               v.Type = mem.Type
-               v.AddArg(mem)
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMOR)
+               v.AddArg(x)
+               v.AddArg(y)
                return true
        }
-       // match: (Zero [1] ptr mem)
+}
+func rewriteValueARM_OpRound32F_0(v *Value) bool {
+       // match: (Round32F x)
        // cond:
-       // result: (MOVBstore ptr (MOVWconst [0]) mem)
+       // result: x
        for {
-               if v.AuxInt != 1 {
-                       break
-               }
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBstore)
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
-               v.AddArg(v0)
-               v.AddArg(mem)
+               x := v.Args[0]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
                return true
        }
-       // match: (Zero [2] {t} ptr mem)
-       // cond: t.(*types.Type).Alignment()%2 == 0
-       // result: (MOVHstore ptr (MOVWconst [0]) mem)
+}
+func rewriteValueARM_OpRound64F_0(v *Value) bool {
+       // match: (Round64F x)
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh16Ux16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16Ux16 x y)
+       // cond:
+       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
        for {
-               if v.AuxInt != 2 {
-                       break
-               }
-               t := v.Aux
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(t.(*types.Type).Alignment()%2 == 0) {
-                       break
-               }
-               v.reset(OpARMMOVHstore)
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
-               v.AddArg(mem)
+               v3 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v3.AuxInt = 256
+               v4 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v4.AddArg(y)
+               v3.AddArg(v4)
+               v.AddArg(v3)
                return true
        }
-       // match: (Zero [2] ptr mem)
+}
+func rewriteValueARM_OpRsh16Ux32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16Ux32 x y)
        // cond:
-       // result: (MOVBstore [1] ptr (MOVWconst [0])           (MOVBstore [0] ptr (MOVWconst [0]) mem))
+       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0])
        for {
-               if v.AuxInt != 2 {
-                       break
-               }
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = 1
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v1.AuxInt = 0
-               v1.AddArg(ptr)
-               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v2.AuxInt = 0
-               v1.AddArg(v2)
-               v1.AddArg(mem)
-               v.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v2.AuxInt = 256
+               v2.AddArg(y)
+               v.AddArg(v2)
                return true
        }
-       // match: (Zero [4] {t} ptr mem)
-       // cond: t.(*types.Type).Alignment()%4 == 0
-       // result: (MOVWstore ptr (MOVWconst [0]) mem)
+}
+func rewriteValueARM_OpRsh16Ux64_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16Ux64 x (Const64 [c]))
+       // cond: uint64(c) < 16
+       // result: (SRLconst (SLLconst <typ.UInt32> x [16]) [c+16])
        for {
-               if v.AuxInt != 4 {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
                        break
                }
-               t := v.Aux
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(t.(*types.Type).Alignment()%4 == 0) {
+               c := v_1.AuxInt
+               if !(uint64(c) < 16) {
                        break
                }
-               v.reset(OpARMMOVWstore)
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
+               v.reset(OpARMSRLconst)
+               v.AuxInt = c + 16
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
+               v0.AuxInt = 16
+               v0.AddArg(x)
                v.AddArg(v0)
-               v.AddArg(mem)
                return true
        }
-       // match: (Zero [4] {t} ptr mem)
-       // cond: t.(*types.Type).Alignment()%2 == 0
-       // result: (MOVHstore [2] ptr (MOVWconst [0])           (MOVHstore [0] ptr (MOVWconst [0]) mem))
+       // match: (Rsh16Ux64 _ (Const64 [c]))
+       // cond: uint64(c) >= 16
+       // result: (Const16 [0])
        for {
-               if v.AuxInt != 4 {
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
                        break
                }
-               t := v.Aux
-               _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(t.(*types.Type).Alignment()%2 == 0) {
+               c := v_1.AuxInt
+               if !(uint64(c) >= 16) {
                        break
                }
-               v.reset(OpARMMOVHstore)
-               v.AuxInt = 2
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVHstore, types.TypeMem)
-               v1.AuxInt = 0
-               v1.AddArg(ptr)
-               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v2.AuxInt = 0
-               v1.AddArg(v2)
-               v1.AddArg(mem)
-               v.AddArg(v1)
+               v.reset(OpConst16)
+               v.AuxInt = 0
                return true
        }
-       // match: (Zero [4] ptr mem)
+       return false
+}
+func rewriteValueARM_OpRsh16Ux8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16Ux8 x y)
        // cond:
-       // result: (MOVBstore [3] ptr (MOVWconst [0])           (MOVBstore [2] ptr (MOVWconst [0])                      (MOVBstore [1] ptr (MOVWconst [0])                              (MOVBstore [0] ptr (MOVWconst [0]) mem))))
+       // result: (SRL (ZeroExt16to32 x) (ZeroExt8to32 y))
        for {
-               if v.AuxInt != 4 {
-                       break
-               }
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = 3
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRL)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v1.AuxInt = 2
-               v1.AddArg(ptr)
-               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v2.AuxInt = 0
-               v1.AddArg(v2)
-               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v3.AuxInt = 1
-               v3.AddArg(ptr)
-               v4 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v4.AuxInt = 0
-               v3.AddArg(v4)
-               v5 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v5.AuxInt = 0
-               v5.AddArg(ptr)
-               v6 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v6.AuxInt = 0
-               v5.AddArg(v6)
-               v5.AddArg(mem)
-               v3.AddArg(v5)
-               v1.AddArg(v3)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(y)
                v.AddArg(v1)
                return true
        }
-       // match: (Zero [3] ptr mem)
+}
+func rewriteValueARM_OpRsh16x16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16x16 x y)
        // cond:
-       // result: (MOVBstore [2] ptr (MOVWconst [0])           (MOVBstore [1] ptr (MOVWconst [0])                      (MOVBstore [0] ptr (MOVWconst [0]) mem)))
+       // result: (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
        for {
-               if v.AuxInt != 3 {
-                       break
-               }
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVBstore)
-               v.AuxInt = 2
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
-               v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v1.AuxInt = 1
-               v1.AddArg(ptr)
-               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v2.AuxInt = 0
-               v1.AddArg(v2)
-               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
-               v3.AuxInt = 0
-               v3.AddArg(ptr)
-               v4 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v4.AuxInt = 0
-               v3.AddArg(v4)
-               v3.AddArg(mem)
-               v1.AddArg(v3)
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRAcond)
+               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(y)
                v.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v2.AuxInt = 256
+               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v.AddArg(v2)
                return true
        }
-       // match: (Zero [s] {t} ptr mem)
-       // cond: s%4 == 0 && s > 4 && s <= 512  && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice
-       // result: (DUFFZERO [4 * (128 - int64(s/4))] ptr (MOVWconst [0]) mem)
+}
+func rewriteValueARM_OpRsh16x32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16x32 x y)
+       // cond:
+       // result: (SRAcond (SignExt16to32 x) y (CMPconst [256] y))
        for {
-               s := v.AuxInt
-               t := v.Aux
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !(s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice) {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRAcond)
+               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v1.AuxInt = 256
+               v1.AddArg(y)
+               v.AddArg(v1)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh16x64_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16x64 x (Const64 [c]))
+       // cond: uint64(c) < 16
+       // result: (SRAconst (SLLconst <typ.UInt32> x [16]) [c+16])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
                        break
                }
-               v.reset(OpARMDUFFZERO)
-               v.AuxInt = 4 * (128 - int64(s/4))
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v0.AuxInt = 0
+               c := v_1.AuxInt
+               if !(uint64(c) < 16) {
+                       break
+               }
+               v.reset(OpARMSRAconst)
+               v.AuxInt = c + 16
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
+               v0.AuxInt = 16
+               v0.AddArg(x)
                v.AddArg(v0)
-               v.AddArg(mem)
                return true
        }
-       // match: (Zero [s] {t} ptr mem)
-       // cond: (s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0
-       // result: (LoweredZero [t.(*types.Type).Alignment()]           ptr             (ADDconst <ptr.Type> ptr [s-moveSize(t.(*types.Type).Alignment(), config)])             (MOVWconst [0])                 mem)
+       // match: (Rsh16x64 x (Const64 [c]))
+       // cond: uint64(c) >= 16
+       // result: (SRAconst (SLLconst <typ.UInt32> x [16]) [31])
        for {
-               s := v.AuxInt
-               t := v.Aux
                _ = v.Args[1]
-               ptr := v.Args[0]
-               mem := v.Args[1]
-               if !((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
                        break
                }
-               v.reset(OpARMLoweredZero)
-               v.AuxInt = t.(*types.Type).Alignment()
-               v.AddArg(ptr)
-               v0 := b.NewValue0(v.Pos, OpARMADDconst, ptr.Type)
-               v0.AuxInt = s - moveSize(t.(*types.Type).Alignment(), config)
-               v0.AddArg(ptr)
+               c := v_1.AuxInt
+               if !(uint64(c) >= 16) {
+                       break
+               }
+               v.reset(OpARMSRAconst)
+               v.AuxInt = 31
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
+               v0.AuxInt = 16
+               v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
-               v1.AuxInt = 0
-               v.AddArg(v1)
-               v.AddArg(mem)
                return true
        }
        return false
 }
-func rewriteValueARM_OpZeroExt16to32_0(v *Value) bool {
-       // match: (ZeroExt16to32 x)
+func rewriteValueARM_OpRsh16x8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh16x8 x y)
        // cond:
-       // result: (MOVHUreg x)
+       // result: (SRA (SignExt16to32 x) (ZeroExt8to32 y))
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVHUreg)
-               v.AddArg(x)
+               y := v.Args[1]
+               v.reset(OpARMSRA)
+               v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(y)
+               v.AddArg(v1)
                return true
        }
 }
-func rewriteValueARM_OpZeroExt8to16_0(v *Value) bool {
-       // match: (ZeroExt8to16 x)
+func rewriteValueARM_OpRsh32Ux16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh32Ux16 x y)
        // cond:
-       // result: (MOVBUreg x)
+       // result: (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVBUreg)
-               v.AddArg(x)
+               y := v.Args[1]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(y)
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v2.AuxInt = 256
+               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v.AddArg(v2)
                return true
        }
 }
-func rewriteValueARM_OpZeroExt8to32_0(v *Value) bool {
-       // match: (ZeroExt8to32 x)
+func rewriteValueARM_OpRsh32Ux32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Rsh32Ux32 x y)
        // cond:
-       // result: (MOVBUreg x)
+       // result: (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0])
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMMOVBUreg)
+               y := v.Args[1]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v1.AuxInt = 256
+               v1.AddArg(y)
+               v.AddArg(v1)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh32Ux64_0(v *Value) bool {
+       // match: (Rsh32Ux64 x (Const64 [c]))
+       // cond: uint64(c) < 32
+       // result: (SRLconst x [c])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) < 32) {
+                       break
+               }
+               v.reset(OpARMSRLconst)
+               v.AuxInt = c
                v.AddArg(x)
                return true
        }
+       // match: (Rsh32Ux64 _ (Const64 [c]))
+       // cond: uint64(c) >= 32
+       // result: (Const32 [0])
+       for {
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 32) {
+                       break
+               }
+               v.reset(OpConst32)
+               v.AuxInt = 0
+               return true
+       }
+       return false
 }
-func rewriteValueARM_OpZeromask_0(v *Value) bool {
+func rewriteValueARM_OpRsh32Ux8_0(v *Value) bool {
        b := v.Block
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Zeromask x)
+       // match: (Rsh32Ux8 x y)
        // cond:
-       // result: (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31])
+       // result: (SRL x (ZeroExt8to32 y))
        for {
+               _ = v.Args[1]
                x := v.Args[0]
-               v.reset(OpARMSRAconst)
-               v.AuxInt = 31
-               v0 := b.NewValue0(v.Pos, OpARMRSBshiftRL, typ.Int32)
-               v0.AuxInt = 1
-               v0.AddArg(x)
-               v0.AddArg(x)
+               y := v.Args[1]
+               v.reset(OpARMSRL)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
 }
-func rewriteBlockARM(b *Block) bool {
-       config := b.Func.Config
-       _ = config
-       fe := b.Func.fe
-       _ = fe
-       typ := &config.Types
+func rewriteValueARM_OpRsh32x16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
        _ = typ
-       switch b.Kind {
+       // match: (Rsh32x16 x y)
+       // cond:
+       // result: (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRAcond)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v1.AuxInt = 256
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v1.AddArg(v2)
+               v.AddArg(v1)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh32x32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Rsh32x32 x y)
+       // cond:
+       // result: (SRAcond x y (CMPconst [256] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRAcond)
+               v.AddArg(x)
+               v.AddArg(y)
+               v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v0.AuxInt = 256
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh32x64_0(v *Value) bool {
+       // match: (Rsh32x64 x (Const64 [c]))
+       // cond: uint64(c) < 32
+       // result: (SRAconst x [c])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) < 32) {
+                       break
+               }
+               v.reset(OpARMSRAconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (Rsh32x64 x (Const64 [c]))
+       // cond: uint64(c) >= 32
+       // result: (SRAconst x [31])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 32) {
+                       break
+               }
+               v.reset(OpARMSRAconst)
+               v.AuxInt = 31
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpRsh32x8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh32x8 x y)
+       // cond:
+       // result: (SRA x (ZeroExt8to32 y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRA)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh8Ux16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8Ux16 x y)
+       // cond:
+       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v2.AddArg(y)
+               v0.AddArg(v2)
+               v.AddArg(v0)
+               v3 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v3.AuxInt = 256
+               v4 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v4.AddArg(y)
+               v3.AddArg(v4)
+               v.AddArg(v3)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh8Ux32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8Ux32 x y)
+       // cond:
+       // result: (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMCMOVWHSconst)
+               v.AuxInt = 0
+               v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(x)
+               v0.AddArg(v1)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v2.AuxInt = 256
+               v2.AddArg(y)
+               v.AddArg(v2)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh8Ux64_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8Ux64 x (Const64 [c]))
+       // cond: uint64(c) < 8
+       // result: (SRLconst (SLLconst <typ.UInt32> x [24]) [c+24])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) < 8) {
+                       break
+               }
+               v.reset(OpARMSRLconst)
+               v.AuxInt = c + 24
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
+               v0.AuxInt = 24
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Rsh8Ux64 _ (Const64 [c]))
+       // cond: uint64(c) >= 8
+       // result: (Const8 [0])
+       for {
+               _ = v.Args[1]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 8) {
+                       break
+               }
+               v.reset(OpConst8)
+               v.AuxInt = 0
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpRsh8Ux8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8Ux8 x y)
+       // cond:
+       // result: (SRL (ZeroExt8to32 x) (ZeroExt8to32 y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRL)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(y)
+               v.AddArg(v1)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh8x16_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8x16 x y)
+       // cond:
+       // result: (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRAcond)
+               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v1.AddArg(y)
+               v.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v2.AuxInt = 256
+               v3 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v.AddArg(v2)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh8x32_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8x32 x y)
+       // cond:
+       // result: (SRAcond (SignExt8to32 x) y (CMPconst [256] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRAcond)
+               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+               v1.AuxInt = 256
+               v1.AddArg(y)
+               v.AddArg(v1)
+               return true
+       }
+}
+func rewriteValueARM_OpRsh8x64_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8x64 x (Const64 [c]))
+       // cond: uint64(c) < 8
+       // result: (SRAconst (SLLconst <typ.UInt32> x [24]) [c+24])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) < 8) {
+                       break
+               }
+               v.reset(OpARMSRAconst)
+               v.AuxInt = c + 24
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
+               v0.AuxInt = 24
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Rsh8x64 x (Const64 [c]))
+       // cond: uint64(c) >= 8
+       // result: (SRAconst (SLLconst <typ.UInt32> x [24]) [31])
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 8) {
+                       break
+               }
+               v.reset(OpARMSRAconst)
+               v.AuxInt = 31
+               v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32)
+               v0.AuxInt = 24
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpRsh8x8_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh8x8 x y)
+       // cond:
+       // result: (SRA (SignExt8to32 x) (ZeroExt8to32 y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSRA)
+               v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v1.AddArg(y)
+               v.AddArg(v1)
+               return true
+       }
+}
+func rewriteValueARM_OpSelect0_0(v *Value) bool {
+       // match: (Select0 (CALLudiv x (MOVWconst [1])))
+       // cond:
+       // result: x
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMCALLudiv {
+                       break
+               }
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               if v_0_1.AuxInt != 1 {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Select0 (CALLudiv x (MOVWconst [c])))
+       // cond: isPowerOfTwo(c)
+       // result: (SRLconst [log2(c)] x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMCALLudiv {
+                       break
+               }
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_1.AuxInt
+               if !(isPowerOfTwo(c)) {
+                       break
+               }
+               v.reset(OpARMSRLconst)
+               v.AuxInt = log2(c)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
+       // cond:
+       // result: (MOVWconst [int64(uint32(c)/uint32(d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMCALLudiv {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_0.AuxInt
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               d := v_0_1.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(uint32(c) / uint32(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpSelect1_0(v *Value) bool {
+       // match: (Select1 (CALLudiv _ (MOVWconst [1])))
+       // cond:
+       // result: (MOVWconst [0])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMCALLudiv {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               if v_0_1.AuxInt != 1 {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
+               return true
+       }
+       // match: (Select1 (CALLudiv x (MOVWconst [c])))
+       // cond: isPowerOfTwo(c)
+       // result: (ANDconst [c-1] x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMCALLudiv {
+                       break
+               }
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_1.AuxInt
+               if !(isPowerOfTwo(c)) {
+                       break
+               }
+               v.reset(OpARMANDconst)
+               v.AuxInt = c - 1
+               v.AddArg(x)
+               return true
+       }
+       // match: (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
+       // cond:
+       // result: (MOVWconst [int64(uint32(c)%uint32(d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMCALLudiv {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_0.AuxInt
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               d := v_0_1.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(uint32(c) % uint32(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpSignExt16to32_0(v *Value) bool {
+       // match: (SignExt16to32 x)
+       // cond:
+       // result: (MOVHreg x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVHreg)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpSignExt8to16_0(v *Value) bool {
+       // match: (SignExt8to16 x)
+       // cond:
+       // result: (MOVBreg x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVBreg)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpSignExt8to32_0(v *Value) bool {
+       // match: (SignExt8to32 x)
+       // cond:
+       // result: (MOVBreg x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVBreg)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpSignmask_0(v *Value) bool {
+       // match: (Signmask x)
+       // cond:
+       // result: (SRAconst x [31])
+       for {
+               x := v.Args[0]
+               v.reset(OpARMSRAconst)
+               v.AuxInt = 31
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpSlicemask_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       // match: (Slicemask <t> x)
+       // cond:
+       // result: (SRAconst (RSBconst <t> [0] x) [31])
+       for {
+               t := v.Type
+               x := v.Args[0]
+               v.reset(OpARMSRAconst)
+               v.AuxInt = 31
+               v0 := b.NewValue0(v.Pos, OpARMRSBconst, t)
+               v0.AuxInt = 0
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpSqrt_0(v *Value) bool {
+       // match: (Sqrt x)
+       // cond:
+       // result: (SQRTD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMSQRTD)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpStaticCall_0(v *Value) bool {
+       // match: (StaticCall [argwid] {target} mem)
+       // cond:
+       // result: (CALLstatic [argwid] {target} mem)
+       for {
+               argwid := v.AuxInt
+               target := v.Aux
+               mem := v.Args[0]
+               v.reset(OpARMCALLstatic)
+               v.AuxInt = argwid
+               v.Aux = target
+               v.AddArg(mem)
+               return true
+       }
+}
+func rewriteValueARM_OpStore_0(v *Value) bool {
+       // match: (Store {t} ptr val mem)
+       // cond: t.(*types.Type).Size() == 1
+       // result: (MOVBstore ptr val mem)
+       for {
+               t := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Size() == 1) {
+                       break
+               }
+               v.reset(OpARMMOVBstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Store {t} ptr val mem)
+       // cond: t.(*types.Type).Size() == 2
+       // result: (MOVHstore ptr val mem)
+       for {
+               t := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Size() == 2) {
+                       break
+               }
+               v.reset(OpARMMOVHstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Store {t} ptr val mem)
+       // cond: t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type)
+       // result: (MOVWstore ptr val mem)
+       for {
+               t := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type)) {
+                       break
+               }
+               v.reset(OpARMMOVWstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Store {t} ptr val mem)
+       // cond: t.(*types.Type).Size() == 4 && is32BitFloat(val.Type)
+       // result: (MOVFstore ptr val mem)
+       for {
+               t := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Size() == 4 && is32BitFloat(val.Type)) {
+                       break
+               }
+               v.reset(OpARMMOVFstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Store {t} ptr val mem)
+       // cond: t.(*types.Type).Size() == 8 && is64BitFloat(val.Type)
+       // result: (MOVDstore ptr val mem)
+       for {
+               t := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(t.(*types.Type).Size() == 8 && is64BitFloat(val.Type)) {
+                       break
+               }
+               v.reset(OpARMMOVDstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpSub16_0(v *Value) bool {
+       // match: (Sub16 x y)
+       // cond:
+       // result: (SUB x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUB)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpSub32_0(v *Value) bool {
+       // match: (Sub32 x y)
+       // cond:
+       // result: (SUB x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUB)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpSub32F_0(v *Value) bool {
+       // match: (Sub32F x y)
+       // cond:
+       // result: (SUBF x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUBF)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpSub32carry_0(v *Value) bool {
+       // match: (Sub32carry x y)
+       // cond:
+       // result: (SUBS x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUBS)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpSub32withcarry_0(v *Value) bool {
+       // match: (Sub32withcarry x y c)
+       // cond:
+       // result: (SBC x y c)
+       for {
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               c := v.Args[2]
+               v.reset(OpARMSBC)
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(c)
+               return true
+       }
+}
+func rewriteValueARM_OpSub64F_0(v *Value) bool {
+       // match: (Sub64F x y)
+       // cond:
+       // result: (SUBD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUBD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpSub8_0(v *Value) bool {
+       // match: (Sub8 x y)
+       // cond:
+       // result: (SUB x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUB)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpSubPtr_0(v *Value) bool {
+       // match: (SubPtr x y)
+       // cond:
+       // result: (SUB x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUB)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpTrunc16to8_0(v *Value) bool {
+       // match: (Trunc16to8 x)
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpTrunc32to16_0(v *Value) bool {
+       // match: (Trunc32to16 x)
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpTrunc32to8_0(v *Value) bool {
+       // match: (Trunc32to8 x)
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpXor16_0(v *Value) bool {
+       // match: (Xor16 x y)
+       // cond:
+       // result: (XOR x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMXOR)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpXor32_0(v *Value) bool {
+       // match: (Xor32 x y)
+       // cond:
+       // result: (XOR x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMXOR)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpXor8_0(v *Value) bool {
+       // match: (Xor8 x y)
+       // cond:
+       // result: (XOR x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMXOR)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
+func rewriteValueARM_OpZero_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Zero [0] _ mem)
+       // cond:
+       // result: mem
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               _ = v.Args[1]
+               mem := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = mem.Type
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Zero [1] ptr mem)
+       // cond:
+       // result: (MOVBstore ptr (MOVWconst [0]) mem)
+       for {
+               if v.AuxInt != 1 {
+                       break
+               }
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVBstore)
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Zero [2] {t} ptr mem)
+       // cond: t.(*types.Type).Alignment()%2 == 0
+       // result: (MOVHstore ptr (MOVWconst [0]) mem)
+       for {
+               if v.AuxInt != 2 {
+                       break
+               }
+               t := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(t.(*types.Type).Alignment()%2 == 0) {
+                       break
+               }
+               v.reset(OpARMMOVHstore)
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Zero [2] ptr mem)
+       // cond:
+       // result: (MOVBstore [1] ptr (MOVWconst [0])           (MOVBstore [0] ptr (MOVWconst [0]) mem))
+       for {
+               if v.AuxInt != 2 {
+                       break
+               }
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = 1
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v1.AuxInt = 0
+               v1.AddArg(ptr)
+               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v2.AuxInt = 0
+               v1.AddArg(v2)
+               v1.AddArg(mem)
+               v.AddArg(v1)
+               return true
+       }
+       // match: (Zero [4] {t} ptr mem)
+       // cond: t.(*types.Type).Alignment()%4 == 0
+       // result: (MOVWstore ptr (MOVWconst [0]) mem)
+       for {
+               if v.AuxInt != 4 {
+                       break
+               }
+               t := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(t.(*types.Type).Alignment()%4 == 0) {
+                       break
+               }
+               v.reset(OpARMMOVWstore)
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Zero [4] {t} ptr mem)
+       // cond: t.(*types.Type).Alignment()%2 == 0
+       // result: (MOVHstore [2] ptr (MOVWconst [0])           (MOVHstore [0] ptr (MOVWconst [0]) mem))
+       for {
+               if v.AuxInt != 4 {
+                       break
+               }
+               t := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(t.(*types.Type).Alignment()%2 == 0) {
+                       break
+               }
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = 2
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVHstore, types.TypeMem)
+               v1.AuxInt = 0
+               v1.AddArg(ptr)
+               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v2.AuxInt = 0
+               v1.AddArg(v2)
+               v1.AddArg(mem)
+               v.AddArg(v1)
+               return true
+       }
+       // match: (Zero [4] ptr mem)
+       // cond:
+       // result: (MOVBstore [3] ptr (MOVWconst [0])           (MOVBstore [2] ptr (MOVWconst [0])                      (MOVBstore [1] ptr (MOVWconst [0])                              (MOVBstore [0] ptr (MOVWconst [0]) mem))))
+       for {
+               if v.AuxInt != 4 {
+                       break
+               }
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = 3
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v1.AuxInt = 2
+               v1.AddArg(ptr)
+               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v2.AuxInt = 0
+               v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v3.AuxInt = 1
+               v3.AddArg(ptr)
+               v4 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v4.AuxInt = 0
+               v3.AddArg(v4)
+               v5 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v5.AuxInt = 0
+               v5.AddArg(ptr)
+               v6 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v6.AuxInt = 0
+               v5.AddArg(v6)
+               v5.AddArg(mem)
+               v3.AddArg(v5)
+               v1.AddArg(v3)
+               v.AddArg(v1)
+               return true
+       }
+       // match: (Zero [3] ptr mem)
+       // cond:
+       // result: (MOVBstore [2] ptr (MOVWconst [0])           (MOVBstore [1] ptr (MOVWconst [0])                      (MOVBstore [0] ptr (MOVWconst [0]) mem)))
+       for {
+               if v.AuxInt != 3 {
+                       break
+               }
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = 2
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v1.AuxInt = 1
+               v1.AddArg(ptr)
+               v2 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v2.AuxInt = 0
+               v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem)
+               v3.AuxInt = 0
+               v3.AddArg(ptr)
+               v4 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v4.AuxInt = 0
+               v3.AddArg(v4)
+               v3.AddArg(mem)
+               v1.AddArg(v3)
+               v.AddArg(v1)
+               return true
+       }
+       // match: (Zero [s] {t} ptr mem)
+       // cond: s%4 == 0 && s > 4 && s <= 512  && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice
+       // result: (DUFFZERO [4 * (128 - int64(s/4))] ptr (MOVWconst [0]) mem)
+       for {
+               s := v.AuxInt
+               t := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice) {
+                       break
+               }
+               v.reset(OpARMDUFFZERO)
+               v.AuxInt = 4 * (128 - int64(s/4))
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v0.AuxInt = 0
+               v.AddArg(v0)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Zero [s] {t} ptr mem)
+       // cond: (s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0
+       // result: (LoweredZero [t.(*types.Type).Alignment()]           ptr             (ADDconst <ptr.Type> ptr [s-moveSize(t.(*types.Type).Alignment(), config)])             (MOVWconst [0])                 mem)
+       for {
+               s := v.AuxInt
+               t := v.Aux
+               _ = v.Args[1]
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) {
+                       break
+               }
+               v.reset(OpARMLoweredZero)
+               v.AuxInt = t.(*types.Type).Alignment()
+               v.AddArg(ptr)
+               v0 := b.NewValue0(v.Pos, OpARMADDconst, ptr.Type)
+               v0.AuxInt = s - moveSize(t.(*types.Type).Alignment(), config)
+               v0.AddArg(ptr)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32)
+               v1.AuxInt = 0
+               v.AddArg(v1)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpZeroExt16to32_0(v *Value) bool {
+       // match: (ZeroExt16to32 x)
+       // cond:
+       // result: (MOVHUreg x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVHUreg)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpZeroExt8to16_0(v *Value) bool {
+       // match: (ZeroExt8to16 x)
+       // cond:
+       // result: (MOVBUreg x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVBUreg)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpZeroExt8to32_0(v *Value) bool {
+       // match: (ZeroExt8to32 x)
+       // cond:
+       // result: (MOVBUreg x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVBUreg)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpZeromask_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Zeromask x)
+       // cond:
+       // result: (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31])
+       for {
+               x := v.Args[0]
+               v.reset(OpARMSRAconst)
+               v.AuxInt = 31
+               v0 := b.NewValue0(v.Pos, OpARMRSBshiftRL, typ.Int32)
+               v0.AuxInt = 1
+               v0.AddArg(x)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteBlockARM(b *Block) bool {
+       config := b.Func.Config
+       _ = config
+       fe := b.Func.fe
+       _ = fe
+       typ := &config.Types
+       _ = typ
+       switch b.Kind {
        case BlockARMEQ:
                // match: (EQ (FlagEQ) yes no)
                // cond:
@@ -20251,9 +22086,1290 @@ func rewriteBlockARM(b *Block) bool {
                        b.Aux = nil
                        return true
                }
-               // match: (EQ (FlagLT_ULT) yes no)
+               // match: (EQ (FlagLT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (EQ (FlagLT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (EQ (FlagGT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (EQ (FlagGT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (EQ (InvertFlags cmp) yes no)
+               // cond:
+               // result: (EQ cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMEQ
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUB x y)) yes no)
+               // cond:
+               // result: (EQ (CMP x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUB {
+                               break
+                       }
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBconst [c] x)) yes no)
+               // cond:
+               // result: (EQ (CMPconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBconst {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBshiftLL x y [c])) yes no)
+               // cond:
+               // result: (EQ (CMPshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftLL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBshiftRL x y [c])) yes no)
+               // cond:
+               // result: (EQ (CMPshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBshiftRA x y [c])) yes no)
+               // cond:
+               // result: (EQ (CMPshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (CMPshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (CMPshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (SUBshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (EQ (CMPshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADD x y)) yes no)
+               // cond:
+               // result: (EQ (CMN x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADD {
+                               break
+                       }
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDconst [c] x)) yes no)
+               // cond:
+               // result: (EQ (CMNconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDconst {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (EQ (CMNshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftLL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (EQ (CMNshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (EQ (CMNshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (CMNshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (CMNshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ADDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (EQ (CMNshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (AND x y)) yes no)
+               // cond:
+               // result: (EQ (TST x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMAND {
+                               break
+                       }
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDconst [c] x)) yes no)
+               // cond:
+               // result: (EQ (TSTconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDconst {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (EQ (TSTshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDshiftLL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (EQ (TSTshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (EQ (TSTshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (TSTshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (TSTshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (ANDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (EQ (TSTshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMANDshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XOR x y)) yes no)
+               // cond:
+               // result: (EQ (TEQ x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXOR {
+                               break
+                       }
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORconst [c] x)) yes no)
+               // cond:
+               // result: (EQ (TEQconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORconst {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORshiftLL x y [c])) yes no)
+               // cond:
+               // result: (EQ (TEQshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftLL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORshiftRL x y [c])) yes no)
+               // cond:
+               // result: (EQ (TEQshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORshiftRA x y [c])) yes no)
+               // cond:
+               // result: (EQ (TEQshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (TEQshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (EQ (TEQshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (EQ (CMPconst [0] (XORshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (EQ (TEQshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMEQ
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockARMGE:
+               // match: (GE (FlagEQ) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagEQ {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (FlagLT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GE (FlagLT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GE (FlagGT_ULT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (FlagGT_UGT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (InvertFlags cmp) yes no)
+               // cond:
+               // result: (LE cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMLE
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockARMGT:
+               // match: (GT (FlagEQ) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagEQ {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GT (FlagLT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GT (FlagLT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GT (FlagGT_ULT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (FlagGT_UGT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (InvertFlags cmp) yes no)
+               // cond:
+               // result: (LT cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMLT
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockIf:
+               // match: (If (Equal cc) yes no)
+               // cond:
+               // result: (EQ cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMEQ
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (NotEqual cc) yes no)
+               // cond:
+               // result: (NE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMNotEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMNE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessThan cc) yes no)
+               // cond:
+               // result: (LT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessThan {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMLT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessThanU cc) yes no)
+               // cond:
+               // result: (ULT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessThanU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMULT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessEqual cc) yes no)
+               // cond:
+               // result: (LE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMLE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessEqualU cc) yes no)
+               // cond:
+               // result: (ULE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessEqualU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMULE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterThan cc) yes no)
+               // cond:
+               // result: (GT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterThan {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMGT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterThanU cc) yes no)
+               // cond:
+               // result: (UGT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterThanU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMUGT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterEqual cc) yes no)
+               // cond:
+               // result: (GE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMGE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterEqualU cc) yes no)
+               // cond:
+               // result: (UGE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterEqualU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMUGE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If cond yes no)
+               // cond:
+               // result: (NE (CMPconst [0] cond) yes no)
+               for {
+                       v := b.Control
+                       _ = v
+                       cond := b.Control
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = 0
+                       v0.AddArg(cond)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockARMLE:
+               // match: (LE (FlagEQ) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagEQ {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (FlagLT_ULT) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (First nil yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagLT_ULT {
@@ -20262,12 +23378,11 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (EQ (FlagLT_UGT) yes no)
+               // match: (LE (FlagLT_UGT) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (First nil yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagLT_UGT {
@@ -20276,10 +23391,9 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (EQ (FlagGT_ULT) yes no)
+               // match: (LE (FlagGT_ULT) yes no)
                // cond:
                // result: (First nil no yes)
                for {
@@ -20293,7 +23407,7 @@ func rewriteBlockARM(b *Block) bool {
                        b.swapSuccessors()
                        return true
                }
-               // match: (EQ (FlagGT_UGT) yes no)
+               // match: (LE (FlagGT_UGT) yes no)
                // cond:
                // result: (First nil no yes)
                for {
@@ -20307,24 +23421,24 @@ func rewriteBlockARM(b *Block) bool {
                        b.swapSuccessors()
                        return true
                }
-               // match: (EQ (InvertFlags cmp) yes no)
+               // match: (LE (InvertFlags cmp) yes no)
                // cond:
-               // result: (EQ cmp yes no)
+               // result: (GE cmp yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMInvertFlags {
                                break
                        }
                        cmp := v.Args[0]
-                       b.Kind = BlockARMEQ
+                       b.Kind = BlockARMGE
                        b.SetControl(cmp)
                        b.Aux = nil
                        return true
                }
-       case BlockARMGE:
-               // match: (GE (FlagEQ) yes no)
+       case BlockARMLT:
+               // match: (LT (FlagEQ) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (First nil no yes)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagEQ {
@@ -20333,11 +23447,12 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
+                       b.swapSuccessors()
                        return true
                }
-               // match: (GE (FlagLT_ULT) yes no)
+               // match: (LT (FlagLT_ULT) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (First nil yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagLT_ULT {
@@ -20346,12 +23461,11 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GE (FlagLT_UGT) yes no)
+               // match: (LT (FlagLT_UGT) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (First nil yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagLT_UGT {
@@ -20360,12 +23474,11 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GE (FlagGT_ULT) yes no)
+               // match: (LT (FlagGT_ULT) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (First nil no yes)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagGT_ULT {
@@ -20374,11 +23487,12 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
+                       b.swapSuccessors()
                        return true
                }
-               // match: (GE (FlagGT_UGT) yes no)
+               // match: (LT (FlagGT_UGT) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (First nil no yes)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagGT_UGT {
@@ -20387,24 +23501,235 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
+                       b.swapSuccessors()
                        return true
                }
-               // match: (GE (InvertFlags cmp) yes no)
+               // match: (LT (InvertFlags cmp) yes no)
+               // cond:
+               // result: (GT cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMGT
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockARMNE:
+               // match: (NE (CMPconst [0] (Equal cc)) yes no)
+               // cond:
+               // result: (EQ cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMEqual {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMEQ
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (NotEqual cc)) yes no)
+               // cond:
+               // result: (NE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMNotEqual {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMNE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (LessThan cc)) yes no)
+               // cond:
+               // result: (LT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMLessThan {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMLT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (LessThanU cc)) yes no)
+               // cond:
+               // result: (ULT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMLessThanU {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMULT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (LessEqual cc)) yes no)
+               // cond:
+               // result: (LE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMLessEqual {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMLE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (LessEqualU cc)) yes no)
+               // cond:
+               // result: (ULE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMLessEqualU {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMULE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (GreaterThan cc)) yes no)
+               // cond:
+               // result: (GT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMGreaterThan {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMGT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (GreaterThanU cc)) yes no)
+               // cond:
+               // result: (UGT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMGreaterThanU {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMUGT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (GreaterEqual cc)) yes no)
+               // cond:
+               // result: (GE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMGreaterEqual {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMGE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (NE (CMPconst [0] (GreaterEqualU cc)) yes no)
                // cond:
-               // result: (LE cmp yes no)
+               // result: (UGE cc yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
-                       b.Kind = BlockARMLE
-                       b.SetControl(cmp)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMGreaterEqualU {
+                               break
+                       }
+                       cc := v_0.Args[0]
+                       b.Kind = BlockARMUGE
+                       b.SetControl(cc)
                        b.Aux = nil
                        return true
                }
-       case BlockARMGT:
-               // match: (GT (FlagEQ) yes no)
+               // match: (NE (FlagEQ) yes no)
                // cond:
                // result: (First nil no yes)
                for {
@@ -20418,9 +23743,9 @@ func rewriteBlockARM(b *Block) bool {
                        b.swapSuccessors()
                        return true
                }
-               // match: (GT (FlagLT_ULT) yes no)
+               // match: (NE (FlagLT_ULT) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (First nil yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagLT_ULT {
@@ -20429,12 +23754,11 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GT (FlagLT_UGT) yes no)
+               // match: (NE (FlagLT_UGT) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (First nil yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMFlagLT_UGT {
@@ -20443,10 +23767,9 @@ func rewriteBlockARM(b *Block) bool {
                        b.Kind = BlockFirst
                        b.SetControl(nil)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GT (FlagGT_ULT) yes no)
+               // match: (NE (FlagGT_ULT) yes no)
                // cond:
                // result: (First nil yes no)
                for {
@@ -20459,7 +23782,7 @@ func rewriteBlockARM(b *Block) bool {
                        b.Aux = nil
                        return true
                }
-               // match: (GT (FlagGT_UGT) yes no)
+               // match: (NE (FlagGT_UGT) yes no)
                // cond:
                // result: (First nil yes no)
                for {
@@ -20472,345 +23795,461 @@ func rewriteBlockARM(b *Block) bool {
                        b.Aux = nil
                        return true
                }
-               // match: (GT (InvertFlags cmp) yes no)
+               // match: (NE (InvertFlags cmp) yes no)
                // cond:
-               // result: (LT cmp yes no)
+               // result: (NE cmp yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMInvertFlags {
                                break
                        }
                        cmp := v.Args[0]
-                       b.Kind = BlockARMLT
+                       b.Kind = BlockARMNE
                        b.SetControl(cmp)
                        b.Aux = nil
                        return true
                }
-       case BlockIf:
-               // match: (If (Equal cc) yes no)
+               // match: (NE (CMPconst [0] (SUB x y)) yes no)
                // cond:
-               // result: (EQ cc yes no)
+               // result: (NE (CMP x y) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMEqual {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMEQ
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If (NotEqual cc) yes no)
-               // cond:
-               // result: (NE cc yes no)
-               for {
-                       v := b.Control
-                       if v.Op != OpARMNotEqual {
+                       if v.AuxInt != 0 {
                                break
                        }
-                       cc := v.Args[0]
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUB {
+                               break
+                       }
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
                        b.Kind = BlockARMNE
-                       b.SetControl(cc)
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (LessThan cc) yes no)
+               // match: (NE (CMPconst [0] (SUBconst [c] x)) yes no)
                // cond:
-               // result: (LT cc yes no)
+               // result: (NE (CMPconst [c] x) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMLessThan {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMLT
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If (LessThanU cc) yes no)
-               // cond:
-               // result: (ULT cc yes no)
-               for {
-                       v := b.Control
-                       if v.Op != OpARMLessThanU {
+                       if v.AuxInt != 0 {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMULT
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If (LessEqual cc) yes no)
-               // cond:
-               // result: (LE cc yes no)
-               for {
-                       v := b.Control
-                       if v.Op != OpARMLessEqual {
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMLE
-                       b.SetControl(cc)
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (LessEqualU cc) yes no)
+               // match: (NE (CMPconst [0] (SUBshiftLL x y [c])) yes no)
                // cond:
-               // result: (ULE cc yes no)
+               // result: (NE (CMPshiftLL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMLessEqualU {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMULE
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If (GreaterThan cc) yes no)
-               // cond:
-               // result: (GT cc yes no)
-               for {
-                       v := b.Control
-                       if v.Op != OpARMGreaterThan {
+                       if v.AuxInt != 0 {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMGT
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If (GreaterThanU cc) yes no)
-               // cond:
-               // result: (UGT cc yes no)
-               for {
-                       v := b.Control
-                       if v.Op != OpARMGreaterThanU {
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftLL {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMUGT
-                       b.SetControl(cc)
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (GreaterEqual cc) yes no)
+               // match: (NE (CMPconst [0] (SUBshiftRL x y [c])) yes no)
                // cond:
-               // result: (GE cc yes no)
+               // result: (NE (CMPshiftRL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMGreaterEqual {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMGE
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If (GreaterEqualU cc) yes no)
-               // cond:
-               // result: (UGE cc yes no)
-               for {
-                       v := b.Control
-                       if v.Op != OpARMGreaterEqualU {
+                       if v.AuxInt != 0 {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMUGE
-                       b.SetControl(cc)
-                       b.Aux = nil
-                       return true
-               }
-               // match: (If cond yes no)
-               // cond:
-               // result: (NE (CMPconst [0] cond) yes no)
-               for {
-                       v := b.Control
-                       _ = v
-                       cond := b.Control
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
                        b.Kind = BlockARMNE
-                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-                       v0.AuxInt = 0
-                       v0.AddArg(cond)
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
                        b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-       case BlockARMLE:
-               // match: (LE (FlagEQ) yes no)
+               // match: (NE (CMPconst [0] (SUBshiftRA x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (CMPshiftRA x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagEQ {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LE (FlagLT_ULT) yes no)
+               // match: (NE (CMPconst [0] (SUBshiftLLreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (CMPshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LE (FlagLT_UGT) yes no)
+               // match: (NE (CMPconst [0] (SUBshiftRLreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (CMPshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LE (FlagGT_ULT) yes no)
+               // match: (NE (CMPconst [0] (SUBshiftRAreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (NE (CMPshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMSUBshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LE (FlagGT_UGT) yes no)
+               // match: (NE (CMPconst [0] (ADD x y)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (NE (CMN x y) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADD {
+                               break
+                       }
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LE (InvertFlags cmp) yes no)
+               // match: (NE (CMPconst [0] (ADDconst [c] x)) yes no)
                // cond:
-               // result: (GE cmp yes no)
+               // result: (NE (CMNconst [c] x) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
-                       b.Kind = BlockARMGE
-                       b.SetControl(cmp)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDconst {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-       case BlockARMLT:
-               // match: (LT (FlagEQ) yes no)
+               // match: (NE (CMPconst [0] (ADDshiftLL x y [c])) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (NE (CMNshiftLL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagEQ {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftLL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LT (FlagLT_ULT) yes no)
+               // match: (NE (CMPconst [0] (ADDshiftRL x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (CMNshiftRL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LT (FlagLT_UGT) yes no)
+               // match: (NE (CMPconst [0] (ADDshiftRA x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (CMNshiftRA x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LT (FlagGT_ULT) yes no)
+               // match: (NE (CMPconst [0] (ADDshiftLLreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (NE (CMNshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LT (FlagGT_UGT) yes no)
+               // match: (NE (CMPconst [0] (ADDshiftRLreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (NE (CMNshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LT (InvertFlags cmp) yes no)
+               // match: (NE (CMPconst [0] (ADDshiftRAreg x y z)) yes no)
                // cond:
-               // result: (GT cmp yes no)
+               // result: (NE (CMNshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
-                       b.Kind = BlockARMGT
-                       b.SetControl(cmp)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMADDshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-       case BlockARMNE:
-               // match: (NE (CMPconst [0] (Equal cc)) yes no)
+               // match: (NE (CMPconst [0] (AND x y)) yes no)
                // cond:
-               // result: (EQ cc yes no)
+               // result: (NE (TST x y) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20820,18 +24259,23 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMEqual {
+                       if v_0.Op != OpARMAND {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMEQ
-                       b.SetControl(cc)
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (NotEqual cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDconst [c] x)) yes no)
                // cond:
-               // result: (NE cc yes no)
+               // result: (NE (TSTconst [c] x) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20841,18 +24285,22 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMNotEqual {
+                       if v_0.Op != OpARMANDconst {
                                break
                        }
-                       cc := v_0.Args[0]
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
                        b.Kind = BlockARMNE
-                       b.SetControl(cc)
+                       v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (LessThan cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDshiftLL x y [c])) yes no)
                // cond:
-               // result: (LT cc yes no)
+               // result: (NE (TSTshiftLL x y [c]) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20862,18 +24310,25 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMLessThan {
+                       if v_0.Op != OpARMANDshiftLL {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMLT
-                       b.SetControl(cc)
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (LessThanU cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDshiftRL x y [c])) yes no)
                // cond:
-               // result: (ULT cc yes no)
+               // result: (NE (TSTshiftRL x y [c]) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20883,18 +24338,25 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMLessThanU {
+                       if v_0.Op != OpARMANDshiftRL {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMULT
-                       b.SetControl(cc)
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (LessEqual cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDshiftRA x y [c])) yes no)
                // cond:
-               // result: (LE cc yes no)
+               // result: (NE (TSTshiftRA x y [c]) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20904,18 +24366,25 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMLessEqual {
+                       if v_0.Op != OpARMANDshiftRA {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMLE
-                       b.SetControl(cc)
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (LessEqualU cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDshiftLLreg x y z)) yes no)
                // cond:
-               // result: (ULE cc yes no)
+               // result: (NE (TSTshiftLLreg x y z) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20925,18 +24394,25 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMLessEqualU {
+                       if v_0.Op != OpARMANDshiftLLreg {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMULE
-                       b.SetControl(cc)
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (GreaterThan cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDshiftRLreg x y z)) yes no)
                // cond:
-               // result: (GT cc yes no)
+               // result: (NE (TSTshiftRLreg x y z) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20946,18 +24422,25 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMGreaterThan {
+                       if v_0.Op != OpARMANDshiftRLreg {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMGT
-                       b.SetControl(cc)
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (GreaterThanU cc)) yes no)
+               // match: (NE (CMPconst [0] (ANDshiftRAreg x y z)) yes no)
                // cond:
-               // result: (UGT cc yes no)
+               // result: (NE (TSTshiftRAreg x y z) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20967,18 +24450,25 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMGreaterThanU {
+                       if v_0.Op != OpARMANDshiftRAreg {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMUGT
-                       b.SetControl(cc)
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (GreaterEqual cc)) yes no)
+               // match: (NE (CMPconst [0] (XOR x y)) yes no)
                // cond:
-               // result: (GE cc yes no)
+               // result: (NE (TEQ x y) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -20988,18 +24478,23 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMGreaterEqual {
+                       if v_0.Op != OpARMXOR {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMGE
-                       b.SetControl(cc)
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (CMPconst [0] (GreaterEqualU cc)) yes no)
+               // match: (NE (CMPconst [0] (XORconst [c] x)) yes no)
                // cond:
-               // result: (UGE cc yes no)
+               // result: (NE (TEQconst [c] x) yes no)
                for {
                        v := b.Control
                        if v.Op != OpARMCMPconst {
@@ -21009,92 +24504,184 @@ func rewriteBlockARM(b *Block) bool {
                                break
                        }
                        v_0 := v.Args[0]
-                       if v_0.Op != OpARMGreaterEqualU {
+                       if v_0.Op != OpARMXORconst {
                                break
                        }
-                       cc := v_0.Args[0]
-                       b.Kind = BlockARMUGE
-                       b.SetControl(cc)
+                       c := v_0.AuxInt
+                       x := v_0.Args[0]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (FlagEQ) yes no)
+               // match: (NE (CMPconst [0] (XORshiftLL x y [c])) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (NE (TEQshiftLL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagEQ {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftLL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (NE (FlagLT_ULT) yes no)
+               // match: (NE (CMPconst [0] (XORshiftRL x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (TEQshiftRL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRL {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (FlagLT_UGT) yes no)
+               // match: (NE (CMPconst [0] (XORshiftRA x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (TEQshiftRA x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRA {
+                               break
+                       }
+                       c := v_0.AuxInt
+                       _ = v_0.Args[1]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (FlagGT_ULT) yes no)
+               // match: (NE (CMPconst [0] (XORshiftLLreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (TEQshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftLLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (FlagGT_UGT) yes no)
+               // match: (NE (CMPconst [0] (XORshiftRLreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (NE (TEQshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRLreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (NE (InvertFlags cmp) yes no)
+               // match: (NE (CMPconst [0] (XORshiftRAreg x y z)) yes no)
                // cond:
-               // result: (NE cmp yes no)
+               // result: (NE (TEQshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMXORshiftRAreg {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       z := v_0.Args[2]
                        b.Kind = BlockARMNE
-                       b.SetControl(cmp)
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }