1e8d8bef9SDimitry Andric//===- RISCVInstrInfoVSDPatterns.td - RVV SDNode patterns --*- tablegen -*-===// 2e8d8bef9SDimitry Andric// 3e8d8bef9SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric// 7e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric/// 9e8d8bef9SDimitry Andric/// This file contains the required infrastructure and SDNode patterns to 10e8d8bef9SDimitry Andric/// support code generation for the standard 'V' (Vector) extension, version 1181ad6265SDimitry Andric/// version 1.0. 12e8d8bef9SDimitry Andric/// 13e8d8bef9SDimitry Andric/// This file is included from and depends upon RISCVInstrInfoVPseudos.td 14e8d8bef9SDimitry Andric/// 15e8d8bef9SDimitry Andric/// Note: the patterns for RVV intrinsics are found in 16e8d8bef9SDimitry Andric/// RISCVInstrInfoVPseudos.td. 17e8d8bef9SDimitry Andric/// 18e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 19e8d8bef9SDimitry Andric 20e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 21e8d8bef9SDimitry Andric// Helpers to define the SDNode patterns. 22e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 23e8d8bef9SDimitry Andric 24fe6060f1SDimitry Andricdef rvv_vnot : PatFrag<(ops node:$in), 25fe6060f1SDimitry Andric (xor node:$in, (riscv_vmset_vl (XLenVT srcvalue)))>; 26e8d8bef9SDimitry Andric 27fe6060f1SDimitry Andricmulticlass VPatUSLoadStoreSDNode<ValueType type, 28fe6060f1SDimitry Andric int log2sew, 29e8d8bef9SDimitry Andric LMULInfo vlmul, 30e8d8bef9SDimitry Andric OutPatFrag avl, 31fe6060f1SDimitry Andric VReg reg_class, 3206c3fb27SDimitry Andric int sew = !shl(1, log2sew)> { 33e8d8bef9SDimitry Andric defvar load_instr = !cast<Instruction>("PseudoVLE"#sew#"_V_"#vlmul.MX); 34e8d8bef9SDimitry Andric defvar store_instr = !cast<Instruction>("PseudoVSE"#sew#"_V_"#vlmul.MX); 35e8d8bef9SDimitry Andric // Load 36753f127fSDimitry Andric def : Pat<(type (load GPR:$rs1)), 3706c3fb27SDimitry Andric (load_instr (type (IMPLICIT_DEF)), GPR:$rs1, avl, 385f757f3fSDimitry Andric log2sew, TA_MA)>; 39e8d8bef9SDimitry Andric // Store 40753f127fSDimitry Andric def : Pat<(store type:$rs2, GPR:$rs1), 41753f127fSDimitry Andric (store_instr reg_class:$rs2, GPR:$rs1, avl, log2sew)>; 42e8d8bef9SDimitry Andric} 43e8d8bef9SDimitry Andric 44fe6060f1SDimitry Andricmulticlass VPatUSLoadStoreWholeVRSDNode<ValueType type, 45fe6060f1SDimitry Andric int log2sew, 46fe6060f1SDimitry Andric LMULInfo vlmul, 47fe6060f1SDimitry Andric VReg reg_class, 4806c3fb27SDimitry Andric int sew = !shl(1, log2sew)> { 49fe6060f1SDimitry Andric defvar load_instr = 50fe6060f1SDimitry Andric !cast<Instruction>("VL"#!substr(vlmul.MX, 1)#"RE"#sew#"_V"); 51fe6060f1SDimitry Andric defvar store_instr = 52fe6060f1SDimitry Andric !cast<Instruction>("VS"#!substr(vlmul.MX, 1)#"R_V"); 53fe6060f1SDimitry Andric 54fe6060f1SDimitry Andric // Load 55753f127fSDimitry Andric def : Pat<(type (load GPR:$rs1)), 56753f127fSDimitry Andric (load_instr GPR:$rs1)>; 57fe6060f1SDimitry Andric // Store 58753f127fSDimitry Andric def : Pat<(store type:$rs2, GPR:$rs1), 59753f127fSDimitry Andric (store_instr reg_class:$rs2, GPR:$rs1)>; 60fe6060f1SDimitry Andric} 61fe6060f1SDimitry Andric 6206c3fb27SDimitry Andricmulticlass VPatUSLoadStoreMaskSDNode<MTypeInfo m> { 63349cc55cSDimitry Andric defvar load_instr = !cast<Instruction>("PseudoVLM_V_"#m.BX); 64349cc55cSDimitry Andric defvar store_instr = !cast<Instruction>("PseudoVSM_V_"#m.BX); 65fe6060f1SDimitry Andric // Load 66753f127fSDimitry Andric def : Pat<(m.Mask (load GPR:$rs1)), 6706c3fb27SDimitry Andric (load_instr (m.Mask (IMPLICIT_DEF)), GPR:$rs1, m.AVL, 6806c3fb27SDimitry Andric m.Log2SEW, TA_MA)>; 69fe6060f1SDimitry Andric // Store 70753f127fSDimitry Andric def : Pat<(store m.Mask:$rs2, GPR:$rs1), 71753f127fSDimitry Andric (store_instr VR:$rs2, GPR:$rs1, m.AVL, m.Log2SEW)>; 72e8d8bef9SDimitry Andric} 73e8d8bef9SDimitry Andric 7406c3fb27SDimitry Andricclass VPatBinarySDNode_VV<SDPatternOperator vop, 75e8d8bef9SDimitry Andric string instruction_name, 76e8d8bef9SDimitry Andric ValueType result_type, 77e8d8bef9SDimitry Andric ValueType op_type, 7806c3fb27SDimitry Andric int log2sew, 79e8d8bef9SDimitry Andric LMULInfo vlmul, 80e8d8bef9SDimitry Andric OutPatFrag avl, 8106c3fb27SDimitry Andric VReg op_reg_class, 8206c3fb27SDimitry Andric bit isSEWAware = 0> : 83e8d8bef9SDimitry Andric Pat<(result_type (vop 84e8d8bef9SDimitry Andric (op_type op_reg_class:$rs1), 85e8d8bef9SDimitry Andric (op_type op_reg_class:$rs2))), 8606c3fb27SDimitry Andric (!cast<Instruction>( 8706c3fb27SDimitry Andric !if(isSEWAware, 8806c3fb27SDimitry Andric instruction_name#"_VV_"# vlmul.MX#"_E"#!shl(1, log2sew), 8906c3fb27SDimitry Andric instruction_name#"_VV_"# vlmul.MX)) 9006c3fb27SDimitry Andric (result_type (IMPLICIT_DEF)), 91e8d8bef9SDimitry Andric op_reg_class:$rs1, 92e8d8bef9SDimitry Andric op_reg_class:$rs2, 9306c3fb27SDimitry Andric avl, log2sew, TA_MA)>; 94e8d8bef9SDimitry Andric 9506c3fb27SDimitry Andricclass VPatBinarySDNode_VV_RM<SDPatternOperator vop, 9606c3fb27SDimitry Andric string instruction_name, 9706c3fb27SDimitry Andric ValueType result_type, 9806c3fb27SDimitry Andric ValueType op_type, 9906c3fb27SDimitry Andric int log2sew, 10006c3fb27SDimitry Andric LMULInfo vlmul, 10106c3fb27SDimitry Andric OutPatFrag avl, 10206c3fb27SDimitry Andric VReg op_reg_class, 10306c3fb27SDimitry Andric bit isSEWAware = 0> : 10406c3fb27SDimitry Andric Pat<(result_type (vop 10506c3fb27SDimitry Andric (op_type op_reg_class:$rs1), 10606c3fb27SDimitry Andric (op_type op_reg_class:$rs2))), 10706c3fb27SDimitry Andric (!cast<Instruction>( 10806c3fb27SDimitry Andric !if(isSEWAware, 10906c3fb27SDimitry Andric instruction_name#"_VV_"# vlmul.MX#"_E"#!shl(1, log2sew), 11006c3fb27SDimitry Andric instruction_name#"_VV_"# vlmul.MX)) 11106c3fb27SDimitry Andric (result_type (IMPLICIT_DEF)), 11206c3fb27SDimitry Andric op_reg_class:$rs1, 11306c3fb27SDimitry Andric op_reg_class:$rs2, 11406c3fb27SDimitry Andric // Value to indicate no rounding mode change in 11506c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 11606c3fb27SDimitry Andric FRM_DYN, 11706c3fb27SDimitry Andric avl, log2sew, TA_MA)>; 11806c3fb27SDimitry Andric 11906c3fb27SDimitry Andricclass VPatBinarySDNode_XI<SDPatternOperator vop, 120e8d8bef9SDimitry Andric string instruction_name, 121e8d8bef9SDimitry Andric string suffix, 122e8d8bef9SDimitry Andric ValueType result_type, 123e8d8bef9SDimitry Andric ValueType vop_type, 12406c3fb27SDimitry Andric int log2sew, 125e8d8bef9SDimitry Andric LMULInfo vlmul, 126e8d8bef9SDimitry Andric OutPatFrag avl, 127e8d8bef9SDimitry Andric VReg vop_reg_class, 128e8d8bef9SDimitry Andric ComplexPattern SplatPatKind, 12906c3fb27SDimitry Andric DAGOperand xop_kind, 13006c3fb27SDimitry Andric bit isSEWAware = 0> : 131e8d8bef9SDimitry Andric Pat<(result_type (vop 132e8d8bef9SDimitry Andric (vop_type vop_reg_class:$rs1), 13306c3fb27SDimitry Andric (vop_type (SplatPatKind (XLenVT xop_kind:$rs2))))), 13406c3fb27SDimitry Andric (!cast<Instruction>( 13506c3fb27SDimitry Andric !if(isSEWAware, 13606c3fb27SDimitry Andric instruction_name#_#suffix#_# vlmul.MX#"_E"#!shl(1, log2sew), 13706c3fb27SDimitry Andric instruction_name#_#suffix#_# vlmul.MX)) 13806c3fb27SDimitry Andric (result_type (IMPLICIT_DEF)), 139e8d8bef9SDimitry Andric vop_reg_class:$rs1, 140e8d8bef9SDimitry Andric xop_kind:$rs2, 14106c3fb27SDimitry Andric avl, log2sew, TA_MA)>; 142e8d8bef9SDimitry Andric 14306c3fb27SDimitry Andricmulticlass VPatBinarySDNode_VV_VX<SDPatternOperator vop, string instruction_name, 14406c3fb27SDimitry Andric list<VTypeInfo> vtilist = AllIntegerVectors, 14506c3fb27SDimitry Andric bit isSEWAware = 0> { 14606c3fb27SDimitry Andric foreach vti = vtilist in { 14706c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 148e8d8bef9SDimitry Andric def : VPatBinarySDNode_VV<vop, instruction_name, 149349cc55cSDimitry Andric vti.Vector, vti.Vector, vti.Log2SEW, 15006c3fb27SDimitry Andric vti.LMul, vti.AVL, vti.RegClass, isSEWAware>; 151e8d8bef9SDimitry Andric def : VPatBinarySDNode_XI<vop, instruction_name, "VX", 152349cc55cSDimitry Andric vti.Vector, vti.Vector, vti.Log2SEW, 153349cc55cSDimitry Andric vti.LMul, vti.AVL, vti.RegClass, 15406c3fb27SDimitry Andric SplatPat, GPR, isSEWAware>; 15506c3fb27SDimitry Andric } 156e8d8bef9SDimitry Andric } 157e8d8bef9SDimitry Andric} 158e8d8bef9SDimitry Andric 15906c3fb27SDimitry Andricmulticlass VPatBinarySDNode_VV_VX_VI<SDPatternOperator vop, string instruction_name, 160e8d8bef9SDimitry Andric Operand ImmType = simm5> 161fe6060f1SDimitry Andric : VPatBinarySDNode_VV_VX<vop, instruction_name> { 162e8d8bef9SDimitry Andric foreach vti = AllIntegerVectors in { 16306c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in 164e8d8bef9SDimitry Andric def : VPatBinarySDNode_XI<vop, instruction_name, "VI", 165349cc55cSDimitry Andric vti.Vector, vti.Vector, vti.Log2SEW, 166349cc55cSDimitry Andric vti.LMul, vti.AVL, vti.RegClass, 167e8d8bef9SDimitry Andric !cast<ComplexPattern>(SplatPat#_#ImmType), 168e8d8bef9SDimitry Andric ImmType>; 169e8d8bef9SDimitry Andric } 170e8d8bef9SDimitry Andric} 171e8d8bef9SDimitry Andric 17206c3fb27SDimitry Andricclass VPatBinarySDNode_VF<SDPatternOperator vop, 173e8d8bef9SDimitry Andric string instruction_name, 174e8d8bef9SDimitry Andric ValueType result_type, 175e8d8bef9SDimitry Andric ValueType vop_type, 176e8d8bef9SDimitry Andric ValueType xop_type, 17706c3fb27SDimitry Andric int log2sew, 178e8d8bef9SDimitry Andric LMULInfo vlmul, 179e8d8bef9SDimitry Andric OutPatFrag avl, 180e8d8bef9SDimitry Andric VReg vop_reg_class, 18106c3fb27SDimitry Andric DAGOperand xop_kind, 18206c3fb27SDimitry Andric bit isSEWAware = 0> : 183e8d8bef9SDimitry Andric Pat<(result_type (vop (vop_type vop_reg_class:$rs1), 18481ad6265SDimitry Andric (vop_type (SplatFPOp xop_kind:$rs2)))), 18506c3fb27SDimitry Andric (!cast<Instruction>( 18606c3fb27SDimitry Andric !if(isSEWAware, 18706c3fb27SDimitry Andric instruction_name#"_"#vlmul.MX#"_E"#!shl(1, log2sew), 18806c3fb27SDimitry Andric instruction_name#"_"#vlmul.MX)) 18906c3fb27SDimitry Andric (result_type (IMPLICIT_DEF)), 190e8d8bef9SDimitry Andric vop_reg_class:$rs1, 191e8d8bef9SDimitry Andric (xop_type xop_kind:$rs2), 19206c3fb27SDimitry Andric avl, log2sew, TA_MA)>; 193e8d8bef9SDimitry Andric 19406c3fb27SDimitry Andricclass VPatBinarySDNode_VF_RM<SDPatternOperator vop, 19506c3fb27SDimitry Andric string instruction_name, 19606c3fb27SDimitry Andric ValueType result_type, 19706c3fb27SDimitry Andric ValueType vop_type, 19806c3fb27SDimitry Andric ValueType xop_type, 19906c3fb27SDimitry Andric int log2sew, 20006c3fb27SDimitry Andric LMULInfo vlmul, 20106c3fb27SDimitry Andric OutPatFrag avl, 20206c3fb27SDimitry Andric VReg vop_reg_class, 20306c3fb27SDimitry Andric DAGOperand xop_kind, 20406c3fb27SDimitry Andric bit isSEWAware = 0> : 20506c3fb27SDimitry Andric Pat<(result_type (vop (vop_type vop_reg_class:$rs1), 20606c3fb27SDimitry Andric (vop_type (SplatFPOp xop_kind:$rs2)))), 20706c3fb27SDimitry Andric (!cast<Instruction>( 20806c3fb27SDimitry Andric !if(isSEWAware, 20906c3fb27SDimitry Andric instruction_name#"_"#vlmul.MX#"_E"#!shl(1, log2sew), 21006c3fb27SDimitry Andric instruction_name#"_"#vlmul.MX)) 21106c3fb27SDimitry Andric (result_type (IMPLICIT_DEF)), 21206c3fb27SDimitry Andric vop_reg_class:$rs1, 21306c3fb27SDimitry Andric (xop_type xop_kind:$rs2), 21406c3fb27SDimitry Andric // Value to indicate no rounding mode change in 21506c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 21606c3fb27SDimitry Andric FRM_DYN, 21706c3fb27SDimitry Andric avl, log2sew, TA_MA)>; 21806c3fb27SDimitry Andric 21906c3fb27SDimitry Andricmulticlass VPatBinaryFPSDNode_VV_VF<SDPatternOperator vop, string instruction_name, 22006c3fb27SDimitry Andric bit isSEWAware = 0> { 221e8d8bef9SDimitry Andric foreach vti = AllFloatVectors in { 22206c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 223e8d8bef9SDimitry Andric def : VPatBinarySDNode_VV<vop, instruction_name, 224349cc55cSDimitry Andric vti.Vector, vti.Vector, vti.Log2SEW, 22506c3fb27SDimitry Andric vti.LMul, vti.AVL, vti.RegClass, isSEWAware>; 226e8d8bef9SDimitry Andric def : VPatBinarySDNode_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, 227349cc55cSDimitry Andric vti.Vector, vti.Vector, vti.Scalar, 228349cc55cSDimitry Andric vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass, 22906c3fb27SDimitry Andric vti.ScalarRegClass, isSEWAware>; 23006c3fb27SDimitry Andric } 231e8d8bef9SDimitry Andric } 232e8d8bef9SDimitry Andric} 233e8d8bef9SDimitry Andric 23406c3fb27SDimitry Andricmulticlass VPatBinaryFPSDNode_VV_VF_RM<SDPatternOperator vop, string instruction_name, 23506c3fb27SDimitry Andric bit isSEWAware = 0> { 23606c3fb27SDimitry Andric foreach vti = AllFloatVectors in { 23706c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 23806c3fb27SDimitry Andric def : VPatBinarySDNode_VV_RM<vop, instruction_name, 23906c3fb27SDimitry Andric vti.Vector, vti.Vector, vti.Log2SEW, 24006c3fb27SDimitry Andric vti.LMul, vti.AVL, vti.RegClass, isSEWAware>; 24106c3fb27SDimitry Andric def : VPatBinarySDNode_VF_RM<vop, instruction_name#"_V"#vti.ScalarSuffix, 24206c3fb27SDimitry Andric vti.Vector, vti.Vector, vti.Scalar, 24306c3fb27SDimitry Andric vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass, 24406c3fb27SDimitry Andric vti.ScalarRegClass, isSEWAware>; 24506c3fb27SDimitry Andric } 24606c3fb27SDimitry Andric } 24706c3fb27SDimitry Andric} 24806c3fb27SDimitry Andric 24906c3fb27SDimitry Andricmulticlass VPatBinaryFPSDNode_R_VF<SDPatternOperator vop, string instruction_name, 25006c3fb27SDimitry Andric bit isSEWAware = 0> { 251e8d8bef9SDimitry Andric foreach fvti = AllFloatVectors in 25206c3fb27SDimitry Andric let Predicates = GetVTypePredicates<fvti>.Predicates in 25381ad6265SDimitry Andric def : Pat<(fvti.Vector (vop (fvti.Vector (SplatFPOp fvti.Scalar:$rs2)), 254e8d8bef9SDimitry Andric (fvti.Vector fvti.RegClass:$rs1))), 25506c3fb27SDimitry Andric (!cast<Instruction>( 25606c3fb27SDimitry Andric !if(isSEWAware, 25706c3fb27SDimitry Andric instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_E"#fvti.SEW, 25806c3fb27SDimitry Andric instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)) 25906c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 260e8d8bef9SDimitry Andric fvti.RegClass:$rs1, 261e8d8bef9SDimitry Andric (fvti.Scalar fvti.ScalarRegClass:$rs2), 26206c3fb27SDimitry Andric fvti.AVL, fvti.Log2SEW, TA_MA)>; 26306c3fb27SDimitry Andric} 26406c3fb27SDimitry Andric 26506c3fb27SDimitry Andricmulticlass VPatBinaryFPSDNode_R_VF_RM<SDPatternOperator vop, string instruction_name, 26606c3fb27SDimitry Andric bit isSEWAware = 0> { 26706c3fb27SDimitry Andric foreach fvti = AllFloatVectors in 26806c3fb27SDimitry Andric let Predicates = GetVTypePredicates<fvti>.Predicates in 26906c3fb27SDimitry Andric def : Pat<(fvti.Vector (vop (fvti.Vector (SplatFPOp fvti.Scalar:$rs2)), 27006c3fb27SDimitry Andric (fvti.Vector fvti.RegClass:$rs1))), 27106c3fb27SDimitry Andric (!cast<Instruction>( 27206c3fb27SDimitry Andric !if(isSEWAware, 27306c3fb27SDimitry Andric instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_E"#fvti.SEW, 27406c3fb27SDimitry Andric instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)) 27506c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 27606c3fb27SDimitry Andric fvti.RegClass:$rs1, 27706c3fb27SDimitry Andric (fvti.Scalar fvti.ScalarRegClass:$rs2), 27806c3fb27SDimitry Andric // Value to indicate no rounding mode change in 27906c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 28006c3fb27SDimitry Andric FRM_DYN, 28106c3fb27SDimitry Andric fvti.AVL, fvti.Log2SEW, TA_MA)>; 282e8d8bef9SDimitry Andric} 283e8d8bef9SDimitry Andric 28481ad6265SDimitry Andricmulticlass VPatIntegerSetCCSDNode_VV<string instruction_name, 28581ad6265SDimitry Andric CondCode cc> { 286e8d8bef9SDimitry Andric foreach vti = AllIntegerVectors in { 287e8d8bef9SDimitry Andric defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX); 28806c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in 289e8d8bef9SDimitry Andric def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 290e8d8bef9SDimitry Andric (vti.Vector vti.RegClass:$rs2), cc)), 29181ad6265SDimitry Andric (instruction vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, 29281ad6265SDimitry Andric vti.Log2SEW)>; 293e8d8bef9SDimitry Andric } 294e8d8bef9SDimitry Andric} 295e8d8bef9SDimitry Andric 29681ad6265SDimitry Andricmulticlass VPatIntegerSetCCSDNode_VV_Swappable<string instruction_name, 29781ad6265SDimitry Andric CondCode cc, CondCode invcc> 29881ad6265SDimitry Andric : VPatIntegerSetCCSDNode_VV<instruction_name, cc> { 29981ad6265SDimitry Andric foreach vti = AllIntegerVectors in { 30081ad6265SDimitry Andric defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX); 30106c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in 30281ad6265SDimitry Andric def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs2), 30381ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), invcc)), 30481ad6265SDimitry Andric (instruction vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, 30581ad6265SDimitry Andric vti.Log2SEW)>; 30681ad6265SDimitry Andric } 30781ad6265SDimitry Andric} 30881ad6265SDimitry Andric 30981ad6265SDimitry Andricmulticlass VPatIntegerSetCCSDNode_XI_Swappable<string instruction_name, 31081ad6265SDimitry Andric CondCode cc, CondCode invcc, 31181ad6265SDimitry Andric string kind, 31281ad6265SDimitry Andric ComplexPattern SplatPatKind, 313*0fca6ea1SDimitry Andric DAGOperand xop_kind> { 31481ad6265SDimitry Andric foreach vti = AllIntegerVectors in { 31581ad6265SDimitry Andric defvar instruction = !cast<Instruction>(instruction_name#_#kind#_#vti.LMul.MX); 31606c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 31781ad6265SDimitry Andric def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 31806c3fb27SDimitry Andric (vti.Vector (SplatPatKind (XLenVT xop_kind:$rs2))), cc)), 31981ad6265SDimitry Andric (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>; 32006c3fb27SDimitry Andric def : Pat<(vti.Mask (setcc (vti.Vector (SplatPatKind (XLenVT xop_kind:$rs2))), 32181ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), invcc)), 32281ad6265SDimitry Andric (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>; 32381ad6265SDimitry Andric } 324e8d8bef9SDimitry Andric } 32506c3fb27SDimitry Andric} 326e8d8bef9SDimitry Andric 32781ad6265SDimitry Andricmulticlass VPatIntegerSetCCSDNode_VX_Swappable<string instruction_name, 32881ad6265SDimitry Andric CondCode cc, CondCode invcc> 32981ad6265SDimitry Andric : VPatIntegerSetCCSDNode_XI_Swappable<instruction_name, cc, invcc, "VX", 33081ad6265SDimitry Andric SplatPat, GPR>; 331e8d8bef9SDimitry Andric 332*0fca6ea1SDimitry Andricmulticlass VPatIntegerSetCCSDNode_VI_Swappable<string instruction_name, 333*0fca6ea1SDimitry Andric CondCode cc, CondCode invcc> 334*0fca6ea1SDimitry Andric : VPatIntegerSetCCSDNode_XI_Swappable<instruction_name, cc, invcc, "VI", 335*0fca6ea1SDimitry Andric SplatPat_simm5, simm5>; 336e8d8bef9SDimitry Andric 337*0fca6ea1SDimitry Andricmulticlass VPatIntegerSetCCSDNode_VIPlus1_Swappable<string instruction_name, 338*0fca6ea1SDimitry Andric CondCode cc, CondCode invcc, 339fe6060f1SDimitry Andric ComplexPattern splatpat_kind> { 340fe6060f1SDimitry Andric foreach vti = AllIntegerVectors in { 341fe6060f1SDimitry Andric defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX); 342*0fca6ea1SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 343fe6060f1SDimitry Andric def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 344fe6060f1SDimitry Andric (vti.Vector (splatpat_kind simm5:$rs2)), 345e8d8bef9SDimitry Andric cc)), 346fe6060f1SDimitry Andric (instruction vti.RegClass:$rs1, (DecImm simm5:$rs2), 347fe6060f1SDimitry Andric vti.AVL, vti.Log2SEW)>; 348*0fca6ea1SDimitry Andric def : Pat<(vti.Mask (setcc (vti.Vector (splatpat_kind simm5:$rs2)), 349*0fca6ea1SDimitry Andric (vti.Vector vti.RegClass:$rs1), 350*0fca6ea1SDimitry Andric invcc)), 351*0fca6ea1SDimitry Andric (instruction vti.RegClass:$rs1, (DecImm simm5:$rs2), 352*0fca6ea1SDimitry Andric vti.AVL, vti.Log2SEW)>; 353*0fca6ea1SDimitry Andric } 354e8d8bef9SDimitry Andric } 355e8d8bef9SDimitry Andric} 356e8d8bef9SDimitry Andric 357e8d8bef9SDimitry Andricmulticlass VPatFPSetCCSDNode_VV_VF_FV<CondCode cc, 358e8d8bef9SDimitry Andric string inst_name, 359e8d8bef9SDimitry Andric string swapped_op_inst_name> { 360fe6060f1SDimitry Andric foreach fvti = AllFloatVectors in { 36106c3fb27SDimitry Andric let Predicates = GetVTypePredicates<fvti>.Predicates in { 362fe6060f1SDimitry Andric def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1), 363fe6060f1SDimitry Andric (fvti.Vector fvti.RegClass:$rs2), 364fe6060f1SDimitry Andric cc)), 365fe6060f1SDimitry Andric (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX) 366fe6060f1SDimitry Andric fvti.RegClass:$rs1, fvti.RegClass:$rs2, fvti.AVL, fvti.Log2SEW)>; 367fe6060f1SDimitry Andric def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1), 36881ad6265SDimitry Andric (SplatFPOp fvti.ScalarRegClass:$rs2), 369fe6060f1SDimitry Andric cc)), 370fe6060f1SDimitry Andric (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 371fe6060f1SDimitry Andric fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 372fe6060f1SDimitry Andric fvti.AVL, fvti.Log2SEW)>; 37381ad6265SDimitry Andric def : Pat<(fvti.Mask (setcc (SplatFPOp fvti.ScalarRegClass:$rs2), 374fe6060f1SDimitry Andric (fvti.Vector fvti.RegClass:$rs1), 375fe6060f1SDimitry Andric cc)), 376fe6060f1SDimitry Andric (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 377fe6060f1SDimitry Andric fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 378fe6060f1SDimitry Andric fvti.AVL, fvti.Log2SEW)>; 379fe6060f1SDimitry Andric } 380e8d8bef9SDimitry Andric } 38106c3fb27SDimitry Andric} 382e8d8bef9SDimitry Andric 383e8d8bef9SDimitry Andricmulticlass VPatExtendSDNode_V<list<SDNode> ops, string inst_name, string suffix, 384e8d8bef9SDimitry Andric list <VTypeInfoToFraction> fraction_list> { 385e8d8bef9SDimitry Andric foreach vtiTofti = fraction_list in { 386e8d8bef9SDimitry Andric defvar vti = vtiTofti.Vti; 387e8d8bef9SDimitry Andric defvar fti = vtiTofti.Fti; 388e8d8bef9SDimitry Andric foreach op = ops in 38906c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 39006c3fb27SDimitry Andric GetVTypePredicates<fti>.Predicates) in 391e8d8bef9SDimitry Andric def : Pat<(vti.Vector (op (fti.Vector fti.RegClass:$rs2))), 392e8d8bef9SDimitry Andric (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX) 39306c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 3945f757f3fSDimitry Andric fti.RegClass:$rs2, fti.AVL, vti.Log2SEW, TA_MA)>; 395fe6060f1SDimitry Andric } 396fe6060f1SDimitry Andric} 397fe6060f1SDimitry Andric 39806c3fb27SDimitry Andricmulticlass VPatConvertI2FPSDNode_V_RM<SDPatternOperator vop, 39906c3fb27SDimitry Andric string instruction_name> { 400fe6060f1SDimitry Andric foreach fvti = AllFloatVectors in { 401fe6060f1SDimitry Andric defvar ivti = GetIntVTypeInfo<fvti>.Vti; 40206c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 40306c3fb27SDimitry Andric GetVTypePredicates<ivti>.Predicates) in 404fe6060f1SDimitry Andric def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))), 405*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW) 40606c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 40706c3fb27SDimitry Andric ivti.RegClass:$rs1, 40806c3fb27SDimitry Andric // Value to indicate no rounding mode change in 40906c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 41006c3fb27SDimitry Andric FRM_DYN, 4115f757f3fSDimitry Andric fvti.AVL, fvti.Log2SEW, TA_MA)>; 412fe6060f1SDimitry Andric } 413fe6060f1SDimitry Andric} 414fe6060f1SDimitry Andric 41506c3fb27SDimitry Andricmulticlass VPatConvertFP2ISDNode_V<SDPatternOperator vop, 41606c3fb27SDimitry Andric string instruction_name> { 417fe6060f1SDimitry Andric foreach fvti = AllFloatVectors in { 418fe6060f1SDimitry Andric defvar ivti = GetIntVTypeInfo<fvti>.Vti; 41906c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 42006c3fb27SDimitry Andric GetVTypePredicates<ivti>.Predicates) in 421fe6060f1SDimitry Andric def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))), 422fe6060f1SDimitry Andric (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 42306c3fb27SDimitry Andric (ivti.Vector (IMPLICIT_DEF)), 4245f757f3fSDimitry Andric fvti.RegClass:$rs1, ivti.AVL, ivti.Log2SEW, TA_MA)>; 425fe6060f1SDimitry Andric } 426fe6060f1SDimitry Andric} 427fe6060f1SDimitry Andric 42806c3fb27SDimitry Andricmulticlass VPatWConvertI2FPSDNode_V<SDPatternOperator vop, 42906c3fb27SDimitry Andric string instruction_name> { 430fe6060f1SDimitry Andric foreach vtiToWti = AllWidenableIntToFloatVectors in { 431fe6060f1SDimitry Andric defvar ivti = vtiToWti.Vti; 432fe6060f1SDimitry Andric defvar fwti = vtiToWti.Wti; 43306c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<ivti>.Predicates, 43406c3fb27SDimitry Andric GetVTypePredicates<fwti>.Predicates) in 435fe6060f1SDimitry Andric def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))), 436*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_E"#ivti.SEW) 43706c3fb27SDimitry Andric (fwti.Vector (IMPLICIT_DEF)), 43806c3fb27SDimitry Andric ivti.RegClass:$rs1, 4395f757f3fSDimitry Andric ivti.AVL, ivti.Log2SEW, TA_MA)>; 440fe6060f1SDimitry Andric } 441fe6060f1SDimitry Andric} 442fe6060f1SDimitry Andric 44306c3fb27SDimitry Andricmulticlass VPatWConvertFP2ISDNode_V<SDPatternOperator vop, 44406c3fb27SDimitry Andric string instruction_name> { 445fe6060f1SDimitry Andric foreach fvtiToFWti = AllWidenableFloatVectors in { 446fe6060f1SDimitry Andric defvar fvti = fvtiToFWti.Vti; 447fe6060f1SDimitry Andric defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 44806c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 44906c3fb27SDimitry Andric GetVTypePredicates<iwti>.Predicates) in 450fe6060f1SDimitry Andric def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))), 451fe6060f1SDimitry Andric (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 45206c3fb27SDimitry Andric (iwti.Vector (IMPLICIT_DEF)), 4535f757f3fSDimitry Andric fvti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW, TA_MA)>; 454fe6060f1SDimitry Andric } 455fe6060f1SDimitry Andric} 456fe6060f1SDimitry Andric 45706c3fb27SDimitry Andricmulticlass VPatNConvertI2FPSDNode_W_RM<SDPatternOperator vop, 45806c3fb27SDimitry Andric string instruction_name> { 459fe6060f1SDimitry Andric foreach fvtiToFWti = AllWidenableFloatVectors in { 460fe6060f1SDimitry Andric defvar fvti = fvtiToFWti.Vti; 461fe6060f1SDimitry Andric defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 46206c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 46306c3fb27SDimitry Andric GetVTypePredicates<iwti>.Predicates) in 464fe6060f1SDimitry Andric def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1))), 465*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW) 46606c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 46706c3fb27SDimitry Andric iwti.RegClass:$rs1, 46806c3fb27SDimitry Andric // Value to indicate no rounding mode change in 46906c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 47006c3fb27SDimitry Andric FRM_DYN, 4715f757f3fSDimitry Andric fvti.AVL, fvti.Log2SEW, TA_MA)>; 472fe6060f1SDimitry Andric } 473fe6060f1SDimitry Andric} 474fe6060f1SDimitry Andric 47506c3fb27SDimitry Andricmulticlass VPatNConvertFP2ISDNode_W<SDPatternOperator vop, 47606c3fb27SDimitry Andric string instruction_name> { 477fe6060f1SDimitry Andric foreach vtiToWti = AllWidenableIntToFloatVectors in { 478fe6060f1SDimitry Andric defvar vti = vtiToWti.Vti; 479fe6060f1SDimitry Andric defvar fwti = vtiToWti.Wti; 48006c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 48106c3fb27SDimitry Andric GetVTypePredicates<fwti>.Predicates) in 482fe6060f1SDimitry Andric def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1))), 483fe6060f1SDimitry Andric (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX) 48406c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 4855f757f3fSDimitry Andric fwti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 486e8d8bef9SDimitry Andric } 487e8d8bef9SDimitry Andric} 488e8d8bef9SDimitry Andric 48981ad6265SDimitry Andricmulticlass VPatWidenBinarySDNode_VV_VX<SDNode op, PatFrags extop1, PatFrags extop2, 49081ad6265SDimitry Andric string instruction_name> { 49181ad6265SDimitry Andric foreach vtiToWti = AllWidenableIntVectors in { 49281ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 49381ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 49406c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 49506c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 49681ad6265SDimitry Andric def : Pat<(op (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs2))), 49781ad6265SDimitry Andric (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs1)))), 49881ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 49906c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 5005f757f3fSDimitry Andric vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 50181ad6265SDimitry Andric def : Pat<(op (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs2))), 50206c3fb27SDimitry Andric (wti.Vector (extop2 (vti.Vector (SplatPat (XLenVT GPR:$rs1)))))), 50381ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX) 50406c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 5055f757f3fSDimitry Andric GPR:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 50606c3fb27SDimitry Andric } 50704eeddc0SDimitry Andric } 50804eeddc0SDimitry Andric} 50904eeddc0SDimitry Andric 51081ad6265SDimitry Andricmulticlass VPatWidenBinarySDNode_WV_WX<SDNode op, PatFrags extop, 51181ad6265SDimitry Andric string instruction_name> { 51281ad6265SDimitry Andric foreach vtiToWti = AllWidenableIntVectors in { 51381ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 51481ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 51506c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 51606c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 51781ad6265SDimitry Andric def : Pat<(op (wti.Vector wti.RegClass:$rs2), 51881ad6265SDimitry Andric (wti.Vector (extop (vti.Vector vti.RegClass:$rs1)))), 519bdd1243dSDimitry Andric (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX#"_TIED") 520bdd1243dSDimitry Andric wti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, 521bdd1243dSDimitry Andric TAIL_AGNOSTIC)>; 52281ad6265SDimitry Andric def : Pat<(op (wti.Vector wti.RegClass:$rs2), 52306c3fb27SDimitry Andric (wti.Vector (extop (vti.Vector (SplatPat (XLenVT GPR:$rs1)))))), 52481ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) 52506c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2, GPR:$rs1, 5265f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 52706c3fb27SDimitry Andric } 52881ad6265SDimitry Andric } 52981ad6265SDimitry Andric} 53081ad6265SDimitry Andric 53181ad6265SDimitry Andricmulticlass VPatWidenBinarySDNode_VV_VX_WV_WX<SDNode op, PatFrags extop, 53206c3fb27SDimitry Andric string instruction_name> 53306c3fb27SDimitry Andric : VPatWidenBinarySDNode_VV_VX<op, extop, extop, instruction_name>, 53406c3fb27SDimitry Andric VPatWidenBinarySDNode_WV_WX<op, extop, instruction_name>; 53581ad6265SDimitry Andric 53604eeddc0SDimitry Andricmulticlass VPatWidenMulAddSDNode_VV<PatFrags extop1, PatFrags extop2, string instruction_name> { 53781ad6265SDimitry Andric foreach vtiToWti = AllWidenableIntVectors in { 53881ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 53981ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 54006c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 54106c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in 54204eeddc0SDimitry Andric def : Pat< 54381ad6265SDimitry Andric (add (wti.Vector wti.RegClass:$rd), 54481ad6265SDimitry Andric (mul_oneuse (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs1))), 54581ad6265SDimitry Andric (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs2))))), 54681ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 54781ad6265SDimitry Andric wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 54881ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC 54904eeddc0SDimitry Andric )>; 55004eeddc0SDimitry Andric } 55104eeddc0SDimitry Andric} 55204eeddc0SDimitry Andricmulticlass VPatWidenMulAddSDNode_VX<PatFrags extop1, PatFrags extop2, string instruction_name> { 55381ad6265SDimitry Andric foreach vtiToWti = AllWidenableIntVectors in { 55481ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 55581ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 55606c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 55706c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in 55804eeddc0SDimitry Andric def : Pat< 55981ad6265SDimitry Andric (add (wti.Vector wti.RegClass:$rd), 56006c3fb27SDimitry Andric (mul_oneuse (wti.Vector (extop1 (vti.Vector (SplatPat (XLenVT GPR:$rs1))))), 56181ad6265SDimitry Andric (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs2))))), 56281ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX) 56381ad6265SDimitry Andric wti.RegClass:$rd, GPR:$rs1, vti.RegClass:$rs2, 56481ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC 56504eeddc0SDimitry Andric )>; 56604eeddc0SDimitry Andric } 56704eeddc0SDimitry Andric} 56804eeddc0SDimitry Andric 56904eeddc0SDimitry Andricmulticlass VPatWidenBinaryFPSDNode_VV_VF<SDNode op, string instruction_name> { 57081ad6265SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 57181ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 57281ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 57306c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 57406c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 57581ad6265SDimitry Andric def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 57681ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 57781ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 57881ad6265SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 57981ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), 58081ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 58181ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 58206c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 5835f757f3fSDimitry Andric vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 58481ad6265SDimitry Andric def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 58581ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 58681ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 58781ad6265SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 58881ad6265SDimitry Andric (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 58981ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 59081ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 59106c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 5925f757f3fSDimitry Andric vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 59381ad6265SDimitry Andric def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 59481ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 59581ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 59681ad6265SDimitry Andric (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)))), 59781ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 59806c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 5995f757f3fSDimitry Andric vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 60006c3fb27SDimitry Andric } 60104eeddc0SDimitry Andric } 60204eeddc0SDimitry Andric} 60304eeddc0SDimitry Andric 60406c3fb27SDimitry Andricmulticlass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name> { 60581ad6265SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 60681ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 60781ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 60806c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 60906c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 61006c3fb27SDimitry Andric def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 61106c3fb27SDimitry Andric (vti.Vector vti.RegClass:$rs2), 61206c3fb27SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 61306c3fb27SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 61406c3fb27SDimitry Andric (vti.Vector vti.RegClass:$rs1), 61506c3fb27SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 616*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX#"_E"#vti.SEW) 61706c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 61806c3fb27SDimitry Andric vti.RegClass:$rs1, 61906c3fb27SDimitry Andric // Value to indicate no rounding mode change in 62006c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 62106c3fb27SDimitry Andric FRM_DYN, 6225f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 62306c3fb27SDimitry Andric def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 62406c3fb27SDimitry Andric (vti.Vector vti.RegClass:$rs2), 62506c3fb27SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 62606c3fb27SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 62706c3fb27SDimitry Andric (vti.Vector (SplatFPOp (vti.Scalar vti.ScalarRegClass:$rs1))), 62806c3fb27SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 629*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) 63006c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 63106c3fb27SDimitry Andric vti.ScalarRegClass:$rs1, 63206c3fb27SDimitry Andric // Value to indicate no rounding mode change in 63306c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 63406c3fb27SDimitry Andric FRM_DYN, 6355f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 63606c3fb27SDimitry Andric def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 63706c3fb27SDimitry Andric (vti.Vector vti.RegClass:$rs2), 63806c3fb27SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 63906c3fb27SDimitry Andric (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))), 640*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) 64106c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 64206c3fb27SDimitry Andric vti.ScalarRegClass:$rs1, 64306c3fb27SDimitry Andric // Value to indicate no rounding mode change in 64406c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 64506c3fb27SDimitry Andric FRM_DYN, 6465f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 64706c3fb27SDimitry Andric } 64806c3fb27SDimitry Andric } 64906c3fb27SDimitry Andric} 65006c3fb27SDimitry Andric 65106c3fb27SDimitry Andricmulticlass VPatWidenBinaryFPSDNode_WV_WF_RM<SDNode op, string instruction_name> { 65206c3fb27SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 65306c3fb27SDimitry Andric defvar vti = vtiToWti.Vti; 65406c3fb27SDimitry Andric defvar wti = vtiToWti.Wti; 65506c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 65606c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 65781ad6265SDimitry Andric def : Pat<(op (wti.Vector wti.RegClass:$rs2), 65881ad6265SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 65981ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), 66081ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 661*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX#"_E"#vti.SEW#"_TIED") 66206c3fb27SDimitry Andric wti.RegClass:$rs2, vti.RegClass:$rs1, 66306c3fb27SDimitry Andric // Value to indicate no rounding mode change in 66406c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 66506c3fb27SDimitry Andric FRM_DYN, 66606c3fb27SDimitry Andric vti.AVL, vti.Log2SEW, 667bdd1243dSDimitry Andric TAIL_AGNOSTIC)>; 66881ad6265SDimitry Andric def : Pat<(op (wti.Vector wti.RegClass:$rs2), 66981ad6265SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 67081ad6265SDimitry Andric (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 67181ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 672*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) 67306c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2, 67406c3fb27SDimitry Andric vti.ScalarRegClass:$rs1, 67506c3fb27SDimitry Andric // Value to indicate no rounding mode change in 67606c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 67706c3fb27SDimitry Andric FRM_DYN, 6785f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 67981ad6265SDimitry Andric def : Pat<(op (wti.Vector wti.RegClass:$rs2), 68006c3fb27SDimitry Andric (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))), 681*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) 68206c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2, 68306c3fb27SDimitry Andric vti.ScalarRegClass:$rs1, 68406c3fb27SDimitry Andric // Value to indicate no rounding mode change in 68506c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 68606c3fb27SDimitry Andric FRM_DYN, 6875f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 68806c3fb27SDimitry Andric } 68904eeddc0SDimitry Andric } 69004eeddc0SDimitry Andric} 69104eeddc0SDimitry Andric 69206c3fb27SDimitry Andricmulticlass VPatWidenBinaryFPSDNode_VV_VF_WV_WF_RM<SDNode op, 69306c3fb27SDimitry Andric string instruction_name> 69406c3fb27SDimitry Andric : VPatWidenBinaryFPSDNode_VV_VF_RM<op, instruction_name>, 69506c3fb27SDimitry Andric VPatWidenBinaryFPSDNode_WV_WF_RM<op, instruction_name>; 69604eeddc0SDimitry Andric 69706c3fb27SDimitry Andricmulticlass VPatWidenFPMulAccSDNode_VV_VF_RM<string instruction_name> { 69881ad6265SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 69981ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 70081ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 701*0fca6ea1SDimitry Andric defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 70206c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 70306c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 70481ad6265SDimitry Andric def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 70581ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), 70681ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 70781ad6265SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 70881ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 70981ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 71081ad6265SDimitry Andric (wti.Vector wti.RegClass:$rd)), 711*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#suffix) 71281ad6265SDimitry Andric wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 71306c3fb27SDimitry Andric // Value to indicate no rounding mode change in 71406c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 71506c3fb27SDimitry Andric FRM_DYN, 71681ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 717bdd1243dSDimitry Andric def : Pat<(fma (wti.Vector (SplatFPOp 71806c3fb27SDimitry Andric (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1)))), 71981ad6265SDimitry Andric (wti.Vector (riscv_fpextend_vl_oneuse 72081ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 72181ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 72281ad6265SDimitry Andric (wti.Vector wti.RegClass:$rd)), 723*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix) 72481ad6265SDimitry Andric wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 72506c3fb27SDimitry Andric // Value to indicate no rounding mode change in 72606c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 72706c3fb27SDimitry Andric FRM_DYN, 72881ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 72981ad6265SDimitry Andric } 73081ad6265SDimitry Andric } 73106c3fb27SDimitry Andric} 73281ad6265SDimitry Andric 73306c3fb27SDimitry Andricmulticlass VPatWidenFPNegMulAccSDNode_VV_VF_RM<string instruction_name> { 73481ad6265SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 73581ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 73681ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 737*0fca6ea1SDimitry Andric defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 73806c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 73906c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 74081ad6265SDimitry Andric def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse 74181ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), 74281ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 74381ad6265SDimitry Andric (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 74481ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)), 74581ad6265SDimitry Andric (fneg wti.RegClass:$rd)), 746*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#suffix) 74781ad6265SDimitry Andric wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 74806c3fb27SDimitry Andric // Value to indicate no rounding mode change in 74906c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 75006c3fb27SDimitry Andric FRM_DYN, 75181ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 75206c3fb27SDimitry Andric def : Pat<(fma (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))), 75381ad6265SDimitry Andric (fneg (wti.Vector (riscv_fpextend_vl_oneuse 75481ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 75581ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 75681ad6265SDimitry Andric (fneg wti.RegClass:$rd)), 757*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix) 75881ad6265SDimitry Andric wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 75906c3fb27SDimitry Andric // Value to indicate no rounding mode change in 76006c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 76106c3fb27SDimitry Andric FRM_DYN, 76281ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 76306c3fb27SDimitry Andric def : Pat<(fma (fneg (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))), 76481ad6265SDimitry Andric (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 76581ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)), 76681ad6265SDimitry Andric (fneg wti.RegClass:$rd)), 767*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix) 76881ad6265SDimitry Andric wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 76906c3fb27SDimitry Andric // Value to indicate no rounding mode change in 77006c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 77106c3fb27SDimitry Andric FRM_DYN, 77281ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 77381ad6265SDimitry Andric } 77481ad6265SDimitry Andric } 77506c3fb27SDimitry Andric} 77681ad6265SDimitry Andric 77706c3fb27SDimitry Andricmulticlass VPatWidenFPMulSacSDNode_VV_VF_RM<string instruction_name> { 77881ad6265SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 77981ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 78081ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 781*0fca6ea1SDimitry Andric defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 78206c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 78306c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 78481ad6265SDimitry Andric def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 78581ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), 78681ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 78781ad6265SDimitry Andric (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 78881ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)), 78981ad6265SDimitry Andric (fneg wti.RegClass:$rd)), 790*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#suffix) 79181ad6265SDimitry Andric wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 79206c3fb27SDimitry Andric // Value to indicate no rounding mode change in 79306c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 79406c3fb27SDimitry Andric FRM_DYN, 79581ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 79606c3fb27SDimitry Andric def : Pat<(fma (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1)))), 79781ad6265SDimitry Andric (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 79881ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)), 79981ad6265SDimitry Andric (fneg wti.RegClass:$rd)), 800*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix) 80181ad6265SDimitry Andric wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 80206c3fb27SDimitry Andric // Value to indicate no rounding mode change in 80306c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 80406c3fb27SDimitry Andric FRM_DYN, 80581ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 80681ad6265SDimitry Andric } 80781ad6265SDimitry Andric } 80806c3fb27SDimitry Andric} 80981ad6265SDimitry Andric 81006c3fb27SDimitry Andricmulticlass VPatWidenFPNegMulSacSDNode_VV_VF_RM<string instruction_name> { 81181ad6265SDimitry Andric foreach vtiToWti = AllWidenableFloatVectors in { 81281ad6265SDimitry Andric defvar vti = vtiToWti.Vti; 81381ad6265SDimitry Andric defvar wti = vtiToWti.Wti; 814*0fca6ea1SDimitry Andric defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 81506c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 81606c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 81781ad6265SDimitry Andric def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse 81881ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs1), 81981ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 82081ad6265SDimitry Andric (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 82181ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)), 82281ad6265SDimitry Andric wti.RegClass:$rd), 823*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"#suffix) 82481ad6265SDimitry Andric wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 82506c3fb27SDimitry Andric // Value to indicate no rounding mode change in 82606c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 82706c3fb27SDimitry Andric FRM_DYN, 82881ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 82906c3fb27SDimitry Andric def : Pat<(fma (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1)))), 83081ad6265SDimitry Andric (fneg (wti.Vector (riscv_fpextend_vl_oneuse 83181ad6265SDimitry Andric (vti.Vector vti.RegClass:$rs2), 83281ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)))), 83381ad6265SDimitry Andric wti.RegClass:$rd), 834*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix) 83581ad6265SDimitry Andric wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 83606c3fb27SDimitry Andric // Value to indicate no rounding mode change in 83706c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 83806c3fb27SDimitry Andric FRM_DYN, 83981ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 84006c3fb27SDimitry Andric def : Pat<(fma (fneg (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))), 84181ad6265SDimitry Andric (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 84281ad6265SDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue)), 84381ad6265SDimitry Andric wti.RegClass:$rd), 844*0fca6ea1SDimitry Andric (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix) 84581ad6265SDimitry Andric wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 84606c3fb27SDimitry Andric // Value to indicate no rounding mode change in 84706c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 84806c3fb27SDimitry Andric FRM_DYN, 84981ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 85081ad6265SDimitry Andric } 85181ad6265SDimitry Andric } 85206c3fb27SDimitry Andric} 85381ad6265SDimitry Andric 85481ad6265SDimitry Andricmulticlass VPatMultiplyAddSDNode_VV_VX<SDNode op, string instruction_name> { 85581ad6265SDimitry Andric foreach vti = AllIntegerVectors in { 85681ad6265SDimitry Andric defvar suffix = vti.LMul.MX; 85706c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 85881ad6265SDimitry Andric // NOTE: We choose VMADD because it has the most commuting freedom. So it 85981ad6265SDimitry Andric // works best with how TwoAddressInstructionPass tries commuting. 86081ad6265SDimitry Andric def : Pat<(vti.Vector (op vti.RegClass:$rs2, 86181ad6265SDimitry Andric (mul_oneuse vti.RegClass:$rs1, vti.RegClass:$rd))), 86281ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VV_"# suffix) 86381ad6265SDimitry Andric vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 86481ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 86581ad6265SDimitry Andric // The choice of VMADD here is arbitrary, vmadd.vx and vmacc.vx are equally 86681ad6265SDimitry Andric // commutable. 86781ad6265SDimitry Andric def : Pat<(vti.Vector (op vti.RegClass:$rs2, 86881ad6265SDimitry Andric (mul_oneuse (SplatPat XLenVT:$rs1), vti.RegClass:$rd))), 86981ad6265SDimitry Andric (!cast<Instruction>(instruction_name#"_VX_" # suffix) 87081ad6265SDimitry Andric vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 87181ad6265SDimitry Andric vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 87281ad6265SDimitry Andric } 87381ad6265SDimitry Andric } 87406c3fb27SDimitry Andric} 87581ad6265SDimitry Andric 876*0fca6ea1SDimitry Andricmulticlass VPatAVGADD_VV_VX_RM<SDNode vop, int vxrm, string suffix = ""> { 877297eecfbSDimitry Andric foreach vti = AllIntegerVectors in { 878297eecfbSDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 879297eecfbSDimitry Andric def : Pat<(vop (vti.Vector vti.RegClass:$rs1), 880297eecfbSDimitry Andric (vti.Vector vti.RegClass:$rs2)), 881*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVAADD"#suffix#"_VV_"#vti.LMul.MX) 882297eecfbSDimitry Andric (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs2, 883297eecfbSDimitry Andric vxrm, vti.AVL, vti.Log2SEW, TA_MA)>; 884297eecfbSDimitry Andric def : Pat<(vop (vti.Vector vti.RegClass:$rs1), 885297eecfbSDimitry Andric (vti.Vector (SplatPat (XLenVT GPR:$rs2)))), 886*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVAADD"#suffix#"_VX_"#vti.LMul.MX) 887297eecfbSDimitry Andric (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, GPR:$rs2, 888297eecfbSDimitry Andric vxrm, vti.AVL, vti.Log2SEW, TA_MA)>; 889297eecfbSDimitry Andric } 890297eecfbSDimitry Andric } 891297eecfbSDimitry Andric} 892297eecfbSDimitry Andric 893e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 894e8d8bef9SDimitry Andric// Patterns. 895e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 896e8d8bef9SDimitry Andric 897e8d8bef9SDimitry Andric// 7.4. Vector Unit-Stride Instructions 898fe6060f1SDimitry Andricforeach vti = !listconcat(FractionalGroupIntegerVectors, 8995f757f3fSDimitry Andric FractionalGroupFloatVectors, 9005f757f3fSDimitry Andric FractionalGroupBFloatVectors) in 9015f757f3fSDimitry Andric let Predicates = !if(!eq(vti.Scalar, f16), [HasVInstructionsF16Minimal], 9025f757f3fSDimitry Andric GetVTypePredicates<vti>.Predicates) in 903fe6060f1SDimitry Andric defm : VPatUSLoadStoreSDNode<vti.Vector, vti.Log2SEW, vti.LMul, 904fe6060f1SDimitry Andric vti.AVL, vti.RegClass>; 9055f757f3fSDimitry Andricforeach vti = [VI8M1, VI16M1, VI32M1, VI64M1, VBF16M1, VF16M1, VF32M1, VF64M1] in 9065f757f3fSDimitry Andric let Predicates = !if(!eq(vti.Scalar, f16), [HasVInstructionsF16Minimal], 9075f757f3fSDimitry Andric GetVTypePredicates<vti>.Predicates) in 908fe6060f1SDimitry Andric defm : VPatUSLoadStoreWholeVRSDNode<vti.Vector, vti.Log2SEW, vti.LMul, 909fe6060f1SDimitry Andric vti.RegClass>; 9105f757f3fSDimitry Andricforeach vti = !listconcat(GroupIntegerVectors, GroupFloatVectors, GroupBFloatVectors) in 9115f757f3fSDimitry Andric let Predicates = !if(!eq(vti.Scalar, f16), [HasVInstructionsF16Minimal], 9125f757f3fSDimitry Andric GetVTypePredicates<vti>.Predicates) in 913fe6060f1SDimitry Andric defm : VPatUSLoadStoreWholeVRSDNode<vti.Vector, vti.Log2SEW, vti.LMul, 914fe6060f1SDimitry Andric vti.RegClass>; 915fe6060f1SDimitry Andricforeach mti = AllMasks in 91606c3fb27SDimitry Andric let Predicates = [HasVInstructions] in 917fe6060f1SDimitry Andric defm : VPatUSLoadStoreMaskSDNode<mti>; 918e8d8bef9SDimitry Andric 919bdd1243dSDimitry Andric// 11. Vector Integer Arithmetic Instructions 920bdd1243dSDimitry Andric 921bdd1243dSDimitry Andric// 11.1. Vector Single-Width Integer Add and Subtract 922fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<add, "PseudoVADD">; 923fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<sub, "PseudoVSUB">; 924e8d8bef9SDimitry Andric// Handle VRSUB specially since it's the only integer binary op with reversed 925e8d8bef9SDimitry Andric// pattern operands 926e8d8bef9SDimitry Andricforeach vti = AllIntegerVectors in { 92706c3fb27SDimitry Andric // FIXME: The AddedComplexity here is covering up a missing matcher for 92806c3fb27SDimitry Andric // widening vwsub.vx which can recognize a extended folded into the 92906c3fb27SDimitry Andric // scalar of the splat. 93006c3fb27SDimitry Andric let AddedComplexity = 20 in 93106c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 93206c3fb27SDimitry Andric def : Pat<(sub (vti.Vector (SplatPat (XLenVT GPR:$rs2))), 933e8d8bef9SDimitry Andric (vti.Vector vti.RegClass:$rs1)), 934e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX) 93506c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, GPR:$rs2, 9365f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 937fe6060f1SDimitry Andric def : Pat<(sub (vti.Vector (SplatPat_simm5 simm5:$rs2)), 938e8d8bef9SDimitry Andric (vti.Vector vti.RegClass:$rs1)), 939e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX) 94006c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, 9415f757f3fSDimitry Andric simm5:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>; 94206c3fb27SDimitry Andric } 943e8d8bef9SDimitry Andric} 944e8d8bef9SDimitry Andric 945bdd1243dSDimitry Andric// 11.2. Vector Widening Integer Add and Subtract 94604eeddc0SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, sext_oneuse, "PseudoVWADD">; 94704eeddc0SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, zext_oneuse, "PseudoVWADDU">; 94804eeddc0SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, anyext_oneuse, "PseudoVWADDU">; 94904eeddc0SDimitry Andric 95004eeddc0SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, sext_oneuse, "PseudoVWSUB">; 95104eeddc0SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, zext_oneuse, "PseudoVWSUBU">; 95204eeddc0SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, anyext_oneuse, "PseudoVWSUBU">; 95304eeddc0SDimitry Andric 95406c3fb27SDimitry Andric// shl (ext v, splat 1) is a special case of widening add. 95506c3fb27SDimitry Andricforeach vtiToWti = AllWidenableIntVectors in { 95606c3fb27SDimitry Andric defvar vti = vtiToWti.Vti; 95706c3fb27SDimitry Andric defvar wti = vtiToWti.Wti; 95806c3fb27SDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 95906c3fb27SDimitry Andric GetVTypePredicates<wti>.Predicates) in { 96006c3fb27SDimitry Andric def : Pat<(shl (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs1))), 96106c3fb27SDimitry Andric (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), 96206c3fb27SDimitry Andric (!cast<Instruction>("PseudoVWADD_VV_"#vti.LMul.MX) 96306c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1, 9645f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 96506c3fb27SDimitry Andric def : Pat<(shl (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs1))), 96606c3fb27SDimitry Andric (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), 96706c3fb27SDimitry Andric (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX) 96806c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1, 9695f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 97006c3fb27SDimitry Andric def : Pat<(shl (wti.Vector (anyext_oneuse (vti.Vector vti.RegClass:$rs1))), 97106c3fb27SDimitry Andric (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), 97206c3fb27SDimitry Andric (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX) 97306c3fb27SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1, 9745f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 975*0fca6ea1SDimitry Andric def : Pat<(shl (wti.Vector (riscv_sext_vl_oneuse (vti.Vector vti.RegClass:$rs1), (vti.Mask V0), VLOpFrag)), 976*0fca6ea1SDimitry Andric (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), 977*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVWADD_VV_"#vti.LMul.MX#"_MASK") 978*0fca6ea1SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1, 979*0fca6ea1SDimitry Andric (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 980*0fca6ea1SDimitry Andric def : Pat<(shl (wti.Vector (riscv_zext_vl_oneuse (vti.Vector vti.RegClass:$rs1), (vti.Mask V0), VLOpFrag)), 981*0fca6ea1SDimitry Andric (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), 982*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX#"_MASK") 983*0fca6ea1SDimitry Andric (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1, 984*0fca6ea1SDimitry Andric (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 98506c3fb27SDimitry Andric } 98606c3fb27SDimitry Andric} 98706c3fb27SDimitry Andric 988bdd1243dSDimitry Andric// 11.3. Vector Integer Extension 989fe6060f1SDimitry Andricdefm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF2", 990e8d8bef9SDimitry Andric AllFractionableVF2IntVectors>; 991fe6060f1SDimitry Andricdefm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF2", 992e8d8bef9SDimitry Andric AllFractionableVF2IntVectors>; 993fe6060f1SDimitry Andricdefm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF4", 994e8d8bef9SDimitry Andric AllFractionableVF4IntVectors>; 995fe6060f1SDimitry Andricdefm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF4", 996e8d8bef9SDimitry Andric AllFractionableVF4IntVectors>; 997fe6060f1SDimitry Andricdefm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF8", 998e8d8bef9SDimitry Andric AllFractionableVF8IntVectors>; 999fe6060f1SDimitry Andricdefm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF8", 1000e8d8bef9SDimitry Andric AllFractionableVF8IntVectors>; 1001e8d8bef9SDimitry Andric 1002bdd1243dSDimitry Andric// 11.5. Vector Bitwise Logical Instructions 1003fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<and, "PseudoVAND">; 1004fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<or, "PseudoVOR">; 1005fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<xor, "PseudoVXOR">; 1006e8d8bef9SDimitry Andric 1007bdd1243dSDimitry Andric// 11.6. Vector Single-Width Bit Shift Instructions 1008fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<shl, "PseudoVSLL", uimm5>; 1009fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<srl, "PseudoVSRL", uimm5>; 1010fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", uimm5>; 1011e8d8bef9SDimitry Andric 1012fe6060f1SDimitry Andricforeach vti = AllIntegerVectors in { 1013fe6060f1SDimitry Andric // Emit shift by 1 as an add since it might be faster. 101406c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in 1015fe6060f1SDimitry Andric def : Pat<(shl (vti.Vector vti.RegClass:$rs1), 101681ad6265SDimitry Andric (vti.Vector (riscv_vmv_v_x_vl (vti.Vector undef), 1, (XLenVT srcvalue)))), 1017fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX) 101806c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, 10195f757f3fSDimitry Andric vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; 1020fe6060f1SDimitry Andric 1021e8d8bef9SDimitry Andric} 1022e8d8bef9SDimitry Andric 1023bdd1243dSDimitry Andric// 11.8. Vector Integer Comparison Instructions 102481ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VV<"PseudoVMSEQ", SETEQ>; 102581ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VV<"PseudoVMSNE", SETNE>; 1026e8d8bef9SDimitry Andric 102781ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLT", SETLT, SETGT>; 102881ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLTU", SETULT, SETUGT>; 102981ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLE", SETLE, SETGE>; 103081ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLEU", SETULE, SETUGE>; 103181ad6265SDimitry Andric 103281ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSEQ", SETEQ, SETEQ>; 103381ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSNE", SETNE, SETNE>; 103481ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLT", SETLT, SETGT>; 103581ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLTU", SETULT, SETUGT>; 103681ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLE", SETLE, SETGE>; 103781ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLEU", SETULE, SETUGE>; 103881ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSGT", SETGT, SETLT>; 103981ad6265SDimitry Andricdefm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSGTU", SETUGT, SETULT>; 104081ad6265SDimitry Andric// There is no VMSGE(U)_VX instruction 104181ad6265SDimitry Andric 1042*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSEQ", SETEQ, SETEQ>; 1043*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSNE", SETNE, SETNE>; 1044*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSLE", SETLE, SETGE>; 1045*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSLEU", SETULE, SETUGE>; 1046*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSGT", SETGT, SETLT>; 1047*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSGTU", SETUGT, SETULT>; 104881ad6265SDimitry Andric 1049*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VIPlus1_Swappable<"PseudoVMSLE", SETLT, SETGT, 105006c3fb27SDimitry Andric SplatPat_simm5_plus1>; 1051*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VIPlus1_Swappable<"PseudoVMSLEU", SETULT, SETUGT, 1052fe6060f1SDimitry Andric SplatPat_simm5_plus1_nonzero>; 1053*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VIPlus1_Swappable<"PseudoVMSGT", SETGE, SETLE, 1054fe6060f1SDimitry Andric SplatPat_simm5_plus1>; 1055*0fca6ea1SDimitry Andricdefm : VPatIntegerSetCCSDNode_VIPlus1_Swappable<"PseudoVMSGTU", SETUGE, SETULE, 1056fe6060f1SDimitry Andric SplatPat_simm5_plus1_nonzero>; 1057e8d8bef9SDimitry Andric 1058bdd1243dSDimitry Andric// 11.9. Vector Integer Min/Max Instructions 1059fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">; 1060fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">; 1061fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<umax, "PseudoVMAXU">; 1062fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<smax, "PseudoVMAX">; 1063e8d8bef9SDimitry Andric 1064bdd1243dSDimitry Andric// 11.10. Vector Single-Width Integer Multiply Instructions 1065fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<mul, "PseudoVMUL">; 106606c3fb27SDimitry Andric 106706c3fb27SDimitry Andricdefm : VPatBinarySDNode_VV_VX<mulhs, "PseudoVMULH", IntegerVectorsExceptI64>; 106806c3fb27SDimitry Andricdefm : VPatBinarySDNode_VV_VX<mulhu, "PseudoVMULHU", IntegerVectorsExceptI64>; 106906c3fb27SDimitry Andric 107006c3fb27SDimitry Andriclet Predicates = [HasVInstructionsFullMultiply] in { 107106c3fb27SDimitry Andric defm : VPatBinarySDNode_VV_VX<mulhs, "PseudoVMULH", I64IntegerVectors>; 107206c3fb27SDimitry Andric defm : VPatBinarySDNode_VV_VX<mulhu, "PseudoVMULHU", I64IntegerVectors>; 107306c3fb27SDimitry Andric} 1074e8d8bef9SDimitry Andric 1075bdd1243dSDimitry Andric// 11.11. Vector Integer Divide Instructions 107606c3fb27SDimitry Andricdefm : VPatBinarySDNode_VV_VX<udiv, "PseudoVDIVU", isSEWAware=1>; 107706c3fb27SDimitry Andricdefm : VPatBinarySDNode_VV_VX<sdiv, "PseudoVDIV", isSEWAware=1>; 107806c3fb27SDimitry Andricdefm : VPatBinarySDNode_VV_VX<urem, "PseudoVREMU", isSEWAware=1>; 107906c3fb27SDimitry Andricdefm : VPatBinarySDNode_VV_VX<srem, "PseudoVREM", isSEWAware=1>; 1080e8d8bef9SDimitry Andric 10815f757f3fSDimitry Andricforeach vtiTowti = AllWidenableIntVectors in { 10825f757f3fSDimitry Andric defvar vti = vtiTowti.Vti; 10835f757f3fSDimitry Andric defvar wti = vtiTowti.Wti; 10845f757f3fSDimitry Andric let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 10855f757f3fSDimitry Andric GetVTypePredicates<wti>.Predicates) in { 10865f757f3fSDimitry Andric def : Pat< 10875f757f3fSDimitry Andric (vti.Vector 10885f757f3fSDimitry Andric (riscv_trunc_vector_vl 10895f757f3fSDimitry Andric (srem (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs1))), 10905f757f3fSDimitry Andric (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs2)))), 10915f757f3fSDimitry Andric (vti.Mask true_mask), (XLenVT srcvalue))), 10925f757f3fSDimitry Andric (!cast<Instruction>("PseudoVREM_VV_"#vti.LMul.MX#"_E"#!shl(1, vti.Log2SEW)) 10935f757f3fSDimitry Andric (vti.Vector (IMPLICIT_DEF)), 10945f757f3fSDimitry Andric vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>; 10955f757f3fSDimitry Andric } 10965f757f3fSDimitry Andric} 10975f757f3fSDimitry Andric 1098bdd1243dSDimitry Andric// 11.12. Vector Widening Integer Multiply Instructions 109981ad6265SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, sext_oneuse, 110081ad6265SDimitry Andric "PseudoVWMUL">; 110181ad6265SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX<mul, zext_oneuse, zext_oneuse, 110281ad6265SDimitry Andric "PseudoVWMULU">; 110381ad6265SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX<mul, anyext_oneuse, anyext_oneuse, 110481ad6265SDimitry Andric "PseudoVWMULU">; 110581ad6265SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX<mul, zext_oneuse, anyext_oneuse, 110681ad6265SDimitry Andric "PseudoVWMULU">; 110781ad6265SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, zext_oneuse, 110881ad6265SDimitry Andric "PseudoVWMULSU">; 110981ad6265SDimitry Andricdefm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, anyext_oneuse, 111081ad6265SDimitry Andric "PseudoVWMULSU">; 1111fe6060f1SDimitry Andric 1112bdd1243dSDimitry Andric// 11.13 Vector Single-Width Integer Multiply-Add Instructions. 111381ad6265SDimitry Andricdefm : VPatMultiplyAddSDNode_VV_VX<add, "PseudoVMADD">; 111481ad6265SDimitry Andricdefm : VPatMultiplyAddSDNode_VV_VX<sub, "PseudoVNMSUB">; 1115fe6060f1SDimitry Andric 1116bdd1243dSDimitry Andric// 11.14 Vector Widening Integer Multiply-Add Instructions 111704eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VV<sext_oneuse, sext_oneuse, "PseudoVWMACC">; 111804eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VX<sext_oneuse, sext_oneuse, "PseudoVWMACC">; 111904eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VV<zext_oneuse, zext_oneuse, "PseudoVWMACCU">; 112004eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VX<zext_oneuse, zext_oneuse, "PseudoVWMACCU">; 112104eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VV<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">; 112204eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VX<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">; 112304eeddc0SDimitry Andricdefm : VPatWidenMulAddSDNode_VX<zext_oneuse, sext_oneuse, "PseudoVWMACCUS">; 112404eeddc0SDimitry Andric 1125bdd1243dSDimitry Andric// 11.15. Vector Integer Merge Instructions 1126e8d8bef9SDimitry Andricforeach vti = AllIntegerVectors in { 112706c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 1128349cc55cSDimitry Andric def : Pat<(vti.Vector (vselect (vti.Mask V0), vti.RegClass:$rs1, 1129e8d8bef9SDimitry Andric vti.RegClass:$rs2)), 1130e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX) 113106c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 1132349cc55cSDimitry Andric vti.RegClass:$rs2, vti.RegClass:$rs1, (vti.Mask V0), 1133fe6060f1SDimitry Andric vti.AVL, vti.Log2SEW)>; 1134e8d8bef9SDimitry Andric 1135349cc55cSDimitry Andric def : Pat<(vti.Vector (vselect (vti.Mask V0), (SplatPat XLenVT:$rs1), 1136e8d8bef9SDimitry Andric vti.RegClass:$rs2)), 1137e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX) 113806c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 1139349cc55cSDimitry Andric vti.RegClass:$rs2, GPR:$rs1, (vti.Mask V0), vti.AVL, vti.Log2SEW)>; 1140e8d8bef9SDimitry Andric 1141349cc55cSDimitry Andric def : Pat<(vti.Vector (vselect (vti.Mask V0), (SplatPat_simm5 simm5:$rs1), 1142e8d8bef9SDimitry Andric vti.RegClass:$rs2)), 1143e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX) 114406c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 1145349cc55cSDimitry Andric vti.RegClass:$rs2, simm5:$rs1, (vti.Mask V0), vti.AVL, vti.Log2SEW)>; 1146e8d8bef9SDimitry Andric } 114706c3fb27SDimitry Andric} 1148e8d8bef9SDimitry Andric 1149bdd1243dSDimitry Andric// 12. Vector Fixed-Point Arithmetic Instructions 1150bdd1243dSDimitry Andric 1151fe6060f1SDimitry Andric// 12.1. Vector Single-Width Saturating Add and Subtract 1152fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<saddsat, "PseudoVSADD">; 1153fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX_VI<uaddsat, "PseudoVSADDU">; 1154fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<ssubsat, "PseudoVSSUB">; 1155fe6060f1SDimitry Andricdefm : VPatBinarySDNode_VV_VX<usubsat, "PseudoVSSUBU">; 1156fe6060f1SDimitry Andric 11571db9f3b2SDimitry Andric// 12.2. Vector Single-Width Averaging Add and Subtract 1158*0fca6ea1SDimitry Andricdefm : VPatAVGADD_VV_VX_RM<avgfloors, 0b10>; 1159*0fca6ea1SDimitry Andricdefm : VPatAVGADD_VV_VX_RM<avgflooru, 0b10, suffix = "U">; 1160*0fca6ea1SDimitry Andricdefm : VPatAVGADD_VV_VX_RM<avgceils, 0b00>; 1161*0fca6ea1SDimitry Andricdefm : VPatAVGADD_VV_VX_RM<avgceilu, 0b00, suffix = "U">; 11621db9f3b2SDimitry Andric 1163bdd1243dSDimitry Andric// 15. Vector Mask Instructions 1164bdd1243dSDimitry Andric 1165bdd1243dSDimitry Andric// 15.1. Vector Mask-Register Logical Instructions 1166e8d8bef9SDimitry Andricforeach mti = AllMasks in { 116706c3fb27SDimitry Andric let Predicates = [HasVInstructions] in { 1168e8d8bef9SDimitry Andric def : Pat<(mti.Mask (and VR:$rs1, VR:$rs2)), 1169e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMAND_MM_"#mti.LMul.MX) 1170fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1171e8d8bef9SDimitry Andric def : Pat<(mti.Mask (or VR:$rs1, VR:$rs2)), 1172e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMOR_MM_"#mti.LMul.MX) 1173fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1174e8d8bef9SDimitry Andric def : Pat<(mti.Mask (xor VR:$rs1, VR:$rs2)), 1175e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMXOR_MM_"#mti.LMul.MX) 1176fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1177e8d8bef9SDimitry Andric 1178fe6060f1SDimitry Andric def : Pat<(mti.Mask (rvv_vnot (and VR:$rs1, VR:$rs2))), 1179e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMNAND_MM_"#mti.LMul.MX) 1180fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1181fe6060f1SDimitry Andric def : Pat<(mti.Mask (rvv_vnot (or VR:$rs1, VR:$rs2))), 1182e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMNOR_MM_"#mti.LMul.MX) 1183fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1184fe6060f1SDimitry Andric def : Pat<(mti.Mask (rvv_vnot (xor VR:$rs1, VR:$rs2))), 1185e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMXNOR_MM_"#mti.LMul.MX) 1186fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1187e8d8bef9SDimitry Andric 1188fe6060f1SDimitry Andric def : Pat<(mti.Mask (and VR:$rs1, (rvv_vnot VR:$rs2))), 1189349cc55cSDimitry Andric (!cast<Instruction>("PseudoVMANDN_MM_"#mti.LMul.MX) 1190fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1191fe6060f1SDimitry Andric def : Pat<(mti.Mask (or VR:$rs1, (rvv_vnot VR:$rs2))), 1192349cc55cSDimitry Andric (!cast<Instruction>("PseudoVMORN_MM_"#mti.LMul.MX) 1193fe6060f1SDimitry Andric VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 1194fe6060f1SDimitry Andric 1195fe6060f1SDimitry Andric // Handle rvv_vnot the same as the vmnot.m pseudoinstruction. 1196fe6060f1SDimitry Andric def : Pat<(mti.Mask (rvv_vnot VR:$rs)), 1197fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVMNAND_MM_"#mti.LMul.MX) 1198fe6060f1SDimitry Andric VR:$rs, VR:$rs, mti.AVL, mti.Log2SEW)>; 1199e8d8bef9SDimitry Andric } 120006c3fb27SDimitry Andric} 1201e8d8bef9SDimitry Andric 1202bdd1243dSDimitry Andric// 13. Vector Floating-Point Instructions 1203bdd1243dSDimitry Andric 1204bdd1243dSDimitry Andric// 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions 1205*0fca6ea1SDimitry Andricdefm : VPatBinaryFPSDNode_VV_VF_RM<any_fadd, "PseudoVFADD", isSEWAware=1>; 1206*0fca6ea1SDimitry Andricdefm : VPatBinaryFPSDNode_VV_VF_RM<any_fsub, "PseudoVFSUB", isSEWAware=1>; 1207*0fca6ea1SDimitry Andricdefm : VPatBinaryFPSDNode_R_VF_RM<any_fsub, "PseudoVFRSUB", isSEWAware=1>; 1208e8d8bef9SDimitry Andric 1209bdd1243dSDimitry Andric// 13.3. Vector Widening Floating-Point Add/Subtract Instructions 121006c3fb27SDimitry Andricdefm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF_RM<fadd, "PseudoVFWADD">; 121106c3fb27SDimitry Andricdefm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF_RM<fsub, "PseudoVFWSUB">; 121204eeddc0SDimitry Andric 1213bdd1243dSDimitry Andric// 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 1214*0fca6ea1SDimitry Andricdefm : VPatBinaryFPSDNode_VV_VF_RM<any_fmul, "PseudoVFMUL", isSEWAware=1>; 121506c3fb27SDimitry Andricdefm : VPatBinaryFPSDNode_VV_VF_RM<any_fdiv, "PseudoVFDIV", isSEWAware=1>; 121606c3fb27SDimitry Andricdefm : VPatBinaryFPSDNode_R_VF_RM<any_fdiv, "PseudoVFRDIV", isSEWAware=1>; 1217e8d8bef9SDimitry Andric 1218bdd1243dSDimitry Andric// 13.5. Vector Widening Floating-Point Multiply Instructions 121906c3fb27SDimitry Andricdefm : VPatWidenBinaryFPSDNode_VV_VF_RM<fmul, "PseudoVFWMUL">; 122004eeddc0SDimitry Andric 1221bdd1243dSDimitry Andric// 13.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions. 1222fe6060f1SDimitry Andricforeach fvti = AllFloatVectors in { 1223fe6060f1SDimitry Andric // NOTE: We choose VFMADD because it has the most commuting freedom. So it 1224fe6060f1SDimitry Andric // works best with how TwoAddressInstructionPass tries commuting. 1225*0fca6ea1SDimitry Andric defvar suffix = fvti.LMul.MX # "_E" # fvti.SEW; 122606c3fb27SDimitry Andric let Predicates = GetVTypePredicates<fvti>.Predicates in { 122706c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma fvti.RegClass:$rs1, fvti.RegClass:$rd, 1228fe6060f1SDimitry Andric fvti.RegClass:$rs2)), 1229fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFMADD_VV_"# suffix) 1230fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 123106c3fb27SDimitry Andric // Value to indicate no rounding mode change in 123206c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 123306c3fb27SDimitry Andric FRM_DYN, 1234349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 123506c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma fvti.RegClass:$rs1, fvti.RegClass:$rd, 1236fe6060f1SDimitry Andric (fneg fvti.RegClass:$rs2))), 1237fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix) 1238fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 123906c3fb27SDimitry Andric // Value to indicate no rounding mode change in 124006c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 124106c3fb27SDimitry Andric FRM_DYN, 1242349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 124306c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd, 1244fe6060f1SDimitry Andric (fneg fvti.RegClass:$rs2))), 1245fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix) 1246fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 124706c3fb27SDimitry Andric // Value to indicate no rounding mode change in 124806c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 124906c3fb27SDimitry Andric FRM_DYN, 1250349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 125106c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd, 1252fe6060f1SDimitry Andric fvti.RegClass:$rs2)), 1253fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix) 1254fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 125506c3fb27SDimitry Andric // Value to indicate no rounding mode change in 125606c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 125706c3fb27SDimitry Andric FRM_DYN, 1258349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 1259e8d8bef9SDimitry Andric 1260fe6060f1SDimitry Andric // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally 1261fe6060f1SDimitry Andric // commutable. 126206c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1), 1263fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.RegClass:$rs2)), 1264fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFMADD_V" # fvti.ScalarSuffix # "_" # suffix) 1265fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 126606c3fb27SDimitry Andric // Value to indicate no rounding mode change in 126706c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 126806c3fb27SDimitry Andric FRM_DYN, 1269349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 127006c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1), 1271fe6060f1SDimitry Andric fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))), 1272fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFMSUB_V" # fvti.ScalarSuffix # "_" # suffix) 1273fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 127406c3fb27SDimitry Andric // Value to indicate no rounding mode change in 127506c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 127606c3fb27SDimitry Andric FRM_DYN, 1277349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 1278e8d8bef9SDimitry Andric 127906c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1), 1280fe6060f1SDimitry Andric (fneg fvti.RegClass:$rd), (fneg fvti.RegClass:$rs2))), 1281fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix) 1282fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 128306c3fb27SDimitry Andric // Value to indicate no rounding mode change in 128406c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 128506c3fb27SDimitry Andric FRM_DYN, 1286349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 128706c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1), 1288fe6060f1SDimitry Andric (fneg fvti.RegClass:$rd), fvti.RegClass:$rs2)), 1289fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix) 1290fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 129106c3fb27SDimitry Andric // Value to indicate no rounding mode change in 129206c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 129306c3fb27SDimitry Andric FRM_DYN, 1294349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 1295e8d8bef9SDimitry Andric 1296fe6060f1SDimitry Andric // The splat might be negated. 129706c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (fneg (SplatFPOp fvti.ScalarRegClass:$rs1)), 1298fe6060f1SDimitry Andric fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))), 1299fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix) 1300fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 130106c3fb27SDimitry Andric // Value to indicate no rounding mode change in 130206c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 130306c3fb27SDimitry Andric FRM_DYN, 1304349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 130506c3fb27SDimitry Andric def : Pat<(fvti.Vector (any_fma (fneg (SplatFPOp fvti.ScalarRegClass:$rs1)), 1306fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.RegClass:$rs2)), 1307fe6060f1SDimitry Andric (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix) 1308fe6060f1SDimitry Andric fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 130906c3fb27SDimitry Andric // Value to indicate no rounding mode change in 131006c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 131106c3fb27SDimitry Andric FRM_DYN, 1312349cc55cSDimitry Andric fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 1313fe6060f1SDimitry Andric } 131406c3fb27SDimitry Andric} 1315fe6060f1SDimitry Andric 1316bdd1243dSDimitry Andric// 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 131706c3fb27SDimitry Andricdefm : VPatWidenFPMulAccSDNode_VV_VF_RM<"PseudoVFWMACC">; 131806c3fb27SDimitry Andricdefm : VPatWidenFPNegMulAccSDNode_VV_VF_RM<"PseudoVFWNMACC">; 131906c3fb27SDimitry Andricdefm : VPatWidenFPMulSacSDNode_VV_VF_RM<"PseudoVFWMSAC">; 132006c3fb27SDimitry Andricdefm : VPatWidenFPNegMulSacSDNode_VV_VF_RM<"PseudoVFWNMSAC">; 132181ad6265SDimitry Andric 1322fe6060f1SDimitry Andricforeach vti = AllFloatVectors in { 132306c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in { 1324bdd1243dSDimitry Andric // 13.8. Vector Floating-Point Square-Root Instruction 132506c3fb27SDimitry Andric def : Pat<(any_fsqrt (vti.Vector vti.RegClass:$rs2)), 132606c3fb27SDimitry Andric (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX#"_E"#vti.SEW) 132706c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 132806c3fb27SDimitry Andric vti.RegClass:$rs2, 132906c3fb27SDimitry Andric // Value to indicate no rounding mode change in 133006c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 133106c3fb27SDimitry Andric FRM_DYN, 13325f757f3fSDimitry Andric vti.AVL, vti.Log2SEW, TA_MA)>; 1333fe6060f1SDimitry Andric 1334bdd1243dSDimitry Andric // 13.12. Vector Floating-Point Sign-Injection Instructions 1335fe6060f1SDimitry Andric def : Pat<(fabs (vti.Vector vti.RegClass:$rs)), 1336*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX#"_E"#vti.SEW) 133706c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 13385f757f3fSDimitry Andric vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW, TA_MA)>; 1339fe6060f1SDimitry Andric // Handle fneg with VFSGNJN using the same input for both operands. 1340fe6060f1SDimitry Andric def : Pat<(fneg (vti.Vector vti.RegClass:$rs)), 1341*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX#"_E"#vti.SEW) 134206c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 13435f757f3fSDimitry Andric vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW, TA_MA)>; 1344fe6060f1SDimitry Andric 1345fe6060f1SDimitry Andric def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 1346fe6060f1SDimitry Andric (vti.Vector vti.RegClass:$rs2))), 1347*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX#"_E"#vti.SEW) 134806c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 13495f757f3fSDimitry Andric vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>; 1350fe6060f1SDimitry Andric def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 135181ad6265SDimitry Andric (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs2)))), 1352*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) 135306c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 13545f757f3fSDimitry Andric vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>; 1355fe6060f1SDimitry Andric 1356fe6060f1SDimitry Andric def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 1357fe6060f1SDimitry Andric (vti.Vector (fneg vti.RegClass:$rs2)))), 1358*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX#"_E"#vti.SEW) 135906c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 13605f757f3fSDimitry Andric vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>; 1361fe6060f1SDimitry Andric def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 136281ad6265SDimitry Andric (vti.Vector (fneg (SplatFPOp vti.ScalarRegClass:$rs2))))), 1363*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFSGNJN_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) 136406c3fb27SDimitry Andric (vti.Vector (IMPLICIT_DEF)), 13655f757f3fSDimitry Andric vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>; 136606c3fb27SDimitry Andric } 1367fe6060f1SDimitry Andric} 1368fe6060f1SDimitry Andric 1369bdd1243dSDimitry Andric// 13.11. Vector Floating-Point MIN/MAX Instructions 1370*0fca6ea1SDimitry Andricdefm : VPatBinaryFPSDNode_VV_VF<fminnum, "PseudoVFMIN", isSEWAware=1>; 1371*0fca6ea1SDimitry Andricdefm : VPatBinaryFPSDNode_VV_VF<fmaxnum, "PseudoVFMAX", isSEWAware=1>; 1372fe6060f1SDimitry Andric 1373bdd1243dSDimitry Andric// 13.13. Vector Floating-Point Compare Instructions 1374fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 1375fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 1376fe6060f1SDimitry Andric 1377fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETNE, "PseudoVMFNE", "PseudoVMFNE">; 1378fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">; 1379fe6060f1SDimitry Andric 1380fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETLT, "PseudoVMFLT", "PseudoVMFGT">; 1381fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">; 1382fe6060f1SDimitry Andric 1383fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETLE, "PseudoVMFLE", "PseudoVMFGE">; 1384fe6060f1SDimitry Andricdefm : VPatFPSetCCSDNode_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">; 1385e8d8bef9SDimitry Andric 1386e8d8bef9SDimitry Andric// Floating-point vselects: 1387bdd1243dSDimitry Andric// 11.15. Vector Integer Merge Instructions 1388bdd1243dSDimitry Andric// 13.15. Vector Floating-Point Merge Instruction 1389*0fca6ea1SDimitry Andricforeach fvti = !listconcat(AllFloatVectors, AllBFloatVectors) in { 13905f757f3fSDimitry Andric defvar ivti = GetIntVTypeInfo<fvti>.Vti; 13915f757f3fSDimitry Andric let Predicates = GetVTypePredicates<ivti>.Predicates in { 1392349cc55cSDimitry Andric def : Pat<(fvti.Vector (vselect (fvti.Mask V0), fvti.RegClass:$rs1, 1393e8d8bef9SDimitry Andric fvti.RegClass:$rs2)), 1394e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX) 139506c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 1396349cc55cSDimitry Andric fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask V0), 1397fe6060f1SDimitry Andric fvti.AVL, fvti.Log2SEW)>; 1398e8d8bef9SDimitry Andric 1399349cc55cSDimitry Andric def : Pat<(fvti.Vector (vselect (fvti.Mask V0), 1400*0fca6ea1SDimitry Andric (SplatFPOp (SelectFPImm (XLenVT GPR:$imm))), 1401*0fca6ea1SDimitry Andric fvti.RegClass:$rs2)), 1402*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVMERGE_VXM_"#fvti.LMul.MX) 1403*0fca6ea1SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 1404*0fca6ea1SDimitry Andric fvti.RegClass:$rs2, GPR:$imm, (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>; 1405*0fca6ea1SDimitry Andric 1406*0fca6ea1SDimitry Andric def : Pat<(fvti.Vector (vselect (fvti.Mask V0), 14075f757f3fSDimitry Andric (SplatFPOp (fvti.Scalar fpimm0)), 14085f757f3fSDimitry Andric fvti.RegClass:$rs2)), 14095f757f3fSDimitry Andric (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX) 14105f757f3fSDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 14115f757f3fSDimitry Andric fvti.RegClass:$rs2, 0, (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>; 14125f757f3fSDimitry Andric } 1413*0fca6ea1SDimitry Andric} 1414*0fca6ea1SDimitry Andric 1415*0fca6ea1SDimitry Andricforeach fvti = AllFloatVectors in { 14165f757f3fSDimitry Andric let Predicates = GetVTypePredicates<fvti>.Predicates in 14175f757f3fSDimitry Andric def : Pat<(fvti.Vector (vselect (fvti.Mask V0), 141881ad6265SDimitry Andric (SplatFPOp fvti.ScalarRegClass:$rs1), 1419e8d8bef9SDimitry Andric fvti.RegClass:$rs2)), 1420e8d8bef9SDimitry Andric (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX) 142106c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 1422e8d8bef9SDimitry Andric fvti.RegClass:$rs2, 1423e8d8bef9SDimitry Andric (fvti.Scalar fvti.ScalarRegClass:$rs1), 1424349cc55cSDimitry Andric (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>; 142506c3fb27SDimitry Andric} 1426fe6060f1SDimitry Andric 1427bdd1243dSDimitry Andric// 13.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions 142806c3fb27SDimitry Andricdefm : VPatConvertFP2ISDNode_V<any_fp_to_sint, "PseudoVFCVT_RTZ_X_F_V">; 142906c3fb27SDimitry Andricdefm : VPatConvertFP2ISDNode_V<any_fp_to_uint, "PseudoVFCVT_RTZ_XU_F_V">; 143006c3fb27SDimitry Andricdefm : VPatConvertI2FPSDNode_V_RM<any_sint_to_fp, "PseudoVFCVT_F_X_V">; 143106c3fb27SDimitry Andricdefm : VPatConvertI2FPSDNode_V_RM<any_uint_to_fp, "PseudoVFCVT_F_XU_V">; 1432fe6060f1SDimitry Andric 1433bdd1243dSDimitry Andric// 13.18. Widening Floating-Point/Integer Type-Convert Instructions 143406c3fb27SDimitry Andricdefm : VPatWConvertFP2ISDNode_V<any_fp_to_sint, "PseudoVFWCVT_RTZ_X_F_V">; 143506c3fb27SDimitry Andricdefm : VPatWConvertFP2ISDNode_V<any_fp_to_uint, "PseudoVFWCVT_RTZ_XU_F_V">; 143606c3fb27SDimitry Andricdefm : VPatWConvertI2FPSDNode_V<any_sint_to_fp, "PseudoVFWCVT_F_X_V">; 143706c3fb27SDimitry Andricdefm : VPatWConvertI2FPSDNode_V<any_uint_to_fp, "PseudoVFWCVT_F_XU_V">; 1438fe6060f1SDimitry Andric 1439bdd1243dSDimitry Andric// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions 144006c3fb27SDimitry Andricdefm : VPatNConvertFP2ISDNode_W<any_fp_to_sint, "PseudoVFNCVT_RTZ_X_F_W">; 144106c3fb27SDimitry Andricdefm : VPatNConvertFP2ISDNode_W<any_fp_to_uint, "PseudoVFNCVT_RTZ_XU_F_W">; 144206c3fb27SDimitry Andricdefm : VPatNConvertI2FPSDNode_W_RM<any_sint_to_fp, "PseudoVFNCVT_F_X_W">; 144306c3fb27SDimitry Andricdefm : VPatNConvertI2FPSDNode_W_RM<any_uint_to_fp, "PseudoVFNCVT_F_XU_W">; 1444fe6060f1SDimitry Andricforeach fvtiToFWti = AllWidenableFloatVectors in { 1445fe6060f1SDimitry Andric defvar fvti = fvtiToFWti.Vti; 1446fe6060f1SDimitry Andric defvar fwti = fvtiToFWti.Wti; 14475f757f3fSDimitry Andric let Predicates = !if(!eq(fvti.Scalar, f16), [HasVInstructionsF16Minimal], 14485f757f3fSDimitry Andric !listconcat(GetVTypePredicates<fvti>.Predicates, 14495f757f3fSDimitry Andric GetVTypePredicates<fwti>.Predicates)) in 1450fe6060f1SDimitry Andric def : Pat<(fvti.Vector (fpround (fwti.Vector fwti.RegClass:$rs1))), 1451*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX#"_E"#fvti.SEW) 145206c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 145306c3fb27SDimitry Andric fwti.RegClass:$rs1, 145406c3fb27SDimitry Andric // Value to indicate no rounding mode change in 145506c3fb27SDimitry Andric // RISCVInsertReadWriteCSR 145606c3fb27SDimitry Andric FRM_DYN, 14575f757f3fSDimitry Andric fvti.AVL, fvti.Log2SEW, TA_MA)>; 1458e8d8bef9SDimitry Andric} 1459e8d8bef9SDimitry Andric 1460*0fca6ea1SDimitry Andricforeach fvtiToFWti = AllWidenableBFloatToFloatVectors in { 1461*0fca6ea1SDimitry Andric defvar fvti = fvtiToFWti.Vti; 1462*0fca6ea1SDimitry Andric defvar fwti = fvtiToFWti.Wti; 1463*0fca6ea1SDimitry Andric let Predicates = [HasVInstructionsBF16] in 1464*0fca6ea1SDimitry Andric def : Pat<(fvti.Vector (fpround (fwti.Vector fwti.RegClass:$rs1))), 1465*0fca6ea1SDimitry Andric (!cast<Instruction>("PseudoVFNCVTBF16_F_F_W_"#fvti.LMul.MX#"_E"#fvti.SEW) 146606c3fb27SDimitry Andric (fvti.Vector (IMPLICIT_DEF)), 1467*0fca6ea1SDimitry Andric fwti.RegClass:$rs1, 1468*0fca6ea1SDimitry Andric // Value to indicate no rounding mode change in 1469*0fca6ea1SDimitry Andric // RISCVInsertReadWriteCSR 1470*0fca6ea1SDimitry Andric FRM_DYN, 14715f757f3fSDimitry Andric fvti.AVL, fvti.Log2SEW, TA_MA)>; 147206c3fb27SDimitry Andric} 1473e8d8bef9SDimitry Andric 1474e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 1475fe6060f1SDimitry Andric// Vector Element Extracts 1476e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 1477fe6060f1SDimitry Andricforeach vti = AllFloatVectors in { 1478fe6060f1SDimitry Andric defvar vmv_f_s_inst = !cast<Instruction>(!strconcat("PseudoVFMV_", 1479fe6060f1SDimitry Andric vti.ScalarSuffix, 1480fe6060f1SDimitry Andric "_S_", vti.LMul.MX)); 1481fe6060f1SDimitry Andric // Only pattern-match extract-element operations where the index is 0. Any 1482fe6060f1SDimitry Andric // other index will have been custom-lowered to slide the vector correctly 1483fe6060f1SDimitry Andric // into place. 148406c3fb27SDimitry Andric let Predicates = GetVTypePredicates<vti>.Predicates in 1485fe6060f1SDimitry Andric def : Pat<(vti.Scalar (extractelt (vti.Vector vti.RegClass:$rs2), 0)), 1486fe6060f1SDimitry Andric (vmv_f_s_inst vti.RegClass:$rs2, vti.Log2SEW)>; 1487e8d8bef9SDimitry Andric} 1488