(Hmul32 x y) => (SRAI [32] (MUL (SignExt32to64 x) (SignExt32to64 y)))
(Hmul32u x y) => (SRLI [32] (MUL (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Select0 (Add64carry x y c)) => (ADD (ADD <typ.UInt64> x y) c)
+(Select1 (Add64carry x y c)) =>
+ (OR (SLTU <typ.UInt64> s:(ADD <typ.UInt64> x y) x) (SLTU <typ.UInt64> (ADD <typ.UInt64> s c) s))
+
// (x + y) / 2 => (x / 2) + (y / 2) + (x & y & 1)
(Avg64u <t> x y) => (ADD (ADD <t> (SRLI <t> [1] x) (SRLI <t> [1] y)) (ANDI <t> [1] (AND <t> x y)))
(SLTI [x] (MOVDconst [y])) => (MOVDconst [b2i(int64(y) < int64(x))])
(SLTIU [x] (MOVDconst [y])) => (MOVDconst [b2i(uint64(y) < uint64(x))])
+(SLT x x) => (MOVDconst [0])
+(SLTU x x) => (MOVDconst [0])
+
// deadcode for LoweredMuluhilo
(Select0 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MULHU x y)
(Select1 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MUL x y)
return rewriteValueRISCV64_OpRISCV64SLL(v)
case OpRISCV64SLLI:
return rewriteValueRISCV64_OpRISCV64SLLI(v)
+ case OpRISCV64SLT:
+ return rewriteValueRISCV64_OpRISCV64SLT(v)
case OpRISCV64SLTI:
return rewriteValueRISCV64_OpRISCV64SLTI(v)
case OpRISCV64SLTIU:
return rewriteValueRISCV64_OpRISCV64SLTIU(v)
+ case OpRISCV64SLTU:
+ return rewriteValueRISCV64_OpRISCV64SLTU(v)
case OpRISCV64SRA:
return rewriteValueRISCV64_OpRISCV64SRA(v)
case OpRISCV64SRAI:
}
return false
}
+func rewriteValueRISCV64_OpRISCV64SLT(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (SLT x x)
+ // result: (MOVDconst [0])
+ for {
+ x := v_0
+ if x != v_1 {
+ break
+ }
+ v.reset(OpRISCV64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
+ return false
+}
func rewriteValueRISCV64_OpRISCV64SLTI(v *Value) bool {
v_0 := v.Args[0]
// match: (SLTI [x] (MOVDconst [y]))
}
return false
}
+func rewriteValueRISCV64_OpRISCV64SLTU(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (SLTU x x)
+ // result: (MOVDconst [0])
+ for {
+ x := v_0
+ if x != v_1 {
+ break
+ }
+ v.reset(OpRISCV64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
+ return false
+}
func rewriteValueRISCV64_OpRISCV64SRA(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
}
func rewriteValueRISCV64_OpSelect0(v *Value) bool {
v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (Select0 (Add64carry x y c))
+ // result: (ADD (ADD <typ.UInt64> x y) c)
+ for {
+ if v_0.Op != OpAdd64carry {
+ break
+ }
+ c := v_0.Args[2]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ v.reset(OpRISCV64ADD)
+ v0 := b.NewValue0(v.Pos, OpRISCV64ADD, typ.UInt64)
+ v0.AddArg2(x, y)
+ v.AddArg2(v0, c)
+ return true
+ }
// match: (Select0 m:(LoweredMuluhilo x y))
// cond: m.Uses == 1
// result: (MULHU x y)
}
func rewriteValueRISCV64_OpSelect1(v *Value) bool {
v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (Select1 (Add64carry x y c))
+ // result: (OR (SLTU <typ.UInt64> s:(ADD <typ.UInt64> x y) x) (SLTU <typ.UInt64> (ADD <typ.UInt64> s c) s))
+ for {
+ if v_0.Op != OpAdd64carry {
+ break
+ }
+ c := v_0.Args[2]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ v.reset(OpRISCV64OR)
+ v0 := b.NewValue0(v.Pos, OpRISCV64SLTU, typ.UInt64)
+ s := b.NewValue0(v.Pos, OpRISCV64ADD, typ.UInt64)
+ s.AddArg2(x, y)
+ v0.AddArg2(s, x)
+ v2 := b.NewValue0(v.Pos, OpRISCV64SLTU, typ.UInt64)
+ v3 := b.NewValue0(v.Pos, OpRISCV64ADD, typ.UInt64)
+ v3.AddArg2(s, c)
+ v2.AddArg2(v3, s)
+ v.AddArg2(v0, v2)
+ return true
+ }
// match: (Select1 m:(LoweredMuluhilo x y))
// cond: m.Uses == 1
// result: (MUL x y)
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
},
- sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
- alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchS390X)
+ sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.RISCV64)
+ alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchS390X, sys.ArchRISCV64)
addF("math/bits", "Sub64",
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
// ppc64: "ADDC", "ADDE", "ADDZE"
// ppc64le: "ADDC", "ADDE", "ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
+ // riscv64: "ADD","SLTU"
return bits.Add(x, y, ci)
}
// ppc64: "ADDC", "ADDE", "ADDZE"
// ppc64le: "ADDC", "ADDE", "ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
+ // riscv64: "ADD","SLTU"
return bits.Add(x, 7, ci)
}
// ppc64: "ADDC", -"ADDE", "ADDZE"
// ppc64le: "ADDC", -"ADDE", "ADDZE"
// s390x:"ADDC",-"ADDC\t[$]-1,"
+ // riscv64: "ADD","SLTU"
return bits.Add(x, y, 0)
}
// ppc64: "ADDC", "ADDE", -"ADDZE"
// ppc64le: "ADDC", "ADDE", -"ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
+ // riscv64: "ADD",-"SLTU"
r, _ := bits.Add(x, y, ci)
return r
}
// ppc64: "ADDC", "ADDE", "ADDZE"
// ppc64le: "ADDC", "ADDE", "ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
+ // riscv64: "ADD","SLTU"
return bits.Add64(x, y, ci)
}
// ppc64: "ADDC", "ADDE", "ADDZE"
// ppc64le: "ADDC", "ADDE", "ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
+ // riscv64: "ADD","SLTU"
return bits.Add64(x, 7, ci)
}
// ppc64: "ADDC", -"ADDE", "ADDZE"
// ppc64le: "ADDC", -"ADDE", "ADDZE"
// s390x:"ADDC",-"ADDC\t[$]-1,"
+ // riscv64: "ADD","SLTU"
return bits.Add64(x, y, 0)
}
// ppc64: "ADDC", "ADDE", -"ADDZE"
// ppc64le: "ADDC", "ADDE", -"ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
+ // riscv64: "ADD",-"SLTU"
r, _ := bits.Add64(x, y, ci)
return r
}