ssa.OpRISCV64FADDS, ssa.OpRISCV64FSUBS, ssa.OpRISCV64FMULS, ssa.OpRISCV64FDIVS,
ssa.OpRISCV64FEQS, ssa.OpRISCV64FNES, ssa.OpRISCV64FLTS, ssa.OpRISCV64FLES,
ssa.OpRISCV64FADDD, ssa.OpRISCV64FSUBD, ssa.OpRISCV64FMULD, ssa.OpRISCV64FDIVD,
- ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED,
- ssa.OpRISCV64FSGNJD:
+ ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED, ssa.OpRISCV64FSGNJD,
+ ssa.OpRISCV64MIN, ssa.OpRISCV64MAX, ssa.OpRISCV64MINU, ssa.OpRISCV64MAXU:
r := v.Reg()
r1 := v.Args[0].Reg()
r2 := v.Args[1].Reg()
(F(MADD|NMADD|MSUB|NMSUB)S x y neg:(FNEGS z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)S x y z)
(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMSUB|MSUB|NMADD|MADD)D x y z)
(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
+
+//
+// Optimisations for rva22u64 and above.
+//
+
+// Integer minimum and maximum.
+(Min64 x y) && buildcfg.GORISCV64 >= 22 => (MIN x y)
+(Max64 x y) && buildcfg.GORISCV64 >= 22 => (MAX x y)
+(Min64u x y) && buildcfg.GORISCV64 >= 22 => (MINU x y)
+(Max64u x y) && buildcfg.GORISCV64 >= 22 => (MAXU x y)
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true}, // arg0 ^ arg1
{name: "XORI", argLength: 1, reg: gp11, asm: "XORI", aux: "Int64"}, // arg0 ^ auxint
+ // Minimum and maximum
+ {name: "MIN", argLength: 2, reg: gp21, asm: "MIN", commutative: true}, // min(arg0,arg1), signed
+ {name: "MAX", argLength: 2, reg: gp21, asm: "MAX", commutative: true}, // max(arg0,arg1), signed
+ {name: "MINU", argLength: 2, reg: gp21, asm: "MINU", commutative: true}, // min(arg0,arg1), unsigned
+ {name: "MAXU", argLength: 2, reg: gp21, asm: "MAXU", commutative: true}, // max(arg0,arg1), unsigned
+
// Generate boolean values
{name: "SEQZ", argLength: 1, reg: gp11, asm: "SEQZ"}, // arg0 == 0, result is 0 or 1
{name: "SNEZ", argLength: 1, reg: gp11, asm: "SNEZ"}, // arg0 != 0, result is 0 or 1
{name: "Abs", argLength: 1}, // absolute value arg0
{name: "Copysign", argLength: 2}, // copy sign from arg0 to arg1
+ // Integer min/max implementation, if hardware is available.
+ {name: "Min64", argLength: 2}, // min(arg0,arg1), signed
+ {name: "Max64", argLength: 2}, // max(arg0,arg1), signed
+ {name: "Min64u", argLength: 2}, // min(arg0,arg1), unsigned
+ {name: "Max64u", argLength: 2}, // max(arg0,arg1), unsigned
+
// Float min/max implementation, if hardware is available.
{name: "Min64F", argLength: 2}, // min(arg0,arg1)
{name: "Min32F", argLength: 2}, // min(arg0,arg1)
OpRISCV64RORW
OpRISCV64XOR
OpRISCV64XORI
+ OpRISCV64MIN
+ OpRISCV64MAX
+ OpRISCV64MINU
+ OpRISCV64MAXU
OpRISCV64SEQZ
OpRISCV64SNEZ
OpRISCV64SLT
OpRoundToEven
OpAbs
OpCopysign
+ OpMin64
+ OpMax64
+ OpMin64u
+ OpMax64u
OpMin64F
OpMin32F
OpMax64F
},
},
},
+ {
+ name: "MIN",
+ argLen: 2,
+ commutative: true,
+ asm: riscv.AMIN,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ {1, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ outputs: []outputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ },
+ },
+ {
+ name: "MAX",
+ argLen: 2,
+ commutative: true,
+ asm: riscv.AMAX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ {1, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ outputs: []outputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ },
+ },
+ {
+ name: "MINU",
+ argLen: 2,
+ commutative: true,
+ asm: riscv.AMINU,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ {1, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ outputs: []outputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ },
+ },
+ {
+ name: "MAXU",
+ argLen: 2,
+ commutative: true,
+ asm: riscv.AMAXU,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ {1, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ outputs: []outputInfo{
+ {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+ },
+ },
+ },
{
name: "SEQZ",
argLen: 1,
argLen: 2,
generic: true,
},
+ {
+ name: "Min64",
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "Max64",
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "Min64u",
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "Max64u",
+ argLen: 2,
+ generic: true,
+ },
{
name: "Min64F",
argLen: 2,
package ssa
+import "internal/buildcfg"
import "math"
import "cmd/compile/internal/types"
case OpMax32F:
v.Op = OpRISCV64LoweredFMAXS
return true
+ case OpMax64:
+ return rewriteValueRISCV64_OpMax64(v)
case OpMax64F:
v.Op = OpRISCV64LoweredFMAXD
return true
+ case OpMax64u:
+ return rewriteValueRISCV64_OpMax64u(v)
case OpMin32F:
v.Op = OpRISCV64LoweredFMINS
return true
+ case OpMin64:
+ return rewriteValueRISCV64_OpMin64(v)
case OpMin64F:
v.Op = OpRISCV64LoweredFMIND
return true
+ case OpMin64u:
+ return rewriteValueRISCV64_OpMin64u(v)
case OpMod16:
return rewriteValueRISCV64_OpMod16(v)
case OpMod16u:
}
return false
}
+func rewriteValueRISCV64_OpMax64(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (Max64 x y)
+ // cond: buildcfg.GORISCV64 >= 22
+ // result: (MAX x y)
+ for {
+ x := v_0
+ y := v_1
+ if !(buildcfg.GORISCV64 >= 22) {
+ break
+ }
+ v.reset(OpRISCV64MAX)
+ v.AddArg2(x, y)
+ return true
+ }
+ return false
+}
+func rewriteValueRISCV64_OpMax64u(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (Max64u x y)
+ // cond: buildcfg.GORISCV64 >= 22
+ // result: (MAXU x y)
+ for {
+ x := v_0
+ y := v_1
+ if !(buildcfg.GORISCV64 >= 22) {
+ break
+ }
+ v.reset(OpRISCV64MAXU)
+ v.AddArg2(x, y)
+ return true
+ }
+ return false
+}
+func rewriteValueRISCV64_OpMin64(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (Min64 x y)
+ // cond: buildcfg.GORISCV64 >= 22
+ // result: (MIN x y)
+ for {
+ x := v_0
+ y := v_1
+ if !(buildcfg.GORISCV64 >= 22) {
+ break
+ }
+ v.reset(OpRISCV64MIN)
+ v.AddArg2(x, y)
+ return true
+ }
+ return false
+}
+func rewriteValueRISCV64_OpMin64u(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (Min64u x y)
+ // cond: buildcfg.GORISCV64 >= 22
+ // result: (MINU x y)
+ for {
+ x := v_0
+ y := v_1
+ if !(buildcfg.GORISCV64 >= 22) {
+ break
+ }
+ v.reset(OpRISCV64MINU)
+ v.AddArg2(x, y)
+ return true
+ }
+ return false
+}
func rewriteValueRISCV64_OpMod16(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
})
}
+ if typ.IsInteger() {
+ if Arch.LinkArch.Family == sys.RISCV64 && buildcfg.GORISCV64 >= 22 && typ.Size() == 8 {
+ var op ssa.Op
+ switch {
+ case typ.IsSigned() && n.Op() == ir.OMIN:
+ op = ssa.OpMin64
+ case typ.IsSigned() && n.Op() == ir.OMAX:
+ op = ssa.OpMax64
+ case typ.IsUnsigned() && n.Op() == ir.OMIN:
+ op = ssa.OpMin64u
+ case typ.IsUnsigned() && n.Op() == ir.OMAX:
+ op = ssa.OpMax64u
+ }
+ return fold(func(x, a *ssa.Value) *ssa.Value {
+ return s.newValue2(op, typ, x, a)
+ })
+ }
+ }
+
lt := s.ssaOp(ir.OLT, typ)
return fold(func(x, a *ssa.Value) *ssa.Value {