Text file src/cmd/compile/internal/ssa/_gen/ARM.rules

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  (Add(Ptr|32|16|8) ...) => (ADD ...)
     6  (Add(32|64)F ...) => (ADD(F|D) ...)
     7  (Add32carry ...) => (ADDS ...)
     8  (Add32withcarry ...) => (ADC ...)
     9  (Add32carrywithcarry ...) => (ADCS ...)
    10  
    11  (Sub(Ptr|32|16|8) ...) => (SUB ...)
    12  (Sub(32|64)F ...) => (SUB(F|D) ...)
    13  (Sub32carry ...) => (SUBS ...)
    14  (Sub32withcarry ...) => (SBC ...)
    15  
    16  (Mul(32|16|8) ...) => (MUL ...)
    17  (Mul(32|64)F ...) => (MUL(F|D) ...)
    18  (Hmul(32|32u) ...) => (HMU(L|LU) ...)
    19  (Mul32uhilo ...) => (MULLU ...)
    20  
    21  (Div32 x y) =>
    22  	(SUB (XOR <typ.UInt32>                                                        // negate the result if one operand is negative
    23  		(Select0 <typ.UInt32> (CALLudiv
    24  			(SUB <typ.UInt32> (XOR x <typ.UInt32> (Signmask x)) (Signmask x))   // negate x if negative
    25  			(SUB <typ.UInt32> (XOR y <typ.UInt32> (Signmask y)) (Signmask y)))) // negate y if negative
    26  		(Signmask (XOR <typ.UInt32> x y))) (Signmask (XOR <typ.UInt32> x y)))
    27  (Div32u x y) => (Select0 <typ.UInt32> (CALLudiv x y))
    28  (Div16 x y) => (Div32 (SignExt16to32 x) (SignExt16to32 y))
    29  (Div16u x y) => (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
    30  (Div8 x y) => (Div32 (SignExt8to32 x) (SignExt8to32 y))
    31  (Div8u x y) => (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
    32  (Div(32|64)F ...) => (DIV(F|D) ...)
    33  
    34  (Mod32 x y) =>
    35  	(SUB (XOR <typ.UInt32>                                                        // negate the result if x is negative
    36  		(Select1 <typ.UInt32> (CALLudiv
    37  			(SUB <typ.UInt32> (XOR <typ.UInt32> x (Signmask x)) (Signmask x))   // negate x if negative
    38  			(SUB <typ.UInt32> (XOR <typ.UInt32> y (Signmask y)) (Signmask y)))) // negate y if negative
    39  		(Signmask x)) (Signmask x))
    40  (Mod32u x y) => (Select1 <typ.UInt32> (CALLudiv x y))
    41  (Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y))
    42  (Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
    43  (Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y))
    44  (Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
    45  
    46  // (x + y) / 2 with x>=y -> (x - y) / 2 + y
    47  (Avg32u <t> x y) => (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
    48  
    49  (And(32|16|8) ...) => (AND ...)
    50  (Or(32|16|8) ...) => (OR ...)
    51  (Xor(32|16|8) ...) => (XOR ...)
    52  
    53  // unary ops
    54  (Neg(32|16|8) x) => (RSBconst [0] x)
    55  (Neg(32|64)F ...) => (NEG(F|D) ...)
    56  
    57  (Com(32|16|8) ...) => (MVN ...)
    58  
    59  (Sqrt ...) => (SQRTD ...)
    60  (Sqrt32 ...) => (SQRTF ...)
    61  (Abs ...) => (ABSD ...)
    62  
    63  // TODO: optimize this for ARMv5 and ARMv6
    64  (Ctz32NonZero ...) => (Ctz32 ...)
    65  (Ctz16NonZero ...) => (Ctz32 ...)
    66  (Ctz8NonZero ...) => (Ctz32 ...)
    67  
    68  // count trailing zero for ARMv5 and ARMv6
    69  // 32 - CLZ(x&-x - 1)
    70  (Ctz32 <t> x) && buildcfg.GOARM.Version<=6 =>
    71  	(RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
    72  (Ctz16 <t> x) && buildcfg.GOARM.Version<=6 =>
    73  	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
    74  (Ctz8 <t> x) && buildcfg.GOARM.Version<=6 =>
    75  	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
    76  
    77  // count trailing zero for ARMv7
    78  (Ctz32 <t> x) && buildcfg.GOARM.Version==7 => (CLZ <t> (RBIT <t> x))
    79  (Ctz16 <t> x) && buildcfg.GOARM.Version==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
    80  (Ctz8 <t> x) && buildcfg.GOARM.Version==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
    81  
    82  // bit length
    83  (BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x))
    84  (BitLen(16|8) x) => (BitLen32 (ZeroExt(16|8)to32 x))
    85  
    86  // byte swap for ARMv5
    87  // let (a, b, c, d) be the bytes of x from high to low
    88  // t1 = x right rotate 16 bits -- (c,   d,   a,   b  )
    89  // t2 = x ^ t1                 -- (a^c, b^d, a^c, b^d)
    90  // t3 = t2 &^ 0xff0000         -- (a^c, 0,   a^c, b^d)
    91  // t4 = t3 >> 8                -- (0,   a^c, 0,   a^c)
    92  // t5 = x right rotate 8 bits  -- (d,   a,   b,   c  )
    93  // result = t4 ^ t5            -- (d,   c,   b,   a  )
    94  // using shifted ops this can be done in 4 instructions.
    95  (Bswap32 <t> x) && buildcfg.GOARM.Version==5 =>
    96  	(XOR <t>
    97  		(SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])
    98  		(SRRconst <t> x [8]))
    99  
   100  // byte swap for ARMv6 and above
   101  (Bswap32 x) && buildcfg.GOARM.Version>=6 => (REV x)
   102  
   103  // boolean ops -- booleans are represented with 0=false, 1=true
   104  (AndB ...) => (AND ...)
   105  (OrB ...) => (OR ...)
   106  (EqB x y) => (XORconst [1] (XOR <typ.Bool> x y))
   107  (NeqB ...) => (XOR ...)
   108  (Not x) => (XORconst [1] x)
   109  
   110  // shifts
   111  // hardware instruction uses only the low byte of the shift
   112  // we compare to 256 to ensure Go semantics for large shifts
   113  (Lsh32x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
   114  (Lsh32x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
   115  (Lsh32x8  x y) => (SLL x (ZeroExt8to32 y))
   116  
   117  (Lsh16x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
   118  (Lsh16x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
   119  (Lsh16x8  x y) => (SLL x (ZeroExt8to32 y))
   120  
   121  (Lsh8x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
   122  (Lsh8x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
   123  (Lsh8x8  x y) => (SLL x (ZeroExt8to32 y))
   124  
   125  (Rsh32Ux32 x y) => (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0])
   126  (Rsh32Ux16 x y) => (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
   127  (Rsh32Ux8  x y) => (SRL x (ZeroExt8to32 y))
   128  
   129  (Rsh16Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0])
   130  (Rsh16Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
   131  (Rsh16Ux8  x y) => (SRL (ZeroExt16to32 x) (ZeroExt8to32 y))
   132  
   133  (Rsh8Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0])
   134  (Rsh8Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
   135  (Rsh8Ux8  x y) => (SRL (ZeroExt8to32 x) (ZeroExt8to32 y))
   136  
   137  (Rsh32x32 x y) => (SRAcond x y (CMPconst [256] y))
   138  (Rsh32x16 x y) => (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
   139  (Rsh32x8  x y) => (SRA x (ZeroExt8to32 y))
   140  
   141  (Rsh16x32 x y) => (SRAcond (SignExt16to32 x) y (CMPconst [256] y))
   142  (Rsh16x16 x y) => (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
   143  (Rsh16x8  x y) => (SRA (SignExt16to32 x) (ZeroExt8to32 y))
   144  
   145  (Rsh8x32 x y) => (SRAcond (SignExt8to32 x) y (CMPconst [256] y))
   146  (Rsh8x16 x y) => (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
   147  (Rsh8x8  x y) => (SRA (SignExt8to32 x) (ZeroExt8to32 y))
   148  
   149  // constant shifts
   150  // generic opt rewrites all constant shifts to shift by Const64
   151  (Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SLLconst x [int32(c)])
   152  (Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SRAconst x [int32(c)])
   153  (Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SRLconst x [int32(c)])
   154  (Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SLLconst x [int32(c)])
   155  (Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)])
   156  (Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SRLconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)])
   157  (Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SLLconst x [int32(c)])
   158  (Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)])
   159  (Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SRLconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)])
   160  
   161  // large constant shifts
   162  (Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
   163  (Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
   164  (Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
   165  (Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
   166  (Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
   167  (Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
   168  
   169  // large constant signed right shift, we leave the sign bit
   170  (Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SRAconst x [31])
   171  (Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [31])
   172  (Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [31])
   173  
   174  // constants
   175  (Const(8|16|32) [val]) => (MOVWconst [int32(val)])
   176  (Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
   177  (ConstNil) => (MOVWconst [0])
   178  (ConstBool [t]) => (MOVWconst [b2i32(t)])
   179  
   180  // truncations
   181  // Because we ignore high parts of registers, truncates are just copies.
   182  (Trunc16to8 ...) => (Copy ...)
   183  (Trunc32to8 ...) => (Copy ...)
   184  (Trunc32to16 ...) => (Copy ...)
   185  
   186  // Zero-/Sign-extensions
   187  (ZeroExt8to16 ...) => (MOVBUreg ...)
   188  (ZeroExt8to32 ...) => (MOVBUreg ...)
   189  (ZeroExt16to32 ...) => (MOVHUreg ...)
   190  
   191  (SignExt8to16 ...) => (MOVBreg ...)
   192  (SignExt8to32 ...) => (MOVBreg ...)
   193  (SignExt16to32 ...) => (MOVHreg ...)
   194  
   195  (Signmask x) => (SRAconst x [31])
   196  (Zeromask x) => (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31]) // sign bit of uint32(x)>>1 - x
   197  (Slicemask <t> x) => (SRAconst (RSBconst <t> [0] x) [31])
   198  
   199  // float <-> int conversion
   200  (Cvt32to32F ...) => (MOVWF ...)
   201  (Cvt32to64F ...) => (MOVWD ...)
   202  (Cvt32Uto32F ...) => (MOVWUF ...)
   203  (Cvt32Uto64F ...) => (MOVWUD ...)
   204  (Cvt32Fto32 ...) => (MOVFW ...)
   205  (Cvt64Fto32 ...) => (MOVDW ...)
   206  (Cvt32Fto32U ...) => (MOVFWU ...)
   207  (Cvt64Fto32U ...) => (MOVDWU ...)
   208  (Cvt32Fto64F ...) => (MOVFD ...)
   209  (Cvt64Fto32F ...) => (MOVDF ...)
   210  
   211  (Round(32|64)F ...) => (Copy ...)
   212  
   213  (CvtBoolToUint8 ...) => (Copy ...)
   214  
   215  // fused-multiply-add
   216  (FMA x y z) => (FMULAD z x y)
   217  
   218  // comparisons
   219  (Eq8 x y)  => (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
   220  (Eq16 x y) => (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
   221  (Eq32 x y) => (Equal (CMP x y))
   222  (EqPtr x y) => (Equal (CMP x y))
   223  (Eq(32|64)F x y) => (Equal (CMP(F|D) x y))
   224  
   225  (Neq8 x y)  => (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
   226  (Neq16 x y) => (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
   227  (Neq32 x y) => (NotEqual (CMP x y))
   228  (NeqPtr x y) => (NotEqual (CMP x y))
   229  (Neq(32|64)F x y) => (NotEqual (CMP(F|D) x y))
   230  
   231  (Less8 x y)  => (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
   232  (Less16 x y) => (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
   233  (Less32 x y) => (LessThan (CMP x y))
   234  (Less(32|64)F x y) => (GreaterThan (CMP(F|D) y x)) // reverse operands to work around NaN
   235  
   236  (Less8U x y)  => (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
   237  (Less16U x y) => (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
   238  (Less32U x y) => (LessThanU (CMP x y))
   239  
   240  (Leq8 x y)  => (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
   241  (Leq16 x y) => (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
   242  (Leq32 x y) => (LessEqual (CMP x y))
   243  (Leq(32|64)F x y) => (GreaterEqual (CMP(F|D) y x)) // reverse operands to work around NaN
   244  
   245  (Leq8U x y)  => (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
   246  (Leq16U x y) => (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
   247  (Leq32U x y) => (LessEqualU (CMP x y))
   248  
   249  (OffPtr [off] ptr:(SP)) => (MOVWaddr [int32(off)] ptr)
   250  (OffPtr [off] ptr) => (ADDconst [int32(off)] ptr)
   251  
   252  (Addr {sym} base) => (MOVWaddr {sym} base)
   253  (LocalAddr <t> {sym} base mem) && t.Elem().HasPointers() => (MOVWaddr {sym} (SPanchored base mem))
   254  (LocalAddr <t> {sym} base _)  && !t.Elem().HasPointers() => (MOVWaddr {sym} base)
   255  
   256  // loads
   257  (Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
   258  (Load <t> ptr mem) && (is8BitInt(t)  &&  t.IsSigned()) => (MOVBload ptr mem)
   259  (Load <t> ptr mem) && (is8BitInt(t)  && !t.IsSigned()) => (MOVBUload ptr mem)
   260  (Load <t> ptr mem) && (is16BitInt(t) &&  t.IsSigned()) => (MOVHload ptr mem)
   261  (Load <t> ptr mem) && (is16BitInt(t) && !t.IsSigned()) => (MOVHUload ptr mem)
   262  (Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) => (MOVWload ptr mem)
   263  (Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
   264  (Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
   265  
   266  // stores
   267  (Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
   268  (Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
   269  (Store {t} ptr val mem) && t.Size() == 4 && !t.IsFloat() => (MOVWstore ptr val mem)
   270  (Store {t} ptr val mem) && t.Size() == 4 &&  t.IsFloat() => (MOVFstore ptr val mem)
   271  (Store {t} ptr val mem) && t.Size() == 8 &&  t.IsFloat() => (MOVDstore ptr val mem)
   272  
   273  // zero instructions
   274  (Zero [0] _ mem) => mem
   275  (Zero [1] ptr mem) => (MOVBstore ptr (MOVWconst [0]) mem)
   276  (Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
   277  	(MOVHstore ptr (MOVWconst [0]) mem)
   278  (Zero [2] ptr mem) =>
   279  	(MOVBstore [1] ptr (MOVWconst [0])
   280  		(MOVBstore [0] ptr (MOVWconst [0]) mem))
   281  (Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
   282  	(MOVWstore ptr (MOVWconst [0]) mem)
   283  (Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
   284  	(MOVHstore [2] ptr (MOVWconst [0])
   285  		(MOVHstore [0] ptr (MOVWconst [0]) mem))
   286  (Zero [4] ptr mem) =>
   287  	(MOVBstore [3] ptr (MOVWconst [0])
   288  		(MOVBstore [2] ptr (MOVWconst [0])
   289  			(MOVBstore [1] ptr (MOVWconst [0])
   290  				(MOVBstore [0] ptr (MOVWconst [0]) mem))))
   291  
   292  (Zero [3] ptr mem) =>
   293  	(MOVBstore [2] ptr (MOVWconst [0])
   294  		(MOVBstore [1] ptr (MOVWconst [0])
   295  			(MOVBstore [0] ptr (MOVWconst [0]) mem)))
   296  
   297  // Medium zeroing uses a duff device
   298  // 4 and 128 are magic constants, see runtime/mkduff.go
   299  (Zero [s] {t} ptr mem)
   300  	&& s%4 == 0 && s > 4 && s <= 512
   301  	&& t.Alignment()%4 == 0 =>
   302  	(DUFFZERO [4 * (128 - s/4)] ptr (MOVWconst [0]) mem)
   303  
   304  // Large zeroing uses a loop
   305  (Zero [s] {t} ptr mem)
   306  	&& s > 512 || t.Alignment()%4 != 0 =>
   307  	(LoweredZero [t.Alignment()]
   308  		ptr
   309  		(ADDconst <ptr.Type> ptr [int32(s-moveSize(t.Alignment(), config))])
   310  		(MOVWconst [0])
   311  		mem)
   312  
   313  // moves
   314  (Move [0] _ _ mem) => mem
   315  (Move [1] dst src mem) => (MOVBstore dst (MOVBUload src mem) mem)
   316  (Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
   317  	(MOVHstore dst (MOVHUload src mem) mem)
   318  (Move [2] dst src mem) =>
   319  	(MOVBstore [1] dst (MOVBUload [1] src mem)
   320  		(MOVBstore dst (MOVBUload src mem) mem))
   321  (Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
   322  	(MOVWstore dst (MOVWload src mem) mem)
   323  (Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
   324  	(MOVHstore [2] dst (MOVHUload [2] src mem)
   325  		(MOVHstore dst (MOVHUload src mem) mem))
   326  (Move [4] dst src mem) =>
   327  	(MOVBstore [3] dst (MOVBUload [3] src mem)
   328  		(MOVBstore [2] dst (MOVBUload [2] src mem)
   329  			(MOVBstore [1] dst (MOVBUload [1] src mem)
   330  				(MOVBstore dst (MOVBUload src mem) mem))))
   331  
   332  (Move [3] dst src mem) =>
   333  	(MOVBstore [2] dst (MOVBUload [2] src mem)
   334  		(MOVBstore [1] dst (MOVBUload [1] src mem)
   335  			(MOVBstore dst (MOVBUload src mem) mem)))
   336  
   337  // Medium move uses a duff device
   338  // 8 and 128 are magic constants, see runtime/mkduff.go
   339  (Move [s] {t} dst src mem)
   340  	&& s%4 == 0 && s > 4 && s <= 512
   341  	&& t.Alignment()%4 == 0 && logLargeCopy(v, s) =>
   342  	(DUFFCOPY [8 * (128 - s/4)] dst src mem)
   343  
   344  // Large move uses a loop
   345  (Move [s] {t} dst src mem)
   346  	&& (s > 512 || t.Alignment()%4 != 0) && logLargeCopy(v, s) =>
   347  	(LoweredMove [t.Alignment()]
   348  		dst
   349  		src
   350  		(ADDconst <src.Type> src [int32(s-moveSize(t.Alignment(), config))])
   351  		mem)
   352  
   353  // calls
   354  (StaticCall ...) => (CALLstatic ...)
   355  (ClosureCall ...) => (CALLclosure ...)
   356  (InterCall ...) => (CALLinter ...)
   357  (TailCall ...) => (CALLtail ...)
   358  
   359  // checks
   360  (NilCheck ...) => (LoweredNilCheck ...)
   361  (IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
   362  (IsInBounds idx len) => (LessThanU (CMP idx len))
   363  (IsSliceInBounds idx len) => (LessEqualU (CMP idx len))
   364  
   365  // pseudo-ops
   366  (GetClosurePtr ...) => (LoweredGetClosurePtr ...)
   367  (GetCallerSP ...) => (LoweredGetCallerSP ...)
   368  (GetCallerPC ...) => (LoweredGetCallerPC ...)
   369  
   370  // Absorb pseudo-ops into blocks.
   371  (If (Equal cc) yes no) => (EQ cc yes no)
   372  (If (NotEqual cc) yes no) => (NE cc yes no)
   373  (If (LessThan cc) yes no) => (LT cc yes no)
   374  (If (LessThanU cc) yes no) => (ULT cc yes no)
   375  (If (LessEqual cc) yes no) => (LE cc yes no)
   376  (If (LessEqualU cc) yes no) => (ULE cc yes no)
   377  (If (GreaterThan cc) yes no) => (GT cc yes no)
   378  (If (GreaterThanU cc) yes no) => (UGT cc yes no)
   379  (If (GreaterEqual cc) yes no) => (GE cc yes no)
   380  (If (GreaterEqualU cc) yes no) => (UGE cc yes no)
   381  
   382  (If cond yes no) => (NE (CMPconst [0] cond) yes no)
   383  
   384  // Absorb boolean tests into block
   385  (NE (CMPconst [0] (Equal cc)) yes no) => (EQ cc yes no)
   386  (NE (CMPconst [0] (NotEqual cc)) yes no) => (NE cc yes no)
   387  (NE (CMPconst [0] (LessThan cc)) yes no) => (LT cc yes no)
   388  (NE (CMPconst [0] (LessThanU cc)) yes no) => (ULT cc yes no)
   389  (NE (CMPconst [0] (LessEqual cc)) yes no) => (LE cc yes no)
   390  (NE (CMPconst [0] (LessEqualU cc)) yes no) => (ULE cc yes no)
   391  (NE (CMPconst [0] (GreaterThan cc)) yes no) => (GT cc yes no)
   392  (NE (CMPconst [0] (GreaterThanU cc)) yes no) => (UGT cc yes no)
   393  (NE (CMPconst [0] (GreaterEqual cc)) yes no) => (GE cc yes no)
   394  (NE (CMPconst [0] (GreaterEqualU cc)) yes no) => (UGE cc yes no)
   395  
   396  // Write barrier.
   397  (WB ...) => (LoweredWB ...)
   398  
   399  (PanicBounds ...) => (LoweredPanicBoundsRR ...)
   400  (PanicExtend ...) => (LoweredPanicExtendRR ...)
   401  
   402  (LoweredPanicBoundsRR [kind] x (MOVWconst [c]) mem) => (LoweredPanicBoundsRC [kind] x {PanicBoundsC{C:int64(c)}} mem)
   403  (LoweredPanicBoundsRR [kind] (MOVWconst [c]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(c)}} y mem)
   404  (LoweredPanicBoundsRC [kind] {p} (MOVWconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(c), Cy:p.C}} mem)
   405  
   406  (LoweredPanicExtendRR [kind] hi lo (MOVWconst [c]) mem) => (LoweredPanicExtendRC [kind] hi lo {PanicBoundsC{C:int64(c)}} mem)
   407  (LoweredPanicExtendRR [kind] (MOVWconst [hi]) (MOVWconst [lo]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(hi)<<32 + int64(uint32(lo))}} y mem)
   408  (LoweredPanicExtendRC [kind] {p} (MOVWconst [hi]) (MOVWconst [lo]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(hi)<<32+int64(uint32(lo)), Cy:p.C}} mem)
   409  
   410  // Optimizations
   411  
   412  // fold offset into address
   413  (ADDconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off1+off2] {sym} ptr)
   414  (SUBconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off2-off1] {sym} ptr)
   415  
   416  // fold address into load/store
   417  (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBload [off1+off2] {sym} ptr mem)
   418  (MOVBload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBload [off1-off2] {sym} ptr mem)
   419  (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBUload [off1+off2] {sym} ptr mem)
   420  (MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBUload [off1-off2] {sym} ptr mem)
   421  (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHload [off1+off2] {sym} ptr mem)
   422  (MOVHload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHload [off1-off2] {sym} ptr mem)
   423  (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHUload [off1+off2] {sym} ptr mem)
   424  (MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHUload [off1-off2] {sym} ptr mem)
   425  (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVWload [off1+off2] {sym} ptr mem)
   426  (MOVWload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVWload [off1-off2] {sym} ptr mem)
   427  (MOVFload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVFload [off1+off2] {sym} ptr mem)
   428  (MOVFload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVFload [off1-off2] {sym} ptr mem)
   429  (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVDload [off1+off2] {sym} ptr mem)
   430  (MOVDload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVDload [off1-off2] {sym} ptr mem)
   431  
   432  (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVBstore [off1+off2] {sym} ptr val mem)
   433  (MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVBstore [off1-off2] {sym} ptr val mem)
   434  (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVHstore [off1+off2] {sym} ptr val mem)
   435  (MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVHstore [off1-off2] {sym} ptr val mem)
   436  (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVWstore [off1+off2] {sym} ptr val mem)
   437  (MOVWstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVWstore [off1-off2] {sym} ptr val mem)
   438  (MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVFstore [off1+off2] {sym} ptr val mem)
   439  (MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVFstore [off1-off2] {sym} ptr val mem)
   440  (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVDstore [off1+off2] {sym} ptr val mem)
   441  (MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVDstore [off1-off2] {sym} ptr val mem)
   442  
   443  (MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   444  	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   445  (MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   446  	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   447  (MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   448  	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   449  (MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   450  	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   451  (MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   452  	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   453  (MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   454  	(MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   455  (MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
   456  	(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
   457  
   458  (MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
   459  	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
   460  (MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
   461  	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
   462  (MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
   463  	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
   464  (MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
   465  	(MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
   466  (MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
   467  	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
   468  
   469  // replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
   470  (MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBreg x)
   471  (MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBUreg x)
   472  (MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHreg x)
   473  (MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHUreg x)
   474  (MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
   475  
   476  (MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
   477  (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
   478  
   479  (MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => x
   480  (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
   481  (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
   482  (MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
   483  (MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBUreg x)
   484  (MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBreg x)
   485  (MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHUreg x)
   486  (MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHreg x)
   487  
   488  // fold constant into arithmetic ops
   489  (ADD x (MOVWconst <t> [c])) && !t.IsPtr() => (ADDconst [c] x)
   490  (SUB (MOVWconst [c]) x) => (RSBconst [c] x)
   491  (SUB x (MOVWconst [c])) => (SUBconst [c] x)
   492  (RSB (MOVWconst [c]) x) => (SUBconst [c] x)
   493  (RSB x (MOVWconst [c])) => (RSBconst [c] x)
   494  
   495  (ADDS x (MOVWconst [c])) => (ADDSconst [c] x)
   496  (SUBS x (MOVWconst [c])) => (SUBSconst [c] x)
   497  
   498  (ADC (MOVWconst [c]) x flags) => (ADCconst [c] x flags)
   499  (SBC (MOVWconst [c]) x flags) => (RSCconst [c] x flags)
   500  (SBC x (MOVWconst [c]) flags) => (SBCconst [c] x flags)
   501  
   502  (AND x (MOVWconst [c])) => (ANDconst [c] x)
   503  (OR  x (MOVWconst [c])) => (ORconst [c] x)
   504  (XOR x (MOVWconst [c])) => (XORconst [c] x)
   505  (BIC x (MOVWconst [c])) => (BICconst [c] x)
   506  
   507  (SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
   508  (SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
   509  (SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
   510  
   511  (CMP x (MOVWconst [c])) => (CMPconst [c] x)
   512  (CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
   513  (CMN x (MOVWconst [c])) => (CMNconst [c] x)
   514  (TST x (MOVWconst [c])) => (TSTconst [c] x)
   515  (TEQ x (MOVWconst [c])) => (TEQconst [c] x)
   516  
   517  (SRR x (MOVWconst [c])) => (SRRconst x [c&31])
   518  
   519  // Canonicalize the order of arguments to comparisons - helps with CSE.
   520  (CMP x y) && canonLessThan(x,y) => (InvertFlags (CMP y x))
   521  
   522  // don't extend after proper load
   523  // MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type.
   524  (MOVBreg x:(MOVBload _ _)) => (MOVWreg x)
   525  (MOVBUreg x:(MOVBUload _ _)) => (MOVWreg x)
   526  (MOVHreg x:(MOVBload _ _)) => (MOVWreg x)
   527  (MOVHreg x:(MOVBUload _ _)) => (MOVWreg x)
   528  (MOVHreg x:(MOVHload _ _)) => (MOVWreg x)
   529  (MOVHUreg x:(MOVBUload _ _)) => (MOVWreg x)
   530  (MOVHUreg x:(MOVHUload _ _)) => (MOVWreg x)
   531  
   532  // fold extensions and ANDs together
   533  (MOVBUreg (ANDconst [c] x)) => (ANDconst [c&0xff] x)
   534  (MOVHUreg (ANDconst [c] x)) => (ANDconst [c&0xffff] x)
   535  (MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 => (ANDconst [c&0x7f] x)
   536  (MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 => (ANDconst [c&0x7fff] x)
   537  
   538  // fold double extensions
   539  (MOVBreg x:(MOVBreg _)) => (MOVWreg x)
   540  (MOVBUreg x:(MOVBUreg _)) => (MOVWreg x)
   541  (MOVHreg x:(MOVBreg _)) => (MOVWreg x)
   542  (MOVHreg x:(MOVBUreg _)) => (MOVWreg x)
   543  (MOVHreg x:(MOVHreg _)) => (MOVWreg x)
   544  (MOVHUreg x:(MOVBUreg _)) => (MOVWreg x)
   545  (MOVHUreg x:(MOVHUreg _)) => (MOVWreg x)
   546  
   547  // don't extend before store
   548  (MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
   549  (MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
   550  (MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
   551  (MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
   552  (MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
   553  (MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
   554  
   555  // if a register move has only 1 use, just use the same register without emitting instruction
   556  // MOVWnop doesn't emit instruction, only for ensuring the type.
   557  (MOVWreg x) && x.Uses == 1 => (MOVWnop x)
   558  
   559  // TODO: we should be able to get rid of MOVWnop all together.
   560  // But for now, this is enough to get rid of lots of them.
   561  (MOVWnop (MOVWconst [c])) => (MOVWconst [c])
   562  
   563  // mul by constant
   564  (MUL x (MOVWconst [c])) && int32(c) == -1 => (RSBconst [0] x)
   565  (MUL _ (MOVWconst [0])) => (MOVWconst [0])
   566  (MUL x (MOVWconst [1])) => x
   567  (MUL x (MOVWconst [c])) && isPowerOfTwo(c) => (SLLconst [int32(log32(c))] x)
   568  (MUL x (MOVWconst [c])) && isPowerOfTwo(c-1) && c >= 3 => (ADDshiftLL x x [int32(log32(c-1))])
   569  (MUL x (MOVWconst [c])) && isPowerOfTwo(c+1) && c >= 7 => (RSBshiftLL x x [int32(log32(c+1))])
   570  (MUL x (MOVWconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) => (SLLconst [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1]))
   571  (MUL x (MOVWconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) => (SLLconst [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2]))
   572  (MUL x (MOVWconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) => (SLLconst [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3]))
   573  (MUL x (MOVWconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) => (SLLconst [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3]))
   574  
   575  (MULA x (MOVWconst [c]) a) && c == -1 => (SUB a x)
   576  (MULA _ (MOVWconst [0]) a) => a
   577  (MULA x (MOVWconst [1]) a) => (ADD x a)
   578  (MULA x (MOVWconst [c]) a) && isPowerOfTwo(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a)
   579  (MULA x (MOVWconst [c]) a) && isPowerOfTwo(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
   580  (MULA x (MOVWconst [c]) a) && isPowerOfTwo(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
   581  (MULA x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
   582  (MULA x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
   583  (MULA x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
   584  (MULA x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
   585  
   586  (MULA (MOVWconst [c]) x a) && c == -1 => (SUB a x)
   587  (MULA (MOVWconst [0]) _ a) => a
   588  (MULA (MOVWconst [1]) x a) => (ADD x a)
   589  (MULA (MOVWconst [c]) x a) && isPowerOfTwo(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a)
   590  (MULA (MOVWconst [c]) x a) && isPowerOfTwo(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
   591  (MULA (MOVWconst [c]) x a) && isPowerOfTwo(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
   592  (MULA (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
   593  (MULA (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
   594  (MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
   595  (MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
   596  
   597  (MULS x (MOVWconst [c]) a) && c == -1 => (ADD a x)
   598  (MULS _ (MOVWconst [0]) a) => a
   599  (MULS x (MOVWconst [1]) a) => (RSB x a)
   600  (MULS x (MOVWconst [c]) a) && isPowerOfTwo(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a)
   601  (MULS x (MOVWconst [c]) a) && isPowerOfTwo(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
   602  (MULS x (MOVWconst [c]) a) && isPowerOfTwo(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
   603  (MULS x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
   604  (MULS x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
   605  (MULS x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
   606  (MULS x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
   607  
   608  (MULS (MOVWconst [c]) x a) && c == -1 => (ADD a x)
   609  (MULS (MOVWconst [0]) _ a) => a
   610  (MULS (MOVWconst [1]) x a) => (RSB x a)
   611  (MULS (MOVWconst [c]) x a) && isPowerOfTwo(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a)
   612  (MULS (MOVWconst [c]) x a) && isPowerOfTwo(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
   613  (MULS (MOVWconst [c]) x a) && isPowerOfTwo(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
   614  (MULS (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
   615  (MULS (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
   616  (MULS (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
   617  (MULS (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
   618  
   619  // div by constant
   620  (Select0 (CALLudiv x (MOVWconst [1]))) => x
   621  (Select1 (CALLudiv _ (MOVWconst [1]))) => (MOVWconst [0])
   622  (Select0 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo(c) => (SRLconst [int32(log32(c))] x)
   623  (Select1 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo(c) => (ANDconst [c-1] x)
   624  
   625  // constant comparisons
   626  (CMPconst (MOVWconst [x]) [y]) => (FlagConstant [subFlags32(x,y)])
   627  (CMNconst (MOVWconst [x]) [y]) => (FlagConstant [addFlags32(x,y)])
   628  (TSTconst (MOVWconst [x]) [y]) => (FlagConstant [logicFlags32(x&y)])
   629  (TEQconst (MOVWconst [x]) [y]) => (FlagConstant [logicFlags32(x^y)])
   630  
   631  // other known comparisons
   632  (CMPconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags32(0, 1)])
   633  (CMPconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags32(0, 1)])
   634  (CMPconst (ANDconst _ [m]) [n]) && 0 <= m && m < n => (FlagConstant [subFlags32(0, 1)])
   635  (CMPconst (SRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n) => (FlagConstant [subFlags32(0, 1)])
   636  
   637  // absorb flag constants into branches
   638  (EQ (FlagConstant [fc]) yes no) &&  fc.eq() => (First yes no)
   639  (EQ (FlagConstant [fc]) yes no) && !fc.eq() => (First no yes)
   640  
   641  (NE (FlagConstant [fc]) yes no) &&  fc.ne() => (First yes no)
   642  (NE (FlagConstant [fc]) yes no) && !fc.ne() => (First no yes)
   643  
   644  (LT (FlagConstant [fc]) yes no) &&  fc.lt() => (First yes no)
   645  (LT (FlagConstant [fc]) yes no) && !fc.lt() => (First no yes)
   646  
   647  (LE (FlagConstant [fc]) yes no) &&  fc.le() => (First yes no)
   648  (LE (FlagConstant [fc]) yes no) && !fc.le() => (First no yes)
   649  
   650  (GT (FlagConstant [fc]) yes no) &&  fc.gt() => (First yes no)
   651  (GT (FlagConstant [fc]) yes no) && !fc.gt() => (First no yes)
   652  
   653  (GE (FlagConstant [fc]) yes no) &&  fc.ge() => (First yes no)
   654  (GE (FlagConstant [fc]) yes no) && !fc.ge() => (First no yes)
   655  
   656  (ULT (FlagConstant [fc]) yes no) &&  fc.ult() => (First yes no)
   657  (ULT (FlagConstant [fc]) yes no) && !fc.ult() => (First no yes)
   658  
   659  (ULE (FlagConstant [fc]) yes no) &&  fc.ule() => (First yes no)
   660  (ULE (FlagConstant [fc]) yes no) && !fc.ule() => (First no yes)
   661  
   662  (UGT (FlagConstant [fc]) yes no) &&  fc.ugt() => (First yes no)
   663  (UGT (FlagConstant [fc]) yes no) && !fc.ugt() => (First no yes)
   664  
   665  (UGE (FlagConstant [fc]) yes no) &&  fc.uge() => (First yes no)
   666  (UGE (FlagConstant [fc]) yes no) && !fc.uge() => (First no yes)
   667  
   668  (LTnoov (FlagConstant [fc]) yes no) &&  fc.ltNoov() => (First yes no)
   669  (LTnoov (FlagConstant [fc]) yes no) && !fc.ltNoov() => (First no yes)
   670  
   671  (LEnoov (FlagConstant [fc]) yes no) &&  fc.leNoov() => (First yes no)
   672  (LEnoov (FlagConstant [fc]) yes no) && !fc.leNoov() => (First no yes)
   673  
   674  (GTnoov (FlagConstant [fc]) yes no) &&  fc.gtNoov() => (First yes no)
   675  (GTnoov (FlagConstant [fc]) yes no) && !fc.gtNoov() => (First no yes)
   676  
   677  (GEnoov (FlagConstant [fc]) yes no) &&  fc.geNoov() => (First yes no)
   678  (GEnoov (FlagConstant [fc]) yes no) && !fc.geNoov() => (First no yes)
   679  
   680  // absorb InvertFlags into branches
   681  (LT (InvertFlags cmp) yes no) => (GT cmp yes no)
   682  (GT (InvertFlags cmp) yes no) => (LT cmp yes no)
   683  (LE (InvertFlags cmp) yes no) => (GE cmp yes no)
   684  (GE (InvertFlags cmp) yes no) => (LE cmp yes no)
   685  (ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
   686  (UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
   687  (ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
   688  (UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
   689  (EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
   690  (NE (InvertFlags cmp) yes no) => (NE cmp yes no)
   691  (LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no)
   692  (GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no)
   693  (LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
   694  (GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
   695  
   696  // absorb flag constants into boolean values
   697  (Equal (FlagConstant [fc])) => (MOVWconst [b2i32(fc.eq())])
   698  (NotEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ne())])
   699  (LessThan (FlagConstant [fc])) => (MOVWconst [b2i32(fc.lt())])
   700  (LessThanU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ult())])
   701  (LessEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.le())])
   702  (LessEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ule())])
   703  (GreaterThan (FlagConstant [fc])) => (MOVWconst [b2i32(fc.gt())])
   704  (GreaterThanU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ugt())])
   705  (GreaterEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ge())])
   706  (GreaterEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.uge())])
   707  
   708  // absorb InvertFlags into boolean values
   709  (Equal (InvertFlags x)) => (Equal x)
   710  (NotEqual (InvertFlags x)) => (NotEqual x)
   711  (LessThan (InvertFlags x)) => (GreaterThan x)
   712  (LessThanU (InvertFlags x)) => (GreaterThanU x)
   713  (GreaterThan (InvertFlags x)) => (LessThan x)
   714  (GreaterThanU (InvertFlags x)) => (LessThanU x)
   715  (LessEqual (InvertFlags x)) => (GreaterEqual x)
   716  (LessEqualU (InvertFlags x)) => (GreaterEqualU x)
   717  (GreaterEqual (InvertFlags x)) => (LessEqual x)
   718  (GreaterEqualU (InvertFlags x)) => (LessEqualU x)
   719  
   720  // absorb flag constants into conditional instructions
   721  (CMOVWLSconst _ (FlagConstant [fc]) [c]) && fc.ule() => (MOVWconst [c])
   722  (CMOVWLSconst x (FlagConstant [fc]) [c]) && fc.ugt() => x
   723  
   724  (CMOVWHSconst _ (FlagConstant [fc]) [c]) && fc.uge() => (MOVWconst [c])
   725  (CMOVWHSconst x (FlagConstant [fc]) [c]) && fc.ult() => x
   726  
   727  (CMOVWLSconst x (InvertFlags flags) [c]) => (CMOVWHSconst x flags [c])
   728  (CMOVWHSconst x (InvertFlags flags) [c]) => (CMOVWLSconst x flags [c])
   729  
   730  (SRAcond x _ (FlagConstant [fc])) && fc.uge() => (SRAconst x [31])
   731  (SRAcond x y (FlagConstant [fc])) && fc.ult() => (SRA x y)
   732  
   733  // remove redundant *const ops
   734  (ADDconst [0] x) => x
   735  (SUBconst [0] x) => x
   736  (ANDconst [0] _) => (MOVWconst [0])
   737  (ANDconst [c] x) && int32(c)==-1 => x
   738  (ORconst [0] x) => x
   739  (ORconst [c] _) && int32(c)==-1 => (MOVWconst [-1])
   740  (XORconst [0] x) => x
   741  (BICconst [0] x) => x
   742  (BICconst [c] _) && int32(c)==-1 => (MOVWconst [0])
   743  
   744  // generic constant folding
   745  (ADDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (SUBconst [-c] x)
   746  (SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (ADDconst [-c] x)
   747  (ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (BICconst [int32(^uint32(c))] x)
   748  (BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (ANDconst [int32(^uint32(c))] x)
   749  (ADDconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
   750  (SUBconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
   751  (ANDconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
   752  (BICconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
   753  (ADDconst [c] (MOVWconst [d])) => (MOVWconst [c+d])
   754  (ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
   755  (ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
   756  (ADDconst [c] (RSBconst [d] x)) => (RSBconst [c+d] x)
   757  (ADCconst [c] (ADDconst [d] x) flags) => (ADCconst [c+d] x flags)
   758  (ADCconst [c] (SUBconst [d] x) flags) => (ADCconst [c-d] x flags)
   759  (SUBconst [c] (MOVWconst [d])) => (MOVWconst [d-c])
   760  (SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x)
   761  (SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x)
   762  (SUBconst [c] (RSBconst [d] x)) => (RSBconst [-c+d] x)
   763  (SBCconst [c] (ADDconst [d] x) flags) => (SBCconst [c-d] x flags)
   764  (SBCconst [c] (SUBconst [d] x) flags) => (SBCconst [c+d] x flags)
   765  (RSBconst [c] (MOVWconst [d])) => (MOVWconst [c-d])
   766  (RSBconst [c] (RSBconst [d] x)) => (ADDconst [c-d] x)
   767  (RSBconst [c] (ADDconst [d] x)) => (RSBconst [c-d] x)
   768  (RSBconst [c] (SUBconst [d] x)) => (RSBconst [c+d] x)
   769  (RSCconst [c] (ADDconst [d] x) flags) => (RSCconst [c-d] x flags)
   770  (RSCconst [c] (SUBconst [d] x) flags) => (RSCconst [c+d] x flags)
   771  (SLLconst [c] (MOVWconst [d])) => (MOVWconst [d<<uint64(c)])
   772  (SRLconst [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)>>uint64(c))])
   773  (SRAconst [c] (MOVWconst [d])) => (MOVWconst [d>>uint64(c)])
   774  (MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
   775  (MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a)
   776  (MULS (MOVWconst [c]) (MOVWconst [d]) a) => (SUBconst [c*d] a)
   777  (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
   778  (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))])
   779  (ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d])
   780  (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
   781  (ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d])
   782  (ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x)
   783  (XORconst [c] (MOVWconst [d])) => (MOVWconst [c^d])
   784  (XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
   785  (BICconst [c] (MOVWconst [d])) => (MOVWconst [d&^c])
   786  (BICconst [c] (BICconst [d] x)) => (BICconst [c|d] x)
   787  (MVN (MOVWconst [c])) => (MOVWconst [^c])
   788  (MOVBreg (MOVWconst [c])) => (MOVWconst [int32(int8(c))])
   789  (MOVBUreg (MOVWconst [c])) => (MOVWconst [int32(uint8(c))])
   790  (MOVHreg (MOVWconst [c])) => (MOVWconst [int32(int16(c))])
   791  (MOVHUreg (MOVWconst [c])) => (MOVWconst [int32(uint16(c))])
   792  (MOVWreg (MOVWconst [c])) => (MOVWconst [c])
   793  // BFX: Width = c >> 8, LSB = c & 0xff, result = d << (32 - Width - LSB) >> (32 - Width)
   794  (BFX [c] (MOVWconst [d])) => (MOVWconst [d<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))])
   795  (BFXU [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
   796  
   797  // absorb shifts into ops
   798  (ADD x (SLLconst [c] y)) => (ADDshiftLL x y [c])
   799  (ADD x (SRLconst [c] y)) => (ADDshiftRL x y [c])
   800  (ADD x (SRAconst [c] y)) => (ADDshiftRA x y [c])
   801  (ADD x (SLL y z)) => (ADDshiftLLreg x y z)
   802  (ADD x (SRL y z)) => (ADDshiftRLreg x y z)
   803  (ADD x (SRA y z)) => (ADDshiftRAreg x y z)
   804  (ADC x (SLLconst [c] y) flags) => (ADCshiftLL x y [c] flags)
   805  (ADC x (SRLconst [c] y) flags) => (ADCshiftRL x y [c] flags)
   806  (ADC x (SRAconst [c] y) flags) => (ADCshiftRA x y [c] flags)
   807  (ADC x (SLL y z) flags) => (ADCshiftLLreg x y z flags)
   808  (ADC x (SRL y z) flags) => (ADCshiftRLreg x y z flags)
   809  (ADC x (SRA y z) flags) => (ADCshiftRAreg x y z flags)
   810  (ADDS x (SLLconst [c] y)) => (ADDSshiftLL x y [c])
   811  (ADDS x (SRLconst [c] y)) => (ADDSshiftRL x y [c])
   812  (ADDS x (SRAconst [c] y)) => (ADDSshiftRA x y [c])
   813  (ADDS x (SLL y z)) => (ADDSshiftLLreg x y z)
   814  (ADDS x (SRL y z)) => (ADDSshiftRLreg x y z)
   815  (ADDS x (SRA y z)) => (ADDSshiftRAreg x y z)
   816  (SUB x (SLLconst [c] y)) => (SUBshiftLL x y [c])
   817  (SUB (SLLconst [c] y) x) => (RSBshiftLL x y [c])
   818  (SUB x (SRLconst [c] y)) => (SUBshiftRL x y [c])
   819  (SUB (SRLconst [c] y) x) => (RSBshiftRL x y [c])
   820  (SUB x (SRAconst [c] y)) => (SUBshiftRA x y [c])
   821  (SUB (SRAconst [c] y) x) => (RSBshiftRA x y [c])
   822  (SUB x (SLL y z)) => (SUBshiftLLreg x y z)
   823  (SUB (SLL y z) x) => (RSBshiftLLreg x y z)
   824  (SUB x (SRL y z)) => (SUBshiftRLreg x y z)
   825  (SUB (SRL y z) x) => (RSBshiftRLreg x y z)
   826  (SUB x (SRA y z)) => (SUBshiftRAreg x y z)
   827  (SUB (SRA y z) x) => (RSBshiftRAreg x y z)
   828  (SBC x (SLLconst [c] y) flags) => (SBCshiftLL x y [c] flags)
   829  (SBC (SLLconst [c] y) x flags) => (RSCshiftLL x y [c] flags)
   830  (SBC x (SRLconst [c] y) flags) => (SBCshiftRL x y [c] flags)
   831  (SBC (SRLconst [c] y) x flags) => (RSCshiftRL x y [c] flags)
   832  (SBC x (SRAconst [c] y) flags) => (SBCshiftRA x y [c] flags)
   833  (SBC (SRAconst [c] y) x flags) => (RSCshiftRA x y [c] flags)
   834  (SBC x (SLL y z) flags) => (SBCshiftLLreg x y z flags)
   835  (SBC (SLL y z) x flags) => (RSCshiftLLreg x y z flags)
   836  (SBC x (SRL y z) flags) => (SBCshiftRLreg x y z flags)
   837  (SBC (SRL y z) x flags) => (RSCshiftRLreg x y z flags)
   838  (SBC x (SRA y z) flags) => (SBCshiftRAreg x y z flags)
   839  (SBC (SRA y z) x flags) => (RSCshiftRAreg x y z flags)
   840  (SUBS x (SLLconst [c] y)) => (SUBSshiftLL x y [c])
   841  (SUBS (SLLconst [c] y) x) => (RSBSshiftLL x y [c])
   842  (SUBS x (SRLconst [c] y)) => (SUBSshiftRL x y [c])
   843  (SUBS (SRLconst [c] y) x) => (RSBSshiftRL x y [c])
   844  (SUBS x (SRAconst [c] y)) => (SUBSshiftRA x y [c])
   845  (SUBS (SRAconst [c] y) x) => (RSBSshiftRA x y [c])
   846  (SUBS x (SLL y z)) => (SUBSshiftLLreg x y z)
   847  (SUBS (SLL y z) x) => (RSBSshiftLLreg x y z)
   848  (SUBS x (SRL y z)) => (SUBSshiftRLreg x y z)
   849  (SUBS (SRL y z) x) => (RSBSshiftRLreg x y z)
   850  (SUBS x (SRA y z)) => (SUBSshiftRAreg x y z)
   851  (SUBS (SRA y z) x) => (RSBSshiftRAreg x y z)
   852  (RSB x (SLLconst [c] y)) => (RSBshiftLL x y [c])
   853  (RSB (SLLconst [c] y) x) => (SUBshiftLL x y [c])
   854  (RSB x (SRLconst [c] y)) => (RSBshiftRL x y [c])
   855  (RSB (SRLconst [c] y) x) => (SUBshiftRL x y [c])
   856  (RSB x (SRAconst [c] y)) => (RSBshiftRA x y [c])
   857  (RSB (SRAconst [c] y) x) => (SUBshiftRA x y [c])
   858  (RSB x (SLL y z)) => (RSBshiftLLreg x y z)
   859  (RSB (SLL y z) x) => (SUBshiftLLreg x y z)
   860  (RSB x (SRL y z)) => (RSBshiftRLreg x y z)
   861  (RSB (SRL y z) x) => (SUBshiftRLreg x y z)
   862  (RSB x (SRA y z)) => (RSBshiftRAreg x y z)
   863  (RSB (SRA y z) x) => (SUBshiftRAreg x y z)
   864  (AND x (SLLconst [c] y)) => (ANDshiftLL x y [c])
   865  (AND x (SRLconst [c] y)) => (ANDshiftRL x y [c])
   866  (AND x (SRAconst [c] y)) => (ANDshiftRA x y [c])
   867  (AND x (SLL y z)) => (ANDshiftLLreg x y z)
   868  (AND x (SRL y z)) => (ANDshiftRLreg x y z)
   869  (AND x (SRA y z)) => (ANDshiftRAreg x y z)
   870  (OR x (SLLconst [c] y)) => (ORshiftLL x y [c])
   871  (OR x (SRLconst [c] y)) => (ORshiftRL x y [c])
   872  (OR x (SRAconst [c] y)) => (ORshiftRA x y [c])
   873  (OR x (SLL y z)) => (ORshiftLLreg x y z)
   874  (OR x (SRL y z)) => (ORshiftRLreg x y z)
   875  (OR x (SRA y z)) => (ORshiftRAreg x y z)
   876  (XOR x (SLLconst [c] y)) => (XORshiftLL x y [c])
   877  (XOR x (SRLconst [c] y)) => (XORshiftRL x y [c])
   878  (XOR x (SRAconst [c] y)) => (XORshiftRA x y [c])
   879  (XOR x (SRRconst [c] y)) => (XORshiftRR x y [c])
   880  (XOR x (SLL y z)) => (XORshiftLLreg x y z)
   881  (XOR x (SRL y z)) => (XORshiftRLreg x y z)
   882  (XOR x (SRA y z)) => (XORshiftRAreg x y z)
   883  (BIC x (SLLconst [c] y)) => (BICshiftLL x y [c])
   884  (BIC x (SRLconst [c] y)) => (BICshiftRL x y [c])
   885  (BIC x (SRAconst [c] y)) => (BICshiftRA x y [c])
   886  (BIC x (SLL y z)) => (BICshiftLLreg x y z)
   887  (BIC x (SRL y z)) => (BICshiftRLreg x y z)
   888  (BIC x (SRA y z)) => (BICshiftRAreg x y z)
   889  (MVN (SLLconst [c] x)) => (MVNshiftLL x [c])
   890  (MVN (SRLconst [c] x)) => (MVNshiftRL x [c])
   891  (MVN (SRAconst [c] x)) => (MVNshiftRA x [c])
   892  (MVN (SLL x y)) => (MVNshiftLLreg x y)
   893  (MVN (SRL x y)) => (MVNshiftRLreg x y)
   894  (MVN (SRA x y)) => (MVNshiftRAreg x y)
   895  
   896  (CMP x (SLLconst [c] y)) => (CMPshiftLL x y [c])
   897  (CMP (SLLconst [c] y) x) => (InvertFlags (CMPshiftLL x y [c]))
   898  (CMP x (SRLconst [c] y)) => (CMPshiftRL x y [c])
   899  (CMP (SRLconst [c] y) x) => (InvertFlags (CMPshiftRL x y [c]))
   900  (CMP x (SRAconst [c] y)) => (CMPshiftRA x y [c])
   901  (CMP (SRAconst [c] y) x) => (InvertFlags (CMPshiftRA x y [c]))
   902  (CMP x (SLL y z)) => (CMPshiftLLreg x y z)
   903  (CMP (SLL y z) x) => (InvertFlags (CMPshiftLLreg x y z))
   904  (CMP x (SRL y z)) => (CMPshiftRLreg x y z)
   905  (CMP (SRL y z) x) => (InvertFlags (CMPshiftRLreg x y z))
   906  (CMP x (SRA y z)) => (CMPshiftRAreg x y z)
   907  (CMP (SRA y z) x) => (InvertFlags (CMPshiftRAreg x y z))
   908  (TST x (SLLconst [c] y)) => (TSTshiftLL x y [c])
   909  (TST x (SRLconst [c] y)) => (TSTshiftRL x y [c])
   910  (TST x (SRAconst [c] y)) => (TSTshiftRA x y [c])
   911  (TST x (SLL y z)) => (TSTshiftLLreg x y z)
   912  (TST x (SRL y z)) => (TSTshiftRLreg x y z)
   913  (TST x (SRA y z)) => (TSTshiftRAreg x y z)
   914  (TEQ x (SLLconst [c] y)) => (TEQshiftLL x y [c])
   915  (TEQ x (SRLconst [c] y)) => (TEQshiftRL x y [c])
   916  (TEQ x (SRAconst [c] y)) => (TEQshiftRA x y [c])
   917  (TEQ x (SLL y z)) => (TEQshiftLLreg x y z)
   918  (TEQ x (SRL y z)) => (TEQshiftRLreg x y z)
   919  (TEQ x (SRA y z)) => (TEQshiftRAreg x y z)
   920  (CMN x (SLLconst [c] y)) => (CMNshiftLL x y [c])
   921  (CMN x (SRLconst [c] y)) => (CMNshiftRL x y [c])
   922  (CMN x (SRAconst [c] y)) => (CMNshiftRA x y [c])
   923  (CMN x (SLL y z)) => (CMNshiftLLreg x y z)
   924  (CMN x (SRL y z)) => (CMNshiftRLreg x y z)
   925  (CMN x (SRA y z)) => (CMNshiftRAreg x y z)
   926  
   927  // prefer *const ops to *shift ops
   928  (ADDshiftLL (MOVWconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d]))
   929  (ADDshiftRL (MOVWconst [c]) x [d]) => (ADDconst [c] (SRLconst <x.Type> x [d]))
   930  (ADDshiftRA (MOVWconst [c]) x [d]) => (ADDconst [c] (SRAconst <x.Type> x [d]))
   931  (ADCshiftLL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SLLconst <x.Type> x [d]) flags)
   932  (ADCshiftRL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRLconst <x.Type> x [d]) flags)
   933  (ADCshiftRA (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRAconst <x.Type> x [d]) flags)
   934  (ADDSshiftLL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SLLconst <x.Type> x [d]))
   935  (ADDSshiftRL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRLconst <x.Type> x [d]))
   936  (ADDSshiftRA (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRAconst <x.Type> x [d]))
   937  (SUBshiftLL (MOVWconst [c]) x [d]) => (RSBconst [c] (SLLconst <x.Type> x [d]))
   938  (SUBshiftRL (MOVWconst [c]) x [d]) => (RSBconst [c] (SRLconst <x.Type> x [d]))
   939  (SUBshiftRA (MOVWconst [c]) x [d]) => (RSBconst [c] (SRAconst <x.Type> x [d]))
   940  (SBCshiftLL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SLLconst <x.Type> x [d]) flags)
   941  (SBCshiftRL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRLconst <x.Type> x [d]) flags)
   942  (SBCshiftRA (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRAconst <x.Type> x [d]) flags)
   943  (SUBSshiftLL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SLLconst <x.Type> x [d]))
   944  (SUBSshiftRL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRLconst <x.Type> x [d]))
   945  (SUBSshiftRA (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRAconst <x.Type> x [d]))
   946  (RSBshiftLL (MOVWconst [c]) x [d]) => (SUBconst [c] (SLLconst <x.Type> x [d]))
   947  (RSBshiftRL (MOVWconst [c]) x [d]) => (SUBconst [c] (SRLconst <x.Type> x [d]))
   948  (RSBshiftRA (MOVWconst [c]) x [d]) => (SUBconst [c] (SRAconst <x.Type> x [d]))
   949  (RSCshiftLL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SLLconst <x.Type> x [d]) flags)
   950  (RSCshiftRL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRLconst <x.Type> x [d]) flags)
   951  (RSCshiftRA (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRAconst <x.Type> x [d]) flags)
   952  (RSBSshiftLL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SLLconst <x.Type> x [d]))
   953  (RSBSshiftRL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRLconst <x.Type> x [d]))
   954  (RSBSshiftRA (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRAconst <x.Type> x [d]))
   955  (ANDshiftLL (MOVWconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d]))
   956  (ANDshiftRL (MOVWconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d]))
   957  (ANDshiftRA (MOVWconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d]))
   958  (ORshiftLL (MOVWconst [c]) x [d]) => (ORconst [c] (SLLconst <x.Type> x [d]))
   959  (ORshiftRL (MOVWconst [c]) x [d]) => (ORconst [c] (SRLconst <x.Type> x [d]))
   960  (ORshiftRA (MOVWconst [c]) x [d]) => (ORconst [c] (SRAconst <x.Type> x [d]))
   961  (XORshiftLL (MOVWconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d]))
   962  (XORshiftRL (MOVWconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d]))
   963  (XORshiftRA (MOVWconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d]))
   964  (XORshiftRR (MOVWconst [c]) x [d]) => (XORconst [c] (SRRconst <x.Type> x [d]))
   965  (CMPshiftLL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
   966  (CMPshiftRL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
   967  (CMPshiftRA (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
   968  (TSTshiftLL (MOVWconst [c]) x [d]) => (TSTconst [c] (SLLconst <x.Type> x [d]))
   969  (TSTshiftRL (MOVWconst [c]) x [d]) => (TSTconst [c] (SRLconst <x.Type> x [d]))
   970  (TSTshiftRA (MOVWconst [c]) x [d]) => (TSTconst [c] (SRAconst <x.Type> x [d]))
   971  (TEQshiftLL (MOVWconst [c]) x [d]) => (TEQconst [c] (SLLconst <x.Type> x [d]))
   972  (TEQshiftRL (MOVWconst [c]) x [d]) => (TEQconst [c] (SRLconst <x.Type> x [d]))
   973  (TEQshiftRA (MOVWconst [c]) x [d]) => (TEQconst [c] (SRAconst <x.Type> x [d]))
   974  (CMNshiftLL (MOVWconst [c]) x [d]) => (CMNconst [c] (SLLconst <x.Type> x [d]))
   975  (CMNshiftRL (MOVWconst [c]) x [d]) => (CMNconst [c] (SRLconst <x.Type> x [d]))
   976  (CMNshiftRA (MOVWconst [c]) x [d]) => (CMNconst [c] (SRAconst <x.Type> x [d]))
   977  
   978  (ADDshiftLLreg (MOVWconst [c]) x y) => (ADDconst [c] (SLL <x.Type> x y))
   979  (ADDshiftRLreg (MOVWconst [c]) x y) => (ADDconst [c] (SRL <x.Type> x y))
   980  (ADDshiftRAreg (MOVWconst [c]) x y) => (ADDconst [c] (SRA <x.Type> x y))
   981  (ADCshiftLLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SLL <x.Type> x y) flags)
   982  (ADCshiftRLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRL <x.Type> x y) flags)
   983  (ADCshiftRAreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRA <x.Type> x y) flags)
   984  (ADDSshiftLLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SLL <x.Type> x y))
   985  (ADDSshiftRLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRL <x.Type> x y))
   986  (ADDSshiftRAreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRA <x.Type> x y))
   987  (SUBshiftLLreg (MOVWconst [c]) x y) => (RSBconst [c] (SLL <x.Type> x y))
   988  (SUBshiftRLreg (MOVWconst [c]) x y) => (RSBconst [c] (SRL <x.Type> x y))
   989  (SUBshiftRAreg (MOVWconst [c]) x y) => (RSBconst [c] (SRA <x.Type> x y))
   990  (SBCshiftLLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SLL <x.Type> x y) flags)
   991  (SBCshiftRLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRL <x.Type> x y) flags)
   992  (SBCshiftRAreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRA <x.Type> x y) flags)
   993  (SUBSshiftLLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SLL <x.Type> x y))
   994  (SUBSshiftRLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRL <x.Type> x y))
   995  (SUBSshiftRAreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRA <x.Type> x y))
   996  (RSBshiftLLreg (MOVWconst [c]) x y) => (SUBconst [c] (SLL <x.Type> x y))
   997  (RSBshiftRLreg (MOVWconst [c]) x y) => (SUBconst [c] (SRL <x.Type> x y))
   998  (RSBshiftRAreg (MOVWconst [c]) x y) => (SUBconst [c] (SRA <x.Type> x y))
   999  (RSCshiftLLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SLL <x.Type> x y) flags)
  1000  (RSCshiftRLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRL <x.Type> x y) flags)
  1001  (RSCshiftRAreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRA <x.Type> x y) flags)
  1002  (RSBSshiftLLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SLL <x.Type> x y))
  1003  (RSBSshiftRLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRL <x.Type> x y))
  1004  (RSBSshiftRAreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRA <x.Type> x y))
  1005  (ANDshiftLLreg (MOVWconst [c]) x y) => (ANDconst [c] (SLL <x.Type> x y))
  1006  (ANDshiftRLreg (MOVWconst [c]) x y) => (ANDconst [c] (SRL <x.Type> x y))
  1007  (ANDshiftRAreg (MOVWconst [c]) x y) => (ANDconst [c] (SRA <x.Type> x y))
  1008  (ORshiftLLreg (MOVWconst [c]) x y) => (ORconst [c] (SLL <x.Type> x y))
  1009  (ORshiftRLreg (MOVWconst [c]) x y) => (ORconst [c] (SRL <x.Type> x y))
  1010  (ORshiftRAreg (MOVWconst [c]) x y) => (ORconst [c] (SRA <x.Type> x y))
  1011  (XORshiftLLreg (MOVWconst [c]) x y) => (XORconst [c] (SLL <x.Type> x y))
  1012  (XORshiftRLreg (MOVWconst [c]) x y) => (XORconst [c] (SRL <x.Type> x y))
  1013  (XORshiftRAreg (MOVWconst [c]) x y) => (XORconst [c] (SRA <x.Type> x y))
  1014  (CMPshiftLLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
  1015  (CMPshiftRLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
  1016  (CMPshiftRAreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
  1017  (TSTshiftLLreg (MOVWconst [c]) x y) => (TSTconst [c] (SLL <x.Type> x y))
  1018  (TSTshiftRLreg (MOVWconst [c]) x y) => (TSTconst [c] (SRL <x.Type> x y))
  1019  (TSTshiftRAreg (MOVWconst [c]) x y) => (TSTconst [c] (SRA <x.Type> x y))
  1020  (TEQshiftLLreg (MOVWconst [c]) x y) => (TEQconst [c] (SLL <x.Type> x y))
  1021  (TEQshiftRLreg (MOVWconst [c]) x y) => (TEQconst [c] (SRL <x.Type> x y))
  1022  (TEQshiftRAreg (MOVWconst [c]) x y) => (TEQconst [c] (SRA <x.Type> x y))
  1023  (CMNshiftLLreg (MOVWconst [c]) x y) => (CMNconst [c] (SLL <x.Type> x y))
  1024  (CMNshiftRLreg (MOVWconst [c]) x y) => (CMNconst [c] (SRL <x.Type> x y))
  1025  (CMNshiftRAreg (MOVWconst [c]) x y) => (CMNconst [c] (SRA <x.Type> x y))
  1026  
  1027  // constant folding in *shift ops
  1028  (ADDshiftLL x (MOVWconst [c]) [d]) => (ADDconst x [c<<uint64(d)])
  1029  (ADDshiftRL x (MOVWconst [c]) [d]) => (ADDconst x [int32(uint32(c)>>uint64(d))])
  1030  (ADDshiftRA x (MOVWconst [c]) [d]) => (ADDconst x [c>>uint64(d)])
  1031  (ADCshiftLL x (MOVWconst [c]) [d] flags) => (ADCconst x [c<<uint64(d)] flags)
  1032  (ADCshiftRL x (MOVWconst [c]) [d] flags) => (ADCconst x [int32(uint32(c)>>uint64(d))] flags)
  1033  (ADCshiftRA x (MOVWconst [c]) [d] flags) => (ADCconst x [c>>uint64(d)] flags)
  1034  (ADDSshiftLL x (MOVWconst [c]) [d]) => (ADDSconst x [c<<uint64(d)])
  1035  (ADDSshiftRL x (MOVWconst [c]) [d]) => (ADDSconst x [int32(uint32(c)>>uint64(d))])
  1036  (ADDSshiftRA x (MOVWconst [c]) [d]) => (ADDSconst x [c>>uint64(d)])
  1037  (SUBshiftLL x (MOVWconst [c]) [d]) => (SUBconst x [c<<uint64(d)])
  1038  (SUBshiftRL x (MOVWconst [c]) [d]) => (SUBconst x [int32(uint32(c)>>uint64(d))])
  1039  (SUBshiftRA x (MOVWconst [c]) [d]) => (SUBconst x [c>>uint64(d)])
  1040  (SBCshiftLL x (MOVWconst [c]) [d] flags) => (SBCconst x [c<<uint64(d)] flags)
  1041  (SBCshiftRL x (MOVWconst [c]) [d] flags) => (SBCconst x [int32(uint32(c)>>uint64(d))] flags)
  1042  (SBCshiftRA x (MOVWconst [c]) [d] flags) => (SBCconst x [c>>uint64(d)] flags)
  1043  (SUBSshiftLL x (MOVWconst [c]) [d]) => (SUBSconst x [c<<uint64(d)])
  1044  (SUBSshiftRL x (MOVWconst [c]) [d]) => (SUBSconst x [int32(uint32(c)>>uint64(d))])
  1045  (SUBSshiftRA x (MOVWconst [c]) [d]) => (SUBSconst x [c>>uint64(d)])
  1046  (RSBshiftLL x (MOVWconst [c]) [d]) => (RSBconst x [c<<uint64(d)])
  1047  (RSBshiftRL x (MOVWconst [c]) [d]) => (RSBconst x [int32(uint32(c)>>uint64(d))])
  1048  (RSBshiftRA x (MOVWconst [c]) [d]) => (RSBconst x [c>>uint64(d)])
  1049  (RSCshiftLL x (MOVWconst [c]) [d] flags) => (RSCconst x [c<<uint64(d)] flags)
  1050  (RSCshiftRL x (MOVWconst [c]) [d] flags) => (RSCconst x [int32(uint32(c)>>uint64(d))] flags)
  1051  (RSCshiftRA x (MOVWconst [c]) [d] flags) => (RSCconst x [c>>uint64(d)] flags)
  1052  (RSBSshiftLL x (MOVWconst [c]) [d]) => (RSBSconst x [c<<uint64(d)])
  1053  (RSBSshiftRL x (MOVWconst [c]) [d]) => (RSBSconst x [int32(uint32(c)>>uint64(d))])
  1054  (RSBSshiftRA x (MOVWconst [c]) [d]) => (RSBSconst x [c>>uint64(d)])
  1055  (ANDshiftLL x (MOVWconst [c]) [d]) => (ANDconst x [c<<uint64(d)])
  1056  (ANDshiftRL x (MOVWconst [c]) [d]) => (ANDconst x [int32(uint32(c)>>uint64(d))])
  1057  (ANDshiftRA x (MOVWconst [c]) [d]) => (ANDconst x [c>>uint64(d)])
  1058  (ORshiftLL x (MOVWconst [c]) [d]) => (ORconst x [c<<uint64(d)])
  1059  (ORshiftRL x (MOVWconst [c]) [d]) => (ORconst x [int32(uint32(c)>>uint64(d))])
  1060  (ORshiftRA x (MOVWconst [c]) [d]) => (ORconst x [c>>uint64(d)])
  1061  (XORshiftLL x (MOVWconst [c]) [d]) => (XORconst x [c<<uint64(d)])
  1062  (XORshiftRL x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d))])
  1063  (XORshiftRA x (MOVWconst [c]) [d]) => (XORconst x [c>>uint64(d)])
  1064  (XORshiftRR x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
  1065  (BICshiftLL x (MOVWconst [c]) [d]) => (BICconst x [c<<uint64(d)])
  1066  (BICshiftRL x (MOVWconst [c]) [d]) => (BICconst x [int32(uint32(c)>>uint64(d))])
  1067  (BICshiftRA x (MOVWconst [c]) [d]) => (BICconst x [c>>uint64(d)])
  1068  (MVNshiftLL (MOVWconst [c]) [d]) => (MOVWconst [^(c<<uint64(d))])
  1069  (MVNshiftRL (MOVWconst [c]) [d]) => (MOVWconst [^int32(uint32(c)>>uint64(d))])
  1070  (MVNshiftRA (MOVWconst [c]) [d]) => (MOVWconst [int32(c)>>uint64(d)])
  1071  (CMPshiftLL x (MOVWconst [c]) [d]) => (CMPconst x [c<<uint64(d)])
  1072  (CMPshiftRL x (MOVWconst [c]) [d]) => (CMPconst x [int32(uint32(c)>>uint64(d))])
  1073  (CMPshiftRA x (MOVWconst [c]) [d]) => (CMPconst x [c>>uint64(d)])
  1074  (TSTshiftLL x (MOVWconst [c]) [d]) => (TSTconst x [c<<uint64(d)])
  1075  (TSTshiftRL x (MOVWconst [c]) [d]) => (TSTconst x [int32(uint32(c)>>uint64(d))])
  1076  (TSTshiftRA x (MOVWconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
  1077  (TEQshiftLL x (MOVWconst [c]) [d]) => (TEQconst x [c<<uint64(d)])
  1078  (TEQshiftRL x (MOVWconst [c]) [d]) => (TEQconst x [int32(uint32(c)>>uint64(d))])
  1079  (TEQshiftRA x (MOVWconst [c]) [d]) => (TEQconst x [c>>uint64(d)])
  1080  (CMNshiftLL x (MOVWconst [c]) [d]) => (CMNconst x [c<<uint64(d)])
  1081  (CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
  1082  (CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
  1083  
  1084  (ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
  1085  (ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
  1086  (ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
  1087  (ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
  1088  (ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
  1089  (ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
  1090  (ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
  1091  (ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
  1092  (ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
  1093  (SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
  1094  (SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
  1095  (SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
  1096  (SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
  1097  (SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
  1098  (SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
  1099  (SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
  1100  (SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
  1101  (SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
  1102  (RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
  1103  (RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
  1104  (RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
  1105  (RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
  1106  (RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
  1107  (RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
  1108  (RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
  1109  (RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
  1110  (RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
  1111  (ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
  1112  (ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
  1113  (ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
  1114  (ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
  1115  (ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
  1116  (ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
  1117  (XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
  1118  (XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
  1119  (XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
  1120  (BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
  1121  (BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
  1122  (BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
  1123  (MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
  1124  (MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
  1125  (MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
  1126  (CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
  1127  (CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
  1128  (CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
  1129  (TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
  1130  (TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
  1131  (TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
  1132  (TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
  1133  (TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
  1134  (TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
  1135  (CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
  1136  (CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
  1137  (CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
  1138  
  1139  (RotateLeft16 <t> x (MOVWconst [c])) => (Or16 (Lsh16x32 <t> x (MOVWconst [c&15])) (Rsh16Ux32 <t> x (MOVWconst [-c&15])))
  1140  (RotateLeft8 <t> x (MOVWconst [c])) => (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7])))
  1141  (RotateLeft32 x y) => (SRR x (RSBconst [0] <y.Type> y))
  1142  
  1143  // ((x>>8) | (x<<8)) -> (REV16 x), the type of x is uint16, "|" can also be "^" or "+".
  1144  // UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
  1145  // ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL.
  1146  ((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x)
  1147  ((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && buildcfg.GOARM.Version>=6 => (REV16 x)
  1148  
  1149  // use indexed loads and stores
  1150  (MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVWloadidx ptr idx mem)
  1151  (MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVWstoreidx ptr idx val mem)
  1152  (MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftLL ptr idx [c] mem)
  1153  (MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRL ptr idx [c] mem)
  1154  (MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRA ptr idx [c] mem)
  1155  (MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftLL ptr idx [c] val mem)
  1156  (MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRL ptr idx [c] val mem)
  1157  (MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRA ptr idx [c] val mem)
  1158  (MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBUloadidx ptr idx mem)
  1159  (MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBloadidx ptr idx mem)
  1160  (MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVBstoreidx ptr idx val mem)
  1161  (MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHUloadidx ptr idx mem)
  1162  (MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHloadidx ptr idx mem)
  1163  (MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVHstoreidx ptr idx val mem)
  1164  
  1165  // constant folding in indexed loads and stores
  1166  (MOVWloadidx ptr (MOVWconst [c]) mem) => (MOVWload [c] ptr mem)
  1167  (MOVWloadidx (MOVWconst [c]) ptr mem) => (MOVWload [c] ptr mem)
  1168  (MOVBloadidx ptr (MOVWconst [c]) mem) => (MOVBload [c] ptr mem)
  1169  (MOVBloadidx (MOVWconst [c]) ptr mem) => (MOVBload [c] ptr mem)
  1170  (MOVBUloadidx ptr (MOVWconst [c]) mem) => (MOVBUload [c] ptr mem)
  1171  (MOVBUloadidx (MOVWconst [c]) ptr mem) => (MOVBUload [c] ptr mem)
  1172  (MOVHUloadidx ptr (MOVWconst [c]) mem) => (MOVHUload [c] ptr mem)
  1173  (MOVHUloadidx (MOVWconst [c]) ptr mem) => (MOVHUload [c] ptr mem)
  1174  (MOVHloadidx ptr (MOVWconst [c]) mem) => (MOVHload [c] ptr mem)
  1175  (MOVHloadidx (MOVWconst [c]) ptr mem) => (MOVHload [c] ptr mem)
  1176  
  1177  (MOVWstoreidx ptr (MOVWconst [c]) val mem) => (MOVWstore [c] ptr val mem)
  1178  (MOVWstoreidx (MOVWconst [c]) ptr val mem) => (MOVWstore [c] ptr val mem)
  1179  (MOVBstoreidx ptr (MOVWconst [c]) val mem) => (MOVBstore [c] ptr val mem)
  1180  (MOVBstoreidx (MOVWconst [c]) ptr val mem) => (MOVBstore [c] ptr val mem)
  1181  (MOVHstoreidx ptr (MOVWconst [c]) val mem) => (MOVHstore [c] ptr val mem)
  1182  (MOVHstoreidx (MOVWconst [c]) ptr val mem) => (MOVHstore [c] ptr val mem)
  1183  
  1184  (MOVWloadidx ptr (SLLconst idx [c]) mem) => (MOVWloadshiftLL ptr idx [c] mem)
  1185  (MOVWloadidx (SLLconst idx [c]) ptr mem) => (MOVWloadshiftLL ptr idx [c] mem)
  1186  (MOVWloadidx ptr (SRLconst idx [c]) mem) => (MOVWloadshiftRL ptr idx [c] mem)
  1187  (MOVWloadidx (SRLconst idx [c]) ptr mem) => (MOVWloadshiftRL ptr idx [c] mem)
  1188  (MOVWloadidx ptr (SRAconst idx [c]) mem) => (MOVWloadshiftRA ptr idx [c] mem)
  1189  (MOVWloadidx (SRAconst idx [c]) ptr mem) => (MOVWloadshiftRA ptr idx [c] mem)
  1190  
  1191  (MOVWstoreidx ptr (SLLconst idx [c]) val mem) => (MOVWstoreshiftLL ptr idx [c] val mem)
  1192  (MOVWstoreidx (SLLconst idx [c]) ptr val mem) => (MOVWstoreshiftLL ptr idx [c] val mem)
  1193  (MOVWstoreidx ptr (SRLconst idx [c]) val mem) => (MOVWstoreshiftRL ptr idx [c] val mem)
  1194  (MOVWstoreidx (SRLconst idx [c]) ptr val mem) => (MOVWstoreshiftRL ptr idx [c] val mem)
  1195  (MOVWstoreidx ptr (SRAconst idx [c]) val mem) => (MOVWstoreshiftRA ptr idx [c] val mem)
  1196  (MOVWstoreidx (SRAconst idx [c]) ptr val mem) => (MOVWstoreshiftRA ptr idx [c] val mem)
  1197  
  1198  (MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)<<uint64(d))] ptr mem)
  1199  (MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)>>uint64(d))] ptr mem)
  1200  (MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) => (MOVWload [c>>uint64(d)] ptr mem)
  1201  
  1202  (MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)<<uint64(d))] ptr val mem)
  1203  (MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)>>uint64(d))] ptr val mem)
  1204  (MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [c>>uint64(d)] ptr val mem)
  1205  
  1206  // generic simplifications
  1207  (ADD x (RSBconst [0] y)) => (SUB x y)
  1208  (ADD <t> (RSBconst [c] x) (RSBconst [d] y)) => (RSBconst [c+d] (ADD <t> x y))
  1209  (SUB x x) => (MOVWconst [0])
  1210  (RSB x x) => (MOVWconst [0])
  1211  (AND x x) => x
  1212  (OR x x) => x
  1213  (XOR x x) => (MOVWconst [0])
  1214  (BIC x x) => (MOVWconst [0])
  1215  
  1216  (ADD (MUL x y) a) => (MULA x y a)
  1217  (SUB a (MUL x y)) && buildcfg.GOARM.Version == 7 => (MULS x y a)
  1218  (RSB (MUL x y) a) && buildcfg.GOARM.Version == 7 => (MULS x y a)
  1219  
  1220  (NEGF (MULF x y)) && buildcfg.GOARM.Version >= 6 => (NMULF x y)
  1221  (NEGD (MULD x y)) && buildcfg.GOARM.Version >= 6 => (NMULD x y)
  1222  (MULF (NEGF x) y) && buildcfg.GOARM.Version >= 6 => (NMULF x y)
  1223  (MULD (NEGD x) y) && buildcfg.GOARM.Version >= 6 => (NMULD x y)
  1224  (NMULF (NEGF x) y) => (MULF x y)
  1225  (NMULD (NEGD x) y) => (MULD x y)
  1226  
  1227  // the result will overwrite the addend, since they are in the same register
  1228  (ADDF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAF a x y)
  1229  (ADDF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSF a x y)
  1230  (ADDD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAD a x y)
  1231  (ADDD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSD a x y)
  1232  (SUBF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSF a x y)
  1233  (SUBF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAF a x y)
  1234  (SUBD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSD a x y)
  1235  (SUBD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAD a x y)
  1236  
  1237  (AND x (MVN y)) => (BIC x y)
  1238  
  1239  // simplification with *shift ops
  1240  (SUBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
  1241  (SUBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
  1242  (SUBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
  1243  (RSBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
  1244  (RSBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
  1245  (RSBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
  1246  (ANDshiftLL y:(SLLconst x [c]) x [c]) => y
  1247  (ANDshiftRL y:(SRLconst x [c]) x [c]) => y
  1248  (ANDshiftRA y:(SRAconst x [c]) x [c]) => y
  1249  (ORshiftLL y:(SLLconst x [c]) x [c]) => y
  1250  (ORshiftRL y:(SRLconst x [c]) x [c]) => y
  1251  (ORshiftRA y:(SRAconst x [c]) x [c]) => y
  1252  (XORshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
  1253  (XORshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
  1254  (XORshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
  1255  (BICshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
  1256  (BICshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
  1257  (BICshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
  1258  (AND x (MVNshiftLL y [c])) => (BICshiftLL x y [c])
  1259  (AND x (MVNshiftRL y [c])) => (BICshiftRL x y [c])
  1260  (AND x (MVNshiftRA y [c])) => (BICshiftRA x y [c])
  1261  
  1262  // floating point optimizations
  1263  (CMPF x (MOVFconst [0])) => (CMPF0 x)
  1264  (CMPD x (MOVDconst [0])) => (CMPD0 x)
  1265  
  1266  // bit extraction
  1267  (SRAconst (SLLconst x [c]) [d]) && buildcfg.GOARM.Version==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x)
  1268  (SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM.Version==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
  1269  
  1270  // comparison simplification
  1271  ((EQ|NE) (CMP x (RSBconst [0] y))) => ((EQ|NE) (CMN x y)) // sense of carry bit not preserved; see also #50854
  1272  ((EQ|NE) (CMN x (RSBconst [0] y))) => ((EQ|NE) (CMP x y)) // sense of carry bit not preserved; see also #50864
  1273  (EQ (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (EQ (CMP x y) yes no)
  1274  (EQ (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no)
  1275  (EQ (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (EQ (CMPconst [c] x) yes no)
  1276  (EQ (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftLL x y [c]) yes no)
  1277  (EQ (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRL x y [c]) yes no)
  1278  (EQ (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRA x y [c]) yes no)
  1279  (EQ (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftLLreg x y z) yes no)
  1280  (EQ (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRLreg x y z) yes no)
  1281  (EQ (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRAreg x y z) yes no)
  1282  (NE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (NE (CMP x y) yes no)
  1283  (NE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (NE (CMP a (MUL <x.Type> x y)) yes no)
  1284  (NE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (NE (CMPconst [c] x) yes no)
  1285  (NE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftLL x y [c]) yes no)
  1286  (NE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRL x y [c]) yes no)
  1287  (NE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRA x y [c]) yes no)
  1288  (NE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftLLreg x y z) yes no)
  1289  (NE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRLreg x y z) yes no)
  1290  (NE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRAreg x y z) yes no)
  1291  (EQ (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (EQ (CMN x y) yes no)
  1292  (EQ (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (EQ (CMN a (MUL <x.Type> x y)) yes no)
  1293  (EQ (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (EQ (CMNconst [c] x) yes no)
  1294  (EQ (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftLL x y [c]) yes no)
  1295  (EQ (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRL x y [c]) yes no)
  1296  (EQ (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRA x y [c]) yes no)
  1297  (EQ (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftLLreg x y z) yes no)
  1298  (EQ (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRLreg x y z) yes no)
  1299  (EQ (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRAreg x y z) yes no)
  1300  (NE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (NE (CMN x y) yes no)
  1301  (NE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (NE (CMN a (MUL <x.Type> x y)) yes no)
  1302  (NE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (NE (CMNconst [c] x) yes no)
  1303  (NE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftLL x y [c]) yes no)
  1304  (NE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRL x y [c]) yes no)
  1305  (NE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRA x y [c]) yes no)
  1306  (NE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftLLreg x y z) yes no)
  1307  (NE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRLreg x y z) yes no)
  1308  (NE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRAreg x y z) yes no)
  1309  (EQ (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (EQ (TST x y) yes no)
  1310  (EQ (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (EQ (TSTconst [c] x) yes no)
  1311  (EQ (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftLL x y [c]) yes no)
  1312  (EQ (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRL x y [c]) yes no)
  1313  (EQ (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRA x y [c]) yes no)
  1314  (EQ (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftLLreg x y z) yes no)
  1315  (EQ (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRLreg x y z) yes no)
  1316  (EQ (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRAreg x y z) yes no)
  1317  (NE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (NE (TST x y) yes no)
  1318  (NE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (NE (TSTconst [c] x) yes no)
  1319  (NE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftLL x y [c]) yes no)
  1320  (NE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRL x y [c]) yes no)
  1321  (NE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRA x y [c]) yes no)
  1322  (NE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftLLreg x y z) yes no)
  1323  (NE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRLreg x y z) yes no)
  1324  (NE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRAreg x y z) yes no)
  1325  (EQ (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (EQ (TEQ x y) yes no)
  1326  (EQ (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (EQ (TEQconst [c] x) yes no)
  1327  (EQ (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftLL x y [c]) yes no)
  1328  (EQ (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRL x y [c]) yes no)
  1329  (EQ (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRA x y [c]) yes no)
  1330  (EQ (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftLLreg x y z) yes no)
  1331  (EQ (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRLreg x y z) yes no)
  1332  (EQ (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRAreg x y z) yes no)
  1333  (NE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (NE (TEQ x y) yes no)
  1334  (NE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (NE (TEQconst [c] x) yes no)
  1335  (NE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftLL x y [c]) yes no)
  1336  (NE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRL x y [c]) yes no)
  1337  (NE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRA x y [c]) yes no)
  1338  (NE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftLLreg x y z) yes no)
  1339  (NE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRLreg x y z) yes no)
  1340  (NE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRAreg x y z) yes no)
  1341  (LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LTnoov (CMP x y) yes no)
  1342  (LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
  1343  (LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMPconst [c] x) yes no)
  1344  (LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftLL x y [c]) yes no)
  1345  (LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRL x y [c]) yes no)
  1346  (LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRA x y [c]) yes no)
  1347  (LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftLLreg x y z) yes no)
  1348  (LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRLreg x y z) yes no)
  1349  (LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRAreg x y z) yes no)
  1350  (LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LEnoov (CMP x y) yes no)
  1351  (LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
  1352  (LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LEnoov (CMPconst [c] x) yes no)
  1353  (LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftLL x y [c]) yes no)
  1354  (LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRL x y [c]) yes no)
  1355  (LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRA x y [c]) yes no)
  1356  (LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftLLreg x y z) yes no)
  1357  (LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRLreg x y z) yes no)
  1358  (LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRAreg x y z) yes no)
  1359  (LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LTnoov (CMN x y) yes no)
  1360  (LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
  1361  (LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMNconst [c] x) yes no)
  1362  (LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftLL x y [c]) yes no)
  1363  (LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRL x y [c]) yes no)
  1364  (LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRA x y [c]) yes no)
  1365  (LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftLLreg x y z) yes no)
  1366  (LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRLreg x y z) yes no)
  1367  (LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRAreg x y z) yes no)
  1368  (LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LEnoov (CMN x y) yes no)
  1369  (LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
  1370  (LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1  => (LEnoov (CMNconst [c] x) yes no)
  1371  (LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftLL x y [c]) yes no)
  1372  (LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRL x y [c]) yes no)
  1373  (LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRA x y [c]) yes no)
  1374  (LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftLLreg x y z) yes no)
  1375  (LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRLreg x y z) yes no)
  1376  (LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRAreg x y z) yes no)
  1377  (LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LTnoov (TST x y) yes no)
  1378  (LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TSTconst [c] x) yes no)
  1379  (LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftLL x y [c]) yes no)
  1380  (LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRL x y [c]) yes no)
  1381  (LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRA x y [c]) yes no)
  1382  (LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftLLreg x y z) yes no)
  1383  (LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRLreg x y z) yes no)
  1384  (LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRAreg x y z) yes no)
  1385  (LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LEnoov (TST x y) yes no)
  1386  (LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LEnoov (TSTconst [c] x) yes no)
  1387  (LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftLL x y [c]) yes no)
  1388  (LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRL x y [c]) yes no)
  1389  (LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRA x y [c]) yes no)
  1390  (LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftLLreg x y z) yes no)
  1391  (LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRLreg x y z) yes no)
  1392  (LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRAreg x y z) yes no)
  1393  (LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LTnoov (TEQ x y) yes no)
  1394  (LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TEQconst [c] x) yes no)
  1395  (LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftLL x y [c]) yes no)
  1396  (LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRL x y [c]) yes no)
  1397  (LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRA x y [c]) yes no)
  1398  (LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftLLreg x y z) yes no)
  1399  (LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRLreg x y z) yes no)
  1400  (LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRAreg x y z) yes no)
  1401  (LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LEnoov (TEQ x y) yes no)
  1402  (LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1  => (LEnoov (TEQconst [c] x) yes no)
  1403  (LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftLL x y [c]) yes no)
  1404  (LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRL x y [c]) yes no)
  1405  (LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRA x y [c]) yes no)
  1406  (LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftLLreg x y z) yes no)
  1407  (LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRLreg x y z) yes no)
  1408  (LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRAreg x y z) yes no)
  1409  (GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GTnoov (CMP x y) yes no)
  1410  (GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
  1411  (GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMPconst [c] x) yes no)
  1412  (GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftLL x y [c]) yes no)
  1413  (GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRL x y [c]) yes no)
  1414  (GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRA x y [c]) yes no)
  1415  (GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftLLreg x y z) yes no)
  1416  (GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRLreg x y z) yes no)
  1417  (GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRAreg x y z) yes no)
  1418  (GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GEnoov (CMP x y) yes no)
  1419  (GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
  1420  (GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMPconst [c] x) yes no)
  1421  (GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftLL x y [c]) yes no)
  1422  (GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRL x y [c]) yes no)
  1423  (GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRA x y [c]) yes no)
  1424  (GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftLLreg x y z) yes no)
  1425  (GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRLreg x y z) yes no)
  1426  (GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRAreg x y z) yes no)
  1427  (GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GTnoov (CMN x y) yes no)
  1428  (GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMNconst [c] x) yes no)
  1429  (GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftLL x y [c]) yes no)
  1430  (GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRL x y [c]) yes no)
  1431  (GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRA x y [c]) yes no)
  1432  (GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftLLreg x y z) yes no)
  1433  (GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRLreg x y z) yes no)
  1434  (GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRAreg x y z) yes no)
  1435  (GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GEnoov (CMN x y) yes no)
  1436  (GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
  1437  (GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMNconst [c] x) yes no)
  1438  (GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftLL x y [c]) yes no)
  1439  (GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRL x y [c]) yes no)
  1440  (GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRA x y [c]) yes no)
  1441  (GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftLLreg x y z) yes no)
  1442  (GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRLreg x y z) yes no)
  1443  (GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRAreg x y z) yes no)
  1444  (GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
  1445  (GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GTnoov (TST x y) yes no)
  1446  (GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TSTconst [c] x) yes no)
  1447  (GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftLL x y [c]) yes no)
  1448  (GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRL x y [c]) yes no)
  1449  (GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRA x y [c]) yes no)
  1450  (GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftLLreg x y z) yes no)
  1451  (GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRLreg x y z) yes no)
  1452  (GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRAreg x y z) yes no)
  1453  (GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GEnoov (TST x y) yes no)
  1454  (GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TSTconst [c] x) yes no)
  1455  (GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftLL x y [c]) yes no)
  1456  (GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRL x y [c]) yes no)
  1457  (GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRA x y [c]) yes no)
  1458  (GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftLLreg x y z) yes no)
  1459  (GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRLreg x y z) yes no)
  1460  (GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRAreg x y z) yes no)
  1461  (GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GTnoov (TEQ x y) yes no)
  1462  (GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TEQconst [c] x) yes no)
  1463  (GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftLL x y [c]) yes no)
  1464  (GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRL x y [c]) yes no)
  1465  (GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRA x y [c]) yes no)
  1466  (GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftLLreg x y z) yes no)
  1467  (GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRLreg x y z) yes no)
  1468  (GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRAreg x y z) yes no)
  1469  (GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GEnoov (TEQ x y) yes no)
  1470  (GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TEQconst [c] x) yes no)
  1471  (GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftLL x y [c]) yes no)
  1472  (GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRL x y [c]) yes no)
  1473  (GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRA x y [c]) yes no)
  1474  (GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftLLreg x y z) yes no)
  1475  (GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRLreg x y z) yes no)
  1476  (GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRAreg x y z) yes no)
  1477  
  1478  (MOVBUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read8(sym, int64(off)))])
  1479  (MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
  1480  (MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
  1481  (MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(int8(read8(sym, int64(off))))])
  1482  (MOVHload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(int16(read16(sym, int64(off), config.ctxt.Arch.ByteOrder)))])
  1483  

View as plain text