diff --git a/src/cmd/compile/internal/riscv64/ssa.go b/src/cmd/compile/internal/riscv64/ssa.go index 9aa77c3d02bd91..2231219579b284 100644 --- a/src/cmd/compile/internal/riscv64/ssa.go +++ b/src/cmd/compile/internal/riscv64/ssa.go @@ -294,7 +294,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpRISCV64FADDD, ssa.OpRISCV64FSUBD, ssa.OpRISCV64FMULD, ssa.OpRISCV64FDIVD, ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED, ssa.OpRISCV64FSGNJD, ssa.OpRISCV64MIN, ssa.OpRISCV64MAX, ssa.OpRISCV64MINU, ssa.OpRISCV64MAXU, - ssa.OpRISCV64SH1ADD, ssa.OpRISCV64SH2ADD, ssa.OpRISCV64SH3ADD: + ssa.OpRISCV64SH1ADD, ssa.OpRISCV64SH2ADD, ssa.OpRISCV64SH3ADD, + ssa.OpRISCV64CZEROEQZ, ssa.OpRISCV64CZERONEZ: r := v.Reg() r1 := v.Args[0].Reg() r2 := v.Args[1].Reg() diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules index 31829a5eed7d0f..36f58f68bb4c1b 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules @@ -848,3 +848,21 @@ (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) + +// Zicond Extension for Integer Conditional Operations +(CondSelect x y cond) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ x cond) (CZERONEZ y cond)) +(CZERO(EQ|NE)Z x (SNEZ y)) => (CZERO(EQ|NE)Z x y) +(CZERO(EQ|NE)Z x (SEQZ y)) => (CZERO(NE|EQ)Z x y) +(CZEROEQZ x x) => x +(CZERONEZ x x) => (MOVDconst [0]) +(CZERO(EQ|NE)Z (MOVDconst [0]) _) => (MOVDconst [0]) + +// Optimize conditional arithmetic operations +(OR (CZERONEZ ((ADD|SUB|OR|XOR|SUBW) x y) cond) (CZEROEQZ x cond)) => ((ADD|SUB|OR|XOR|SUBW) x (CZERONEZ y cond)) +(OR (CZEROEQZ ((ADD|SUB|OR|XOR|SUBW) x y) cond) (CZERONEZ x cond)) => ((ADD|SUB|OR|XOR|SUBW) x (CZEROEQZ y cond)) +(OR (CZERONEZ x:(AND z _) cond) y:(CZEROEQZ z cond)) => (OR x y) +(OR (CZEROEQZ x:(AND z _) cond) y:(CZERONEZ z cond)) => (OR x y) +(OR (CZERONEZ x:(ANDI [c] z) cond) y:(CZEROEQZ z cond)) => (OR x y) +(OR (CZEROEQZ x:(ANDI [c] z) cond) y:(CZERONEZ z cond)) => (OR x y) +(OR (CZERONEZ ((ADDI|ORI|XORI) [c] x) cond) (CZEROEQZ x cond)) => ((ADD|OR|XOR) x (CZERONEZ (MOVDconst [c]) cond)) +(OR (CZEROEQZ ((ADDI|ORI|XORI) [c] x) cond) (CZERONEZ x cond)) => ((ADD|OR|XOR) x (CZEROEQZ (MOVDconst [c]) cond)) diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go b/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go index a0e1ab9754d349..65ddbb146025d4 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go @@ -523,6 +523,10 @@ func init() { // ====+============================= {name: "FCLASSS", argLength: 1, reg: fpgp, asm: "FCLASSS", typ: "Int64"}, // classify float32 {name: "FCLASSD", argLength: 1, reg: fpgp, asm: "FCLASSD", typ: "Int64"}, // classify float64 + + // RISC-V Integer Conditional (Zicond) operations extension + {name: "CZEROEQZ", argLength: 2, reg: gp21, asm: "CZEROEQZ"}, + {name: "CZERONEZ", argLength: 2, reg: gp21, asm: "CZERONEZ"}, } RISCV64blocks := []blockData{ diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go index ec0240941cfa21..5952433cde99d3 100644 --- a/src/cmd/compile/internal/ssa/config.go +++ b/src/cmd/compile/internal/ssa/config.go @@ -11,6 +11,7 @@ import ( "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" + "internal/buildcfg" ) // A Config holds readonly compilation information. @@ -342,6 +343,7 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo c.floatParamRegs = paramFloatRegRISCV64 c.FPReg = framepointerRegRISCV64 c.hasGReg = true + c.haveCondSelect = buildcfg.GORISCV64 >= 23 case "wasm": c.PtrSize = 8 c.RegSize = 8 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 264f4b3bf378f1..bfb187c3cf1d0b 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -2654,6 +2654,8 @@ const ( OpRISCV64LoweredFMAXD OpRISCV64FCLASSS OpRISCV64FCLASSD + OpRISCV64CZEROEQZ + OpRISCV64CZERONEZ OpS390XFADDS OpS390XFADD @@ -35722,6 +35724,34 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "CZEROEQZ", + argLen: 2, + asm: riscv.ACZEROEQZ, + 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: "CZERONEZ", + argLen: 2, + asm: riscv.ACZERONEZ, + 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: "FADDS", diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index 52870fe19921ce..ee4a70b4cc911b 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -132,6 +132,8 @@ func rewriteValueRISCV64(v *Value) bool { case OpCom8: v.Op = OpRISCV64NOT return true + case OpCondSelect: + return rewriteValueRISCV64_OpCondSelect(v) case OpConst16: return rewriteValueRISCV64_OpConst16(v) case OpConst32: @@ -513,6 +515,10 @@ func rewriteValueRISCV64(v *Value) bool { return rewriteValueRISCV64_OpRISCV64AND(v) case OpRISCV64ANDI: return rewriteValueRISCV64_OpRISCV64ANDI(v) + case OpRISCV64CZEROEQZ: + return rewriteValueRISCV64_OpRISCV64CZEROEQZ(v) + case OpRISCV64CZERONEZ: + return rewriteValueRISCV64_OpRISCV64CZERONEZ(v) case OpRISCV64FADDD: return rewriteValueRISCV64_OpRISCV64FADDD(v) case OpRISCV64FADDS: @@ -1080,6 +1086,32 @@ func rewriteValueRISCV64_OpBswap32(v *Value) bool { return true } } +func rewriteValueRISCV64_OpCondSelect(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + // match: (CondSelect x y cond) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR (CZEROEQZ x cond) (CZERONEZ y cond)) + for { + t := v.Type + x := v_0 + y := v_1 + cond := v_2 + if !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(x, cond) + v1 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1.AddArg2(y, cond) + v.AddArg2(v0, v1) + return true + } + return false +} func rewriteValueRISCV64_OpConst16(v *Value) bool { // match: (Const16 [val]) // result: (MOVDconst [int64(val)]) @@ -3527,6 +3559,105 @@ func rewriteValueRISCV64_OpRISCV64ANDI(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64CZEROEQZ(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (CZEROEQZ x (SNEZ y)) + // result: (CZEROEQZ x y) + for { + x := v_0 + if v_1.Op != OpRISCV64SNEZ { + break + } + y := v_1.Args[0] + v.reset(OpRISCV64CZEROEQZ) + v.AddArg2(x, y) + return true + } + // match: (CZEROEQZ x (SEQZ y)) + // result: (CZERONEZ x y) + for { + x := v_0 + if v_1.Op != OpRISCV64SEQZ { + break + } + y := v_1.Args[0] + v.reset(OpRISCV64CZERONEZ) + v.AddArg2(x, y) + return true + } + // match: (CZEROEQZ x x) + // result: x + for { + x := v_0 + if x != v_1 { + break + } + v.copyOf(x) + return true + } + // match: (CZEROEQZ (MOVDconst [0]) _) + // result: (MOVDconst [0]) + for { + if v_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 { + break + } + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + return false +} +func rewriteValueRISCV64_OpRISCV64CZERONEZ(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (CZERONEZ x (SNEZ y)) + // result: (CZERONEZ x y) + for { + x := v_0 + if v_1.Op != OpRISCV64SNEZ { + break + } + y := v_1.Args[0] + v.reset(OpRISCV64CZERONEZ) + v.AddArg2(x, y) + return true + } + // match: (CZERONEZ x (SEQZ y)) + // result: (CZEROEQZ x y) + for { + x := v_0 + if v_1.Op != OpRISCV64SEQZ { + break + } + y := v_1.Args[0] + v.reset(OpRISCV64CZEROEQZ) + v.AddArg2(x, y) + return true + } + // match: (CZERONEZ x x) + // result: (MOVDconst [0]) + for { + x := v_0 + if x != v_1 { + break + } + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (CZERONEZ (MOVDconst [0]) _) + // result: (MOVDconst [0]) + for { + if v_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 { + break + } + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64FADDD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -6860,6 +6991,8 @@ func rewriteValueRISCV64_OpRISCV64NEGW(v *Value) bool { func rewriteValueRISCV64_OpRISCV64OR(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types // match: (OR (MOVDconst [val]) x) // cond: is32Bit(val) // result: (ORI [val] x) @@ -6890,6 +7023,644 @@ func rewriteValueRISCV64_OpRISCV64OR(v *Value) bool { v.copyOf(x) return true } + // match: (OR (CZERONEZ (ADD x y) cond) (CZEROEQZ x cond)) + // result: (ADD x (CZERONEZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64ADD { + continue + } + _ = v_0_0.Args[1] + v_0_0_0 := v_0_0.Args[0] + v_0_0_1 := v_0_0.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 { + x := v_0_0_0 + y := v_0_0_1 + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64ADD) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + } + break + } + // match: (OR (CZERONEZ (SUB x y) cond) (CZEROEQZ x cond)) + // result: (SUB x (CZERONEZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64SUB { + continue + } + y := v_0_0.Args[1] + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64SUB) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZERONEZ (OR x y) cond) (CZEROEQZ x cond)) + // result: (OR x (CZERONEZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64OR { + continue + } + _ = v_0_0.Args[1] + v_0_0_0 := v_0_0.Args[0] + v_0_0_1 := v_0_0.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 { + x := v_0_0_0 + y := v_0_0_1 + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + } + break + } + // match: (OR (CZERONEZ (XOR x y) cond) (CZEROEQZ x cond)) + // result: (XOR x (CZERONEZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64XOR { + continue + } + _ = v_0_0.Args[1] + v_0_0_0 := v_0_0.Args[0] + v_0_0_1 := v_0_0.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 { + x := v_0_0_0 + y := v_0_0_1 + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64XOR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + } + break + } + // match: (OR (CZERONEZ (SUBW x y) cond) (CZEROEQZ x cond)) + // result: (SUBW x (CZERONEZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64SUBW { + continue + } + y := v_0_0.Args[1] + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64SUBW) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZEROEQZ (ADD x y) cond) (CZERONEZ x cond)) + // result: (ADD x (CZEROEQZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64ADD { + continue + } + _ = v_0_0.Args[1] + v_0_0_0 := v_0_0.Args[0] + v_0_0_1 := v_0_0.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 { + x := v_0_0_0 + y := v_0_0_1 + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64ADD) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + } + break + } + // match: (OR (CZEROEQZ (SUB x y) cond) (CZERONEZ x cond)) + // result: (SUB x (CZEROEQZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64SUB { + continue + } + y := v_0_0.Args[1] + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64SUB) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZEROEQZ (OR x y) cond) (CZERONEZ x cond)) + // result: (OR x (CZEROEQZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64OR { + continue + } + _ = v_0_0.Args[1] + v_0_0_0 := v_0_0.Args[0] + v_0_0_1 := v_0_0.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 { + x := v_0_0_0 + y := v_0_0_1 + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + } + break + } + // match: (OR (CZEROEQZ (XOR x y) cond) (CZERONEZ x cond)) + // result: (XOR x (CZEROEQZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64XOR { + continue + } + _ = v_0_0.Args[1] + v_0_0_0 := v_0_0.Args[0] + v_0_0_1 := v_0_0.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 { + x := v_0_0_0 + y := v_0_0_1 + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64XOR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + } + break + } + // match: (OR (CZEROEQZ (SUBW x y) cond) (CZERONEZ x cond)) + // result: (SUBW x (CZEROEQZ y cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64SUBW { + continue + } + y := v_0_0.Args[1] + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64SUBW) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZERONEZ x:(AND z _) cond) y:(CZEROEQZ z cond)) + // result: (OR x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + cond := v_0.Args[1] + x := v_0.Args[0] + if x.Op != OpRISCV64AND { + continue + } + x_0 := x.Args[0] + x_1 := x.Args[1] + for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 { + z := x_0 + y := v_1 + if y.Op != OpRISCV64CZEROEQZ { + continue + } + _ = y.Args[1] + if z != y.Args[0] || cond != y.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v.AddArg2(x, y) + return true + } + } + break + } + // match: (OR (CZEROEQZ x:(AND z _) cond) y:(CZERONEZ z cond)) + // result: (OR x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + cond := v_0.Args[1] + x := v_0.Args[0] + if x.Op != OpRISCV64AND { + continue + } + x_0 := x.Args[0] + x_1 := x.Args[1] + for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 { + z := x_0 + y := v_1 + if y.Op != OpRISCV64CZERONEZ { + continue + } + _ = y.Args[1] + if z != y.Args[0] || cond != y.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v.AddArg2(x, y) + return true + } + } + break + } + // match: (OR (CZERONEZ x:(ANDI [c] z) cond) y:(CZEROEQZ z cond)) + // result: (OR x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + cond := v_0.Args[1] + x := v_0.Args[0] + if x.Op != OpRISCV64ANDI { + continue + } + z := x.Args[0] + y := v_1 + if y.Op != OpRISCV64CZEROEQZ { + continue + } + _ = y.Args[1] + if z != y.Args[0] || cond != y.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v.AddArg2(x, y) + return true + } + break + } + // match: (OR (CZEROEQZ x:(ANDI [c] z) cond) y:(CZERONEZ z cond)) + // result: (OR x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + cond := v_0.Args[1] + x := v_0.Args[0] + if x.Op != OpRISCV64ANDI { + continue + } + z := x.Args[0] + y := v_1 + if y.Op != OpRISCV64CZERONEZ { + continue + } + _ = y.Args[1] + if z != y.Args[0] || cond != y.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v.AddArg2(x, y) + return true + } + break + } + // match: (OR (CZERONEZ (ADDI [c] x) cond) (CZEROEQZ x cond)) + // result: (ADD x (CZERONEZ (MOVDconst [c]) cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64ADDI { + continue + } + c := auxIntToInt64(v_0_0.AuxInt) + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64ADD) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(c) + v0.AddArg2(v1, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZERONEZ (ORI [c] x) cond) (CZEROEQZ x cond)) + // result: (OR x (CZERONEZ (MOVDconst [c]) cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64ORI { + continue + } + c := auxIntToInt64(v_0_0.AuxInt) + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(c) + v0.AddArg2(v1, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZERONEZ (XORI [c] x) cond) (CZEROEQZ x cond)) + // result: (XOR x (CZERONEZ (MOVDconst [c]) cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZERONEZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64XORI { + continue + } + c := auxIntToInt64(v_0_0.AuxInt) + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZEROEQZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64XOR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(c) + v0.AddArg2(v1, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZEROEQZ (ADDI [c] x) cond) (CZERONEZ x cond)) + // result: (ADD x (CZEROEQZ (MOVDconst [c]) cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64ADDI { + continue + } + c := auxIntToInt64(v_0_0.AuxInt) + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64ADD) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(c) + v0.AddArg2(v1, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZEROEQZ (ORI [c] x) cond) (CZERONEZ x cond)) + // result: (OR x (CZEROEQZ (MOVDconst [c]) cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64ORI { + continue + } + c := auxIntToInt64(v_0_0.AuxInt) + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(c) + v0.AddArg2(v1, cond) + v.AddArg2(x, v0) + return true + } + break + } + // match: (OR (CZEROEQZ (XORI [c] x) cond) (CZERONEZ x cond)) + // result: (XOR x (CZEROEQZ (MOVDconst [c]) cond)) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpRISCV64CZEROEQZ { + continue + } + t := v_0.Type + cond := v_0.Args[1] + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpRISCV64XORI { + continue + } + c := auxIntToInt64(v_0_0.AuxInt) + x := v_0_0.Args[0] + if v_1.Op != OpRISCV64CZERONEZ || v_1.Type != t { + continue + } + _ = v_1.Args[1] + if x != v_1.Args[0] || cond != v_1.Args[1] { + continue + } + v.reset(OpRISCV64XOR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(c) + v0.AddArg2(v1, cond) + v.AddArg2(x, v0) + return true + } + break + } return false } func rewriteValueRISCV64_OpRISCV64ORI(v *Value) bool { diff --git a/test/codegen/condmove.go b/test/codegen/condmove.go index 54e5f361fea10b..73827c4164de6e 100644 --- a/test/codegen/condmove.go +++ b/test/codegen/condmove.go @@ -15,6 +15,8 @@ func cmovint(c int) int { // arm64:"CSEL LT" // ppc64x:"ISEL [$]0" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return x } @@ -26,6 +28,8 @@ func cmovchan(x, y chan int) chan int { // arm64:"CSEL NE" // ppc64x:"ISEL [$]2" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return x } @@ -37,6 +41,8 @@ func cmovuintptr(x, y uintptr) uintptr { // arm64:"CSNEG LS" // ppc64x:"ISEL [$]1" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return x } @@ -48,6 +54,8 @@ func cmov32bit(x, y uint32) uint32 { // arm64:"CSNEG (LS|HS)" // ppc64x:"ISEL [$]1" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return x } @@ -59,6 +67,8 @@ func cmov16bit(x, y uint16) uint16 { // arm64:"CSNEG (LS|HS)" // ppc64x:"ISEL [$][01]" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return x } @@ -73,6 +83,8 @@ func cmovfloateq(x, y float64) int { // arm64:"CSEL EQ" // ppc64x:"ISEL [$]2" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return a } @@ -85,6 +97,8 @@ func cmovfloatne(x, y float64) int { // arm64:"CSEL NE" // ppc64x:"ISEL [$]2" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return a } @@ -112,6 +126,8 @@ func cmovfloatint2(x, y float64) float64 { // arm64:"CSEL MI" // ppc64x:"ISEL [$]0" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" -"CZERONEZ" -"OR" r = r - ldexp(y, rexp-yexp) } return r @@ -127,6 +143,8 @@ func cmovloaded(x [4]int, y int) int { // arm64:"CSEL NE" // ppc64x:"ISEL [$]2" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZERONEZ" "OR" -"CZEROEQZ" -"SNEZ" return y } @@ -139,6 +157,8 @@ func cmovuintptr2(x, y uintptr) uintptr { // arm64:"CSEL EQ" // ppc64x:"ISEL [$]2" // wasm:"Select" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZERONEZ" "OR" -"CZEROEQZ" -"SEQZ" return a } @@ -165,6 +185,8 @@ func cmovinvert1(x, y int64) int64 { y = -y } // amd64:"CMOVQGT" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return y } func cmovinvert2(x, y int64) int64 { @@ -179,6 +201,8 @@ func cmovinvert3(x, y int64) int64 { y = -y } // amd64:"CMOVQEQ" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return y } func cmovinvert4(x, y int64) int64 { @@ -186,6 +210,8 @@ func cmovinvert4(x, y int64) int64 { y = -y } // amd64:"CMOVQNE" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return y } func cmovinvert5(x, y uint64) uint64 { @@ -193,6 +219,8 @@ func cmovinvert5(x, y uint64) uint64 { y = -y } // amd64:"CMOVQCS" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return y } func cmovinvert6(x, y uint64) uint64 { @@ -200,6 +228,8 @@ func cmovinvert6(x, y uint64) uint64 { y = -y } // amd64:"CMOVQLS" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" return y } @@ -217,6 +247,8 @@ func cmovstore(a []int, i int, b bool) { i += 42 } // amd64:"CMOVQNE" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" -"CZERONEZ" a[i] = 7 } @@ -231,6 +263,8 @@ func cmovinc(cond bool, a, b, c int) { x0 = b + 1 } // arm64:"CSINC NE", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r0 = x0 if cond { @@ -239,6 +273,8 @@ func cmovinc(cond bool, a, b, c int) { x1 = a } // arm64:"CSINC EQ", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r1 = x1 if cond { @@ -257,6 +293,8 @@ func cmovinv(cond bool, a, b int) { x0 = ^b } // arm64:"CSINV NE", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r0 = x0 if cond { @@ -265,6 +303,8 @@ func cmovinv(cond bool, a, b int) { x1 = a } // arm64:"CSINV EQ", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r1 = x1 } @@ -277,6 +317,8 @@ func cmovneg(cond bool, a, b, c int) { x0 = -b } // arm64:"CSNEG NE", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r0 = x0 if cond { @@ -285,6 +327,8 @@ func cmovneg(cond bool, a, b, c int) { x1 = a } // arm64:"CSNEG EQ", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r1 = x1 } @@ -297,6 +341,8 @@ func cmovsetm(cond bool, x int) { x0 = 0 } // arm64:"CSETM NE", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" -"CZERONEZ" r0 = x0 if cond { @@ -305,6 +351,8 @@ func cmovsetm(cond bool, x int) { x1 = -1 } // arm64:"CSETM EQ", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZERONEZ" -"CZEROEQZ" r1 = x1 } @@ -317,6 +365,8 @@ func cmovFcmp0(s, t float64, a, b int) { x0 = b + 1 } // arm64:"CSINC MI", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r0 = x0 if s <= t { @@ -325,6 +375,8 @@ func cmovFcmp0(s, t float64, a, b int) { x1 = ^b } // arm64:"CSINV LS", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r1 = x1 if s > t { @@ -333,6 +385,8 @@ func cmovFcmp0(s, t float64, a, b int) { x2 = -b } // arm64:"CSNEG MI", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r2 = x2 if s >= t { @@ -341,6 +395,8 @@ func cmovFcmp0(s, t float64, a, b int) { x3 = 0 } // arm64:"CSETM LS", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" -"CZERONEZ" r3 = x3 if s == t { @@ -349,6 +405,8 @@ func cmovFcmp0(s, t float64, a, b int) { x4 = b + 1 } // arm64:"CSINC EQ", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r4 = x4 if s != t { @@ -357,6 +415,8 @@ func cmovFcmp0(s, t float64, a, b int) { x5 = b + 1 } // arm64:"CSINC NE", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r5 = x5 } @@ -369,6 +429,8 @@ func cmovFcmp1(s, t float64, a, b int) { x0 = a } // arm64:"CSINC PL", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r0 = x0 if s <= t { @@ -377,6 +439,8 @@ func cmovFcmp1(s, t float64, a, b int) { x1 = a } // arm64:"CSINV HI", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r1 = x1 if s > t { @@ -385,6 +449,8 @@ func cmovFcmp1(s, t float64, a, b int) { x2 = a } // arm64:"CSNEG PL", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r2 = x2 if s >= t { @@ -393,6 +459,8 @@ func cmovFcmp1(s, t float64, a, b int) { x3 = -1 } // arm64:"CSETM HI", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZERONEZ" -"CZEROEQZ" r3 = x3 if s == t { @@ -401,6 +469,8 @@ func cmovFcmp1(s, t float64, a, b int) { x4 = a } // arm64:"CSINC NE", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r4 = x4 if s != t { @@ -409,6 +479,8 @@ func cmovFcmp1(s, t float64, a, b int) { x5 = a } // arm64:"CSINC EQ", -"CSEL" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" "CZERONEZ" "OR" r5 = x5 } @@ -418,6 +490,8 @@ func cmovzero1(c bool) int { x = 182 } // loong64:"MASKEQZ", -"MASKNEZ" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" -"CZERONEZ" return x } @@ -427,6 +501,8 @@ func cmovzero2(c bool) int { x = 182 } // loong64:"MASKNEZ", -"MASKEQZ" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZERONEZ" -"CZEROEQZ" return x } @@ -434,12 +510,14 @@ func cmovzero2(c bool) int { // an extra load of 0 to a register on PPC64 by using R0 (which always // holds the value $0) instead. Verify both cases where either arg1 // or arg2 is zero. -func cmovzeroreg0(a, b int) int { +func cmovzeroregZero(a, b int) int { x := 0 if a == b { x = a } // ppc64x:"ISEL [$]2, R[0-9]+, R0, R[0-9]+" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZERONEZ" -"CZEROEQZ" return x } @@ -449,6 +527,8 @@ func cmovzeroreg1(a, b int) int { x = 0 } // ppc64x:"ISEL [$]2, R0, R[0-9]+, R[0-9]+" + // riscv64/rva20u64,riscv64/rva22u64:-"CZEROEQZ" -"CZERONEZ" + // riscv64/rva23u64:"CZEROEQZ" -"CZERONEZ" return x } @@ -527,3 +607,196 @@ func cmovFromMulFromFlags64sext(x int64, b bool) int64 { // amd64:"CMOV",-"MOVB.ZX",-"MUL" return x * r } + +func cmoveAddZero(cond, a, b int) int { + if cond == 0 { + a += b + } + // riscv64/rva23u64:"CZERONEZ" "ADD" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveAddNonZero(cond, a, b int) int { + if cond != 0 { + a += b + } + // riscv64/rva23u64:"CZEROEQZ" "ADD" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveSubZero(cond, a, b int) int { + if cond == 0 { + a -= b + } + // riscv64/rva23u64:"CZERONEZ" "SUB" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveSubNonZero(cond, a, b int) int { + if cond != 0 { + a -= b + } + // riscv64/rva23u64:"CZEROEQZ" "SUB" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveOrZero(cond, a, b int) int { + if cond == 0 { + a |= b + } + // riscv64/rva23u64:"CZERONEZ" "OR" -"SEQZ" -"CZEROEQZ" + return a +} + +func cmoveOrNonZero(cond, a, b int) int { + if cond != 0 { + a |= b + } + // riscv64/rva23u64:"CZEROEQZ" "OR" -"SNEZ" -"CZERONEZ" + return a +} + +func cmoveXorZero(cond, a, b int) int { + if cond == 0 { + a ^= b + } + // riscv64/rva23u64:"CZERONEZ" "XOR" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveXorNonZero(cond, a, b int) int { + if cond != 0 { + a ^= b + } + // riscv64/rva23u64:"CZEROEQZ" "XOR" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveAndZero(cond, a, b int) int { + if cond == 0 { + a &= b + } + // riscv64/rva23u64:"CZEROEQZ" "OR" -"SEQZ" -"CZERONEZ" + return a +} + +func CondAndNonZero(cond, a, b int) int { + if cond != 0 { + a &= b + } + // riscv64/rva23u64:"CZERONEZ" "OR" -"SNEZ" -"CZEROEQZ" + return a +} + +func cmoveAddiZero(cond, a int) int { + if cond == 0 { + a += 42 + } + // riscv64/rva23u64:"CZERONEZ" "ADD" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveAddiNonZero(cond, a int) int { + if cond != 0 { + a += 42 + } + // riscv64/rva23u64:"CZEROEQZ" "ADD" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveOriZero(cond, a int) int { + if cond == 0 { + a |= 0xFF + } + // riscv64/rva23u64:"CZERONEZ" -"SEQZ" -"CZEROEQZ" + return a +} + +func cmoveOriNonZero(cond, a int) int { + if cond != 0 { + a |= 0xFF + } + // riscv64/rva23u64:"CZEROEQZ" -"SNEZ" -"CZERONEZ" + return a +} + +func cmoveXoriZero(cond, a int) int { + if cond == 0 { + a ^= 0xFFFF + } + // riscv64/rva23u64:"CZERONEZ" "XOR" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveXoriNonZero(cond, a int) int { + if cond != 0 { + a ^= 0xFFFF + } + // riscv64/rva23u64:"CZEROEQZ" "XOR" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveAndiZero(cond, a int) int { + if cond == 0 { + a &= 0xFF + } + // riscv64/rva23u64:"CZEROEQZ" "OR" -"SEQZ" -`CZERONEZ` + return a +} + +func cmoveAndiNonZero(cond, a int) int { + if cond != 0 { + a &= 0xFF + } + // riscv64/rva23u64:"CZERONEZ" "OR" -"SNEZ" -"CZEROEQZ" + return a +} + +// 32-bit immediate variant tests +func cmoveAddiwZero(cond int32, a int32) int32 { + if cond == 0 { + a += 42 + } + // riscv64/rva23u64:"CZERONEZ" "ADD" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveAddiwNonZero(cond int32, a int32) int32 { + if cond != 0 { + a += 42 + } + // riscv64/rva23u64:"CZEROEQZ" "ADD" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveAddwZero(cond int32, a, b int32) int32 { + if cond == 0 { + a += b + } + // riscv64/rva23u64:"CZERONEZ" "ADD" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveAddwNonZero(cond int32, a, b int32) int32 { + if cond != 0 { + a += b + } + // riscv64/rva23u64:"CZEROEQZ" "ADD" -"SNEZ" -"CZERONEZ" -"OR" + return a +} + +func cmoveSubwZero(cond int32, a, b int32) int32 { + if cond == 0 { + a -= b + } + // riscv64/rva23u64:"CZERONEZ" "SUB" -"SEQZ" -"CZEROEQZ" -"OR" + return a +} + +func cmoveSubwNonZero(cond int32, a, b int32) int32 { + if cond != 0 { + a -= b + } + // riscv64/rva23u64:"CZEROEQZ" "SUB" -"SNEZ" -"CZERONEZ" -"OR" + return a +}