1//===-- RISCVInstrInfoZvk.td - RISC-V 'Zvk' instructions -------*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the RISC-V instructions from the standard 'Zvk', 10// Vector Cryptography Instructions extension, version 1.0.0-rc1. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Operand and SDNode transformation definitions. 16//===----------------------------------------------------------------------===// 17 18def RnumArg_0_7 : AsmOperandClass { 19 let Name = "RnumArg_0_7"; 20 let RenderMethod = "addImmOperands"; 21 let DiagnosticType = "InvalidRnumArg_0_7"; 22} 23 24def RnumArg_1_10 : AsmOperandClass { 25 let Name = "RnumArg_1_10"; 26 let RenderMethod = "addImmOperands"; 27 let DiagnosticType = "InvalidRnumArg_1_10"; 28} 29 30def RnumArg_2_14 : AsmOperandClass { 31 let Name = "RnumArg_2_14"; 32 let RenderMethod = "addImmOperands"; 33 let DiagnosticType = "InvalidRnumArg_2_14"; 34} 35 36def rnum_0_7 : Operand<XLenVT>, ImmLeaf<XLenVT, 37 [{return (0 <= Imm && Imm <= 7);}]> { 38 let ParserMatchClass = RnumArg_0_7; 39 let DecoderMethod = "decodeUImmOperand<5>"; 40 let OperandType = "OPERAND_RVKRNUM_0_7"; 41 let OperandNamespace = "RISCVOp"; 42} 43 44def rnum_1_10 : Operand<XLenVT>, ImmLeaf<XLenVT, 45 [{return (1 <= Imm && Imm <= 10);}]> { 46 let ParserMatchClass = RnumArg_1_10; 47 let DecoderMethod = "decodeUImmOperand<5>"; 48 let OperandType = "OPERAND_RVKRNUM_1_10"; 49 let OperandNamespace = "RISCVOp"; 50} 51 52def rnum_2_14 : Operand<XLenVT>, ImmLeaf<XLenVT, 53 [{return (2 <= Imm && Imm <= 14);}]> { 54 let ParserMatchClass = RnumArg_2_14; 55 let DecoderMethod = "decodeUImmOperand<5>"; 56 let OperandType = "OPERAND_RVKRNUM_2_14"; 57 let OperandNamespace = "RISCVOp"; 58} 59 60//===----------------------------------------------------------------------===// 61// Instruction class templates 62//===----------------------------------------------------------------------===// 63 64let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 65multiclass VCLMUL_MV_V_X<string opcodestr, bits<6> funct6> { 66 def V : VALUVV<funct6, OPMVV, opcodestr # "." # "vv">, 67 Sched<[WriteVIALUV_WorstCase, ReadVIALUV_WorstCase, 68 ReadVIALUV_WorstCase, ReadVMask]>; 69 def X : VALUVX<funct6, OPMVX, opcodestr # "." # "vx">, 70 Sched<[WriteVIALUX_WorstCase, ReadVIALUV_WorstCase, 71 ReadVIALUX_WorstCase, ReadVMask]>; 72} 73 74class RVInstIVI_VROR<bits<6> funct6, dag outs, dag ins, string opcodestr, 75 string argstr> 76 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 77 bits<5> vs2; 78 bits<6> imm; 79 bits<5> vd; 80 bit vm; 81 82 let Inst{31-27} = funct6{5-1}; 83 let Inst{26} = imm{5}; 84 let Inst{25} = vm; 85 let Inst{24-20} = vs2; 86 let Inst{19-15} = imm{4-0}; 87 let Inst{14-12} = OPIVI.Value; 88 let Inst{11-7} = vd; 89 let Inst{6-0} = OPC_OP_V.Value; 90 91 let Uses = [VTYPE, VL]; 92 let RVVConstraint = VMConstraint; 93} 94 95multiclass VROR_IV_V_X_I<string opcodestr, bits<6> funct6> 96 : VALU_IV_V_X<opcodestr, funct6> { 97 def I : RVInstIVI_VROR<funct6, (outs VR:$vd), 98 (ins VR:$vs2, uimm6:$imm, VMaskOp:$vm), 99 opcodestr # ".vi", "$vd, $vs2, $imm$vm">, 100 Sched<[WriteVIALUI_WorstCase, ReadVIALUV_WorstCase, 101 ReadVMask]>; 102} 103 104// op vd, vs2, vs1 105class PALUVVNoVm<bits<6> funct6, RISCVVFormat opv, string opcodestr> 106 : VALUVVNoVm<funct6, opv, opcodestr> { 107 let Inst{6-0} = OPC_OP_P.Value; 108} 109 110// op vd, vs2, imm, vm 111class PALUVINoVm<bits<6> funct6, string opcodestr, Operand optype = simm5> 112 : VALUVINoVm<funct6, opcodestr, optype> { 113 let Inst{6-0} = OPC_OP_P.Value; 114 let Inst{14-12} = OPMVV.Value; 115} 116 117// op vd, vs2 (use vs1 as instruction encoding) 118class PALUVs2NoVm<bits<6> funct6, bits<5> vs1, RISCVVFormat opv, string opcodestr> 119 : VALUVs2NoVm<funct6, vs1, opv, opcodestr> { 120 let Inst{6-0} = OPC_OP_P.Value; 121} 122 123multiclass VAES_MV_V_S<bits<6> funct6_vv, bits<6> funct6_vs, bits<5> vs1, 124 RISCVVFormat opv, string opcodestr> { 125 def NAME # _VV : PALUVs2NoVm<funct6_vv, vs1, opv, opcodestr # ".vv">; 126 def NAME # _VS : PALUVs2NoVm<funct6_vs, vs1, opv, opcodestr # ".vs">; 127} 128 129// vaeskf1.vi and vaeskf2.vi uses different opcode and format, we need 130// to customize one for them. 131class VAESKF_MV_I<bits<6> funct6, string opcodestr, Operand optype> 132 : VALUVINoVm<funct6, opcodestr, optype> { 133 let Inst{6-0} = OPC_OP_P.Value; 134 let Inst{14-12} = OPMVV.Value; 135} 136} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 137 138//===----------------------------------------------------------------------===// 139// Instructions 140//===----------------------------------------------------------------------===// 141 142let Predicates = [HasStdExtZvbb] in { 143 defm VANDN_V : VALU_IV_V_X<"vandn", 0b000001>; 144 def VBREV8_V : VALUVs2<0b010010, 0b01000, OPMVV, "vbrev8.v">; 145 def VBREV_V : VALUVs2<0b010010, 0b01010, OPMVV, "vbrev.v">; 146 def VCLZ_V : VALUVs2<0b010010, 0b01100, OPMVV, "vclz.v">; 147 def VCPOP_V : VALUVs2<0b010010, 0b01110, OPMVV, "vcpop.v">; 148 def VCTZ_V : VALUVs2<0b010010, 0b01101, OPMVV, "vctz.v">; 149 def VREV8_V : VALUVs2<0b010010, 0b01001, OPMVV, "vrev8.v">; 150 defm VROL_V : VALU_IV_V_X<"vrol", 0b010101>; 151 defm VROR_V : VROR_IV_V_X_I<"vror", 0b010100>; 152 let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in 153 defm VWSLL_V : VSHT_IV_V_X_I<"vwsll", 0b110101>; 154} // Predicates = [HasStdExtZvbb] 155 156let Predicates = [HasStdExtZvbc] in { 157 defm VCLMUL_V : VCLMUL_MV_V_X<"vclmul", 0b001100>; 158 defm VCLMULH_V : VCLMUL_MV_V_X<"vclmulh", 0b001101>; 159} // Predicates = [HasStdExtZvbc] 160 161let Predicates = [HasStdExtZvkg], RVVConstraint = NoConstraint in { 162 def VGHSH_VV : PALUVVNoVm<0b101100, OPMVV, "vghsh.vv">; 163 def VGMUL_VV : PALUVs2NoVm<0b101000, 0b10001, OPMVV, "vgmul.vv">; 164} // Predicates = [HasStdExtZvkg] 165 166let Predicates = [HasStdExtZvknha], RVVConstraint = NoConstraint in { 167 def VSHA2CH_VV : PALUVVNoVm<0b101110, OPMVV, "vsha2ch.vv">; 168 def VSHA2CL_VV : PALUVVNoVm<0b101111, OPMVV, "vsha2cl.vv">; 169 def VSHA2MS_VV : PALUVVNoVm<0b101101, OPMVV, "vsha2ms.vv">; 170} // Predicates = [HasStdExtZvknha] 171 172let Predicates = [HasStdExtZvkned], RVVConstraint = NoConstraint in { 173 defm VAESDF : VAES_MV_V_S<0b101000, 0b101001, 0b00001, OPMVV, "vaesdf">; 174 defm VAESDM : VAES_MV_V_S<0b101000, 0b101001, 0b00000, OPMVV, "vaesdm">; 175 defm VAESEF : VAES_MV_V_S<0b101000, 0b101001, 0b00011, OPMVV, "vaesef">; 176 defm VAESEM : VAES_MV_V_S<0b101000, 0b101001, 0b00010, OPMVV, "vaesem">; 177 def VAESKF1_VI : VAESKF_MV_I<0b100010, "vaeskf1.vi", uimm5>; 178 def VAESKF2_VI : VAESKF_MV_I<0b101010, "vaeskf2.vi", uimm5>; 179 def VAESZ_VS : PALUVs2NoVm<0b101001, 0b00111, OPMVV, "vaesz.vs">; 180} // Predicates = [HasStdExtZvkned] 181 182let Predicates = [HasStdExtZvksed], RVVConstraint = NoConstraint in { 183 def VSM4K_VI : PALUVINoVm<0b100001, "vsm4k.vi", uimm5>; 184 defm VSM4R : VAES_MV_V_S<0b101000, 0b101001, 0b10000, OPMVV, "vsm4r">; 185} // Predicates = [HasStdExtZvksed] 186 187let Predicates = [HasStdExtZvksh], RVVConstraint = NoConstraint in { 188 def VSM3C_VI : PALUVINoVm<0b101011, "vsm3c.vi", uimm5>; 189 def VSM3ME_VV : PALUVVNoVm<0b100000, OPMVV, "vsm3me.vv">; 190} // Predicates = [HasStdExtZvksh] 191 192//===----------------------------------------------------------------------===// 193// Pseudo instructions 194//===----------------------------------------------------------------------===// 195 196defm PseudoVANDN : VPseudoVALU_VV_VX; 197 198multiclass VPseudoUnaryV_V { 199 foreach m = MxList in { 200 let VLMul = m.value in { 201 def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>; 202 def "_V_" # m.MX # "_MASK" : VPseudoUnaryMask<m.vrclass, m.vrclass>, 203 RISCVMaskedPseudo<MaskIdx=2>; 204 } 205 } 206} 207 208defm PseudoVBREV : VPseudoUnaryV_V; 209defm PseudoVREV8 : VPseudoUnaryV_V; 210defm PseudoVCLZ : VPseudoUnaryV_V; 211defm PseudoVCTZ : VPseudoUnaryV_V; 212defm PseudoVCPOP : VPseudoUnaryV_V; 213 214defm PseudoVROL : VPseudoVALU_VV_VX; 215defm PseudoVROR : VPseudoVALU_VV_VX_VI<uimm6>; 216 217//===----------------------------------------------------------------------===// 218// SDNode patterns 219//===----------------------------------------------------------------------===// 220 221multiclass VPatUnarySDNode_V<SDPatternOperator op, string instruction_name> { 222 foreach vti = AllIntegerVectors in { 223 let Predicates = !listconcat([HasStdExtZvbb], 224 GetVTypePredicates<vti>.Predicates) in { 225 def : Pat<(vti.Vector (op (vti.Vector vti.RegClass:$rs1))), 226 (!cast<Instruction>(instruction_name#"_V_"#vti.LMul.MX) 227 (vti.Vector (IMPLICIT_DEF)), 228 vti.RegClass:$rs1, 229 vti.AVL, vti.Log2SEW, TA_MA)>; 230 } 231 } 232} 233 234// Helpers for detecting splats since we preprocess splat_vector to vmv.v.x 235// This should match the logic in RISCVDAGToDAGISel::selectVSplat 236def riscv_splat_vector : PatFrag<(ops node:$rs1), 237 (riscv_vmv_v_x_vl undef, node:$rs1, srcvalue)>; 238def riscv_vnot : PatFrag<(ops node:$rs1), (xor node:$rs1, 239 (riscv_splat_vector -1))>; 240 241foreach vti = AllIntegerVectors in { 242 let Predicates = !listconcat([HasStdExtZvbb], 243 GetVTypePredicates<vti>.Predicates) in { 244 def : Pat<(vti.Vector (and (riscv_vnot vti.RegClass:$rs1), 245 vti.RegClass:$rs2)), 246 (!cast<Instruction>("PseudoVANDN_VV_"#vti.LMul.MX) 247 (vti.Vector (IMPLICIT_DEF)), 248 vti.RegClass:$rs2, 249 vti.RegClass:$rs1, 250 vti.AVL, vti.Log2SEW, TA_MA)>; 251 def : Pat<(vti.Vector (and (riscv_splat_vector 252 (not vti.ScalarRegClass:$rs1)), 253 vti.RegClass:$rs2)), 254 (!cast<Instruction>("PseudoVANDN_VX_"#vti.LMul.MX) 255 (vti.Vector (IMPLICIT_DEF)), 256 vti.RegClass:$rs2, 257 vti.ScalarRegClass:$rs1, 258 vti.AVL, vti.Log2SEW, TA_MA)>; 259 } 260} 261 262defm : VPatUnarySDNode_V<bitreverse, "PseudoVBREV">; 263defm : VPatUnarySDNode_V<bswap, "PseudoVREV8">; 264defm : VPatUnarySDNode_V<ctlz, "PseudoVCLZ">; 265defm : VPatUnarySDNode_V<cttz, "PseudoVCTZ">; 266defm : VPatUnarySDNode_V<ctpop, "PseudoVCPOP">; 267 268defm : VPatBinarySDNode_VV_VX<rotl, "PseudoVROL">; 269 270def NegImm64 : SDNodeXForm<imm, [{ 271 return CurDAG->getTargetConstant(0x3f & (64 - N->getZExtValue()), SDLoc(N), 272 N->getValueType(0)); 273}]>; 274 275// Although there is no vrol.vi, an immediate rotate left can be achieved by 276// negating the immediate in vror.vi 277foreach vti = AllIntegerVectors in { 278 let Predicates = !listconcat([HasStdExtZvbb], 279 GetVTypePredicates<vti>.Predicates) in { 280 def : Pat<(vti.Vector (rotl vti.RegClass:$rs2, 281 (vti.Vector (SplatPat_uimm6 uimm6:$rs1)))), 282 (!cast<Instruction>("PseudoVROR_VI_"#vti.LMul.MX) 283 (vti.Vector (IMPLICIT_DEF)), 284 vti.RegClass:$rs2, 285 (NegImm64 uimm6:$rs1), 286 vti.AVL, vti.Log2SEW, TA_MA)>; 287 } 288} 289defm : VPatBinarySDNode_VV_VX_VI<rotr, "PseudoVROR", uimm6>; 290 291//===----------------------------------------------------------------------===// 292// VL patterns 293//===----------------------------------------------------------------------===// 294 295multiclass VPatUnaryVL_V<SDPatternOperator op, string instruction_name> { 296 foreach vti = AllIntegerVectors in { 297 let Predicates = !listconcat([HasStdExtZvbb], 298 GetVTypePredicates<vti>.Predicates) in { 299 def : Pat<(vti.Vector (op (vti.Vector vti.RegClass:$rs1), 300 (vti.Vector vti.RegClass:$merge), 301 (vti.Mask V0), 302 VLOpFrag)), 303 (!cast<Instruction>(instruction_name#"_V_"#vti.LMul.MX#"_MASK") 304 vti.RegClass:$merge, 305 vti.RegClass:$rs1, 306 (vti.Mask V0), 307 GPR:$vl, 308 vti.Log2SEW, 309 TAIL_AGNOSTIC)>; 310 } 311 } 312} 313 314foreach vti = AllIntegerVectors in { 315 let Predicates = !listconcat([HasStdExtZvbb], 316 GetVTypePredicates<vti>.Predicates) in { 317 def : Pat<(vti.Vector (riscv_and_vl (riscv_xor_vl 318 (vti.Vector vti.RegClass:$rs1), 319 (riscv_splat_vector -1), 320 (vti.Vector vti.RegClass:$merge), 321 (vti.Mask V0), 322 VLOpFrag), 323 (vti.Vector vti.RegClass:$rs2), 324 (vti.Vector vti.RegClass:$merge), 325 (vti.Mask V0), 326 VLOpFrag)), 327 (!cast<Instruction>("PseudoVANDN_VV_"#vti.LMul.MX#"_MASK") 328 vti.RegClass:$merge, 329 vti.RegClass:$rs2, 330 vti.RegClass:$rs1, 331 (vti.Mask V0), 332 GPR:$vl, 333 vti.Log2SEW, 334 TAIL_AGNOSTIC)>; 335 336 def : Pat<(vti.Vector (riscv_and_vl (riscv_splat_vector 337 (not vti.ScalarRegClass:$rs1)), 338 (vti.Vector vti.RegClass:$rs2), 339 (vti.Vector vti.RegClass:$merge), 340 (vti.Mask V0), 341 VLOpFrag)), 342 (!cast<Instruction>("PseudoVANDN_VX_"#vti.LMul.MX#"_MASK") 343 vti.RegClass:$merge, 344 vti.RegClass:$rs2, 345 vti.ScalarRegClass:$rs1, 346 (vti.Mask V0), 347 GPR:$vl, 348 vti.Log2SEW, 349 TAIL_AGNOSTIC)>; 350 } 351} 352 353defm : VPatUnaryVL_V<riscv_bitreverse_vl, "PseudoVBREV">; 354defm : VPatUnaryVL_V<riscv_bswap_vl, "PseudoVREV8">; 355defm : VPatUnaryVL_V<riscv_ctlz_vl, "PseudoVCLZ">; 356defm : VPatUnaryVL_V<riscv_cttz_vl, "PseudoVCTZ">; 357defm : VPatUnaryVL_V<riscv_ctpop_vl, "PseudoVCPOP">; 358