Break really long lines.
Add spacing to line up columns.
In AMD64, put all the optimization rules after all the
lowering rules.
Change-Id: I45cc7368bf278416e67f89e74358db1bd4326a93
Reviewed-on: https://go-review.googlesource.com/22470
Reviewed-by: David Chase <drchase@google.com>
// license that can be found in the LICENSE file.
// Lowering arithmetic
-(Add64 x y) -> (ADDQ x y)
-(AddPtr x y) -> (ADDQ x y)
-(Add32 x y) -> (ADDL x y)
-(Add16 x y) -> (ADDL x y)
-(Add8 x y) -> (ADDL x y)
+(Add64 x y) -> (ADDQ x y)
+(AddPtr x y) -> (ADDQ x y)
+(Add32 x y) -> (ADDL x y)
+(Add16 x y) -> (ADDL x y)
+(Add8 x y) -> (ADDL x y)
(Add32F x y) -> (ADDSS x y)
(Add64F x y) -> (ADDSD x y)
-(Sub64 x y) -> (SUBQ x y)
-(SubPtr x y) -> (SUBQ x y)
-(Sub32 x y) -> (SUBL x y)
-(Sub16 x y) -> (SUBL x y)
-(Sub8 x y) -> (SUBL x y)
+(Sub64 x y) -> (SUBQ x y)
+(SubPtr x y) -> (SUBQ x y)
+(Sub32 x y) -> (SUBL x y)
+(Sub16 x y) -> (SUBL x y)
+(Sub8 x y) -> (SUBL x y)
(Sub32F x y) -> (SUBSS x y)
(Sub64F x y) -> (SUBSD x y)
-(Mul64 x y) -> (MULQ x y)
-(Mul32 x y) -> (MULL x y)
-(Mul16 x y) -> (MULL x y)
-(Mul8 x y) -> (MULL x y)
+(Mul64 x y) -> (MULQ x y)
+(Mul32 x y) -> (MULL x y)
+(Mul16 x y) -> (MULL x y)
+(Mul8 x y) -> (MULL x y)
(Mul32F x y) -> (MULSS x y)
(Mul64F x y) -> (MULSD x y)
(Div32F x y) -> (DIVSS x y)
(Div64F x y) -> (DIVSD x y)
-(Div64 x y) -> (DIVQ x y)
+(Div64 x y) -> (DIVQ x y)
(Div64u x y) -> (DIVQU x y)
-(Div32 x y) -> (DIVL x y)
+(Div32 x y) -> (DIVL x y)
(Div32u x y) -> (DIVLU x y)
-(Div16 x y) -> (DIVW x y)
+(Div16 x y) -> (DIVW x y)
(Div16u x y) -> (DIVWU x y)
-(Div8 x y) -> (DIVW (SignExt8to16 x) (SignExt8to16 y))
-(Div8u x y) -> (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+(Div8 x y) -> (DIVW (SignExt8to16 x) (SignExt8to16 y))
+(Div8u x y) -> (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
-(Hmul64 x y) -> (HMULQ x y)
+(Hmul64 x y) -> (HMULQ x y)
(Hmul64u x y) -> (HMULQU x y)
-(Hmul32 x y) -> (HMULL x y)
+(Hmul32 x y) -> (HMULL x y)
(Hmul32u x y) -> (HMULLU x y)
-(Hmul16 x y) -> (HMULW x y)
+(Hmul16 x y) -> (HMULW x y)
(Hmul16u x y) -> (HMULWU x y)
-(Hmul8 x y) -> (HMULB x y)
-(Hmul8u x y) -> (HMULBU x y)
+(Hmul8 x y) -> (HMULB x y)
+(Hmul8u x y) -> (HMULBU x y)
(Avg64u x y) -> (AVGQU x y)
-(Mod64 x y) -> (MODQ x y)
+(Mod64 x y) -> (MODQ x y)
(Mod64u x y) -> (MODQU x y)
-(Mod32 x y) -> (MODL x y)
+(Mod32 x y) -> (MODL x y)
(Mod32u x y) -> (MODLU x y)
-(Mod16 x y) -> (MODW x y)
+(Mod16 x y) -> (MODW x y)
(Mod16u x y) -> (MODWU x y)
-(Mod8 x y) -> (MODW (SignExt8to16 x) (SignExt8to16 y))
-(Mod8u x y) -> (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+(Mod8 x y) -> (MODW (SignExt8to16 x) (SignExt8to16 y))
+(Mod8u x y) -> (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
(And64 x y) -> (ANDQ x y)
(And32 x y) -> (ANDL x y)
(And16 x y) -> (ANDL x y)
-(And8 x y) -> (ANDL x y)
+(And8 x y) -> (ANDL x y)
(Or64 x y) -> (ORQ x y)
(Or32 x y) -> (ORL x y)
(Or16 x y) -> (ORL x y)
-(Or8 x y) -> (ORL x y)
+(Or8 x y) -> (ORL x y)
(Xor64 x y) -> (XORQ x y)
(Xor32 x y) -> (XORL x y)
(Xor16 x y) -> (XORL x y)
-(Xor8 x y) -> (XORL x y)
+(Xor8 x y) -> (XORL x y)
-(Neg64 x) -> (NEGQ x)
-(Neg32 x) -> (NEGL x)
-(Neg16 x) -> (NEGL x)
-(Neg8 x) -> (NEGL x)
+(Neg64 x) -> (NEGQ x)
+(Neg32 x) -> (NEGL x)
+(Neg16 x) -> (NEGL x)
+(Neg8 x) -> (NEGL x)
(Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
(Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
(Com64 x) -> (NOTQ x)
(Com32 x) -> (NOTL x)
(Com16 x) -> (NOTL x)
-(Com8 x) -> (NOTL x)
+(Com8 x) -> (NOTL x)
-// CMPQconst 0 below is redundant because BSF sets Z but how to remove?
+// Lowering boolean ops
+(AndB x y) -> (ANDL x y)
+(OrB x y) -> (ORL x y)
+(Not x) -> (XORLconst [1] x)
+
+// Lowering pointer arithmetic
+(OffPtr [off] ptr) && is32Bit(off) -> (ADDQconst [off] ptr)
+(OffPtr [off] ptr) -> (ADDQ (MOVQconst [off]) ptr)
+
+// Lowering other arithmetic
+// TODO: CMPQconst 0 below is redundant because BSF sets Z but how to remove?
(Ctz64 <t> x) -> (CMOVQEQconst (BSFQ <t> x) (CMPQconst x [0]) [64])
(Ctz32 <t> x) -> (CMOVLEQconst (BSFL <t> x) (CMPLconst x [0]) [32])
(Ctz16 <t> x) -> (CMOVWEQconst (BSFW <t> x) (CMPWconst x [0]) [16])
-(CMOVQEQconst x (InvertFlags y) [c]) -> (CMOVQNEconst x y [c])
-(CMOVLEQconst x (InvertFlags y) [c]) -> (CMOVLNEconst x y [c])
-(CMOVWEQconst x (InvertFlags y) [c]) -> (CMOVWNEconst x y [c])
-
-(CMOVQEQconst _ (FlagEQ) [c]) -> (Const64 [c])
-(CMOVLEQconst _ (FlagEQ) [c]) -> (Const32 [c])
-(CMOVWEQconst _ (FlagEQ) [c]) -> (Const16 [c])
-
-(CMOVQEQconst x (FlagLT_ULT)) -> x
-(CMOVLEQconst x (FlagLT_ULT)) -> x
-(CMOVWEQconst x (FlagLT_ULT)) -> x
-
-(CMOVQEQconst x (FlagLT_UGT)) -> x
-(CMOVLEQconst x (FlagLT_UGT)) -> x
-(CMOVWEQconst x (FlagLT_UGT)) -> x
-
-(CMOVQEQconst x (FlagGT_ULT)) -> x
-(CMOVLEQconst x (FlagGT_ULT)) -> x
-(CMOVWEQconst x (FlagGT_ULT)) -> x
-
-(CMOVQEQconst x (FlagGT_UGT)) -> x
-(CMOVLEQconst x (FlagGT_UGT)) -> x
-(CMOVWEQconst x (FlagGT_UGT)) -> x
-
(Bswap64 x) -> (BSWAPQ x)
(Bswap32 x) -> (BSWAPL x)
(Sqrt x) -> (SQRTSD x)
+// Lowering extension
// Note: we always extend to 64 bits even though some ops don't need that many result bits.
-(SignExt8to16 x) -> (MOVBQSX x)
-(SignExt8to32 x) -> (MOVBQSX x)
-(SignExt8to64 x) -> (MOVBQSX x)
+(SignExt8to16 x) -> (MOVBQSX x)
+(SignExt8to32 x) -> (MOVBQSX x)
+(SignExt8to64 x) -> (MOVBQSX x)
(SignExt16to32 x) -> (MOVWQSX x)
(SignExt16to64 x) -> (MOVWQSX x)
(SignExt32to64 x) -> (MOVLQSX x)
-(ZeroExt8to16 x) -> (MOVBQZX x)
-(ZeroExt8to32 x) -> (MOVBQZX x)
-(ZeroExt8to64 x) -> (MOVBQZX x)
+(ZeroExt8to16 x) -> (MOVBQZX x)
+(ZeroExt8to32 x) -> (MOVBQZX x)
+(ZeroExt8to64 x) -> (MOVBQZX x)
(ZeroExt16to32 x) -> (MOVWQZX x)
(ZeroExt16to64 x) -> (MOVWQZX x)
(ZeroExt32to64 x) -> (MOVLQZX x)
+// Lowering truncation
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8 x) -> x
+(Trunc32to8 x) -> x
+(Trunc32to16 x) -> x
+(Trunc64to8 x) -> x
+(Trunc64to16 x) -> x
+(Trunc64to32 x) -> x
+
+// Lowering float <-> int
(Cvt32to32F x) -> (CVTSL2SS x)
(Cvt32to64F x) -> (CVTSL2SD x)
(Cvt64to32F x) -> (CVTSQ2SS x)
(Cvt32Fto64F x) -> (CVTSS2SD x)
(Cvt64Fto32F x) -> (CVTSD2SS x)
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 x) -> x
-(Trunc32to8 x) -> x
-(Trunc32to16 x) -> x
-(Trunc64to8 x) -> x
-(Trunc64to16 x) -> x
-(Trunc64to32 x) -> x
-
// Lowering shifts
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
// result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
-// Note: for small shifts we generate 32 bits of mask even when we don't need it all.
(Lsh64x64 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPQconst y [64])))
(Lsh64x32 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPLconst y [64])))
(Lsh64x16 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPWconst y [64])))
-(Lsh64x8 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst y [64])))
+(Lsh64x8 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst y [64])))
(Lsh32x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst y [32])))
(Lsh32x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst y [32])))
(Lsh32x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
-(Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
+(Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Lsh16x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst y [32])))
(Lsh16x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst y [32])))
(Lsh16x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
-(Lsh16x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
+(Lsh16x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Lsh8x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst y [32])))
(Lsh8x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst y [32])))
(Lsh8x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
-(Lsh8x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
+(Lsh8x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Lrot64 <t> x [c]) -> (ROLQconst <t> [c&63] x)
(Lrot32 <t> x [c]) -> (ROLLconst <t> [c&31] x)
(Lrot16 <t> x [c]) -> (ROLWconst <t> [c&15] x)
-(Lrot8 <t> x [c]) -> (ROLBconst <t> [c&7] x)
+(Lrot8 <t> x [c]) -> (ROLBconst <t> [c&7] x)
(Rsh64Ux64 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPQconst y [64])))
(Rsh64Ux32 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPLconst y [64])))
(Rsh64Ux16 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPWconst y [64])))
-(Rsh64Ux8 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst y [64])))
+(Rsh64Ux8 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst y [64])))
(Rsh32Ux64 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPQconst y [32])))
(Rsh32Ux32 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPLconst y [32])))
(Rsh32Ux16 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
-(Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
+(Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Rsh16Ux64 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst y [16])))
(Rsh16Ux32 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst y [16])))
(Rsh16Ux16 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst y [16])))
-(Rsh16Ux8 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst y [16])))
+(Rsh16Ux8 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst y [16])))
(Rsh8Ux64 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst y [8])))
(Rsh8Ux32 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst y [8])))
(Rsh8Ux16 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst y [8])))
-(Rsh8Ux8 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst y [8])))
+(Rsh8Ux8 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst y [8])))
// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
-// Note: for small shift widths we generate 32 bits of mask even when we don't need it all.
(Rsh64x64 <t> x y) -> (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [64])))))
(Rsh64x32 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [64])))))
(Rsh64x16 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [64])))))
-(Rsh64x8 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [64])))))
+(Rsh64x8 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [64])))))
(Rsh32x64 <t> x y) -> (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [32])))))
(Rsh32x32 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [32])))))
(Rsh32x16 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [32])))))
-(Rsh32x8 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [32])))))
+(Rsh32x8 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [32])))))
(Rsh16x64 <t> x y) -> (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [16])))))
(Rsh16x32 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [16])))))
(Rsh16x16 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [16])))))
-(Rsh16x8 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [16])))))
+(Rsh16x8 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [16])))))
(Rsh8x64 <t> x y) -> (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [8])))))
(Rsh8x32 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [8])))))
(Rsh8x16 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [8])))))
-(Rsh8x8 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [8])))))
+(Rsh8x8 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [8])))))
-(Less64 x y) -> (SETL (CMPQ x y))
-(Less32 x y) -> (SETL (CMPL x y))
-(Less16 x y) -> (SETL (CMPW x y))
-(Less8 x y) -> (SETL (CMPB x y))
+// Lowering comparisons
+(Less64 x y) -> (SETL (CMPQ x y))
+(Less32 x y) -> (SETL (CMPL x y))
+(Less16 x y) -> (SETL (CMPW x y))
+(Less8 x y) -> (SETL (CMPB x y))
(Less64U x y) -> (SETB (CMPQ x y))
(Less32U x y) -> (SETB (CMPL x y))
(Less16U x y) -> (SETB (CMPW x y))
(Less64F x y) -> (SETGF (UCOMISD y x))
(Less32F x y) -> (SETGF (UCOMISS y x))
-(Leq64 x y) -> (SETLE (CMPQ x y))
-(Leq32 x y) -> (SETLE (CMPL x y))
-(Leq16 x y) -> (SETLE (CMPW x y))
-(Leq8 x y) -> (SETLE (CMPB x y))
+(Leq64 x y) -> (SETLE (CMPQ x y))
+(Leq32 x y) -> (SETLE (CMPL x y))
+(Leq16 x y) -> (SETLE (CMPW x y))
+(Leq8 x y) -> (SETLE (CMPB x y))
(Leq64U x y) -> (SETBE (CMPQ x y))
(Leq32U x y) -> (SETBE (CMPL x y))
(Leq16U x y) -> (SETBE (CMPW x y))
(Leq64F x y) -> (SETGEF (UCOMISD y x))
(Leq32F x y) -> (SETGEF (UCOMISS y x))
-(Greater64 x y) -> (SETG (CMPQ x y))
-(Greater32 x y) -> (SETG (CMPL x y))
-(Greater16 x y) -> (SETG (CMPW x y))
-(Greater8 x y) -> (SETG (CMPB x y))
+(Greater64 x y) -> (SETG (CMPQ x y))
+(Greater32 x y) -> (SETG (CMPL x y))
+(Greater16 x y) -> (SETG (CMPW x y))
+(Greater8 x y) -> (SETG (CMPB x y))
(Greater64U x y) -> (SETA (CMPQ x y))
(Greater32U x y) -> (SETA (CMPL x y))
(Greater16U x y) -> (SETA (CMPW x y))
(Greater64F x y) -> (SETGF (UCOMISD x y))
(Greater32F x y) -> (SETGF (UCOMISS x y))
-(Geq64 x y) -> (SETGE (CMPQ x y))
-(Geq32 x y) -> (SETGE (CMPL x y))
-(Geq16 x y) -> (SETGE (CMPW x y))
-(Geq8 x y) -> (SETGE (CMPB x y))
+(Geq64 x y) -> (SETGE (CMPQ x y))
+(Geq32 x y) -> (SETGE (CMPL x y))
+(Geq16 x y) -> (SETGE (CMPW x y))
+(Geq8 x y) -> (SETGE (CMPB x y))
(Geq64U x y) -> (SETAE (CMPQ x y))
(Geq32U x y) -> (SETAE (CMPL x y))
(Geq16U x y) -> (SETAE (CMPW x y))
(Geq64F x y) -> (SETGEF (UCOMISD x y))
(Geq32F x y) -> (SETGEF (UCOMISS x y))
-(Eq64 x y) -> (SETEQ (CMPQ x y))
-(Eq32 x y) -> (SETEQ (CMPL x y))
-(Eq16 x y) -> (SETEQ (CMPW x y))
-(Eq8 x y) -> (SETEQ (CMPB x y))
-(EqB x y) -> (SETEQ (CMPB x y))
+(Eq64 x y) -> (SETEQ (CMPQ x y))
+(Eq32 x y) -> (SETEQ (CMPL x y))
+(Eq16 x y) -> (SETEQ (CMPW x y))
+(Eq8 x y) -> (SETEQ (CMPB x y))
+(EqB x y) -> (SETEQ (CMPB x y))
(EqPtr x y) -> (SETEQ (CMPQ x y))
(Eq64F x y) -> (SETEQF (UCOMISD x y))
(Eq32F x y) -> (SETEQF (UCOMISS x y))
-(Neq64 x y) -> (SETNE (CMPQ x y))
-(Neq32 x y) -> (SETNE (CMPL x y))
-(Neq16 x y) -> (SETNE (CMPW x y))
-(Neq8 x y) -> (SETNE (CMPB x y))
-(NeqB x y) -> (SETNE (CMPB x y))
+(Neq64 x y) -> (SETNE (CMPQ x y))
+(Neq32 x y) -> (SETNE (CMPL x y))
+(Neq16 x y) -> (SETNE (CMPW x y))
+(Neq8 x y) -> (SETNE (CMPB x y))
+(NeqB x y) -> (SETNE (CMPB x y))
(NeqPtr x y) -> (SETNE (CMPQ x y))
(Neq64F x y) -> (SETNEF (UCOMISD x y))
(Neq32F x y) -> (SETNEF (UCOMISS x y))
+// Lowering loads
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVQload ptr mem)
(Load <t> ptr mem) && is32BitInt(t) -> (MOVLload ptr mem)
(Load <t> ptr mem) && is16BitInt(t) -> (MOVWload ptr mem)
(Load <t> ptr mem) && is32BitFloat(t) -> (MOVSSload ptr mem)
(Load <t> ptr mem) && is64BitFloat(t) -> (MOVSDload ptr mem)
+// Lowering stores
// These more-specific FP versions of Store pattern should come first.
(Store [8] ptr val mem) && is64BitFloat(val.Type) -> (MOVSDstore ptr val mem)
(Store [4] ptr val mem) && is32BitFloat(val.Type) -> (MOVSSstore ptr val mem)
(Store [2] ptr val mem) -> (MOVWstore ptr val mem)
(Store [1] ptr val mem) -> (MOVBstore ptr val mem)
-// We want this to stick out so the to/from ptr conversion is obvious
-(Convert <t> x mem) -> (MOVQconvert <t> x mem)
-
-// checks
-(IsNonNil p) -> (SETNE (TESTQ p p))
-(IsInBounds idx len) -> (SETB (CMPQ idx len))
-(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len))
-(NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
-
-(GetG mem) -> (LoweredGetG mem)
-(GetClosurePtr) -> (LoweredGetClosurePtr)
-
-// Small moves
+// Lowering moves
(Move [0] _ _ mem) -> mem
(Move [1] dst src mem) -> (MOVBstore dst (MOVBload src mem) mem)
(Move [2] dst src mem) -> (MOVWstore dst (MOVWload src mem) mem)
(Move [size] dst src mem) && (size > 16*64 || config.noDuffDevice) && size%8 == 0 ->
(REPMOVSQ dst src (MOVQconst [size/8]) mem)
-(AndB x y) -> (ANDL x y)
-(OrB x y) -> (ORL x y)
-(Not x) -> (XORLconst [1] x)
+// Lowering Zero instructions
+(Zero [0] _ mem) -> mem
+(Zero [1] destptr mem) -> (MOVBstoreconst [0] destptr mem)
+(Zero [2] destptr mem) -> (MOVWstoreconst [0] destptr mem)
+(Zero [4] destptr mem) -> (MOVLstoreconst [0] destptr mem)
+(Zero [8] destptr mem) -> (MOVQstoreconst [0] destptr mem)
-(OffPtr [off] ptr) && is32Bit(off) -> (ADDQconst [off] ptr)
-(OffPtr [off] ptr) -> (ADDQ (MOVQconst [off]) ptr)
+(Zero [3] destptr mem) ->
+ (MOVBstoreconst [makeValAndOff(0,2)] destptr
+ (MOVWstoreconst [0] destptr mem))
+(Zero [5] destptr mem) ->
+ (MOVBstoreconst [makeValAndOff(0,4)] destptr
+ (MOVLstoreconst [0] destptr mem))
+(Zero [6] destptr mem) ->
+ (MOVWstoreconst [makeValAndOff(0,4)] destptr
+ (MOVLstoreconst [0] destptr mem))
+(Zero [7] destptr mem) ->
+ (MOVLstoreconst [makeValAndOff(0,3)] destptr
+ (MOVLstoreconst [0] destptr mem))
-(Const8 [val]) -> (MOVLconst [val])
-(Const16 [val]) -> (MOVLconst [val])
-(Const32 [val]) -> (MOVLconst [val])
-(Const64 [val]) -> (MOVQconst [val])
+// Strip off any fractional word zeroing.
+(Zero [size] destptr mem) && size%8 != 0 && size > 8 ->
+ (Zero [size-size%8] (ADDQconst destptr [size%8])
+ (MOVQstoreconst [0] destptr mem))
+
+// Zero small numbers of words directly.
+(Zero [16] destptr mem) ->
+ (MOVQstoreconst [makeValAndOff(0,8)] destptr
+ (MOVQstoreconst [0] destptr mem))
+(Zero [24] destptr mem) ->
+ (MOVQstoreconst [makeValAndOff(0,16)] destptr
+ (MOVQstoreconst [makeValAndOff(0,8)] destptr
+ (MOVQstoreconst [0] destptr mem)))
+(Zero [32] destptr mem) ->
+ (MOVQstoreconst [makeValAndOff(0,24)] destptr
+ (MOVQstoreconst [makeValAndOff(0,16)] destptr
+ (MOVQstoreconst [makeValAndOff(0,8)] destptr
+ (MOVQstoreconst [0] destptr mem))))
+
+// Medium zeroing uses a duff device.
+(Zero [size] destptr mem) && size <= 1024 && size%8 == 0 && size%16 != 0 && !config.noDuffDevice ->
+ (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
+(Zero [size] destptr mem) && size <= 1024 && size%16 == 0 && !config.noDuffDevice ->
+ (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem)
+
+// Large zeroing uses REP STOSQ.
+(Zero [size] destptr mem) && (size > 1024 || (config.noDuffDevice && size > 32)) && size%8 == 0 ->
+ (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem)
+
+// Lowering constants
+(Const8 [val]) -> (MOVLconst [val])
+(Const16 [val]) -> (MOVLconst [val])
+(Const32 [val]) -> (MOVLconst [val])
+(Const64 [val]) -> (MOVQconst [val])
(Const32F [val]) -> (MOVSSconst [val])
(Const64F [val]) -> (MOVSDconst [val])
(ConstNil) -> (MOVQconst [0])
(ConstBool [b]) -> (MOVLconst [b])
-(Addr {sym} base) -> (LEAQ {sym} base)
+// Lowering calls
+(StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem)
+(ClosureCall [argwid] entry closure mem) -> (CALLclosure [argwid] entry closure mem)
+(DeferCall [argwid] mem) -> (CALLdefer [argwid] mem)
+(GoCall [argwid] mem) -> (CALLgo [argwid] mem)
+(InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
+// Miscellaneous
+(Convert <t> x mem) -> (MOVQconvert <t> x mem)
+(IsNonNil p) -> (SETNE (TESTQ p p))
+(IsInBounds idx len) -> (SETB (CMPQ idx len))
+(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len))
+(NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
+(GetG mem) -> (LoweredGetG mem)
+(GetClosurePtr) -> (LoweredGetClosurePtr)
+(Addr {sym} base) -> (LEAQ {sym} base)
(ITab (Load ptr mem)) -> (MOVQload ptr mem)
// block rewrites
(If cond yes no) -> (NE (TESTB cond cond) yes no)
+// ***************************
+// Above: lowering rules
+// Below: optimizations
+// ***************************
+// TODO: Should the optimizations be a separate pass?
+
+// Fold boolean tests into blocks
(NE (TESTB (SETL cmp) (SETL cmp)) yes no) -> (LT cmp yes no)
(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) -> (LE cmp yes no)
(NE (TESTB (SETG cmp) (SETG cmp)) yes no) -> (GT cmp yes no)
// (SETNEF x) -> (ORQ (SETNE <config.Frontend().TypeInt8()> x) (SETNAN <config.Frontend().TypeInt8()> x))
// (SETEQF x) -> (ANDQ (SETEQ <config.Frontend().TypeInt8()> x) (SETORD <config.Frontend().TypeInt8()> x))
-(StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem)
-(ClosureCall [argwid] entry closure mem) -> (CALLclosure [argwid] entry closure mem)
-(DeferCall [argwid] mem) -> (CALLdefer [argwid] mem)
-(GoCall [argwid] mem) -> (CALLgo [argwid] mem)
-(InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
-
-// Rules below here apply some simple optimizations after lowering.
-// TODO: Should this be a separate pass?
-
// fold constants into instructions
(ADDQ x (MOVQconst [c])) && is32Bit(c) -> (ADDQconst [c] x)
(ADDQ (MOVQconst [c]) x) && is32Bit(c) -> (ADDQconst [c] x)
(MOVLstoreconst [x] {sym} (ADDQ ptr idx) mem) -> (MOVLstoreconstidx1 [x] {sym} ptr idx mem)
(MOVQstoreconst [x] {sym} (ADDQ ptr idx) mem) -> (MOVQstoreconstidx1 [x] {sym} ptr idx mem)
-
// combine SHLQ into indexed loads and stores
(MOVWloadidx1 [c] {sym} ptr (SHLQconst [1] idx) mem) -> (MOVWloadidx2 [c] {sym} ptr idx mem)
(MOVLloadidx1 [c] {sym} ptr (SHLQconst [2] idx) mem) -> (MOVLloadidx4 [c] {sym} ptr idx mem)
(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
(LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y)
-// lower Zero instructions with word sizes
-(Zero [0] _ mem) -> mem
-(Zero [1] destptr mem) -> (MOVBstoreconst [0] destptr mem)
-(Zero [2] destptr mem) -> (MOVWstoreconst [0] destptr mem)
-(Zero [4] destptr mem) -> (MOVLstoreconst [0] destptr mem)
-(Zero [8] destptr mem) -> (MOVQstoreconst [0] destptr mem)
-
-(Zero [3] destptr mem) ->
- (MOVBstoreconst [makeValAndOff(0,2)] destptr
- (MOVWstoreconst [0] destptr mem))
-(Zero [5] destptr mem) ->
- (MOVBstoreconst [makeValAndOff(0,4)] destptr
- (MOVLstoreconst [0] destptr mem))
-(Zero [6] destptr mem) ->
- (MOVWstoreconst [makeValAndOff(0,4)] destptr
- (MOVLstoreconst [0] destptr mem))
-(Zero [7] destptr mem) ->
- (MOVLstoreconst [makeValAndOff(0,3)] destptr
- (MOVLstoreconst [0] destptr mem))
-
-// Strip off any fractional word zeroing.
-(Zero [size] destptr mem) && size%8 != 0 && size > 8 ->
- (Zero [size-size%8] (ADDQconst destptr [size%8])
- (MOVQstoreconst [0] destptr mem))
-
-// Zero small numbers of words directly.
-(Zero [16] destptr mem) ->
- (MOVQstoreconst [makeValAndOff(0,8)] destptr
- (MOVQstoreconst [0] destptr mem))
-(Zero [24] destptr mem) ->
- (MOVQstoreconst [makeValAndOff(0,16)] destptr
- (MOVQstoreconst [makeValAndOff(0,8)] destptr
- (MOVQstoreconst [0] destptr mem)))
-(Zero [32] destptr mem) ->
- (MOVQstoreconst [makeValAndOff(0,24)] destptr
- (MOVQstoreconst [makeValAndOff(0,16)] destptr
- (MOVQstoreconst [makeValAndOff(0,8)] destptr
- (MOVQstoreconst [0] destptr mem))))
-
-// Medium zeroing uses a duff device.
-(Zero [size] destptr mem) && size <= 1024 && size%8 == 0 && size%16 != 0 && !config.noDuffDevice ->
- (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
-(Zero [size] destptr mem) && size <= 1024 && size%16 == 0 && !config.noDuffDevice ->
- (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem)
-
-// Large zeroing uses REP STOSQ.
-(Zero [size] destptr mem) && (size > 1024 || (config.noDuffDevice && size > 32)) && size%8 == 0 ->
- (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem)
-
// Absorb InvertFlags into branches.
(LT (InvertFlags cmp) yes no) -> (GT cmp yes no)
(GT (InvertFlags cmp) yes no) -> (LT cmp yes no)
(CMPWconst x [0]) -> (TESTW x x)
(CMPBconst x [0]) -> (TESTB x x)
+// Optimizing conditional moves
+(CMOVQEQconst x (InvertFlags y) [c]) -> (CMOVQNEconst x y [c])
+(CMOVLEQconst x (InvertFlags y) [c]) -> (CMOVLNEconst x y [c])
+(CMOVWEQconst x (InvertFlags y) [c]) -> (CMOVWNEconst x y [c])
+
+(CMOVQEQconst _ (FlagEQ) [c]) -> (Const64 [c])
+(CMOVLEQconst _ (FlagEQ) [c]) -> (Const32 [c])
+(CMOVWEQconst _ (FlagEQ) [c]) -> (Const16 [c])
+
+(CMOVQEQconst x (FlagLT_ULT)) -> x
+(CMOVLEQconst x (FlagLT_ULT)) -> x
+(CMOVWEQconst x (FlagLT_ULT)) -> x
+
+(CMOVQEQconst x (FlagLT_UGT)) -> x
+(CMOVLEQconst x (FlagLT_UGT)) -> x
+(CMOVWEQconst x (FlagLT_UGT)) -> x
+
+(CMOVQEQconst x (FlagGT_ULT)) -> x
+(CMOVLEQconst x (FlagGT_ULT)) -> x
+(CMOVWEQconst x (FlagGT_ULT)) -> x
+
+(CMOVQEQconst x (FlagGT_UGT)) -> x
+(CMOVLEQconst x (FlagGT_UGT)) -> x
+(CMOVWEQconst x (FlagGT_UGT)) -> x
+
// Combining byte loads into larger (unaligned) loads.
// There are many ways these combinations could occur. This is
// designed to match the way encoding/binary.LittleEndian does it.
// - an additional conditional can be provided after the match pattern with "&&".
// on the generated side
// - the type of the top-level expression is the same as the one on the left-hand side.
-// - the type of any subexpressions must be specified explicitly.
+// - the type of any subexpressions must be specified explicitly (or
+// be specified in the op's type field).
// - auxint will be 0 if not specified.
// - aux will be nil if not specified.
// For now, the generated successors must be a permutation of the matched successors.
// constant folding
-(Trunc16to8 (Const16 [c])) -> (Const8 [int64(int8(c))])
-(Trunc32to8 (Const32 [c])) -> (Const8 [int64(int8(c))])
-(Trunc32to16 (Const32 [c])) -> (Const16 [int64(int16(c))])
-(Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))])
-(Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))])
-(Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))])
+(Trunc16to8 (Const16 [c])) -> (Const8 [int64(int8(c))])
+(Trunc32to8 (Const32 [c])) -> (Const8 [int64(int8(c))])
+(Trunc32to16 (Const32 [c])) -> (Const16 [int64(int16(c))])
+(Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))])
+(Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))])
+(Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))])
(Cvt64Fto32F (Const64F [c])) -> (Const32F [f2i(float64(i2f32(c)))])
(Cvt32Fto64F (Const32F [c])) -> (Const64F [c]) // c is already a 64 bit float
//(Neg32F (Const32F [c])) -> (Const32F [f2i(-i2f(c))])
//(Neg64F (Const64F [c])) -> (Const64F [f2i(-i2f(c))])
-(Add8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c+d))])
-(Add16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c+d))])
-(Add32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c+d))])
-(Add64 (Const64 [c]) (Const64 [d])) -> (Const64 [c+d])
+(Add8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c+d))])
+(Add16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c+d))])
+(Add32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c+d))])
+(Add64 (Const64 [c]) (Const64 [d])) -> (Const64 [c+d])
(Add32F (Const32F [c]) (Const32F [d])) ->
(Const32F [f2i(float64(i2f32(c) + i2f32(d)))]) // ensure we combine the operands with 32 bit precision
(Add64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) + i2f(d))])
(AddPtr <t> x (Const64 [c])) -> (OffPtr <t> x [c])
-(Sub8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c-d))])
-(Sub16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c-d))])
-(Sub32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c-d))])
-(Sub64 (Const64 [c]) (Const64 [d])) -> (Const64 [c-d])
+(Sub8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c-d))])
+(Sub16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c-d))])
+(Sub32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c-d))])
+(Sub64 (Const64 [c]) (Const64 [d])) -> (Const64 [c-d])
(Sub32F (Const32F [c]) (Const32F [d])) ->
(Const32F [f2i(float64(i2f32(c) - i2f32(d)))])
(Sub64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) - i2f(d))])
-(Mul8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c*d))])
-(Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c*d))])
-(Mul32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c*d))])
-(Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
+(Mul8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c*d))])
+(Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c*d))])
+(Mul32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c*d))])
+(Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
(Mul32F (Const32F [c]) (Const32F [d])) ->
(Const32F [f2i(float64(i2f32(c) * i2f32(d)))])
(Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) * i2f(d))])
-(Mod8 (Const8 [c]) (Const8 [d])) && d != 0-> (Const8 [int64(int8(c % d))])
-(Mod16 (Const16 [c]) (Const16 [d])) && d != 0-> (Const16 [int64(int16(c % d))])
-(Mod32 (Const32 [c]) (Const32 [d])) && d != 0-> (Const32 [int64(int32(c % d))])
-(Mod64 (Const64 [c]) (Const64 [d])) && d != 0-> (Const64 [c % d])
+(Mod8 (Const8 [c]) (Const8 [d])) && d != 0 -> (Const8 [int64(int8(c % d))])
+(Mod16 (Const16 [c]) (Const16 [d])) && d != 0 -> (Const16 [int64(int16(c % d))])
+(Mod32 (Const32 [c]) (Const32 [d])) && d != 0 -> (Const32 [int64(int32(c % d))])
+(Mod64 (Const64 [c]) (Const64 [d])) && d != 0 -> (Const64 [c % d])
-(Mod8u (Const8 [c]) (Const8 [d])) && d != 0-> (Const8 [int64(uint8(c) % uint8(d))])
-(Mod16u (Const16 [c]) (Const16 [d])) && d != 0-> (Const16 [int64(uint16(c) % uint16(d))])
-(Mod32u (Const32 [c]) (Const32 [d])) && d != 0-> (Const32 [int64(uint32(c) % uint32(d))])
-(Mod64u (Const64 [c]) (Const64 [d])) && d != 0-> (Const64 [int64(uint64(c) % uint64(d))])
+(Mod8u (Const8 [c]) (Const8 [d])) && d != 0 -> (Const8 [int64(uint8(c) % uint8(d))])
+(Mod16u (Const16 [c]) (Const16 [d])) && d != 0 -> (Const16 [int64(uint16(c) % uint16(d))])
+(Mod32u (Const32 [c]) (Const32 [d])) && d != 0 -> (Const32 [int64(uint32(c) % uint32(d))])
+(Mod64u (Const64 [c]) (Const64 [d])) && d != 0 -> (Const64 [int64(uint64(c) % uint64(d))])
(Lsh64x64 (Const64 [c]) (Const64 [d])) -> (Const64 [c << uint64(d)])
(Rsh64x64 (Const64 [c]) (Const64 [d])) -> (Const64 [c >> uint64(d)])
(Rsh8x64 (Const8 [c]) (Const64 [d])) -> (Const8 [int64(int8(c) >> uint64(d))])
(Rsh8Ux64 (Const8 [c]) (Const64 [d])) -> (Const8 [int64(int8(uint8(c) >> uint64(d)))])
-(Lsh64x64 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64x64 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64Ux64 (Const64 [0]) _) -> (Const64 [0])
-(Lsh32x64 (Const32 [0]) _) -> (Const32 [0])
-(Rsh32x64 (Const32 [0]) _) -> (Const32 [0])
-(Rsh32Ux64 (Const32 [0]) _) -> (Const32 [0])
-(Lsh16x64 (Const16 [0]) _) -> (Const16 [0])
-(Rsh16x64 (Const16 [0]) _) -> (Const16 [0])
-(Rsh16Ux64 (Const16 [0]) _) -> (Const16 [0])
-(Lsh8x64 (Const8 [0]) _) -> (Const8 [0])
-(Rsh8x64 (Const8 [0]) _) -> (Const8 [0])
-(Rsh8Ux64 (Const8 [0]) _) -> (Const8 [0])
-
-// ((x >> c1) << c2) >> c3
-(Rsh64Ux64 (Lsh64x64 (Rsh64Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3])) && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) -> (Rsh64Ux64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
-(Rsh32Ux32 (Lsh32x32 (Rsh32Ux32 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3])) && uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2) -> (Rsh32Ux32 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
-(Rsh16Ux16 (Lsh16x16 (Rsh16Ux16 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3])) && uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2) -> (Rsh16Ux16 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
-(Rsh8Ux8 (Lsh8x8 (Rsh8Ux8 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3])) && uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2) -> (Rsh8Ux8 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
-
-// ((x << c1) >> c2) << c3
-(Lsh64x64 (Rsh64Ux64 (Lsh64x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3])) && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) -> (Lsh64x64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
-(Lsh32x32 (Rsh32Ux32 (Lsh32x32 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3])) && uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2) -> (Lsh32x32 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
-(Lsh16x16 (Rsh16Ux16 (Lsh16x16 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3])) && uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2) -> (Lsh16x16 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
-(Lsh8x8 (Rsh8Ux8 (Lsh8x8 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3])) && uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2) -> (Lsh8x8 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
-
// Fold IsInBounds when the range of the index cannot exceed the limit.
-(IsInBounds (ZeroExt8to32 _) (Const32 [c])) && (1 << 8) <= c -> (ConstBool [1])
-(IsInBounds (ZeroExt8to64 _) (Const64 [c])) && (1 << 8) <= c -> (ConstBool [1])
+(IsInBounds (ZeroExt8to32 _) (Const32 [c])) && (1 << 8) <= c -> (ConstBool [1])
+(IsInBounds (ZeroExt8to64 _) (Const64 [c])) && (1 << 8) <= c -> (ConstBool [1])
(IsInBounds (ZeroExt16to32 _) (Const32 [c])) && (1 << 16) <= c -> (ConstBool [1])
(IsInBounds (ZeroExt16to64 _) (Const64 [c])) && (1 << 16) <= c -> (ConstBool [1])
(IsInBounds x x) -> (ConstBool [0])
(Eq64 x x) -> (ConstBool [1])
(Eq32 x x) -> (ConstBool [1])
(Eq16 x x) -> (ConstBool [1])
-(Eq8 x x) -> (ConstBool [1])
+(Eq8 x x) -> (ConstBool [1])
(EqB (ConstBool [c]) (ConstBool [d])) -> (ConstBool [b2i(c == d)])
(EqB (ConstBool [0]) x) -> (Not x)
(EqB (ConstBool [1]) x) -> x
(Neq64 x x) -> (ConstBool [0])
(Neq32 x x) -> (ConstBool [0])
(Neq16 x x) -> (ConstBool [0])
-(Neq8 x x) -> (ConstBool [0])
+(Neq8 x x) -> (ConstBool [0])
(NeqB (ConstBool [c]) (ConstBool [d])) -> (ConstBool [b2i(c != d)])
(NeqB (ConstBool [0]) x) -> x
(NeqB (ConstBool [1]) x) -> (Not x)
(Eq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) -> (Eq64 (Const64 <t> [c-d]) x)
(Eq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) -> (Eq32 (Const32 <t> [int64(int32(c-d))]) x)
(Eq16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) -> (Eq16 (Const16 <t> [int64(int16(c-d))]) x)
-(Eq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x)) -> (Eq8 (Const8 <t> [int64(int8(c-d))]) x)
+(Eq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x)) -> (Eq8 (Const8 <t> [int64(int8(c-d))]) x)
(Neq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) -> (Neq64 (Const64 <t> [c-d]) x)
(Neq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) -> (Neq32 (Const32 <t> [int64(int32(c-d))]) x)
(Neq16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) -> (Neq16 (Const16 <t> [int64(int16(c-d))]) x)
-(Neq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x)) -> (Neq8 (Const8 <t> [int64(int8(c-d))]) x)
+(Neq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x)) -> (Neq8 (Const8 <t> [int64(int8(c-d))]) x)
// canonicalize: swap arguments for commutative operations when one argument is a constant.
(Eq64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Eq64 (Const64 <t> [c]) x)
(Eq32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Eq32 (Const32 <t> [c]) x)
(Eq16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Eq16 (Const16 <t> [c]) x)
-(Eq8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Eq8 (Const8 <t> [c]) x)
+(Eq8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Eq8 (Const8 <t> [c]) x)
(Neq64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Neq64 (Const64 <t> [c]) x)
(Neq32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Neq32 (Const32 <t> [c]) x)
(Neq16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Neq16 (Const16 <t> [c]) x)
-(Neq8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Neq8 (Const8 <t> [c]) x)
+(Neq8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Neq8 (Const8 <t> [c]) x)
// AddPtr is not canonicalized because nilcheck ptr checks the first argument to be non-nil.
(Add64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Add64 (Const64 <t> [c]) x)
(Add32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Add32 (Const32 <t> [c]) x)
(Add16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Add16 (Const16 <t> [c]) x)
-(Add8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Add8 (Const8 <t> [c]) x)
+(Add8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Add8 (Const8 <t> [c]) x)
(Mul64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Mul64 (Const64 <t> [c]) x)
(Mul32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Mul32 (Const32 <t> [c]) x)
(Mul16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Mul16 (Const16 <t> [c]) x)
-(Mul8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Mul8 (Const8 <t> [c]) x)
+(Mul8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Mul8 (Const8 <t> [c]) x)
(Sub64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Add64 (Const64 <t> [-c]) x)
(Sub32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Add32 (Const32 <t> [int64(int32(-c))]) x)
(Sub16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Add16 (Const16 <t> [int64(int16(-c))]) x)
-(Sub8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Add8 (Const8 <t> [int64(int8(-c))]) x)
+(Sub8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Add8 (Const8 <t> [int64(int8(-c))]) x)
(And64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (And64 (Const64 <t> [c]) x)
(And32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (And32 (Const32 <t> [c]) x)
(And16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (And16 (Const16 <t> [c]) x)
-(And8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (And8 (Const8 <t> [c]) x)
+(And8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (And8 (Const8 <t> [c]) x)
(Or64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Or64 (Const64 <t> [c]) x)
(Or32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Or32 (Const32 <t> [c]) x)
(Or16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Or16 (Const16 <t> [c]) x)
-(Or8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Or8 (Const8 <t> [c]) x)
+(Or8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Or8 (Const8 <t> [c]) x)
(Xor64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Xor64 (Const64 <t> [c]) x)
(Xor32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Xor32 (Const32 <t> [c]) x)
(Xor16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Xor16 (Const16 <t> [c]) x)
-(Xor8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Xor8 (Const8 <t> [c]) x)
+(Xor8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Xor8 (Const8 <t> [c]) x)
// Distribute multiplication c * (d+x) -> c*d + c*x. Useful for:
// a[i].b = ...; a[i+1].b = ...
-(Mul64 (Const64 <t> [c]) (Add64 <t> (Const64 <t> [d]) x)) -> (Add64 (Const64 <t> [c*d]) (Mul64 <t> (Const64 <t> [c]) x))
-(Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) -> (Add32 (Const32 <t> [int64(int32(c*d))]) (Mul32 <t> (Const32 <t> [c]) x))
+(Mul64 (Const64 <t> [c]) (Add64 <t> (Const64 <t> [d]) x)) ->
+ (Add64 (Const64 <t> [c*d]) (Mul64 <t> (Const64 <t> [c]) x))
+(Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) ->
+ (Add32 (Const32 <t> [int64(int32(c*d))]) (Mul32 <t> (Const32 <t> [c]) x))
// rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce
// the number of the other rewrite rules for const shifts
(Lsh64x32 <t> x (Const32 [c])) -> (Lsh64x64 x (Const64 <t> [int64(uint32(c))]))
(Lsh64x16 <t> x (Const16 [c])) -> (Lsh64x64 x (Const64 <t> [int64(uint16(c))]))
-(Lsh64x8 <t> x (Const8 [c])) -> (Lsh64x64 x (Const64 <t> [int64(uint8(c))]))
+(Lsh64x8 <t> x (Const8 [c])) -> (Lsh64x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh64x32 <t> x (Const32 [c])) -> (Rsh64x64 x (Const64 <t> [int64(uint32(c))]))
(Rsh64x16 <t> x (Const16 [c])) -> (Rsh64x64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh64x8 <t> x (Const8 [c])) -> (Rsh64x64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh64x8 <t> x (Const8 [c])) -> (Rsh64x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh64Ux32 <t> x (Const32 [c])) -> (Rsh64Ux64 x (Const64 <t> [int64(uint32(c))]))
(Rsh64Ux16 <t> x (Const16 [c])) -> (Rsh64Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh64Ux8 <t> x (Const8 [c])) -> (Rsh64Ux64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh64Ux8 <t> x (Const8 [c])) -> (Rsh64Ux64 x (Const64 <t> [int64(uint8(c))]))
(Lsh32x32 <t> x (Const32 [c])) -> (Lsh32x64 x (Const64 <t> [int64(uint32(c))]))
(Lsh32x16 <t> x (Const16 [c])) -> (Lsh32x64 x (Const64 <t> [int64(uint16(c))]))
-(Lsh32x8 <t> x (Const8 [c])) -> (Lsh32x64 x (Const64 <t> [int64(uint8(c))]))
+(Lsh32x8 <t> x (Const8 [c])) -> (Lsh32x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh32x32 <t> x (Const32 [c])) -> (Rsh32x64 x (Const64 <t> [int64(uint32(c))]))
(Rsh32x16 <t> x (Const16 [c])) -> (Rsh32x64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh32x8 <t> x (Const8 [c])) -> (Rsh32x64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh32x8 <t> x (Const8 [c])) -> (Rsh32x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh32Ux32 <t> x (Const32 [c])) -> (Rsh32Ux64 x (Const64 <t> [int64(uint32(c))]))
(Rsh32Ux16 <t> x (Const16 [c])) -> (Rsh32Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh32Ux8 <t> x (Const8 [c])) -> (Rsh32Ux64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh32Ux8 <t> x (Const8 [c])) -> (Rsh32Ux64 x (Const64 <t> [int64(uint8(c))]))
(Lsh16x32 <t> x (Const32 [c])) -> (Lsh16x64 x (Const64 <t> [int64(uint32(c))]))
(Lsh16x16 <t> x (Const16 [c])) -> (Lsh16x64 x (Const64 <t> [int64(uint16(c))]))
-(Lsh16x8 <t> x (Const8 [c])) -> (Lsh16x64 x (Const64 <t> [int64(uint8(c))]))
+(Lsh16x8 <t> x (Const8 [c])) -> (Lsh16x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh16x32 <t> x (Const32 [c])) -> (Rsh16x64 x (Const64 <t> [int64(uint32(c))]))
(Rsh16x16 <t> x (Const16 [c])) -> (Rsh16x64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh16x8 <t> x (Const8 [c])) -> (Rsh16x64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh16x8 <t> x (Const8 [c])) -> (Rsh16x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh16Ux32 <t> x (Const32 [c])) -> (Rsh16Ux64 x (Const64 <t> [int64(uint32(c))]))
(Rsh16Ux16 <t> x (Const16 [c])) -> (Rsh16Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh16Ux8 <t> x (Const8 [c])) -> (Rsh16Ux64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh16Ux8 <t> x (Const8 [c])) -> (Rsh16Ux64 x (Const64 <t> [int64(uint8(c))]))
(Lsh8x32 <t> x (Const32 [c])) -> (Lsh8x64 x (Const64 <t> [int64(uint32(c))]))
(Lsh8x16 <t> x (Const16 [c])) -> (Lsh8x64 x (Const64 <t> [int64(uint16(c))]))
-(Lsh8x8 <t> x (Const8 [c])) -> (Lsh8x64 x (Const64 <t> [int64(uint8(c))]))
+(Lsh8x8 <t> x (Const8 [c])) -> (Lsh8x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh8x32 <t> x (Const32 [c])) -> (Rsh8x64 x (Const64 <t> [int64(uint32(c))]))
(Rsh8x16 <t> x (Const16 [c])) -> (Rsh8x64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh8x8 <t> x (Const8 [c])) -> (Rsh8x64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh8x8 <t> x (Const8 [c])) -> (Rsh8x64 x (Const64 <t> [int64(uint8(c))]))
(Rsh8Ux32 <t> x (Const32 [c])) -> (Rsh8Ux64 x (Const64 <t> [int64(uint32(c))]))
(Rsh8Ux16 <t> x (Const16 [c])) -> (Rsh8Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh8Ux8 <t> x (Const8 [c])) -> (Rsh8Ux64 x (Const64 <t> [int64(uint8(c))]))
+(Rsh8Ux8 <t> x (Const8 [c])) -> (Rsh8Ux64 x (Const64 <t> [int64(uint8(c))]))
// shifts by zero
(Lsh64x64 x (Const64 [0])) -> x
(Rsh8Ux64 x (Const64 [0])) -> x
// zero shifted.
-// TODO: other bit sizes.
(Lsh64x64 (Const64 [0]) _) -> (Const64 [0])
(Rsh64x64 (Const64 [0]) _) -> (Const64 [0])
(Rsh64Ux64 (Const64 [0]) _) -> (Const64 [0])
-(Lsh64x32 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64x32 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64Ux32 (Const64 [0]) _) -> (Const64 [0])
-(Lsh64x16 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64x16 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64Ux16 (Const64 [0]) _) -> (Const64 [0])
-(Lsh64x8 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64x8 (Const64 [0]) _) -> (Const64 [0])
-(Rsh64Ux8 (Const64 [0]) _) -> (Const64 [0])
+(Lsh32x64 (Const64 [0]) _) -> (Const32 [0])
+(Rsh32x64 (Const64 [0]) _) -> (Const32 [0])
+(Rsh32Ux64 (Const64 [0]) _) -> (Const32 [0])
+(Lsh16x64 (Const64 [0]) _) -> (Const16 [0])
+(Rsh16x64 (Const64 [0]) _) -> (Const16 [0])
+(Rsh16Ux64 (Const64 [0]) _) -> (Const16 [0])
+(Lsh8x64 (Const64 [0]) _) -> (Const8 [0])
+(Rsh8x64 (Const64 [0]) _) -> (Const8 [0])
+(Rsh8Ux64 (Const64 [0]) _) -> (Const8 [0])
// large left shifts of all values, and right shifts of unsigned values
(Lsh64x64 _ (Const64 [c])) && uint64(c) >= 64 -> (Const64 [0])
(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 -> (Const32 [0])
(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 -> (Const16 [0])
(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 -> (Const16 [0])
-(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0])
-(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0])
+(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0])
+(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0])
// combine const shifts
(Lsh64x64 <t> (Lsh64x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) -> (Lsh64x64 x (Const64 <t> [c+d]))
(Rsh16Ux64 <t> (Rsh16Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) -> (Rsh16Ux64 x (Const64 <t> [c+d]))
(Rsh8Ux64 <t> (Rsh8Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) -> (Rsh8Ux64 x (Const64 <t> [c+d]))
+// ((x >> c1) << c2) >> c3
+(Rsh64Ux64 (Lsh64x64 (Rsh64Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
+ && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)
+ -> (Rsh64Ux64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
+(Rsh32Ux64 (Lsh32x64 (Rsh32Ux64 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3]))
+ && uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)
+ -> (Rsh32Ux64 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
+(Rsh16Ux64 (Lsh16x64 (Rsh16Ux64 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3]))
+ && uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)
+ -> (Rsh16Ux64 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
+(Rsh8Ux64 (Lsh8x64 (Rsh8Ux64 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3]))
+ && uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2)
+ -> (Rsh8Ux64 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
+
+// ((x << c1) >> c2) << c3
+(Lsh64x64 (Rsh64Ux64 (Lsh64x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
+ && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)
+ -> (Lsh64x64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
+(Lsh32x64 (Rsh32Ux64 (Lsh32x64 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3]))
+ && uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)
+ -> (Lsh32x64 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
+(Lsh16x64 (Rsh16Ux64 (Lsh16x64 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3]))
+ && uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)
+ -> (Lsh16x64 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
+(Lsh8x64 (Rsh8Ux64 (Lsh8x64 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3]))
+ && uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2)
+ -> (Lsh8x64 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
+
// constant comparisons
(Eq64 (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(c == d)])
(Eq32 (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(c == d)])
(Or64 x x) -> x
(Or32 x x) -> x
(Or16 x x) -> x
-(Or8 x x) -> x
+(Or8 x x) -> x
(Or64 (Const64 [0]) x) -> x
(Or32 (Const32 [0]) x) -> x
(Or16 (Const16 [0]) x) -> x
-(Or8 (Const8 [0]) x) -> x
+(Or8 (Const8 [0]) x) -> x
(Or64 (Const64 [-1]) _) -> (Const64 [-1])
(Or32 (Const32 [-1]) _) -> (Const32 [-1])
(Or16 (Const16 [-1]) _) -> (Const16 [-1])
-(Or8 (Const8 [-1]) _) -> (Const8 [-1])
+(Or8 (Const8 [-1]) _) -> (Const8 [-1])
(And64 x x) -> x
(And32 x x) -> x
(And16 x x) -> x
-(And8 x x) -> x
+(And8 x x) -> x
(And64 (Const64 [-1]) x) -> x
(And32 (Const32 [-1]) x) -> x
(And16 (Const16 [-1]) x) -> x
-(And8 (Const8 [-1]) x) -> x
+(And8 (Const8 [-1]) x) -> x
(And64 (Const64 [0]) _) -> (Const64 [0])
(And32 (Const32 [0]) _) -> (Const32 [0])
(And16 (Const16 [0]) _) -> (Const16 [0])
-(And8 (Const8 [0]) _) -> (Const8 [0])
+(And8 (Const8 [0]) _) -> (Const8 [0])
(Xor64 x x) -> (Const64 [0])
(Xor32 x x) -> (Const32 [0])
(Xor16 x x) -> (Const16 [0])
-(Xor8 x x) -> (Const8 [0])
+(Xor8 x x) -> (Const8 [0])
(Xor64 (Const64 [0]) x) -> x
(Xor32 (Const32 [0]) x) -> x
(Xor16 (Const16 [0]) x) -> x
-(Xor8 (Const8 [0]) x) -> x
+(Xor8 (Const8 [0]) x) -> x
(Add64 (Const64 [0]) x) -> x
(Add32 (Const32 [0]) x) -> x
(Add16 (Const16 [0]) x) -> x
-(Add8 (Const8 [0]) x) -> x
+(Add8 (Const8 [0]) x) -> x
(Sub64 x x) -> (Const64 [0])
(Sub32 x x) -> (Const32 [0])
(Sub16 x x) -> (Const16 [0])
-(Sub8 x x) -> (Const8 [0])
+(Sub8 x x) -> (Const8 [0])
(Mul64 (Const64 [0]) _) -> (Const64 [0])
(Mul32 (Const32 [0]) _) -> (Const32 [0])
(Mul16 (Const16 [0]) _) -> (Const16 [0])
-(Mul8 (Const8 [0]) _) -> (Const8 [0])
-(Com8 (Com8 x)) -> x
+(Mul8 (Const8 [0]) _) -> (Const8 [0])
+(Com8 (Com8 x)) -> x
(Com16 (Com16 x)) -> x
(Com32 (Com32 x)) -> x
(Com64 (Com64 x)) -> x
-(Neg8 (Sub8 x y)) -> (Sub8 y x)
+(Neg8 (Sub8 x y)) -> (Sub8 y x)
(Neg16 (Sub16 x y)) -> (Sub16 y x)
(Neg32 (Sub32 x y)) -> (Sub32 y x)
(Neg64 (Sub64 x y)) -> (Sub64 y x)
(Xor16 (Xor16 x y) y) -> x
(Xor8 (Xor8 x y) y) -> x
-(Trunc64to8 (And64 (Const64 [y]) x)) && y&0xFF == 0xFF -> (Trunc64to8 x)
+(Trunc64to8 (And64 (Const64 [y]) x)) && y&0xFF == 0xFF -> (Trunc64to8 x)
(Trunc64to16 (And64 (Const64 [y]) x)) && y&0xFFFF == 0xFFFF -> (Trunc64to16 x)
(Trunc64to32 (And64 (Const64 [y]) x)) && y&0xFFFFFFFF == 0xFFFFFFFF -> (Trunc64to32 x)
-(Trunc32to8 (And32 (Const32 [y]) x)) && y&0xFF == 0xFF -> (Trunc32to8 x)
+(Trunc32to8 (And32 (Const32 [y]) x)) && y&0xFF == 0xFF -> (Trunc32to8 x)
(Trunc32to16 (And32 (Const32 [y]) x)) && y&0xFFFF == 0xFFFF -> (Trunc32to16 x)
-(Trunc16to8 (And16 (Const16 [y]) x)) && y&0xFF == 0xFF -> (Trunc16to8 x)
+(Trunc16to8 (And16 (Const16 [y]) x)) && y&0xFF == 0xFF -> (Trunc16to8 x)
// Rewrite AND of consts as shifts if possible, slightly faster for 64 bit operands
// leading zeros can be shifted left, then right
-(And64 <t> (Const64 [y]) x) && nlz(y) + nto(y) == 64 && nto(y) >= 32 -> (Rsh64Ux64 (Lsh64x64 <t> x (Const64 <t> [nlz(y)])) (Const64 <t> [nlz(y)]))
+(And64 <t> (Const64 [y]) x) && nlz(y) + nto(y) == 64 && nto(y) >= 32
+ -> (Rsh64Ux64 (Lsh64x64 <t> x (Const64 <t> [nlz(y)])) (Const64 <t> [nlz(y)]))
// trailing zeros can be shifted right, then left
-(And64 <t> (Const64 [y]) x) && nlo(y) + ntz(y) == 64 && ntz(y) >= 32 -> (Lsh64x64 (Rsh64Ux64 <t> x (Const64 <t> [ntz(y)])) (Const64 <t> [ntz(y)]))
+(And64 <t> (Const64 [y]) x) && nlo(y) + ntz(y) == 64 && ntz(y) >= 32
+ -> (Lsh64x64 (Rsh64Ux64 <t> x (Const64 <t> [ntz(y)])) (Const64 <t> [ntz(y)]))
// simplifications often used for lengths. e.g. len(s[i:i+5])==5
(Sub64 (Add64 x y) x) -> y
(Sub32 (Add32 x y) y) -> x
(Sub16 (Add16 x y) x) -> y
(Sub16 (Add16 x y) y) -> x
-(Sub8 (Add8 x y) x) -> y
-(Sub8 (Add8 x y) y) -> x
+(Sub8 (Add8 x y) x) -> y
+(Sub8 (Add8 x y) y) -> x
// basic phi simplifications
-(Phi (Const8 [c]) (Const8 [c])) -> (Const8 [c])
+(Phi (Const8 [c]) (Const8 [c])) -> (Const8 [c])
(Phi (Const16 [c]) (Const16 [c])) -> (Const16 [c])
(Phi (Const32 [c]) (Const32 [c])) -> (Const32 [c])
(Phi (Const64 [c]) (Const64 [c])) -> (Const64 [c])
// A%B = A-(A/B*B).
// This implements % with two * and a bunch of ancillary ops.
// One of the * is free if the user's code also computes A/B.
-(Mod64 <t> x (Const64 [c])) && x.Op != OpConst64 && smagic64ok(c) -> (Sub64 x (Mul64 <t> (Div64 <t> x (Const64 <t> [c])) (Const64 <t> [c])))
-(Mod64u <t> x (Const64 [c])) && x.Op != OpConst64 && umagic64ok(c) -> (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
+(Mod64 <t> x (Const64 [c])) && x.Op != OpConst64 && smagic64ok(c)
+ -> (Sub64 x (Mul64 <t> (Div64 <t> x (Const64 <t> [c])) (Const64 <t> [c])))
+(Mod64u <t> x (Const64 [c])) && x.Op != OpConst64 && umagic64ok(c)
+ -> (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
func rewriteValueAMD64_OpAdd16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add16 x y)
+ // match: (Add16 x y)
// cond:
- // result: (ADDL x y)
+ // result: (ADDL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpAdd32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add32 x y)
+ // match: (Add32 x y)
// cond:
- // result: (ADDL x y)
+ // result: (ADDL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpAdd64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add64 x y)
+ // match: (Add64 x y)
// cond:
- // result: (ADDQ x y)
+ // result: (ADDQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpAdd8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add8 x y)
+ // match: (Add8 x y)
// cond:
- // result: (ADDL x y)
+ // result: (ADDL x y)
for {
x := v.Args[0]
y := v.Args[1]
_ = b
// match: (AddPtr x y)
// cond:
- // result: (ADDQ x y)
+ // result: (ADDQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpAnd8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (And8 x y)
+ // match: (And8 x y)
// cond:
// result: (ANDL x y)
for {
func rewriteValueAMD64_OpCom8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Com8 x)
+ // match: (Com8 x)
// cond:
// result: (NOTL x)
for {
func rewriteValueAMD64_OpConst16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Const16 [val])
+ // match: (Const16 [val])
// cond:
// result: (MOVLconst [val])
for {
func rewriteValueAMD64_OpConst32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Const32 [val])
+ // match: (Const32 [val])
// cond:
// result: (MOVLconst [val])
for {
func rewriteValueAMD64_OpConst64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Const64 [val])
+ // match: (Const64 [val])
// cond:
// result: (MOVQconst [val])
for {
func rewriteValueAMD64_OpConst8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Const8 [val])
+ // match: (Const8 [val])
// cond:
// result: (MOVLconst [val])
for {
func rewriteValueAMD64_OpDiv16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Div16 x y)
+ // match: (Div16 x y)
// cond:
- // result: (DIVW x y)
+ // result: (DIVW x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpDiv32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Div32 x y)
+ // match: (Div32 x y)
// cond:
- // result: (DIVL x y)
+ // result: (DIVL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpDiv64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Div64 x y)
+ // match: (Div64 x y)
// cond:
- // result: (DIVQ x y)
+ // result: (DIVQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpDiv8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Div8 x y)
+ // match: (Div8 x y)
// cond:
- // result: (DIVW (SignExt8to16 x) (SignExt8to16 y))
+ // result: (DIVW (SignExt8to16 x) (SignExt8to16 y))
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpDiv8u(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Div8u x y)
+ // match: (Div8u x y)
// cond:
// result: (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
for {
func rewriteValueAMD64_OpEq16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Eq16 x y)
+ // match: (Eq16 x y)
// cond:
// result: (SETEQ (CMPW x y))
for {
func rewriteValueAMD64_OpEq32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Eq32 x y)
+ // match: (Eq32 x y)
// cond:
// result: (SETEQ (CMPL x y))
for {
func rewriteValueAMD64_OpEq64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Eq64 x y)
+ // match: (Eq64 x y)
// cond:
// result: (SETEQ (CMPQ x y))
for {
func rewriteValueAMD64_OpEq8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Eq8 x y)
+ // match: (Eq8 x y)
// cond:
// result: (SETEQ (CMPB x y))
for {
func rewriteValueAMD64_OpEqB(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (EqB x y)
+ // match: (EqB x y)
// cond:
// result: (SETEQ (CMPB x y))
for {
func rewriteValueAMD64_OpGeq16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Geq16 x y)
+ // match: (Geq16 x y)
// cond:
// result: (SETGE (CMPW x y))
for {
func rewriteValueAMD64_OpGeq32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Geq32 x y)
+ // match: (Geq32 x y)
// cond:
// result: (SETGE (CMPL x y))
for {
func rewriteValueAMD64_OpGeq64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Geq64 x y)
+ // match: (Geq64 x y)
// cond:
// result: (SETGE (CMPQ x y))
for {
func rewriteValueAMD64_OpGeq8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Geq8 x y)
+ // match: (Geq8 x y)
// cond:
// result: (SETGE (CMPB x y))
for {
func rewriteValueAMD64_OpGreater16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Greater16 x y)
+ // match: (Greater16 x y)
// cond:
// result: (SETG (CMPW x y))
for {
func rewriteValueAMD64_OpGreater32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Greater32 x y)
+ // match: (Greater32 x y)
// cond:
// result: (SETG (CMPL x y))
for {
func rewriteValueAMD64_OpGreater64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Greater64 x y)
+ // match: (Greater64 x y)
// cond:
// result: (SETG (CMPQ x y))
for {
func rewriteValueAMD64_OpGreater8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Greater8 x y)
+ // match: (Greater8 x y)
// cond:
// result: (SETG (CMPB x y))
for {
func rewriteValueAMD64_OpHmul16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Hmul16 x y)
+ // match: (Hmul16 x y)
// cond:
- // result: (HMULW x y)
+ // result: (HMULW x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpHmul32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Hmul32 x y)
+ // match: (Hmul32 x y)
// cond:
- // result: (HMULL x y)
+ // result: (HMULL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpHmul64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Hmul64 x y)
+ // match: (Hmul64 x y)
// cond:
- // result: (HMULQ x y)
+ // result: (HMULQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpHmul8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Hmul8 x y)
+ // match: (Hmul8 x y)
// cond:
- // result: (HMULB x y)
+ // result: (HMULB x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpHmul8u(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Hmul8u x y)
+ // match: (Hmul8u x y)
// cond:
// result: (HMULBU x y)
for {
func rewriteValueAMD64_OpLeq16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Leq16 x y)
+ // match: (Leq16 x y)
// cond:
// result: (SETLE (CMPW x y))
for {
func rewriteValueAMD64_OpLeq32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Leq32 x y)
+ // match: (Leq32 x y)
// cond:
// result: (SETLE (CMPL x y))
for {
func rewriteValueAMD64_OpLeq64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Leq64 x y)
+ // match: (Leq64 x y)
// cond:
// result: (SETLE (CMPQ x y))
for {
func rewriteValueAMD64_OpLeq8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Leq8 x y)
+ // match: (Leq8 x y)
// cond:
// result: (SETLE (CMPB x y))
for {
func rewriteValueAMD64_OpLess16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Less16 x y)
+ // match: (Less16 x y)
// cond:
// result: (SETL (CMPW x y))
for {
func rewriteValueAMD64_OpLess32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Less32 x y)
+ // match: (Less32 x y)
// cond:
// result: (SETL (CMPL x y))
for {
func rewriteValueAMD64_OpLess64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Less64 x y)
+ // match: (Less64 x y)
// cond:
// result: (SETL (CMPQ x y))
for {
func rewriteValueAMD64_OpLess8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Less8 x y)
+ // match: (Less8 x y)
// cond:
// result: (SETL (CMPB x y))
for {
func rewriteValueAMD64_OpLrot8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lrot8 <t> x [c])
+ // match: (Lrot8 <t> x [c])
// cond:
// result: (ROLBconst <t> [c&7] x)
for {
func rewriteValueAMD64_OpLsh16x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh16x8 <t> x y)
+ // match: (Lsh16x8 <t> x y)
// cond:
// result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
for {
func rewriteValueAMD64_OpLsh32x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh32x8 <t> x y)
+ // match: (Lsh32x8 <t> x y)
// cond:
// result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
for {
func rewriteValueAMD64_OpLsh64x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh64x8 <t> x y)
+ // match: (Lsh64x8 <t> x y)
// cond:
// result: (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst y [64])))
for {
func rewriteValueAMD64_OpLsh8x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh8x8 <t> x y)
+ // match: (Lsh8x8 <t> x y)
// cond:
// result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
for {
func rewriteValueAMD64_OpMod16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod16 x y)
+ // match: (Mod16 x y)
// cond:
- // result: (MODW x y)
+ // result: (MODW x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMod32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod32 x y)
+ // match: (Mod32 x y)
// cond:
- // result: (MODL x y)
+ // result: (MODL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMod64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod64 x y)
+ // match: (Mod64 x y)
// cond:
- // result: (MODQ x y)
+ // result: (MODQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMod8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod8 x y)
+ // match: (Mod8 x y)
// cond:
- // result: (MODW (SignExt8to16 x) (SignExt8to16 y))
+ // result: (MODW (SignExt8to16 x) (SignExt8to16 y))
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMod8u(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod8u x y)
+ // match: (Mod8u x y)
// cond:
// result: (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
for {
func rewriteValueAMD64_OpMul16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul16 x y)
+ // match: (Mul16 x y)
// cond:
- // result: (MULL x y)
+ // result: (MULL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMul32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul32 x y)
+ // match: (Mul32 x y)
// cond:
- // result: (MULL x y)
+ // result: (MULL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMul64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul64 x y)
+ // match: (Mul64 x y)
// cond:
- // result: (MULQ x y)
+ // result: (MULQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpMul8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul8 x y)
+ // match: (Mul8 x y)
// cond:
- // result: (MULL x y)
+ // result: (MULL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpNeg16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neg16 x)
+ // match: (Neg16 x)
// cond:
// result: (NEGL x)
for {
func rewriteValueAMD64_OpNeg32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neg32 x)
+ // match: (Neg32 x)
// cond:
// result: (NEGL x)
for {
func rewriteValueAMD64_OpNeg64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neg64 x)
+ // match: (Neg64 x)
// cond:
// result: (NEGQ x)
for {
func rewriteValueAMD64_OpNeg8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neg8 x)
+ // match: (Neg8 x)
// cond:
// result: (NEGL x)
for {
func rewriteValueAMD64_OpNeq16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neq16 x y)
+ // match: (Neq16 x y)
// cond:
// result: (SETNE (CMPW x y))
for {
func rewriteValueAMD64_OpNeq32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neq32 x y)
+ // match: (Neq32 x y)
// cond:
// result: (SETNE (CMPL x y))
for {
func rewriteValueAMD64_OpNeq64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neq64 x y)
+ // match: (Neq64 x y)
// cond:
// result: (SETNE (CMPQ x y))
for {
func rewriteValueAMD64_OpNeq8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neq8 x y)
+ // match: (Neq8 x y)
// cond:
// result: (SETNE (CMPB x y))
for {
func rewriteValueAMD64_OpNeqB(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (NeqB x y)
+ // match: (NeqB x y)
// cond:
// result: (SETNE (CMPB x y))
for {
func rewriteValueAMD64_OpOr8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Or8 x y)
+ // match: (Or8 x y)
// cond:
// result: (ORL x y)
for {
func rewriteValueAMD64_OpRsh16Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh16Ux8 <t> x y)
+ // match: (Rsh16Ux8 <t> x y)
// cond:
// result: (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst y [16])))
for {
func rewriteValueAMD64_OpRsh16x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh16x8 <t> x y)
+ // match: (Rsh16x8 <t> x y)
// cond:
// result: (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [16])))))
for {
func rewriteValueAMD64_OpRsh32Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh32Ux8 <t> x y)
+ // match: (Rsh32Ux8 <t> x y)
// cond:
// result: (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
for {
func rewriteValueAMD64_OpRsh32x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh32x8 <t> x y)
+ // match: (Rsh32x8 <t> x y)
// cond:
// result: (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [32])))))
for {
func rewriteValueAMD64_OpRsh64Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh64Ux8 <t> x y)
+ // match: (Rsh64Ux8 <t> x y)
// cond:
// result: (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst y [64])))
for {
func rewriteValueAMD64_OpRsh64x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh64x8 <t> x y)
+ // match: (Rsh64x8 <t> x y)
// cond:
// result: (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [64])))))
for {
func rewriteValueAMD64_OpRsh8Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh8Ux8 <t> x y)
+ // match: (Rsh8Ux8 <t> x y)
// cond:
// result: (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst y [8])))
for {
func rewriteValueAMD64_OpRsh8x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh8x8 <t> x y)
+ // match: (Rsh8x8 <t> x y)
// cond:
// result: (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [8])))))
for {
func rewriteValueAMD64_OpSignExt8to16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (SignExt8to16 x)
+ // match: (SignExt8to16 x)
// cond:
// result: (MOVBQSX x)
for {
func rewriteValueAMD64_OpSignExt8to32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (SignExt8to32 x)
+ // match: (SignExt8to32 x)
// cond:
// result: (MOVBQSX x)
for {
func rewriteValueAMD64_OpSignExt8to64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (SignExt8to64 x)
+ // match: (SignExt8to64 x)
// cond:
// result: (MOVBQSX x)
for {
func rewriteValueAMD64_OpSub16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub16 x y)
+ // match: (Sub16 x y)
// cond:
- // result: (SUBL x y)
+ // result: (SUBL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpSub32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub32 x y)
+ // match: (Sub32 x y)
// cond:
- // result: (SUBL x y)
+ // result: (SUBL x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpSub64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub64 x y)
+ // match: (Sub64 x y)
// cond:
- // result: (SUBQ x y)
+ // result: (SUBQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpSub8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub8 x y)
+ // match: (Sub8 x y)
// cond:
- // result: (SUBL x y)
+ // result: (SUBL x y)
for {
x := v.Args[0]
y := v.Args[1]
_ = b
// match: (SubPtr x y)
// cond:
- // result: (SUBQ x y)
+ // result: (SUBQ x y)
for {
x := v.Args[0]
y := v.Args[1]
func rewriteValueAMD64_OpTrunc16to8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Trunc16to8 x)
+ // match: (Trunc16to8 x)
// cond:
// result: x
for {
func rewriteValueAMD64_OpTrunc32to8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Trunc32to8 x)
+ // match: (Trunc32to8 x)
// cond:
// result: x
for {
func rewriteValueAMD64_OpTrunc64to8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Trunc64to8 x)
+ // match: (Trunc64to8 x)
// cond:
// result: x
for {
func rewriteValueAMD64_OpXor8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Xor8 x y)
+ // match: (Xor8 x y)
// cond:
// result: (XORL x y)
for {
func rewriteValueAMD64_OpZeroExt8to16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (ZeroExt8to16 x)
+ // match: (ZeroExt8to16 x)
// cond:
// result: (MOVBQZX x)
for {
func rewriteValueAMD64_OpZeroExt8to32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (ZeroExt8to32 x)
+ // match: (ZeroExt8to32 x)
// cond:
// result: (MOVBQZX x)
for {
func rewriteValueAMD64_OpZeroExt8to64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (ZeroExt8to64 x)
+ // match: (ZeroExt8to64 x)
// cond:
// result: (MOVBQZX x)
for {
func rewriteValuegeneric_OpAdd16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add16 (Const16 [c]) (Const16 [d]))
+ // match: (Add16 (Const16 [c]) (Const16 [d]))
// cond:
// result: (Const16 [int64(int16(c+d))])
for {
func rewriteValuegeneric_OpAdd32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add32 (Const32 [c]) (Const32 [d]))
+ // match: (Add32 (Const32 [c]) (Const32 [d]))
// cond:
// result: (Const32 [int64(int32(c+d))])
for {
func rewriteValuegeneric_OpAdd64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add64 (Const64 [c]) (Const64 [d]))
+ // match: (Add64 (Const64 [c]) (Const64 [d]))
// cond:
// result: (Const64 [c+d])
for {
func rewriteValuegeneric_OpAdd8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Add8 (Const8 [c]) (Const8 [d]))
+ // match: (Add8 (Const8 [c]) (Const8 [d]))
// cond:
- // result: (Const8 [int64(int8(c+d))])
+ // result: (Const8 [int64(int8(c+d))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
v.AuxInt = int64(int8(c + d))
return true
}
- // match: (Add8 x (Const8 <t> [c]))
+ // match: (Add8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Add8 (Const8 <t> [c]) x)
+ // result: (Add8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
v.AddArg(x)
return true
}
- // match: (Add8 (Const8 [0]) x)
+ // match: (Add8 (Const8 [0]) x)
// cond:
// result: x
for {
func rewriteValuegeneric_OpAnd8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (And8 x (Const8 <t> [c]))
+ // match: (And8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (And8 (Const8 <t> [c]) x)
+ // result: (And8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
v.AddArg(x)
return true
}
- // match: (And8 x x)
+ // match: (And8 x x)
// cond:
// result: x
for {
v.AddArg(x)
return true
}
- // match: (And8 (Const8 [-1]) x)
+ // match: (And8 (Const8 [-1]) x)
// cond:
// result: x
for {
v.AddArg(x)
return true
}
- // match: (And8 (Const8 [0]) _)
+ // match: (And8 (Const8 [0]) _)
// cond:
- // result: (Const8 [0])
+ // result: (Const8 [0])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
func rewriteValuegeneric_OpCom8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Com8 (Com8 x))
+ // match: (Com8 (Com8 x))
// cond:
// result: x
for {
func rewriteValuegeneric_OpEq8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Eq8 x x)
+ // match: (Eq8 x x)
// cond:
// result: (ConstBool [1])
for {
v.AuxInt = 1
return true
}
- // match: (Eq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x))
+ // match: (Eq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x))
// cond:
- // result: (Eq8 (Const8 <t> [int64(int8(c-d))]) x)
+ // result: (Eq8 (Const8 <t> [int64(int8(c-d))]) x)
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
v.AddArg(x)
return true
}
- // match: (Eq8 x (Const8 <t> [c]))
+ // match: (Eq8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Eq8 (Const8 <t> [c]) x)
+ // result: (Eq8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
func rewriteValuegeneric_OpIsInBounds(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (IsInBounds (ZeroExt8to32 _) (Const32 [c]))
- // cond: (1 << 8) <= c
+ // match: (IsInBounds (ZeroExt8to32 _) (Const32 [c]))
+ // cond: (1 << 8) <= c
// result: (ConstBool [1])
for {
v_0 := v.Args[0]
v.AuxInt = 1
return true
}
- // match: (IsInBounds (ZeroExt8to64 _) (Const64 [c]))
- // cond: (1 << 8) <= c
+ // match: (IsInBounds (ZeroExt8to64 _) (Const64 [c]))
+ // cond: (1 << 8) <= c
// result: (ConstBool [1])
for {
v_0 := v.Args[0]
func rewriteValuegeneric_OpLsh16x16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh16x16 (Rsh16Ux16 (Lsh16x16 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3]))
- // cond: uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)
- // result: (Lsh16x16 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpRsh16Ux16 {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpLsh16x16 {
- break
- }
- x := v_0_0.Args[0]
- v_0_0_1 := v_0_0.Args[1]
- if v_0_0_1.Op != OpConst16 {
- break
- }
- c1 := v_0_0_1.AuxInt
- v_0_1 := v_0.Args[1]
- if v_0_1.Op != OpConst16 {
- break
- }
- c2 := v_0_1.AuxInt
- v_1 := v.Args[1]
- if v_1.Op != OpConst16 {
- break
- }
- c3 := v_1.AuxInt
- if !(uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)) {
- break
- }
- v.reset(OpLsh16x16)
- v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst16, config.fe.TypeUInt16())
- v0.AuxInt = int64(int16(c1 - c2 + c3))
- v.AddArg(v0)
- return true
- }
// match: (Lsh16x16 <t> x (Const16 [c]))
// cond:
// result: (Lsh16x64 x (Const64 <t> [int64(uint16(c))]))
v.AuxInt = int64(int16(c) << uint64(d))
return true
}
- // match: (Lsh16x64 (Const16 [0]) _)
- // cond:
- // result: (Const16 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst16 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst16)
- v.AuxInt = 0
- return true
- }
// match: (Lsh16x64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Lsh16x64 (Const64 [0]) _)
+ // cond:
+ // result: (Const16 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst16)
+ v.AuxInt = 0
+ return true
+ }
// match: (Lsh16x64 _ (Const64 [c]))
// cond: uint64(c) >= 16
// result: (Const16 [0])
v.AddArg(v0)
return true
}
+ // match: (Lsh16x64 (Rsh16Ux64 (Lsh16x64 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3]))
+ // cond: uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)
+ // result: (Lsh16x64 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpRsh16Ux64 {
+ break
+ }
+ v_0_0 := v_0.Args[0]
+ if v_0_0.Op != OpLsh16x64 {
+ break
+ }
+ x := v_0_0.Args[0]
+ v_0_0_1 := v_0_0.Args[1]
+ if v_0_0_1.Op != OpConst16 {
+ break
+ }
+ c1 := v_0_0_1.AuxInt
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpConst16 {
+ break
+ }
+ c2 := v_0_1.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst16 {
+ break
+ }
+ c3 := v_1.AuxInt
+ if !(uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)) {
+ break
+ }
+ v.reset(OpLsh16x64)
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpConst16, config.fe.TypeUInt16())
+ v0.AuxInt = int64(int16(c1 - c2 + c3))
+ v.AddArg(v0)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpLsh16x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh16x8 <t> x (Const8 [c]))
+ // match: (Lsh16x8 <t> x (Const8 [c]))
// cond:
// result: (Lsh16x64 x (Const64 <t> [int64(uint8(c))]))
for {
func rewriteValuegeneric_OpLsh32x32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh32x32 (Rsh32Ux32 (Lsh32x32 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3]))
- // cond: uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)
- // result: (Lsh32x32 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpRsh32Ux32 {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpLsh32x32 {
- break
- }
- x := v_0_0.Args[0]
- v_0_0_1 := v_0_0.Args[1]
- if v_0_0_1.Op != OpConst32 {
- break
- }
- c1 := v_0_0_1.AuxInt
- v_0_1 := v_0.Args[1]
- if v_0_1.Op != OpConst32 {
- break
- }
- c2 := v_0_1.AuxInt
- v_1 := v.Args[1]
- if v_1.Op != OpConst32 {
- break
- }
- c3 := v_1.AuxInt
- if !(uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)) {
- break
- }
- v.reset(OpLsh32x32)
- v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst32, config.fe.TypeUInt32())
- v0.AuxInt = int64(int32(c1 - c2 + c3))
- v.AddArg(v0)
- return true
- }
// match: (Lsh32x32 <t> x (Const32 [c]))
// cond:
// result: (Lsh32x64 x (Const64 <t> [int64(uint32(c))]))
v.AuxInt = int64(int32(c) << uint64(d))
return true
}
- // match: (Lsh32x64 (Const32 [0]) _)
- // cond:
- // result: (Const32 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst32 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = 0
- return true
- }
// match: (Lsh32x64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Lsh32x64 (Const64 [0]) _)
+ // cond:
+ // result: (Const32 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst32)
+ v.AuxInt = 0
+ return true
+ }
// match: (Lsh32x64 _ (Const64 [c]))
// cond: uint64(c) >= 32
// result: (Const32 [0])
v.AddArg(v0)
return true
}
+ // match: (Lsh32x64 (Rsh32Ux64 (Lsh32x64 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3]))
+ // cond: uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)
+ // result: (Lsh32x64 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpRsh32Ux64 {
+ break
+ }
+ v_0_0 := v_0.Args[0]
+ if v_0_0.Op != OpLsh32x64 {
+ break
+ }
+ x := v_0_0.Args[0]
+ v_0_0_1 := v_0_0.Args[1]
+ if v_0_0_1.Op != OpConst32 {
+ break
+ }
+ c1 := v_0_0_1.AuxInt
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpConst32 {
+ break
+ }
+ c2 := v_0_1.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
+ break
+ }
+ c3 := v_1.AuxInt
+ if !(uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)) {
+ break
+ }
+ v.reset(OpLsh32x64)
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpConst32, config.fe.TypeUInt32())
+ v0.AuxInt = int64(int32(c1 - c2 + c3))
+ v.AddArg(v0)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpLsh32x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh32x8 <t> x (Const8 [c]))
+ // match: (Lsh32x8 <t> x (Const8 [c]))
// cond:
// result: (Lsh32x64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AddArg(v0)
return true
}
- // match: (Lsh64x16 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpLsh64x32(v *Value, config *Config) bool {
v.AddArg(v0)
return true
}
- // match: (Lsh64x32 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpLsh64x64(v *Value, config *Config) bool {
v.AuxInt = c << uint64(d)
return true
}
+ // match: (Lsh64x64 x (Const64 [0]))
+ // cond:
+ // result: x
+ for {
+ x := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ if v_1.AuxInt != 0 {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
// match: (Lsh64x64 (Const64 [0]) _)
// cond:
// result: (Const64 [0])
v.AuxInt = 0
return true
}
- // match: (Lsh64x64 (Rsh64Ux64 (Lsh64x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
- // cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)
- // result: (Lsh64x64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
+ // match: (Lsh64x64 _ (Const64 [c]))
+ // cond: uint64(c) >= 64
+ // result: (Const64 [0])
for {
- v_0 := v.Args[0]
- if v_0.Op != OpRsh64Ux64 {
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
break
}
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpLsh64x64 {
+ c := v_1.AuxInt
+ if !(uint64(c) >= 64) {
break
}
- x := v_0_0.Args[0]
- v_0_0_1 := v_0_0.Args[1]
- if v_0_0_1.Op != OpConst64 {
- break
+ v.reset(OpConst64)
+ v.AuxInt = 0
+ return true
+ }
+ // match: (Lsh64x64 <t> (Lsh64x64 x (Const64 [c])) (Const64 [d]))
+ // cond: !uaddOvf(c,d)
+ // result: (Lsh64x64 x (Const64 <t> [c+d]))
+ for {
+ t := v.Type
+ v_0 := v.Args[0]
+ if v_0.Op != OpLsh64x64 {
+ break
}
- c1 := v_0_0_1.AuxInt
+ x := v_0.Args[0]
v_0_1 := v_0.Args[1]
if v_0_1.Op != OpConst64 {
break
}
- c2 := v_0_1.AuxInt
+ c := v_0_1.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64 {
break
}
- c3 := v_1.AuxInt
- if !(uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)) {
+ d := v_1.AuxInt
+ if !(!uaddOvf(c, d)) {
break
}
v.reset(OpLsh64x64)
v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst64, config.fe.TypeUInt64())
- v0.AuxInt = c1 - c2 + c3
+ v0 := b.NewValue0(v.Line, OpConst64, t)
+ v0.AuxInt = c + d
v.AddArg(v0)
return true
}
- // match: (Lsh64x64 x (Const64 [0]))
- // cond:
- // result: x
- for {
- x := v.Args[0]
- v_1 := v.Args[1]
- if v_1.Op != OpConst64 {
- break
- }
- if v_1.AuxInt != 0 {
- break
- }
- v.reset(OpCopy)
- v.Type = x.Type
- v.AddArg(x)
- return true
- }
- // match: (Lsh64x64 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
+ // match: (Lsh64x64 (Rsh64Ux64 (Lsh64x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
+ // cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)
+ // result: (Lsh64x64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
for {
v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
- // match: (Lsh64x64 _ (Const64 [c]))
- // cond: uint64(c) >= 64
- // result: (Const64 [0])
- for {
- v_1 := v.Args[1]
- if v_1.Op != OpConst64 {
+ if v_0.Op != OpRsh64Ux64 {
break
}
- c := v_1.AuxInt
- if !(uint64(c) >= 64) {
+ v_0_0 := v_0.Args[0]
+ if v_0_0.Op != OpLsh64x64 {
break
}
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
- // match: (Lsh64x64 <t> (Lsh64x64 x (Const64 [c])) (Const64 [d]))
- // cond: !uaddOvf(c,d)
- // result: (Lsh64x64 x (Const64 <t> [c+d]))
- for {
- t := v.Type
- v_0 := v.Args[0]
- if v_0.Op != OpLsh64x64 {
+ x := v_0_0.Args[0]
+ v_0_0_1 := v_0_0.Args[1]
+ if v_0_0_1.Op != OpConst64 {
break
}
- x := v_0.Args[0]
+ c1 := v_0_0_1.AuxInt
v_0_1 := v_0.Args[1]
if v_0_1.Op != OpConst64 {
break
}
- c := v_0_1.AuxInt
+ c2 := v_0_1.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64 {
break
}
- d := v_1.AuxInt
- if !(!uaddOvf(c, d)) {
+ c3 := v_1.AuxInt
+ if !(uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)) {
break
}
v.reset(OpLsh64x64)
v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst64, t)
- v0.AuxInt = c + d
+ v0 := b.NewValue0(v.Line, OpConst64, config.fe.TypeUInt64())
+ v0.AuxInt = c1 - c2 + c3
v.AddArg(v0)
return true
}
func rewriteValuegeneric_OpLsh64x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Lsh64x8 <t> x (Const8 [c]))
+ // match: (Lsh64x8 <t> x (Const8 [c]))
// cond:
// result: (Lsh64x64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AddArg(v0)
return true
}
- // match: (Lsh64x8 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpLsh8x16(v *Value, config *Config) bool {
v.AuxInt = int64(int8(c) << uint64(d))
return true
}
- // match: (Lsh8x64 (Const8 [0]) _)
- // cond:
- // result: (Const8 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst8 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst8)
- v.AuxInt = 0
- return true
- }
// match: (Lsh8x64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Lsh8x64 (Const64 [0]) _)
+ // cond:
+ // result: (Const8 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst8)
+ v.AuxInt = 0
+ return true
+ }
// match: (Lsh8x64 _ (Const64 [c]))
// cond: uint64(c) >= 8
- // result: (Const8 [0])
+ // result: (Const8 [0])
for {
v_1 := v.Args[1]
if v_1.Op != OpConst64 {
v.AddArg(v0)
return true
}
- return false
-}
-func rewriteValuegeneric_OpLsh8x8(v *Value, config *Config) bool {
- b := v.Block
- _ = b
- // match: (Lsh8x8 (Rsh8Ux8 (Lsh8x8 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3]))
+ // match: (Lsh8x64 (Rsh8Ux64 (Lsh8x64 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3]))
// cond: uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2)
- // result: (Lsh8x8 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
+ // result: (Lsh8x64 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
for {
v_0 := v.Args[0]
- if v_0.Op != OpRsh8Ux8 {
+ if v_0.Op != OpRsh8Ux64 {
break
}
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpLsh8x8 {
+ if v_0_0.Op != OpLsh8x64 {
break
}
x := v_0_0.Args[0]
if !(uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2)) {
break
}
- v.reset(OpLsh8x8)
+ v.reset(OpLsh8x64)
v.AddArg(x)
v0 := b.NewValue0(v.Line, OpConst8, config.fe.TypeUInt8())
v0.AuxInt = int64(int8(c1 - c2 + c3))
v.AddArg(v0)
return true
}
- // match: (Lsh8x8 <t> x (Const8 [c]))
+ return false
+}
+func rewriteValuegeneric_OpLsh8x8(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Lsh8x8 <t> x (Const8 [c]))
// cond:
// result: (Lsh8x64 x (Const64 <t> [int64(uint8(c))]))
for {
func rewriteValuegeneric_OpMod8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod8 (Const8 [c]) (Const8 [d]))
+ // match: (Mod8 (Const8 [c]) (Const8 [d]))
// cond: d != 0
- // result: (Const8 [int64(int8(c % d))])
+ // result: (Const8 [int64(int8(c % d))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
func rewriteValuegeneric_OpMod8u(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mod8u (Const8 [c]) (Const8 [d]))
+ // match: (Mod8u (Const8 [c]) (Const8 [d]))
// cond: d != 0
- // result: (Const8 [int64(uint8(c) % uint8(d))])
+ // result: (Const8 [int64(uint8(c) % uint8(d))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
func rewriteValuegeneric_OpMul16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul16 (Const16 [c]) (Const16 [d]))
+ // match: (Mul16 (Const16 [c]) (Const16 [d]))
// cond:
// result: (Const16 [int64(int16(c*d))])
for {
func rewriteValuegeneric_OpMul32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul32 (Const32 [c]) (Const32 [d]))
+ // match: (Mul32 (Const32 [c]) (Const32 [d]))
// cond:
// result: (Const32 [int64(int32(c*d))])
for {
func rewriteValuegeneric_OpMul64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul64 (Const64 [c]) (Const64 [d]))
+ // match: (Mul64 (Const64 [c]) (Const64 [d]))
// cond:
// result: (Const64 [c*d])
for {
func rewriteValuegeneric_OpMul8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Mul8 (Const8 [c]) (Const8 [d]))
+ // match: (Mul8 (Const8 [c]) (Const8 [d]))
// cond:
- // result: (Const8 [int64(int8(c*d))])
+ // result: (Const8 [int64(int8(c*d))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
v.AuxInt = int64(int8(c * d))
return true
}
- // match: (Mul8 x (Const8 <t> [c]))
+ // match: (Mul8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Mul8 (Const8 <t> [c]) x)
+ // result: (Mul8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
v.AddArg(x)
return true
}
- // match: (Mul8 (Const8 [0]) _)
+ // match: (Mul8 (Const8 [0]) _)
// cond:
- // result: (Const8 [0])
+ // result: (Const8 [0])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
func rewriteValuegeneric_OpNeg8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neg8 (Sub8 x y))
+ // match: (Neg8 (Sub8 x y))
// cond:
- // result: (Sub8 y x)
+ // result: (Sub8 y x)
for {
v_0 := v.Args[0]
if v_0.Op != OpSub8 {
func rewriteValuegeneric_OpNeq8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Neq8 x x)
+ // match: (Neq8 x x)
// cond:
// result: (ConstBool [0])
for {
v.AuxInt = 0
return true
}
- // match: (Neq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x))
+ // match: (Neq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x))
// cond:
// result: (Neq8 (Const8 <t> [int64(int8(c-d))]) x)
for {
v.AddArg(x)
return true
}
- // match: (Neq8 x (Const8 <t> [c]))
+ // match: (Neq8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Neq8 (Const8 <t> [c]) x)
+ // result: (Neq8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
func rewriteValuegeneric_OpOr8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Or8 x (Const8 <t> [c]))
+ // match: (Or8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Or8 (Const8 <t> [c]) x)
+ // result: (Or8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
v.AddArg(x)
return true
}
- // match: (Or8 x x)
+ // match: (Or8 x x)
// cond:
// result: x
for {
v.AddArg(x)
return true
}
- // match: (Or8 (Const8 [0]) x)
+ // match: (Or8 (Const8 [0]) x)
// cond:
// result: x
for {
v.AddArg(x)
return true
}
- // match: (Or8 (Const8 [-1]) _)
+ // match: (Or8 (Const8 [-1]) _)
// cond:
- // result: (Const8 [-1])
+ // result: (Const8 [-1])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
func rewriteValuegeneric_OpPhi(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Phi (Const8 [c]) (Const8 [c]))
+ // match: (Phi (Const8 [c]) (Const8 [c]))
// cond:
- // result: (Const8 [c])
+ // result: (Const8 [c])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst8 {
func rewriteValuegeneric_OpRsh16Ux16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh16Ux16 (Lsh16x16 (Rsh16Ux16 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3]))
- // cond: uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)
- // result: (Rsh16Ux16 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpLsh16x16 {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpRsh16Ux16 {
- break
- }
- x := v_0_0.Args[0]
- v_0_0_1 := v_0_0.Args[1]
- if v_0_0_1.Op != OpConst16 {
- break
- }
- c1 := v_0_0_1.AuxInt
- v_0_1 := v_0.Args[1]
- if v_0_1.Op != OpConst16 {
- break
- }
- c2 := v_0_1.AuxInt
- v_1 := v.Args[1]
- if v_1.Op != OpConst16 {
- break
- }
- c3 := v_1.AuxInt
- if !(uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)) {
- break
- }
- v.reset(OpRsh16Ux16)
- v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst16, config.fe.TypeUInt16())
- v0.AuxInt = int64(int16(c1 - c2 + c3))
- v.AddArg(v0)
- return true
- }
// match: (Rsh16Ux16 <t> x (Const16 [c]))
// cond:
// result: (Rsh16Ux64 x (Const64 <t> [int64(uint16(c))]))
v.AuxInt = int64(int16(uint16(c) >> uint64(d)))
return true
}
- // match: (Rsh16Ux64 (Const16 [0]) _)
- // cond:
- // result: (Const16 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst16 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst16)
- v.AuxInt = 0
- return true
- }
// match: (Rsh16Ux64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Rsh16Ux64 (Const64 [0]) _)
+ // cond:
+ // result: (Const16 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst16)
+ v.AuxInt = 0
+ return true
+ }
// match: (Rsh16Ux64 _ (Const64 [c]))
// cond: uint64(c) >= 16
// result: (Const16 [0])
v.AddArg(v0)
return true
}
+ // match: (Rsh16Ux64 (Lsh16x64 (Rsh16Ux64 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3]))
+ // cond: uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)
+ // result: (Rsh16Ux64 x (Const16 <config.fe.TypeUInt16()> [int64(int16(c1-c2+c3))]))
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpLsh16x64 {
+ break
+ }
+ v_0_0 := v_0.Args[0]
+ if v_0_0.Op != OpRsh16Ux64 {
+ break
+ }
+ x := v_0_0.Args[0]
+ v_0_0_1 := v_0_0.Args[1]
+ if v_0_0_1.Op != OpConst16 {
+ break
+ }
+ c1 := v_0_0_1.AuxInt
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpConst16 {
+ break
+ }
+ c2 := v_0_1.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst16 {
+ break
+ }
+ c3 := v_1.AuxInt
+ if !(uint16(c1) >= uint16(c2) && uint16(c3) >= uint16(c2)) {
+ break
+ }
+ v.reset(OpRsh16Ux64)
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpConst16, config.fe.TypeUInt16())
+ v0.AuxInt = int64(int16(c1 - c2 + c3))
+ v.AddArg(v0)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpRsh16Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh16Ux8 <t> x (Const8 [c]))
+ // match: (Rsh16Ux8 <t> x (Const8 [c]))
// cond:
// result: (Rsh16Ux64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AuxInt = int64(int16(c) >> uint64(d))
return true
}
- // match: (Rsh16x64 (Const16 [0]) _)
+ // match: (Rsh16x64 x (Const64 [0]))
// cond:
- // result: (Const16 [0])
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst16 {
+ x := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
break
}
- if v_0.AuxInt != 0 {
+ if v_1.AuxInt != 0 {
break
}
- v.reset(OpConst16)
- v.AuxInt = 0
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (Rsh16x64 x (Const64 [0]))
+ // match: (Rsh16x64 (Const64 [0]) _)
// cond:
- // result: x
+ // result: (Const16 [0])
for {
- x := v.Args[0]
- v_1 := v.Args[1]
- if v_1.Op != OpConst64 {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
break
}
- if v_1.AuxInt != 0 {
+ if v_0.AuxInt != 0 {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
- v.AddArg(x)
+ v.reset(OpConst16)
+ v.AuxInt = 0
return true
}
// match: (Rsh16x64 <t> (Rsh16x64 x (Const64 [c])) (Const64 [d]))
func rewriteValuegeneric_OpRsh16x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh16x8 <t> x (Const8 [c]))
+ // match: (Rsh16x8 <t> x (Const8 [c]))
// cond:
// result: (Rsh16x64 x (Const64 <t> [int64(uint8(c))]))
for {
func rewriteValuegeneric_OpRsh32Ux32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh32Ux32 (Lsh32x32 (Rsh32Ux32 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3]))
- // cond: uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)
- // result: (Rsh32Ux32 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpLsh32x32 {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpRsh32Ux32 {
- break
- }
- x := v_0_0.Args[0]
- v_0_0_1 := v_0_0.Args[1]
- if v_0_0_1.Op != OpConst32 {
- break
- }
- c1 := v_0_0_1.AuxInt
- v_0_1 := v_0.Args[1]
- if v_0_1.Op != OpConst32 {
- break
- }
- c2 := v_0_1.AuxInt
- v_1 := v.Args[1]
- if v_1.Op != OpConst32 {
- break
- }
- c3 := v_1.AuxInt
- if !(uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)) {
- break
- }
- v.reset(OpRsh32Ux32)
- v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst32, config.fe.TypeUInt32())
- v0.AuxInt = int64(int32(c1 - c2 + c3))
- v.AddArg(v0)
- return true
- }
// match: (Rsh32Ux32 <t> x (Const32 [c]))
// cond:
// result: (Rsh32Ux64 x (Const64 <t> [int64(uint32(c))]))
v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
return true
}
- // match: (Rsh32Ux64 (Const32 [0]) _)
- // cond:
- // result: (Const32 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst32 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = 0
- return true
- }
// match: (Rsh32Ux64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Rsh32Ux64 (Const64 [0]) _)
+ // cond:
+ // result: (Const32 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst32)
+ v.AuxInt = 0
+ return true
+ }
// match: (Rsh32Ux64 _ (Const64 [c]))
// cond: uint64(c) >= 32
// result: (Const32 [0])
v.AddArg(v0)
return true
}
+ // match: (Rsh32Ux64 (Lsh32x64 (Rsh32Ux64 x (Const32 [c1])) (Const32 [c2])) (Const32 [c3]))
+ // cond: uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)
+ // result: (Rsh32Ux64 x (Const32 <config.fe.TypeUInt32()> [int64(int32(c1-c2+c3))]))
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpLsh32x64 {
+ break
+ }
+ v_0_0 := v_0.Args[0]
+ if v_0_0.Op != OpRsh32Ux64 {
+ break
+ }
+ x := v_0_0.Args[0]
+ v_0_0_1 := v_0_0.Args[1]
+ if v_0_0_1.Op != OpConst32 {
+ break
+ }
+ c1 := v_0_0_1.AuxInt
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpConst32 {
+ break
+ }
+ c2 := v_0_1.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
+ break
+ }
+ c3 := v_1.AuxInt
+ if !(uint32(c1) >= uint32(c2) && uint32(c3) >= uint32(c2)) {
+ break
+ }
+ v.reset(OpRsh32Ux64)
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpConst32, config.fe.TypeUInt32())
+ v0.AuxInt = int64(int32(c1 - c2 + c3))
+ v.AddArg(v0)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpRsh32Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh32Ux8 <t> x (Const8 [c]))
+ // match: (Rsh32Ux8 <t> x (Const8 [c]))
// cond:
// result: (Rsh32Ux64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AuxInt = int64(int32(c) >> uint64(d))
return true
}
- // match: (Rsh32x64 (Const32 [0]) _)
- // cond:
- // result: (Const32 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst32 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst32)
- v.AuxInt = 0
- return true
- }
// match: (Rsh32x64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Rsh32x64 (Const64 [0]) _)
+ // cond:
+ // result: (Const32 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst32)
+ v.AuxInt = 0
+ return true
+ }
// match: (Rsh32x64 <t> (Rsh32x64 x (Const64 [c])) (Const64 [d]))
// cond: !uaddOvf(c,d)
// result: (Rsh32x64 x (Const64 <t> [c+d]))
func rewriteValuegeneric_OpRsh32x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh32x8 <t> x (Const8 [c]))
+ // match: (Rsh32x8 <t> x (Const8 [c]))
// cond:
// result: (Rsh32x64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AddArg(v0)
return true
}
- // match: (Rsh64Ux16 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpRsh64Ux32(v *Value, config *Config) bool {
v.AddArg(v0)
return true
}
- // match: (Rsh64Ux32 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpRsh64Ux64(v *Value, config *Config) bool {
v.AuxInt = int64(uint64(c) >> uint64(d))
return true
}
- // match: (Rsh64Ux64 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
- // match: (Rsh64Ux64 (Lsh64x64 (Rsh64Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
- // cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)
- // result: (Rsh64Ux64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpLsh64x64 {
- break
- }
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpRsh64Ux64 {
- break
- }
- x := v_0_0.Args[0]
- v_0_0_1 := v_0_0.Args[1]
- if v_0_0_1.Op != OpConst64 {
- break
- }
- c1 := v_0_0_1.AuxInt
- v_0_1 := v_0.Args[1]
- if v_0_1.Op != OpConst64 {
- break
- }
- c2 := v_0_1.AuxInt
- v_1 := v.Args[1]
- if v_1.Op != OpConst64 {
- break
- }
- c3 := v_1.AuxInt
- if !(uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)) {
- break
- }
- v.reset(OpRsh64Ux64)
- v.AddArg(x)
- v0 := b.NewValue0(v.Line, OpConst64, config.fe.TypeUInt64())
- v0.AuxInt = c1 - c2 + c3
- v.AddArg(v0)
- return true
- }
// match: (Rsh64Ux64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(v0)
return true
}
+ // match: (Rsh64Ux64 (Lsh64x64 (Rsh64Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
+ // cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)
+ // result: (Rsh64Ux64 x (Const64 <config.fe.TypeUInt64()> [c1-c2+c3]))
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpLsh64x64 {
+ break
+ }
+ v_0_0 := v_0.Args[0]
+ if v_0_0.Op != OpRsh64Ux64 {
+ break
+ }
+ x := v_0_0.Args[0]
+ v_0_0_1 := v_0_0.Args[1]
+ if v_0_0_1.Op != OpConst64 {
+ break
+ }
+ c1 := v_0_0_1.AuxInt
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpConst64 {
+ break
+ }
+ c2 := v_0_1.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ c3 := v_1.AuxInt
+ if !(uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2)) {
+ break
+ }
+ v.reset(OpRsh64Ux64)
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpConst64, config.fe.TypeUInt64())
+ v0.AuxInt = c1 - c2 + c3
+ v.AddArg(v0)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpRsh64Ux8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh64Ux8 <t> x (Const8 [c]))
+ // match: (Rsh64Ux8 <t> x (Const8 [c]))
// cond:
// result: (Rsh64Ux64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AddArg(v0)
return true
}
- // match: (Rsh64Ux8 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpRsh64x16(v *Value, config *Config) bool {
v.AddArg(v0)
return true
}
- // match: (Rsh64x16 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpRsh64x32(v *Value, config *Config) bool {
v.AddArg(v0)
return true
}
- // match: (Rsh64x32 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpRsh64x64(v *Value, config *Config) bool {
v.AuxInt = c >> uint64(d)
return true
}
- // match: (Rsh64x64 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
// match: (Rsh64x64 x (Const64 [0]))
// cond:
// result: x
func rewriteValuegeneric_OpRsh64x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh64x8 <t> x (Const8 [c]))
+ // match: (Rsh64x8 <t> x (Const8 [c]))
// cond:
// result: (Rsh64x64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AddArg(v0)
return true
}
- // match: (Rsh64x8 (Const64 [0]) _)
- // cond:
- // result: (Const64 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst64 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst64)
- v.AuxInt = 0
- return true
- }
return false
}
func rewriteValuegeneric_OpRsh8Ux16(v *Value, config *Config) bool {
v.AuxInt = int64(int8(uint8(c) >> uint64(d)))
return true
}
- // match: (Rsh8Ux64 (Const8 [0]) _)
- // cond:
- // result: (Const8 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst8 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst8)
- v.AuxInt = 0
- return true
- }
// match: (Rsh8Ux64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Rsh8Ux64 (Const64 [0]) _)
+ // cond:
+ // result: (Const8 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst8)
+ v.AuxInt = 0
+ return true
+ }
// match: (Rsh8Ux64 _ (Const64 [c]))
// cond: uint64(c) >= 8
- // result: (Const8 [0])
+ // result: (Const8 [0])
for {
v_1 := v.Args[1]
if v_1.Op != OpConst64 {
v.AddArg(v0)
return true
}
- return false
-}
-func rewriteValuegeneric_OpRsh8Ux8(v *Value, config *Config) bool {
- b := v.Block
- _ = b
- // match: (Rsh8Ux8 (Lsh8x8 (Rsh8Ux8 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3]))
+ // match: (Rsh8Ux64 (Lsh8x64 (Rsh8Ux64 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3]))
// cond: uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2)
- // result: (Rsh8Ux8 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
+ // result: (Rsh8Ux64 x (Const8 <config.fe.TypeUInt8()> [int64(int8(c1-c2+c3))]))
for {
v_0 := v.Args[0]
- if v_0.Op != OpLsh8x8 {
+ if v_0.Op != OpLsh8x64 {
break
}
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpRsh8Ux8 {
+ if v_0_0.Op != OpRsh8Ux64 {
break
}
x := v_0_0.Args[0]
if !(uint8(c1) >= uint8(c2) && uint8(c3) >= uint8(c2)) {
break
}
- v.reset(OpRsh8Ux8)
+ v.reset(OpRsh8Ux64)
v.AddArg(x)
v0 := b.NewValue0(v.Line, OpConst8, config.fe.TypeUInt8())
v0.AuxInt = int64(int8(c1 - c2 + c3))
v.AddArg(v0)
return true
}
- // match: (Rsh8Ux8 <t> x (Const8 [c]))
+ return false
+}
+func rewriteValuegeneric_OpRsh8Ux8(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Rsh8Ux8 <t> x (Const8 [c]))
// cond:
// result: (Rsh8Ux64 x (Const64 <t> [int64(uint8(c))]))
for {
v.AuxInt = int64(int8(c) >> uint64(d))
return true
}
- // match: (Rsh8x64 (Const8 [0]) _)
- // cond:
- // result: (Const8 [0])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpConst8 {
- break
- }
- if v_0.AuxInt != 0 {
- break
- }
- v.reset(OpConst8)
- v.AuxInt = 0
- return true
- }
// match: (Rsh8x64 x (Const64 [0]))
// cond:
// result: x
v.AddArg(x)
return true
}
+ // match: (Rsh8x64 (Const64 [0]) _)
+ // cond:
+ // result: (Const8 [0])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ v.reset(OpConst8)
+ v.AuxInt = 0
+ return true
+ }
// match: (Rsh8x64 <t> (Rsh8x64 x (Const64 [c])) (Const64 [d]))
// cond: !uaddOvf(c,d)
// result: (Rsh8x64 x (Const64 <t> [c+d]))
func rewriteValuegeneric_OpRsh8x8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Rsh8x8 <t> x (Const8 [c]))
+ // match: (Rsh8x8 <t> x (Const8 [c]))
// cond:
// result: (Rsh8x64 x (Const64 <t> [int64(uint8(c))]))
for {
func rewriteValuegeneric_OpSub16(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub16 (Const16 [c]) (Const16 [d]))
+ // match: (Sub16 (Const16 [c]) (Const16 [d]))
// cond:
// result: (Const16 [int64(int16(c-d))])
for {
func rewriteValuegeneric_OpSub32(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub32 (Const32 [c]) (Const32 [d]))
+ // match: (Sub32 (Const32 [c]) (Const32 [d]))
// cond:
// result: (Const32 [int64(int32(c-d))])
for {
func rewriteValuegeneric_OpSub64(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub64 (Const64 [c]) (Const64 [d]))
+ // match: (Sub64 (Const64 [c]) (Const64 [d]))
// cond:
// result: (Const64 [c-d])
for {
func rewriteValuegeneric_OpSub8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Sub8 (Const8 [c]) (Const8 [d]))
+ // match: (Sub8 (Const8 [c]) (Const8 [d]))
// cond:
// result: (Const8 [int64(int8(c-d))])
for {
v.AuxInt = int64(int8(c - d))
return true
}
- // match: (Sub8 x (Const8 <t> [c]))
+ // match: (Sub8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Add8 (Const8 <t> [int64(int8(-c))]) x)
+ // result: (Add8 (Const8 <t> [int64(int8(-c))]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
v.AddArg(x)
return true
}
- // match: (Sub8 x x)
+ // match: (Sub8 x x)
// cond:
- // result: (Const8 [0])
+ // result: (Const8 [0])
for {
x := v.Args[0]
if x != v.Args[1] {
v.AuxInt = 0
return true
}
- // match: (Sub8 (Add8 x y) x)
+ // match: (Sub8 (Add8 x y) x)
// cond:
// result: y
for {
v.AddArg(y)
return true
}
- // match: (Sub8 (Add8 x y) y)
+ // match: (Sub8 (Add8 x y) y)
// cond:
// result: x
for {
func rewriteValuegeneric_OpTrunc16to8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Trunc16to8 (Const16 [c]))
+ // match: (Trunc16to8 (Const16 [c]))
// cond:
- // result: (Const8 [int64(int8(c))])
+ // result: (Const8 [int64(int8(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst16 {
v.AuxInt = int64(int8(c))
return true
}
- // match: (Trunc16to8 (And16 (Const16 [y]) x))
+ // match: (Trunc16to8 (And16 (Const16 [y]) x))
// cond: y&0xFF == 0xFF
// result: (Trunc16to8 x)
for {
_ = b
// match: (Trunc32to16 (Const32 [c]))
// cond:
- // result: (Const16 [int64(int16(c))])
+ // result: (Const16 [int64(int16(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst32 {
func rewriteValuegeneric_OpTrunc32to8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Trunc32to8 (Const32 [c]))
+ // match: (Trunc32to8 (Const32 [c]))
// cond:
- // result: (Const8 [int64(int8(c))])
+ // result: (Const8 [int64(int8(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst32 {
v.AuxInt = int64(int8(c))
return true
}
- // match: (Trunc32to8 (And32 (Const32 [y]) x))
+ // match: (Trunc32to8 (And32 (Const32 [y]) x))
// cond: y&0xFF == 0xFF
// result: (Trunc32to8 x)
for {
_ = b
// match: (Trunc64to16 (Const64 [c]))
// cond:
- // result: (Const16 [int64(int16(c))])
+ // result: (Const16 [int64(int16(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64 {
_ = b
// match: (Trunc64to32 (Const64 [c]))
// cond:
- // result: (Const32 [int64(int32(c))])
+ // result: (Const32 [int64(int32(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64 {
func rewriteValuegeneric_OpTrunc64to8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Trunc64to8 (Const64 [c]))
+ // match: (Trunc64to8 (Const64 [c]))
// cond:
- // result: (Const8 [int64(int8(c))])
+ // result: (Const8 [int64(int8(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64 {
v.AuxInt = int64(int8(c))
return true
}
- // match: (Trunc64to8 (And64 (Const64 [y]) x))
+ // match: (Trunc64to8 (And64 (Const64 [y]) x))
// cond: y&0xFF == 0xFF
// result: (Trunc64to8 x)
for {
func rewriteValuegeneric_OpXor8(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (Xor8 x (Const8 <t> [c]))
+ // match: (Xor8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
- // result: (Xor8 (Const8 <t> [c]) x)
+ // result: (Xor8 (Const8 <t> [c]) x)
for {
x := v.Args[0]
v_1 := v.Args[1]
v.AddArg(x)
return true
}
- // match: (Xor8 x x)
+ // match: (Xor8 x x)
// cond:
- // result: (Const8 [0])
+ // result: (Const8 [0])
for {
x := v.Args[0]
if x != v.Args[1] {
v.AuxInt = 0
return true
}
- // match: (Xor8 (Const8 [0]) x)
+ // match: (Xor8 (Const8 [0]) x)
// cond:
// result: x
for {