diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules index 40a402eccb2a33..20bcefe36796af 100644 --- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules @@ -145,59 +145,38 @@ // check shiftIsBounded first, if shift value is proved to be valid then we // can do the shift directly. // left shift -(Lsh(64|32|16|8)x64 x y) && shiftIsBounded(v) => (SLL x y) -(Lsh(64|32|16|8)x32 x y) && shiftIsBounded(v) => (SLL x y) -(Lsh(64|32|16|8)x16 x y) && shiftIsBounded(v) => (SLL x y) -(Lsh(64|32|16|8)x8 x y) && shiftIsBounded(v) => (SLL x y) +(Lsh32x(64|32|16|8) ...) => (Lsh64x(64|32|16|8) ...) +(Lsh16x(64|32|16|8) ...) => (Lsh64x(64|32|16|8) ...) +(Lsh8x(64|32|16|8) ...) => (Lsh64x(64|32|16|8) ...) + +(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SLL x y) // signed right shift +(Rsh32x(64|32|16|8) [bounded] x y) => (Rsh64x(64|32|16|8) [bounded] (SignExt32to64 x) y) +(Rsh16x(64|32|16|8) [bounded] x y) => (Rsh64x(64|32|16|8) [bounded] (SignExt16to64 x) y) +(Rsh8x(64|32|16|8) [bounded] x y) => (Rsh64x(64|32|16|8) [bounded] (SignExt8to64 x) y) + (Rsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA x y) -(Rsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt32to64 x) y) -(Rsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt16to64 x) y) -(Rsh8x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt8to64 x) y) // unsigned right shift +(Rsh32Ux(64|32|16|8) [bounded] x y) => (Rsh64Ux(64|32|16|8) [bounded] (ZeroExt32to64 x) y) +(Rsh16Ux(64|32|16|8) [bounded] x y) => (Rsh64Ux(64|32|16|8) [bounded] (ZeroExt16to64 x) y) +(Rsh8Ux(64|32|16|8) [bounded] x y) => (Rsh64Ux(64|32|16|8) [bounded] (ZeroExt8to64 x) y) + (Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL x y) -(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt32to64 x) y) -(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt16to64 x) y) -(Rsh8Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt8to64 x) y) // shift value may be out of range, use CMP + CSEL instead -(Lsh64x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh64x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Lsh32x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh32x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Lsh16x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh16x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Lsh8x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh8x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Rsh64Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] y)) -(Rsh64Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) +(Lsh64x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) +(Lsh64x32 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPWconst [64] y)) +(Lsh64x(16|8) [bounded] x y) && !shiftIsBounded(v) => (Lsh64x32 [bounded] x (ZeroExt(16|8)to32 y)) -(Rsh32Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] y)) -(Rsh32Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) +(Rsh64Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] y)) +(Rsh64Ux32 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPWconst [64] y)) +(Rsh64Ux(16|8) [bounded] x y) && !shiftIsBounded(v) => (Rsh64Ux32 [bounded] x (ZeroExt(16|8)to32 y)) -(Rsh16Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] y)) -(Rsh16Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Rsh8Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] y)) -(Rsh8Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Rsh64x64 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh64x(32|16|8) x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) - -(Rsh32x64 x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh32x(32|16|8) x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) - -(Rsh16x64 x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh16x(32|16|8) x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) - -(Rsh8x64 x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh8x(32|16|8) x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) +(Rsh64x64 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) +(Rsh64x32 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) +(Rsh64x(16|8) [bounded] x y) && !shiftIsBounded(v) => (Rsh64x32 [bounded] x (ZeroExt(16|8)to32 y)) // constants (Const(64|32|16|8) [val]) => (MOVDconst [int64(val)]) @@ -1617,6 +1596,8 @@ && (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) => (REV16 (ANDconst [0xffffffff] x)) +(REV16 (MOVWUreg x)) => (REV16W x) + // Extract from reg pair (ADDshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x) ( ORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x) @@ -1864,3 +1845,8 @@ // 32 mul 32 -> 64 (MUL r:(MOVWUreg x) s:(MOVWUreg y)) && r.Uses == 1 && s.Uses == 1 => (UMULL x y) (MUL r:(MOVWreg x) s:(MOVWreg y)) && r.Uses == 1 && s.Uses == 1 => (MULL x y) + +// ANDconst to zext +(ANDconst [0xffffffff] x) => (MOVWUreg x) +(ANDconst [0xffff ] x) => (MOVHUreg x) +(ANDconst [0xff ] x) => (MOVBUreg x) \ No newline at end of file diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index a75247727cc7b8..661546a088df07 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -336,6 +336,8 @@ func rewriteValueARM64(v *Value) bool { return rewriteValueARM64_OpARM64ORshiftRO(v) case OpARM64REV: return rewriteValueARM64_OpARM64REV(v) + case OpARM64REV16: + return rewriteValueARM64_OpARM64REV16(v) case OpARM64REVW: return rewriteValueARM64_OpARM64REVW(v) case OpARM64ROR: @@ -813,21 +815,29 @@ func rewriteValueARM64(v *Value) bool { case OpLocalAddr: return rewriteValueARM64_OpLocalAddr(v) case OpLsh16x16: - return rewriteValueARM64_OpLsh16x16(v) + v.Op = OpLsh64x16 + return true case OpLsh16x32: - return rewriteValueARM64_OpLsh16x32(v) + v.Op = OpLsh64x32 + return true case OpLsh16x64: - return rewriteValueARM64_OpLsh16x64(v) + v.Op = OpLsh64x64 + return true case OpLsh16x8: - return rewriteValueARM64_OpLsh16x8(v) + v.Op = OpLsh64x8 + return true case OpLsh32x16: - return rewriteValueARM64_OpLsh32x16(v) + v.Op = OpLsh64x16 + return true case OpLsh32x32: - return rewriteValueARM64_OpLsh32x32(v) + v.Op = OpLsh64x32 + return true case OpLsh32x64: - return rewriteValueARM64_OpLsh32x64(v) + v.Op = OpLsh64x64 + return true case OpLsh32x8: - return rewriteValueARM64_OpLsh32x8(v) + v.Op = OpLsh64x8 + return true case OpLsh64x16: return rewriteValueARM64_OpLsh64x16(v) case OpLsh64x32: @@ -837,13 +847,17 @@ func rewriteValueARM64(v *Value) bool { case OpLsh64x8: return rewriteValueARM64_OpLsh64x8(v) case OpLsh8x16: - return rewriteValueARM64_OpLsh8x16(v) + v.Op = OpLsh64x16 + return true case OpLsh8x32: - return rewriteValueARM64_OpLsh8x32(v) + v.Op = OpLsh64x32 + return true case OpLsh8x64: - return rewriteValueARM64_OpLsh8x64(v) + v.Op = OpLsh64x64 + return true case OpLsh8x8: - return rewriteValueARM64_OpLsh8x8(v) + v.Op = OpLsh64x8 + return true case OpMax32F: v.Op = OpARM64FMAXS return true @@ -2296,6 +2310,39 @@ func rewriteValueARM64_OpARM64ANDconst(v *Value) bool { v.AddArg(x) return true } + // match: (ANDconst [0xffffffff] x) + // result: (MOVWUreg x) + for { + if auxIntToInt64(v.AuxInt) != 0xffffffff { + break + } + x := v_0 + v.reset(OpARM64MOVWUreg) + v.AddArg(x) + return true + } + // match: (ANDconst [0xffff ] x) + // result: (MOVHUreg x) + for { + if auxIntToInt64(v.AuxInt) != 0xffff { + break + } + x := v_0 + v.reset(OpARM64MOVHUreg) + v.AddArg(x) + return true + } + // match: (ANDconst [0xff ] x) + // result: (MOVBUreg x) + for { + if auxIntToInt64(v.AuxInt) != 0xff { + break + } + x := v_0 + v.reset(OpARM64MOVBUreg) + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool { @@ -14648,6 +14695,21 @@ func rewriteValueARM64_OpARM64REV(v *Value) bool { } return false } +func rewriteValueARM64_OpARM64REV16(v *Value) bool { + v_0 := v.Args[0] + // match: (REV16 (MOVWUreg x)) + // result: (REV16W x) + for { + if v_0.Op != OpARM64MOVWUreg { + break + } + x := v_0.Args[0] + v.reset(OpARM64REV16W) + v.AddArg(x) + return true + } + return false +} func rewriteValueARM64_OpARM64REVW(v *Value) bool { v_0 := v.Args[0] // match: (REVW (REVW p)) @@ -18683,12 +18745,12 @@ func rewriteValueARM64_OpLocalAddr(v *Value) bool { } return false } -func rewriteValueARM64_OpLsh16x16(v *Value) bool { +func rewriteValueARM64_OpLsh64x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh16x16 x y) + // match: (Lsh64x16 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18703,38 +18765,32 @@ func rewriteValueARM64_OpLsh16x16(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x16 x y) + // match: (Lsh64x16 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) + // result: (Lsh64x32 [bounded] x (ZeroExt16to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpLsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false } -func rewriteValueARM64_OpLsh16x32(v *Value) bool { +func rewriteValueARM64_OpLsh64x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh16x32 x y) + // match: (Lsh64x32 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18749,9 +18805,9 @@ func rewriteValueARM64_OpLsh16x32(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x32 x y) + // match: (Lsh64x32 x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) + // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPWconst [64] y)) for { t := v.Type x := v_0 @@ -18765,21 +18821,19 @@ func rewriteValueARM64_OpLsh16x32(v *Value) bool { v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpConst64, t) v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) + v2 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags) + v2.AuxInt = int32ToAuxInt(64) + v2.AddArg(y) v.AddArg3(v0, v1, v2) return true } return false } -func rewriteValueARM64_OpLsh16x64(v *Value) bool { +func rewriteValueARM64_OpLsh64x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - // match: (Lsh16x64 x y) + // match: (Lsh64x64 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18794,7 +18848,7 @@ func rewriteValueARM64_OpLsh16x64(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x64 x y) + // match: (Lsh64x64 x y) // cond: !shiftIsBounded(v) // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) for { @@ -18818,12 +18872,12 @@ func rewriteValueARM64_OpLsh16x64(v *Value) bool { } return false } -func rewriteValueARM64_OpLsh16x8(v *Value) bool { +func rewriteValueARM64_OpLsh64x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh16x8 x y) + // match: (Lsh64x8 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18838,697 +18892,149 @@ func rewriteValueARM64_OpLsh16x8(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x8 x y) + // match: (Lsh64x8 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) + // result: (Lsh64x32 [bounded] x (ZeroExt8to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpLsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false } -func rewriteValueARM64_OpLsh32x16(v *Value) bool { +func rewriteValueARM64_OpMod16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh32x16 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + // match: (Mod16 x y) + // result: (MODW (SignExt16to32 x) (SignExt16to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) + v.reset(OpARM64MODW) + v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - // match: (Lsh32x16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) +} +func rewriteValueARM64_OpMod16u(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Mod16u x y) + // result: (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpARM64UMODW) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - return false } -func rewriteValueARM64_OpLsh32x32(v *Value) bool { +func rewriteValueARM64_OpMod32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh32x32 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + // match: (Mod32 x y) + // result: (MODW x y) for { - t := v.Type x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t + v.reset(OpARM64MODW) v.AddArg2(x, y) return true } - // match: (Lsh32x32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) +} +func rewriteValueARM64_OpMod64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (Mod64 x y) + // result: (MOD x y) for { - t := v.Type x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpARM64MOD) + v.AddArg2(x, y) return true } - return false } -func rewriteValueARM64_OpLsh32x64(v *Value) bool { +func rewriteValueARM64_OpMod8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - // match: (Lsh32x64 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + typ := &b.Func.Config.Types + // match: (Mod8 x y) + // result: (MODW (SignExt8to32 x) (SignExt8to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) + v.reset(OpARM64MODW) + v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - // match: (Lsh32x64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) +} +func rewriteValueARM64_OpMod8u(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Mod8u x y) + // result: (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v2.AddArg(y) - v.AddArg3(v0, v1, v2) + v.reset(OpARM64UMODW) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - return false } -func rewriteValueARM64_OpLsh32x8(v *Value) bool { +func rewriteValueARM64_OpMove(v *Value) bool { + v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh32x8 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + // match: (Move [0] _ _ mem) + // result: mem for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { + if auxIntToInt64(v.AuxInt) != 0 { break } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) + mem := v_2 + v.copyOf(mem) return true } - // match: (Lsh32x8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) + // match: (Move [1] dst src mem) + // result: (MOVBstore dst (MOVBUload src mem) mem) for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x16(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh64x16 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh64x32 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - // match: (Lsh64x64 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v2.AddArg(y) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x8(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh64x8 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x16(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh8x16 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh8x32 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - // match: (Lsh8x64 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v2.AddArg(y) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x8(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh8x8 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpMod16(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod16 x y) - // result: (MODW (SignExt16to32 x) (SignExt16to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MODW) - v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMod16u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod16u x y) - // result: (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64UMODW) - v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMod32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - // match: (Mod32 x y) - // result: (MODW x y) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MODW) - v.AddArg2(x, y) - return true - } -} -func rewriteValueARM64_OpMod64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - // match: (Mod64 x y) - // result: (MOD x y) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MOD) - v.AddArg2(x, y) - return true - } -} -func rewriteValueARM64_OpMod8(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod8 x y) - // result: (MODW (SignExt8to32 x) (SignExt8to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MODW) - v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMod8u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod8u x y) - // result: (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64UMODW) - v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMove(v *Value) bool { - v_2 := v.Args[2] - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Move [0] _ _ mem) - // result: mem - for { - if auxIntToInt64(v.AuxInt) != 0 { - break - } - mem := v_2 - v.copyOf(mem) - return true - } - // match: (Move [1] dst src mem) - // result: (MOVBstore dst (MOVBUload src mem) mem) - for { - if auxIntToInt64(v.AuxInt) != 1 { + if auxIntToInt64(v.AuxInt) != 1 { break } dst := v_0 @@ -20420,784 +19926,336 @@ func rewriteValueARM64_OpRsh16Ux16(v *Value) bool { v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16Ux16 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) - v.Type = t - v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v0.AddArg(x) - v.AddArg2(v0, y) - return true - } - // match: (Rsh16Ux16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false -} -func rewriteValueARM64_OpRsh16Ux32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Rsh16Ux32 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) - v.Type = t - v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v0.AddArg(x) - v.AddArg2(v0, y) - return true - } - // match: (Rsh16Ux32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false -} -func rewriteValueARM64_OpRsh16Ux64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Rsh16Ux64 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) + // match: (Rsh16Ux16 [bounded] x y) + // result: (Rsh64Ux16 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v0.AddArg(x) - v.AddArg2(v0, y) - return true - } - // match: (Rsh16Ux64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v.AddArg3(v0, v2, v3) + v0.AddArg(x) + v.AddArg2(v0, y) return true } - return false } -func rewriteValueARM64_OpRsh16Ux8(v *Value) bool { +func rewriteValueARM64_OpRsh16Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16Ux8 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) + // match: (Rsh16Ux32 [bounded] x y) + // result: (Rsh64Ux32 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16Ux8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) +} +func rewriteValueARM64_OpRsh16Ux64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh16Ux64 [bounded] x y) + // result: (Rsh64Ux64 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) + v.reset(OpRsh64Ux64) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) + v.AddArg2(v0, y) return true } - return false } -func rewriteValueARM64_OpRsh16x16(v *Value) bool { +func rewriteValueARM64_OpRsh16Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x16 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16Ux8 [bounded] x y) + // result: (Rsh64Ux8 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64Ux8) v.Type = t - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x16 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) +} +func rewriteValueARM64_OpRsh16x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh16x16 [bounded] x y) + // result: (Rsh64x16 [bounded] (SignExt16to64 x) y) for { + t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x16) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) + v.AddArg2(v0, y) return true } - return false } func rewriteValueARM64_OpRsh16x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x32 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16x32 [bounded] x y) + // result: (Rsh64x32 [bounded] (SignExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x32 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh16x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x64 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16x64 [bounded] x y) + // result: (Rsh64x64 [bounded] (SignExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x64 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh16x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x8 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16x8 [bounded] x y) + // result: (Rsh64x8 [bounded] (SignExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x8 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux16 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux16 [bounded] x y) + // result: (Rsh64Ux16 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux32 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux32 [bounded] x y) + // result: (Rsh64Ux32 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux64 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux64 [bounded] x y) + // result: (Rsh64Ux64 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux8 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux8 [bounded] x y) + // result: (Rsh64Ux8 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x16 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x16 [bounded] x y) + // result: (Rsh64x16 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x16 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x32 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x32 [bounded] x y) + // result: (Rsh64x32 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x32 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x64 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x64 [bounded] x y) + // result: (Rsh64x64 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x64 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x8 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x8 [bounded] x y) + // result: (Rsh64x8 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x8 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh64Ux16(v *Value) bool { v_1 := v.Args[1] @@ -21219,28 +20277,23 @@ func rewriteValueARM64_OpRsh64Ux16(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64Ux16 x y) + // match: (Rsh64Ux16 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) + // result: (Rsh64Ux32 [bounded] x (ZeroExt16to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpRsh64Ux32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false @@ -21249,7 +20302,6 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types // match: (Rsh64Ux32 x y) // cond: shiftIsBounded(v) // result: (SRL x y) @@ -21267,7 +20319,7 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool { } // match: (Rsh64Ux32 x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) + // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPWconst [64] y)) for { t := v.Type x := v_0 @@ -21281,11 +20333,9 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool { v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpConst64, t) v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) + v2 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags) + v2.AuxInt = int32ToAuxInt(64) + v2.AddArg(y) v.AddArg3(v0, v1, v2) return true } @@ -21354,28 +20404,23 @@ func rewriteValueARM64_OpRsh64Ux8(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64Ux8 x y) + // match: (Rsh64Ux8 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) + // result: (Rsh64Ux32 [bounded] x (ZeroExt8to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpRsh64Ux32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false @@ -21400,26 +20445,22 @@ func rewriteValueARM64_OpRsh64x16(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x16 x y) + // match: (Rsh64x16 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) + // result: (Rsh64x32 [bounded] x (ZeroExt16to32 y)) for { + t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v0.AuxInt = opToAuxInt(OpARM64LessThanU) - v1 := b.NewValue0(v.Pos, OpConst64, y.Type) - v1.AuxInt = int64ToAuxInt(63) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v0.AddArg3(y, v1, v2) + v.reset(OpRsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(y) v.AddArg2(x, v0) return true } @@ -21429,7 +20470,6 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types // match: (Rsh64x32 x y) // cond: shiftIsBounded(v) // result: (SRA x y) @@ -21445,9 +20485,9 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x32 x y) + // match: (Rsh64x32 x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) + // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) for { x := v_0 y := v_1 @@ -21461,9 +20501,7 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool { v1.AuxInt = int64ToAuxInt(63) v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) + v2.AddArg(y) v0.AddArg3(y, v1, v2) v.AddArg2(x, v0) return true @@ -21489,7 +20527,7 @@ func rewriteValueARM64_OpRsh64x64(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x64 x y) + // match: (Rsh64x64 x y) // cond: !shiftIsBounded(v) // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) for { @@ -21532,26 +20570,22 @@ func rewriteValueARM64_OpRsh64x8(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x8 x y) + // match: (Rsh64x8 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) + // result: (Rsh64x32 [bounded] x (ZeroExt8to32 y)) for { + t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v0.AuxInt = opToAuxInt(OpARM64LessThanU) - v1 := b.NewValue0(v.Pos, OpConst64, y.Type) - v1.AuxInt = int64ToAuxInt(63) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v0.AddArg3(y, v1, v2) + v.reset(OpRsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(y) v.AddArg2(x, v0) return true } @@ -21562,392 +20596,168 @@ func rewriteValueARM64_OpRsh8Ux16(v *Value) bool { v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux16 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux16 [bounded] x y) + // result: (Rsh64Ux16 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux32 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux32 [bounded] x y) + // result: (Rsh64Ux32 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8Ux64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux64 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux64 [bounded] x y) + // result: (Rsh64Ux64 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux8 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux8 [bounded] x y) + // result: (Rsh64Ux8 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x16 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x16 [bounded] x y) + // result: (Rsh64x16 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x16 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh8x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x32 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x32 [bounded] x y) + // result: (Rsh64x32 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x32 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh8x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x64 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x64 [bounded] x y) + // result: (Rsh64x64 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x64 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh8x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x8 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x8 [bounded] x y) + // result: (Rsh64x8 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x8 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpSelect0(v *Value) bool { v_0 := v.Args[0] diff --git a/src/log/slog/logger.go b/src/log/slog/logger.go index 69e1cf9f152860..bda5070cef3dbd 100644 --- a/src/log/slog/logger.go +++ b/src/log/slog/logger.go @@ -195,6 +195,8 @@ func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs .. } // Debug logs at [LevelDebug]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.DebugContext]. func (l *Logger) Debug(msg string, args ...any) { l.log(context.Background(), LevelDebug, msg, args...) } @@ -205,6 +207,8 @@ func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) { } // Info logs at [LevelInfo]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.InfoContext]. func (l *Logger) Info(msg string, args ...any) { l.log(context.Background(), LevelInfo, msg, args...) } @@ -215,6 +219,8 @@ func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) { } // Warn logs at [LevelWarn]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.WarnContext]. func (l *Logger) Warn(msg string, args ...any) { l.log(context.Background(), LevelWarn, msg, args...) } @@ -225,6 +231,8 @@ func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) { } // Error logs at [LevelError]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.ErrorContext]. func (l *Logger) Error(msg string, args ...any) { l.log(context.Background(), LevelError, msg, args...) } @@ -277,6 +285,8 @@ func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs .. } // Debug calls [Logger.Debug] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [DebugContext]. func Debug(msg string, args ...any) { Default().log(context.Background(), LevelDebug, msg, args...) } @@ -287,6 +297,8 @@ func DebugContext(ctx context.Context, msg string, args ...any) { } // Info calls [Logger.Info] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [InfoContext]. func Info(msg string, args ...any) { Default().log(context.Background(), LevelInfo, msg, args...) } @@ -297,6 +309,8 @@ func InfoContext(ctx context.Context, msg string, args ...any) { } // Warn calls [Logger.Warn] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [WarnContext]. func Warn(msg string, args ...any) { Default().log(context.Background(), LevelWarn, msg, args...) } @@ -307,6 +321,8 @@ func WarnContext(ctx context.Context, msg string, args ...any) { } // Error calls [Logger.Error] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [ErrorContext]. func Error(msg string, args ...any) { Default().log(context.Background(), LevelError, msg, args...) } diff --git a/src/runtime/os_linux32.go b/src/runtime/os_linux32.go index 1ee1cdcaf90051..3bc6183276180a 100644 --- a/src/runtime/os_linux32.go +++ b/src/runtime/os_linux32.go @@ -27,11 +27,11 @@ func futex(addr unsafe.Pointer, op int32, val uint32, ts *timespec, addr2 unsafe if use64bitsTimeOn32bits { return futex_time64(addr, op, val, ts, addr2, val3) } - // Downgrade ts. + var ts32 timespec32 var pts32 *timespec32 if ts != nil { - ts32.setNsec(ts.tv_sec*1e9 + int64(ts.tv_nsec)) + ts32 = ts.mustDowncastToTimespec32() pts32 = &ts32 } return futex_time32(addr, op, val, pts32, addr2, val3) @@ -53,16 +53,29 @@ func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 { var new32, old32 *itimerspec32 if new != nil { - newts.it_interval.setNsec(new.it_interval.tv_sec*1e9 + int64(new.it_interval.tv_nsec)) - newts.it_value.setNsec(new.it_value.tv_sec*1e9 + int64(new.it_value.tv_nsec)) + newts.it_interval = new.it_interval.mustDowncastToTimespec32() + newts.it_value = new.it_value.mustDowncastToTimespec32() new32 = &newts } if old != nil { - oldts.it_interval.setNsec(old.it_interval.tv_sec*1e9 + int64(old.it_interval.tv_nsec)) - oldts.it_value.setNsec(old.it_value.tv_sec*1e9 + int64(old.it_value.tv_nsec)) + oldts.it_interval = old.it_interval.mustDowncastToTimespec32() + oldts.it_value = old.it_value.mustDowncastToTimespec32() old32 = &oldts } return timer_settime32(timerid, flags, new32, old32) } + +// mustDowncastToTimespec32 converts a 64-bit timespec to a 32-bit +// timespec and throws if the value cannot be represented in 32 bits. +// +//go:nosplit +func (ts timespec) mustDowncastToTimespec32() (r timespec32) { + r.tv_sec = int32(ts.tv_sec) + if ts.tv_sec != int64(r.tv_sec) { + throw("timespec64 value cannot be represented in timespec32") + } + r.tv_nsec = ts.tv_nsec + return +}