1//===-- VOP2Instructions.td - Vector Instruction Defintions ---------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10//===----------------------------------------------------------------------===// 11// VOP2 Classes 12//===----------------------------------------------------------------------===// 13 14class VOP2e <bits<6> op, VOPProfile P> : Enc32 { 15 bits<8> vdst; 16 bits<9> src0; 17 bits<8> src1; 18 19 let Inst{8-0} = !if(P.HasSrc0, src0, 0); 20 let Inst{16-9} = !if(P.HasSrc1, src1, 0); 21 let Inst{24-17} = !if(P.EmitDst, vdst, 0); 22 let Inst{30-25} = op; 23 let Inst{31} = 0x0; //encoding 24} 25 26class VOP2_MADKe <bits<6> op, VOPProfile P> : Enc64 { 27 bits<8> vdst; 28 bits<9> src0; 29 bits<8> src1; 30 bits<32> imm; 31 32 let Inst{8-0} = !if(P.HasSrc0, src0, 0); 33 let Inst{16-9} = !if(P.HasSrc1, src1, 0); 34 let Inst{24-17} = !if(P.EmitDst, vdst, 0); 35 let Inst{30-25} = op; 36 let Inst{31} = 0x0; // encoding 37 let Inst{63-32} = imm; 38} 39 40class VOP2_SDWAe <bits<6> op, VOPProfile P> : VOP_SDWAe <P> { 41 bits<8> vdst; 42 bits<8> src1; 43 44 let Inst{8-0} = 0xf9; // sdwa 45 let Inst{16-9} = !if(P.HasSrc1, src1{7-0}, 0); 46 let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0); 47 let Inst{30-25} = op; 48 let Inst{31} = 0x0; // encoding 49} 50 51class VOP2_SDWA9Ae <bits<6> op, VOPProfile P> : VOP_SDWA9Ae <P> { 52 bits<8> vdst; 53 bits<9> src1; 54 55 let Inst{8-0} = 0xf9; // sdwa 56 let Inst{16-9} = !if(P.HasSrc1, src1{7-0}, 0); 57 let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0); 58 let Inst{30-25} = op; 59 let Inst{31} = 0x0; // encoding 60 let Inst{63} = !if(P.HasSrc1, src1{8}, 0); // src1_sgpr 61} 62 63class VOP2_Pseudo <string opName, VOPProfile P, list<dag> pattern=[], string suffix = "_e32"> : 64 VOP_Pseudo <opName, suffix, P, P.Outs32, P.Ins32, "", pattern> { 65 66 let AsmOperands = P.Asm32; 67 68 let Size = 4; 69 let mayLoad = 0; 70 let mayStore = 0; 71 let hasSideEffects = 0; 72 let SubtargetPredicate = isGCN; 73 74 let VOP2 = 1; 75 let VALU = 1; 76 let Uses = [EXEC]; 77 78 let AsmVariantName = AMDGPUAsmVariants.Default; 79} 80 81class VOP2_Real <VOP2_Pseudo ps, int EncodingFamily> : 82 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 83 SIMCInstr <ps.PseudoInstr, EncodingFamily> { 84 85 let isPseudo = 0; 86 let isCodeGenOnly = 0; 87 88 let Constraints = ps.Constraints; 89 let DisableEncoding = ps.DisableEncoding; 90 91 // copy relevant pseudo op flags 92 let SubtargetPredicate = ps.SubtargetPredicate; 93 let AsmMatchConverter = ps.AsmMatchConverter; 94 let AsmVariantName = ps.AsmVariantName; 95 let Constraints = ps.Constraints; 96 let DisableEncoding = ps.DisableEncoding; 97 let TSFlags = ps.TSFlags; 98 let UseNamedOperandTable = ps.UseNamedOperandTable; 99 let Uses = ps.Uses; 100 let Defs = ps.Defs; 101} 102 103class VOP2_SDWA_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> : 104 VOP_SDWA_Pseudo <OpName, P, pattern> { 105 let AsmMatchConverter = "cvtSdwaVOP2"; 106} 107 108class VOP2_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> : 109 VOP_DPP_Pseudo <OpName, P, pattern> { 110} 111 112 113class getVOP2Pat64 <SDPatternOperator node, VOPProfile P> : LetDummies { 114 list<dag> ret = !if(P.HasModifiers, 115 [(set P.DstVT:$vdst, 116 (node (P.Src0VT 117 !if(P.HasOMod, 118 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod), 119 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp))), 120 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 121 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]); 122} 123 124multiclass VOP2Inst_e32<string opName, 125 VOPProfile P, 126 SDPatternOperator node = null_frag, 127 string revOp = opName, 128 bit GFX9Renamed = 0> { 129 let renamedInGFX9 = GFX9Renamed in { 130 def _e32 : VOP2_Pseudo <opName, P, VOPPatOrNull<node,P>.ret>, 131 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>; 132 } // End renamedInGFX9 = GFX9Renamed 133} 134 135multiclass VOP2Inst_e64<string opName, 136 VOPProfile P, 137 SDPatternOperator node = null_frag, 138 string revOp = opName, 139 bit GFX9Renamed = 0> { 140 let renamedInGFX9 = GFX9Renamed in { 141 def _e64 : VOP3_Pseudo <opName, P, getVOP2Pat64<node, P>.ret>, 142 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>; 143 } // End renamedInGFX9 = GFX9Renamed 144} 145 146multiclass VOP2Inst_sdwa<string opName, 147 VOPProfile P, 148 SDPatternOperator node = null_frag, 149 string revOp = opName, 150 bit GFX9Renamed = 0> { 151 let renamedInGFX9 = GFX9Renamed in { 152 def _sdwa : VOP2_SDWA_Pseudo <opName, P>; 153 } // End renamedInGFX9 = GFX9Renamed 154} 155 156multiclass VOP2Inst<string opName, 157 VOPProfile P, 158 SDPatternOperator node = null_frag, 159 string revOp = opName, 160 bit GFX9Renamed = 0> : 161 VOP2Inst_e32<opName, P, node, revOp, GFX9Renamed>, 162 VOP2Inst_e64<opName, P, node, revOp, GFX9Renamed>, 163 VOP2Inst_sdwa<opName, P, node, revOp, GFX9Renamed> { 164 let renamedInGFX9 = GFX9Renamed in { 165 foreach _ = BoolToList<P.HasExtDPP>.ret in 166 def _dpp : VOP2_DPP_Pseudo <opName, P>; 167 } 168} 169 170multiclass VOP2bInst <string opName, 171 VOPProfile P, 172 SDPatternOperator node = null_frag, 173 string revOp = opName, 174 bit GFX9Renamed = 0, 175 bit useSGPRInput = !eq(P.NumSrcArgs, 3)> { 176 let renamedInGFX9 = GFX9Renamed in { 177 let SchedRW = [Write32Bit, WriteSALU] in { 178 let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in { 179 def _e32 : VOP2_Pseudo <opName, P, VOPPatOrNull<node,P>.ret>, 180 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>; 181 182 def _sdwa : VOP2_SDWA_Pseudo <opName, P> { 183 let AsmMatchConverter = "cvtSdwaVOP2b"; 184 } 185 foreach _ = BoolToList<P.HasExtDPP>.ret in 186 def _dpp : VOP2_DPP_Pseudo <opName, P>; 187 } 188 189 def _e64 : VOP3_Pseudo <opName, P, getVOP2Pat64<node, P>.ret>, 190 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>; 191 } 192 } 193} 194 195multiclass VOP2eInst <string opName, 196 VOPProfile P, 197 SDPatternOperator node = null_frag, 198 string revOp = opName, 199 bit useSGPRInput = !eq(P.NumSrcArgs, 3)> { 200 201 let SchedRW = [Write32Bit] in { 202 let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]) in { 203 def _e32 : VOP2_Pseudo <opName, P>, 204 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>; 205 206 def _sdwa : VOP2_SDWA_Pseudo <opName, P> { 207 let AsmMatchConverter = "cvtSdwaVOP2b"; 208 } 209 210 foreach _ = BoolToList<P.HasExtDPP>.ret in 211 def _dpp : VOP2_DPP_Pseudo <opName, P>; 212 } 213 214 def _e64 : VOP3_Pseudo <opName, P, getVOP2Pat64<node, P>.ret>, 215 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>; 216 } 217} 218 219class VOP_MADAK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> { 220 field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm); 221 field dag Ins32 = (ins VCSrc_f32:$src0, VGPR_32:$src1, ImmOpType:$imm); 222 field bit HasExt = 0; 223 224 // Hack to stop printing _e64 225 let DstRC = RegisterOperand<VGPR_32>; 226 field string Asm32 = " $vdst, $src0, $src1, $imm"; 227} 228 229def VOP_MADAK_F16 : VOP_MADAK <f16>; 230def VOP_MADAK_F32 : VOP_MADAK <f32>; 231 232class VOP_MADMK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> { 233 field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm); 234 field dag Ins32 = (ins VCSrc_f32:$src0, ImmOpType:$imm, VGPR_32:$src1); 235 field bit HasExt = 0; 236 237 // Hack to stop printing _e64 238 let DstRC = RegisterOperand<VGPR_32>; 239 field string Asm32 = " $vdst, $src0, $imm, $src1"; 240} 241 242def VOP_MADMK_F16 : VOP_MADMK <f16>; 243def VOP_MADMK_F32 : VOP_MADMK <f32>; 244 245// FIXME: Remove src2_modifiers. It isn't used, so is wasting memory 246// and processing time but it makes it easier to convert to mad. 247class VOP_MAC <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> { 248 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2); 249 let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3, 250 0, HasModifiers, HasOMod, Src0Mod, Src1Mod, Src2Mod>.ret; 251 let InsDPP = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0, 252 Src1ModDPP:$src1_modifiers, Src1DPP:$src1, 253 VGPR_32:$src2, // stub argument 254 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 255 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl); 256 257 let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0, 258 Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1, 259 VGPR_32:$src2, // stub argument 260 clampmod:$clamp, omod:$omod, 261 dst_sel:$dst_sel, dst_unused:$dst_unused, 262 src0_sel:$src0_sel, src1_sel:$src1_sel); 263 let Asm32 = getAsm32<1, 2, vt>.ret; 264 let Asm64 = getAsm64<1, 2, 0, HasModifiers, HasOMod, vt>.ret; 265 let AsmDPP = getAsmDPP<1, 2, HasModifiers, vt>.ret; 266 let AsmSDWA = getAsmSDWA<1, 2, vt>.ret; 267 let AsmSDWA9 = getAsmSDWA9<1, 1, 2, vt>.ret; 268 let HasSrc2 = 0; 269 let HasSrc2Mods = 0; 270 271 let HasExt = 1; 272 let HasExtDPP = 1; 273 let HasExtSDWA = 1; 274 let HasExtSDWA9 = 0; 275} 276 277def VOP_MAC_F16 : VOP_MAC <f16>; 278def VOP_MAC_F32 : VOP_MAC <f32>; 279 280// Write out to vcc or arbitrary SGPR. 281def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> { 282 let Asm32 = "$vdst, vcc, $src0, $src1"; 283 let Asm64 = "$vdst, $sdst, $src0, $src1"; 284 let AsmSDWA = "$vdst, vcc, $src0_modifiers, $src1_modifiers$clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 285 let AsmSDWA9 = "$vdst, vcc, $src0_modifiers, $src1_modifiers$clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 286 let AsmDPP = "$vdst, vcc, $src0, $src1 $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 287 let Outs32 = (outs DstRC:$vdst); 288 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 289} 290 291// Write out to vcc or arbitrary SGPR and read in from vcc or 292// arbitrary SGPR. 293def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { 294 // We use VCSrc_b32 to exclude literal constants, even though the 295 // encoding normally allows them since the implicit VCC use means 296 // using one would always violate the constant bus 297 // restriction. SGPRs are still allowed because it should 298 // technically be possible to use VCC again as src0. 299 let Src0RC32 = VCSrc_b32; 300 let Asm32 = "$vdst, vcc, $src0, $src1, vcc"; 301 let Asm64 = "$vdst, $sdst, $src0, $src1, $src2"; 302 let AsmSDWA = "$vdst, vcc, $src0_modifiers, $src1_modifiers, vcc $clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 303 let AsmSDWA9 = "$vdst, vcc, $src0_modifiers, $src1_modifiers, vcc $clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 304 let AsmDPP = "$vdst, vcc, $src0, $src1, vcc $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 305 let Outs32 = (outs DstRC:$vdst); 306 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 307 308 // Suppress src2 implied by type since the 32-bit encoding uses an 309 // implicit VCC use. 310 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); 311 312 let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0, 313 Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1, 314 clampmod:$clamp, 315 dst_sel:$dst_sel, dst_unused:$dst_unused, 316 src0_sel:$src0_sel, src1_sel:$src1_sel); 317 318 let InsDPP = (ins DstRCDPP:$old, 319 Src0DPP:$src0, 320 Src1DPP:$src1, 321 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 322 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl); 323 let HasExt = 1; 324 let HasExtDPP = 1; 325 let HasExtSDWA = 1; 326 let HasExtSDWA9 = 1; 327} 328 329// Read in from vcc or arbitrary SGPR 330def VOP2e_I32_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { 331 let Src0RC32 = VCSrc_b32; // See comment in def VOP2b_I32_I1_I32_I32_I1 above. 332 let Asm32 = "$vdst, $src0, $src1, vcc"; 333 let Asm64 = "$vdst, $src0, $src1, $src2"; 334 let AsmSDWA = "$vdst, $src0_modifiers, $src1_modifiers, vcc $clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 335 let AsmSDWA9 = "$vdst, $src0_modifiers, $src1_modifiers, vcc $clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 336 let AsmDPP = "$vdst, $src0, $src1, vcc $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 337 338 let Outs32 = (outs DstRC:$vdst); 339 let Outs64 = (outs DstRC:$vdst); 340 341 // Suppress src2 implied by type since the 32-bit encoding uses an 342 // implicit VCC use. 343 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); 344 345 let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0, 346 Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1, 347 clampmod:$clamp, 348 dst_sel:$dst_sel, dst_unused:$dst_unused, 349 src0_sel:$src0_sel, src1_sel:$src1_sel); 350 351 let InsDPP = (ins DstRCDPP:$old, 352 Src0DPP:$src0, 353 Src1DPP:$src1, 354 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 355 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl); 356 let HasExt = 1; 357 let HasExtDPP = 1; 358 let HasExtSDWA = 1; 359 let HasExtSDWA9 = 1; 360} 361 362def VOP_READLANE : VOPProfile<[i32, i32, i32]> { 363 let Outs32 = (outs SReg_32:$vdst); 364 let Outs64 = Outs32; 365 let Ins32 = (ins VGPR_32:$src0, SCSrc_b32:$src1); 366 let Ins64 = Ins32; 367 let Asm32 = " $vdst, $src0, $src1"; 368 let Asm64 = Asm32; 369 370 let HasExt = 0; 371 let HasExtDPP = 0; 372 let HasExtSDWA = 0; 373 let HasExtSDWA9 = 0; 374} 375 376def VOP_WRITELANE : VOPProfile<[i32, i32, i32, i32]> { 377 let Outs32 = (outs VGPR_32:$vdst); 378 let Outs64 = Outs32; 379 let Ins32 = (ins SCSrc_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in); 380 let Ins64 = Ins32; 381 let Asm32 = " $vdst, $src0, $src1"; 382 let Asm64 = Asm32; 383 let HasSrc2 = 0; 384 let HasSrc2Mods = 0; 385 386 let HasExt = 0; 387 let HasExtDPP = 0; 388 let HasExtSDWA = 0; 389 let HasExtSDWA9 = 0; 390} 391 392//===----------------------------------------------------------------------===// 393// VOP2 Instructions 394//===----------------------------------------------------------------------===// 395 396let SubtargetPredicate = isGCN, Predicates = [isGCN] in { 397 398defm V_CNDMASK_B32 : VOP2eInst <"v_cndmask_b32", VOP2e_I32_I32_I32_I1>; 399def V_MADMK_F32 : VOP2_Pseudo <"v_madmk_f32", VOP_MADMK_F32, []>; 400 401let isCommutable = 1 in { 402defm V_ADD_F32 : VOP2Inst <"v_add_f32", VOP_F32_F32_F32, fadd>; 403defm V_SUB_F32 : VOP2Inst <"v_sub_f32", VOP_F32_F32_F32, fsub>; 404defm V_SUBREV_F32 : VOP2Inst <"v_subrev_f32", VOP_F32_F32_F32, null_frag, "v_sub_f32">; 405defm V_MUL_LEGACY_F32 : VOP2Inst <"v_mul_legacy_f32", VOP_F32_F32_F32, AMDGPUfmul_legacy>; 406defm V_MUL_F32 : VOP2Inst <"v_mul_f32", VOP_F32_F32_F32, fmul>; 407defm V_MUL_I32_I24 : VOP2Inst <"v_mul_i32_i24", VOP_PAT_GEN<VOP_I32_I32_I32, 2>, AMDGPUmul_i24>; 408defm V_MUL_HI_I32_I24 : VOP2Inst <"v_mul_hi_i32_i24", VOP_PAT_GEN<VOP_I32_I32_I32, 2>, AMDGPUmulhi_i24>; 409defm V_MUL_U32_U24 : VOP2Inst <"v_mul_u32_u24", VOP_PAT_GEN<VOP_I32_I32_I32, 2>, AMDGPUmul_u24>; 410defm V_MUL_HI_U32_U24 : VOP2Inst <"v_mul_hi_u32_u24", VOP_PAT_GEN<VOP_I32_I32_I32, 2>, AMDGPUmulhi_u24>; 411defm V_MIN_F32 : VOP2Inst <"v_min_f32", VOP_F32_F32_F32, fminnum_like>; 412defm V_MAX_F32 : VOP2Inst <"v_max_f32", VOP_F32_F32_F32, fmaxnum_like>; 413defm V_MIN_I32 : VOP2Inst <"v_min_i32", VOP_PAT_GEN<VOP_I32_I32_I32>, smin>; 414defm V_MAX_I32 : VOP2Inst <"v_max_i32", VOP_PAT_GEN<VOP_I32_I32_I32>, smax>; 415defm V_MIN_U32 : VOP2Inst <"v_min_u32", VOP_PAT_GEN<VOP_I32_I32_I32>, umin>; 416defm V_MAX_U32 : VOP2Inst <"v_max_u32", VOP_PAT_GEN<VOP_I32_I32_I32>, umax>; 417defm V_LSHRREV_B32 : VOP2Inst <"v_lshrrev_b32", VOP_I32_I32_I32, null_frag, "v_lshr_b32">; 418defm V_ASHRREV_I32 : VOP2Inst <"v_ashrrev_i32", VOP_I32_I32_I32, null_frag, "v_ashr_i32">; 419defm V_LSHLREV_B32 : VOP2Inst <"v_lshlrev_b32", VOP_I32_I32_I32, null_frag, "v_lshl_b32">; 420defm V_AND_B32 : VOP2Inst <"v_and_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, and>; 421defm V_OR_B32 : VOP2Inst <"v_or_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, or>; 422defm V_XOR_B32 : VOP2Inst <"v_xor_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, xor>; 423 424let Constraints = "$vdst = $src2", DisableEncoding="$src2", 425 isConvertibleToThreeAddress = 1 in { 426defm V_MAC_F32 : VOP2Inst <"v_mac_f32", VOP_MAC_F32>; 427} 428 429def V_MADAK_F32 : VOP2_Pseudo <"v_madak_f32", VOP_MADAK_F32, []>; 430 431// No patterns so that the scalar instructions are always selected. 432// The scalar versions will be replaced with vector when needed later. 433 434// V_ADD_I32, V_SUB_I32, and V_SUBREV_I32 where renamed to *_U32 in VI, 435// but the VI instructions behave the same as the SI versions. 436defm V_ADD_I32 : VOP2bInst <"v_add_i32", VOP2b_I32_I1_I32_I32, null_frag, "v_add_i32", 1>; 437defm V_SUB_I32 : VOP2bInst <"v_sub_i32", VOP2b_I32_I1_I32_I32, null_frag, "v_sub_i32", 1>; 438defm V_SUBREV_I32 : VOP2bInst <"v_subrev_i32", VOP2b_I32_I1_I32_I32, null_frag, "v_sub_i32", 1>; 439defm V_ADDC_U32 : VOP2bInst <"v_addc_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_addc_u32", 1>; 440defm V_SUBB_U32 : VOP2bInst <"v_subb_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_subb_u32", 1>; 441defm V_SUBBREV_U32 : VOP2bInst <"v_subbrev_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_subb_u32", 1>; 442 443 444let SubtargetPredicate = HasAddNoCarryInsts in { 445defm V_ADD_U32 : VOP2Inst <"v_add_u32", VOP_I32_I32_I32, null_frag, "v_add_u32", 1>; 446defm V_SUB_U32 : VOP2Inst <"v_sub_u32", VOP_I32_I32_I32, null_frag, "v_sub_u32", 1>; 447defm V_SUBREV_U32 : VOP2Inst <"v_subrev_u32", VOP_I32_I32_I32, null_frag, "v_sub_u32", 1>; 448} 449 450} // End isCommutable = 1 451 452// These are special and do not read the exec mask. 453let isConvergent = 1, Uses = []<Register> in { 454def V_READLANE_B32 : VOP2_Pseudo<"v_readlane_b32", VOP_READLANE, 455 [(set i32:$vdst, (int_amdgcn_readlane i32:$src0, i32:$src1))]>; 456 457let Constraints = "$vdst = $vdst_in", DisableEncoding="$vdst_in" in { 458def V_WRITELANE_B32 : VOP2_Pseudo<"v_writelane_b32", VOP_WRITELANE, 459 [(set i32:$vdst, (int_amdgcn_writelane i32:$src0, i32:$src1, i32:$vdst_in))]>; 460} // End $vdst = $vdst_in, DisableEncoding $vdst_in 461} // End isConvergent = 1 462 463defm V_BFM_B32 : VOP2Inst <"v_bfm_b32", VOP_NO_EXT<VOP_I32_I32_I32>>; 464defm V_BCNT_U32_B32 : VOP2Inst <"v_bcnt_u32_b32", VOP_NO_EXT<VOP_I32_I32_I32>>; 465defm V_MBCNT_LO_U32_B32 : VOP2Inst <"v_mbcnt_lo_u32_b32", VOP_NO_EXT<VOP_I32_I32_I32>, int_amdgcn_mbcnt_lo>; 466defm V_MBCNT_HI_U32_B32 : VOP2Inst <"v_mbcnt_hi_u32_b32", VOP_NO_EXT<VOP_I32_I32_I32>, int_amdgcn_mbcnt_hi>; 467defm V_LDEXP_F32 : VOP2Inst <"v_ldexp_f32", VOP_NO_EXT<VOP_F32_F32_I32>, AMDGPUldexp>; 468defm V_CVT_PKACCUM_U8_F32 : VOP2Inst <"v_cvt_pkaccum_u8_f32", VOP_NO_EXT<VOP_I32_F32_I32>>; // TODO: set "Uses = dst" 469defm V_CVT_PKNORM_I16_F32 : VOP2Inst <"v_cvt_pknorm_i16_f32", VOP_NO_EXT<VOP_V2I16_F32_F32>, AMDGPUpknorm_i16_f32>; 470defm V_CVT_PKNORM_U16_F32 : VOP2Inst <"v_cvt_pknorm_u16_f32", VOP_NO_EXT<VOP_V2I16_F32_F32>, AMDGPUpknorm_u16_f32>; 471defm V_CVT_PKRTZ_F16_F32 : VOP2Inst <"v_cvt_pkrtz_f16_f32", VOP_NO_EXT<VOP_V2F16_F32_F32>, AMDGPUpkrtz_f16_f32>; 472defm V_CVT_PK_U16_U32 : VOP2Inst <"v_cvt_pk_u16_u32", VOP_NO_EXT<VOP_V2I16_I32_I32>, AMDGPUpk_u16_u32>; 473defm V_CVT_PK_I16_I32 : VOP2Inst <"v_cvt_pk_i16_i32", VOP_NO_EXT<VOP_V2I16_I32_I32>, AMDGPUpk_i16_i32>; 474 475} // End SubtargetPredicate = isGCN, Predicates = [isGCN] 476 477def : GCNPat< 478 (AMDGPUadde i32:$src0, i32:$src1, i1:$src2), 479 (V_ADDC_U32_e64 $src0, $src1, $src2) 480>; 481 482def : GCNPat< 483 (AMDGPUsube i32:$src0, i32:$src1, i1:$src2), 484 (V_SUBB_U32_e64 $src0, $src1, $src2) 485>; 486 487// These instructions only exist on SI and CI 488let SubtargetPredicate = isSICI, Predicates = [isSICI] in { 489 490defm V_MIN_LEGACY_F32 : VOP2Inst <"v_min_legacy_f32", VOP_F32_F32_F32, AMDGPUfmin_legacy>; 491defm V_MAX_LEGACY_F32 : VOP2Inst <"v_max_legacy_f32", VOP_F32_F32_F32, AMDGPUfmax_legacy>; 492 493let isCommutable = 1 in { 494defm V_MAC_LEGACY_F32 : VOP2Inst <"v_mac_legacy_f32", VOP_F32_F32_F32>; 495defm V_LSHR_B32 : VOP2Inst <"v_lshr_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, srl>; 496defm V_ASHR_I32 : VOP2Inst <"v_ashr_i32", VOP_PAT_GEN<VOP_I32_I32_I32>, sra>; 497defm V_LSHL_B32 : VOP2Inst <"v_lshl_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, shl>; 498} // End isCommutable = 1 499 500} // End let SubtargetPredicate = SICI, Predicates = [isSICI] 501 502class DivergentBinOp<SDPatternOperator Op, VOP_Pseudo Inst> : 503 GCNPat< 504 (getDivergentFrag<Op>.ret Inst.Pfl.Src0VT:$src0, Inst.Pfl.Src1VT:$src1), 505 !if(!cast<Commutable_REV>(Inst).IsOrig, 506 (Inst $src0, $src1), 507 (Inst $src1, $src0) 508 ) 509 >; 510 511let AddedComplexity = 1 in { 512 def : DivergentBinOp<srl, V_LSHRREV_B32_e64>; 513 def : DivergentBinOp<sra, V_ASHRREV_I32_e64>; 514 def : DivergentBinOp<shl, V_LSHLREV_B32_e64>; 515} 516 517let SubtargetPredicate = HasAddNoCarryInsts in { 518 def : DivergentBinOp<add, V_ADD_U32_e32>; 519 def : DivergentBinOp<sub, V_SUB_U32_e32>; 520 def : DivergentBinOp<sub, V_SUBREV_U32_e32>; 521} 522 523 524def : DivergentBinOp<add, V_ADD_I32_e32>; 525 526def : DivergentBinOp<add, V_ADD_I32_e64>; 527def : DivergentBinOp<sub, V_SUB_I32_e32>; 528 529def : DivergentBinOp<sub, V_SUBREV_I32_e32>; 530 531def : DivergentBinOp<srl, V_LSHRREV_B32_e32>; 532def : DivergentBinOp<sra, V_ASHRREV_I32_e32>; 533def : DivergentBinOp<shl, V_LSHLREV_B32_e32>; 534def : DivergentBinOp<adde, V_ADDC_U32_e32>; 535def : DivergentBinOp<sube, V_SUBB_U32_e32>; 536 537class divergent_i64_BinOp <SDPatternOperator Op, Instruction Inst> : 538 GCNPat< 539 (getDivergentFrag<Op>.ret i64:$src0, i64:$src1), 540 (REG_SEQUENCE VReg_64, 541 (Inst 542 (i32 (EXTRACT_SUBREG $src0, sub0)), 543 (i32 (EXTRACT_SUBREG $src1, sub0)) 544 ), sub0, 545 (Inst 546 (i32 (EXTRACT_SUBREG $src0, sub1)), 547 (i32 (EXTRACT_SUBREG $src1, sub1)) 548 ), sub1 549 ) 550 >; 551 552def : divergent_i64_BinOp <and, V_AND_B32_e32>; 553def : divergent_i64_BinOp <or, V_OR_B32_e32>; 554def : divergent_i64_BinOp <xor, V_XOR_B32_e32>; 555 556let SubtargetPredicate = Has16BitInsts in { 557 558let FPDPRounding = 1 in { 559def V_MADMK_F16 : VOP2_Pseudo <"v_madmk_f16", VOP_MADMK_F16, [], "">; 560defm V_LDEXP_F16 : VOP2Inst <"v_ldexp_f16", VOP_F16_F16_I32, AMDGPUldexp>; 561} // End FPDPRounding = 1 562 563defm V_LSHLREV_B16 : VOP2Inst <"v_lshlrev_b16", VOP_I16_I16_I16>; 564defm V_LSHRREV_B16 : VOP2Inst <"v_lshrrev_b16", VOP_I16_I16_I16>; 565defm V_ASHRREV_I16 : VOP2Inst <"v_ashrrev_i16", VOP_I16_I16_I16>; 566 567let isCommutable = 1 in { 568let FPDPRounding = 1 in { 569defm V_ADD_F16 : VOP2Inst <"v_add_f16", VOP_F16_F16_F16, fadd>; 570defm V_SUB_F16 : VOP2Inst <"v_sub_f16", VOP_F16_F16_F16, fsub>; 571defm V_SUBREV_F16 : VOP2Inst <"v_subrev_f16", VOP_F16_F16_F16, null_frag, "v_sub_f16">; 572defm V_MUL_F16 : VOP2Inst <"v_mul_f16", VOP_F16_F16_F16, fmul>; 573def V_MADAK_F16 : VOP2_Pseudo <"v_madak_f16", VOP_MADAK_F16, [], "">; 574} // End FPDPRounding = 1 575defm V_ADD_U16 : VOP2Inst <"v_add_u16", VOP_I16_I16_I16>; 576defm V_SUB_U16 : VOP2Inst <"v_sub_u16" , VOP_I16_I16_I16>; 577defm V_SUBREV_U16 : VOP2Inst <"v_subrev_u16", VOP_I16_I16_I16, null_frag, "v_sub_u16">; 578defm V_MUL_LO_U16 : VOP2Inst <"v_mul_lo_u16", VOP_I16_I16_I16>; 579defm V_MAX_F16 : VOP2Inst <"v_max_f16", VOP_F16_F16_F16, fmaxnum_like>; 580defm V_MIN_F16 : VOP2Inst <"v_min_f16", VOP_F16_F16_F16, fminnum_like>; 581defm V_MAX_U16 : VOP2Inst <"v_max_u16", VOP_I16_I16_I16>; 582defm V_MAX_I16 : VOP2Inst <"v_max_i16", VOP_I16_I16_I16>; 583defm V_MIN_U16 : VOP2Inst <"v_min_u16", VOP_I16_I16_I16>; 584defm V_MIN_I16 : VOP2Inst <"v_min_i16", VOP_I16_I16_I16>; 585 586let Constraints = "$vdst = $src2", DisableEncoding="$src2", 587 isConvertibleToThreeAddress = 1 in { 588defm V_MAC_F16 : VOP2Inst <"v_mac_f16", VOP_MAC_F16>; 589} 590} // End isCommutable = 1 591 592} // End SubtargetPredicate = Has16BitInsts 593 594let SubtargetPredicate = HasDLInsts in { 595 596defm V_XNOR_B32 : VOP2Inst <"v_xnor_b32", VOP_I32_I32_I32>; 597 598let Constraints = "$vdst = $src2", 599 DisableEncoding="$src2", 600 isConvertibleToThreeAddress = 1, 601 isCommutable = 1 in { 602defm V_FMAC_F32 : VOP2Inst <"v_fmac_f32", VOP_MAC_F32>; 603} 604 605} // End SubtargetPredicate = HasDLInsts 606 607// Note: 16-bit instructions produce a 0 result in the high 16-bits. 608multiclass Arithmetic_i16_Pats <SDPatternOperator op, Instruction inst> { 609 610def : GCNPat< 611 (op i16:$src0, i16:$src1), 612 (inst $src0, $src1) 613>; 614 615def : GCNPat< 616 (i32 (zext (op i16:$src0, i16:$src1))), 617 (inst $src0, $src1) 618>; 619 620def : GCNPat< 621 (i64 (zext (op i16:$src0, i16:$src1))), 622 (REG_SEQUENCE VReg_64, 623 (inst $src0, $src1), sub0, 624 (V_MOV_B32_e32 (i32 0)), sub1) 625>; 626 627} 628 629multiclass Bits_OpsRev_i16_Pats <SDPatternOperator op, Instruction inst> { 630 631def : GCNPat< 632 (op i16:$src0, i16:$src1), 633 (inst $src1, $src0) 634>; 635 636def : GCNPat< 637 (i32 (zext (op i16:$src0, i16:$src1))), 638 (inst $src1, $src0) 639>; 640 641 642def : GCNPat< 643 (i64 (zext (op i16:$src0, i16:$src1))), 644 (REG_SEQUENCE VReg_64, 645 (inst $src1, $src0), sub0, 646 (V_MOV_B32_e32 (i32 0)), sub1) 647>; 648} 649 650class ZExt_i16_i1_Pat <SDNode ext> : GCNPat < 651 (i16 (ext i1:$src)), 652 (V_CNDMASK_B32_e64 (i32 0), (i32 1), $src) 653>; 654 655let Predicates = [Has16BitInsts] in { 656 657defm : Arithmetic_i16_Pats<add, V_ADD_U16_e64>; 658defm : Arithmetic_i16_Pats<mul, V_MUL_LO_U16_e64>; 659defm : Arithmetic_i16_Pats<sub, V_SUB_U16_e64>; 660defm : Arithmetic_i16_Pats<smin, V_MIN_I16_e64>; 661defm : Arithmetic_i16_Pats<smax, V_MAX_I16_e64>; 662defm : Arithmetic_i16_Pats<umin, V_MIN_U16_e64>; 663defm : Arithmetic_i16_Pats<umax, V_MAX_U16_e64>; 664 665def : GCNPat < 666 (and i16:$src0, i16:$src1), 667 (V_AND_B32_e64 $src0, $src1) 668>; 669 670def : GCNPat < 671 (or i16:$src0, i16:$src1), 672 (V_OR_B32_e64 $src0, $src1) 673>; 674 675def : GCNPat < 676 (xor i16:$src0, i16:$src1), 677 (V_XOR_B32_e64 $src0, $src1) 678>; 679 680defm : Bits_OpsRev_i16_Pats<shl, V_LSHLREV_B16_e64>; 681defm : Bits_OpsRev_i16_Pats<srl, V_LSHRREV_B16_e64>; 682defm : Bits_OpsRev_i16_Pats<sra, V_ASHRREV_I16_e64>; 683 684def : ZExt_i16_i1_Pat<zext>; 685def : ZExt_i16_i1_Pat<anyext>; 686 687def : GCNPat < 688 (i16 (sext i1:$src)), 689 (V_CNDMASK_B32_e64 (i32 0), (i32 -1), $src) 690>; 691 692// Undo sub x, c -> add x, -c canonicalization since c is more likely 693// an inline immediate than -c. 694// TODO: Also do for 64-bit. 695def : GCNPat< 696 (add i16:$src0, (i16 NegSubInlineConst16:$src1)), 697 (V_SUB_U16_e64 $src0, NegSubInlineConst16:$src1) 698>; 699 700} // End Predicates = [Has16BitInsts] 701 702//===----------------------------------------------------------------------===// 703// SI 704//===----------------------------------------------------------------------===// 705 706let AssemblerPredicates = [isSICI], DecoderNamespace = "SICI" in { 707 708multiclass VOP2_Real_si <bits<6> op> { 709 def _si : 710 VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.SI>, 711 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>; 712} 713 714multiclass VOP2_Real_MADK_si <bits<6> op> { 715 def _si : VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.SI>, 716 VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>; 717} 718 719multiclass VOP2_Real_e32_si <bits<6> op> { 720 def _e32_si : 721 VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.SI>, 722 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>; 723} 724 725multiclass VOP2_Real_e32e64_si <bits<6> op> : VOP2_Real_e32_si<op> { 726 def _e64_si : 727 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>, 728 VOP3e_si <{1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 729} 730 731multiclass VOP2be_Real_e32e64_si <bits<6> op> : VOP2_Real_e32_si<op> { 732 def _e64_si : 733 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>, 734 VOP3be_si <{1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 735} 736 737} // End AssemblerPredicates = [isSICI], DecoderNamespace = "SICI" 738 739defm V_CNDMASK_B32 : VOP2_Real_e32e64_si <0x0>; 740defm V_ADD_F32 : VOP2_Real_e32e64_si <0x3>; 741defm V_SUB_F32 : VOP2_Real_e32e64_si <0x4>; 742defm V_SUBREV_F32 : VOP2_Real_e32e64_si <0x5>; 743defm V_MUL_LEGACY_F32 : VOP2_Real_e32e64_si <0x7>; 744defm V_MUL_F32 : VOP2_Real_e32e64_si <0x8>; 745defm V_MUL_I32_I24 : VOP2_Real_e32e64_si <0x9>; 746defm V_MUL_HI_I32_I24 : VOP2_Real_e32e64_si <0xa>; 747defm V_MUL_U32_U24 : VOP2_Real_e32e64_si <0xb>; 748defm V_MUL_HI_U32_U24 : VOP2_Real_e32e64_si <0xc>; 749defm V_MIN_F32 : VOP2_Real_e32e64_si <0xf>; 750defm V_MAX_F32 : VOP2_Real_e32e64_si <0x10>; 751defm V_MIN_I32 : VOP2_Real_e32e64_si <0x11>; 752defm V_MAX_I32 : VOP2_Real_e32e64_si <0x12>; 753defm V_MIN_U32 : VOP2_Real_e32e64_si <0x13>; 754defm V_MAX_U32 : VOP2_Real_e32e64_si <0x14>; 755defm V_LSHRREV_B32 : VOP2_Real_e32e64_si <0x16>; 756defm V_ASHRREV_I32 : VOP2_Real_e32e64_si <0x18>; 757defm V_LSHLREV_B32 : VOP2_Real_e32e64_si <0x1a>; 758defm V_AND_B32 : VOP2_Real_e32e64_si <0x1b>; 759defm V_OR_B32 : VOP2_Real_e32e64_si <0x1c>; 760defm V_XOR_B32 : VOP2_Real_e32e64_si <0x1d>; 761defm V_MAC_F32 : VOP2_Real_e32e64_si <0x1f>; 762defm V_MADMK_F32 : VOP2_Real_MADK_si <0x20>; 763defm V_MADAK_F32 : VOP2_Real_MADK_si <0x21>; 764defm V_ADD_I32 : VOP2be_Real_e32e64_si <0x25>; 765defm V_SUB_I32 : VOP2be_Real_e32e64_si <0x26>; 766defm V_SUBREV_I32 : VOP2be_Real_e32e64_si <0x27>; 767defm V_ADDC_U32 : VOP2be_Real_e32e64_si <0x28>; 768defm V_SUBB_U32 : VOP2be_Real_e32e64_si <0x29>; 769defm V_SUBBREV_U32 : VOP2be_Real_e32e64_si <0x2a>; 770 771defm V_READLANE_B32 : VOP2_Real_si <0x01>; 772 773let InOperandList = (ins SSrc_b32:$src0, SCSrc_b32:$src1, VSrc_b32:$vdst_in) in { 774defm V_WRITELANE_B32 : VOP2_Real_si <0x02>; 775} 776 777defm V_MAC_LEGACY_F32 : VOP2_Real_e32e64_si <0x6>; 778defm V_MIN_LEGACY_F32 : VOP2_Real_e32e64_si <0xd>; 779defm V_MAX_LEGACY_F32 : VOP2_Real_e32e64_si <0xe>; 780defm V_LSHR_B32 : VOP2_Real_e32e64_si <0x15>; 781defm V_ASHR_I32 : VOP2_Real_e32e64_si <0x17>; 782defm V_LSHL_B32 : VOP2_Real_e32e64_si <0x19>; 783 784defm V_BFM_B32 : VOP2_Real_e32e64_si <0x1e>; 785defm V_BCNT_U32_B32 : VOP2_Real_e32e64_si <0x22>; 786defm V_MBCNT_LO_U32_B32 : VOP2_Real_e32e64_si <0x23>; 787defm V_MBCNT_HI_U32_B32 : VOP2_Real_e32e64_si <0x24>; 788defm V_LDEXP_F32 : VOP2_Real_e32e64_si <0x2b>; 789defm V_CVT_PKACCUM_U8_F32 : VOP2_Real_e32e64_si <0x2c>; 790defm V_CVT_PKNORM_I16_F32 : VOP2_Real_e32e64_si <0x2d>; 791defm V_CVT_PKNORM_U16_F32 : VOP2_Real_e32e64_si <0x2e>; 792defm V_CVT_PKRTZ_F16_F32 : VOP2_Real_e32e64_si <0x2f>; 793defm V_CVT_PK_U16_U32 : VOP2_Real_e32e64_si <0x30>; 794defm V_CVT_PK_I16_I32 : VOP2_Real_e32e64_si <0x31>; 795 796 797//===----------------------------------------------------------------------===// 798// VI 799//===----------------------------------------------------------------------===// 800 801class VOP2_DPPe <bits<6> op, VOP2_DPP_Pseudo ps, VOPProfile P = ps.Pfl> : 802 VOP_DPPe <P> { 803 bits<8> vdst; 804 bits<8> src1; 805 let Inst{8-0} = 0xfa; //dpp 806 let Inst{16-9} = !if(P.HasSrc1, src1{7-0}, 0); 807 let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0); 808 let Inst{30-25} = op; 809 let Inst{31} = 0x0; //encoding 810} 811 812let AssemblerPredicates = [isVI], DecoderNamespace = "VI" in { 813 814multiclass VOP2_Real_MADK_vi <bits<6> op> { 815 def _vi : VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.VI>, 816 VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>; 817} 818 819multiclass VOP2_Real_e32_vi <bits<6> op> { 820 def _e32_vi : 821 VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.VI>, 822 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>; 823} 824 825multiclass VOP2_Real_e64_vi <bits<10> op> { 826 def _e64_vi : 827 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>, 828 VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 829} 830 831multiclass VOP2_Real_e64only_vi <bits<10> op> { 832 def _e64_vi : 833 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>, 834 VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> { 835 // Hack to stop printing _e64 836 VOP3_Pseudo ps = !cast<VOP3_Pseudo>(NAME#"_e64"); 837 let OutOperandList = (outs VGPR_32:$vdst); 838 let AsmString = ps.Mnemonic # " " # ps.AsmOperands; 839 } 840} 841 842multiclass Base_VOP2_Real_e32e64_vi <bits<6> op> : 843 VOP2_Real_e32_vi<op>, 844 VOP2_Real_e64_vi<{0, 1, 0, 0, op{5-0}}>; 845 846} // End AssemblerPredicates = [isVI], DecoderNamespace = "VI" 847 848multiclass VOP2_SDWA_Real <bits<6> op> { 849 def _sdwa_vi : 850 VOP_SDWA_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>, 851 VOP2_SDWAe <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl>; 852} 853 854multiclass VOP2_SDWA9_Real <bits<6> op> { 855 def _sdwa_gfx9 : 856 VOP_SDWA9_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>, 857 VOP2_SDWA9Ae <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl>; 858} 859 860let AssemblerPredicates = [isVIOnly] in { 861 862multiclass VOP2be_Real_e32e64_vi_only <bits<6> op, string OpName, string AsmName> { 863 def _e32_vi : 864 VOP2_Real<!cast<VOP2_Pseudo>(OpName#"_e32"), SIEncodingFamily.VI>, 865 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(OpName#"_e32").Pfl> { 866 VOP2_Pseudo ps = !cast<VOP2_Pseudo>(OpName#"_e32"); 867 let AsmString = AsmName # ps.AsmOperands; 868 let DecoderNamespace = "VI"; 869 } 870 def _e64_vi : 871 VOP3_Real<!cast<VOP3_Pseudo>(OpName#"_e64"), SIEncodingFamily.VI>, 872 VOP3be_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(OpName#"_e64").Pfl> { 873 VOP3_Pseudo ps = !cast<VOP3_Pseudo>(OpName#"_e64"); 874 let AsmString = AsmName # ps.AsmOperands; 875 let DecoderNamespace = "VI"; 876 } 877 def _sdwa_vi : 878 VOP_SDWA_Real <!cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa")>, 879 VOP2_SDWAe <op{5-0}, !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa").Pfl> { 880 VOP2_SDWA_Pseudo ps = !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa"); 881 let AsmString = AsmName # ps.AsmOperands; 882 } 883 foreach _ = BoolToList<!cast<VOP2_Pseudo>(OpName#"_e32").Pfl.HasExtDPP>.ret in 884 def _dpp_vi : 885 VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(OpName#"_dpp"), SIEncodingFamily.VI>, 886 VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(OpName#"_dpp")> { 887 VOP2_DPP_Pseudo ps = !cast<VOP2_DPP_Pseudo>(OpName#"_dpp"); 888 let AsmString = AsmName # ps.AsmOperands; 889 } 890} 891} 892 893let AssemblerPredicates = [isGFX9] in { 894 895multiclass VOP2be_Real_e32e64_gfx9 <bits<6> op, string OpName, string AsmName> { 896 def _e32_gfx9 : 897 VOP2_Real<!cast<VOP2_Pseudo>(OpName#"_e32"), SIEncodingFamily.GFX9>, 898 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(OpName#"_e32").Pfl> { 899 VOP2_Pseudo ps = !cast<VOP2_Pseudo>(OpName#"_e32"); 900 let AsmString = AsmName # ps.AsmOperands; 901 let DecoderNamespace = "GFX9"; 902 } 903 def _e64_gfx9 : 904 VOP3_Real<!cast<VOP3_Pseudo>(OpName#"_e64"), SIEncodingFamily.GFX9>, 905 VOP3be_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(OpName#"_e64").Pfl> { 906 VOP3_Pseudo ps = !cast<VOP3_Pseudo>(OpName#"_e64"); 907 let AsmString = AsmName # ps.AsmOperands; 908 let DecoderNamespace = "GFX9"; 909 } 910 def _sdwa_gfx9 : 911 VOP_SDWA9_Real <!cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa")>, 912 VOP2_SDWA9Ae <op{5-0}, !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa").Pfl> { 913 VOP2_SDWA_Pseudo ps = !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa"); 914 let AsmString = AsmName # ps.AsmOperands; 915 } 916 foreach _ = BoolToList<!cast<VOP2_Pseudo>(OpName#"_e32").Pfl.HasExtDPP>.ret in 917 def _dpp_gfx9 : 918 VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(OpName#"_dpp"), SIEncodingFamily.GFX9>, 919 VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(OpName#"_dpp")> { 920 VOP2_DPP_Pseudo ps = !cast<VOP2_DPP_Pseudo>(OpName#"_dpp"); 921 let AsmString = AsmName # ps.AsmOperands; 922 let DecoderNamespace = "SDWA9"; 923 } 924} 925 926multiclass VOP2_Real_e32e64_gfx9 <bits<6> op> { 927 def _e32_gfx9 : 928 VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.GFX9>, 929 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>{ 930 let DecoderNamespace = "GFX9"; 931 } 932 def _e64_gfx9 : 933 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX9>, 934 VOP3e_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> { 935 let DecoderNamespace = "GFX9"; 936 } 937 def _sdwa_gfx9 : 938 VOP_SDWA9_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>, 939 VOP2_SDWA9Ae <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl> { 940 } 941 foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in 942 def _dpp_gfx9 : 943 VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.GFX9>, 944 VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp")> { 945 let DecoderNamespace = "SDWA9"; 946 } 947} 948 949} // AssemblerPredicates = [isGFX9] 950 951multiclass VOP2_Real_e32e64_vi <bits<6> op> : 952 Base_VOP2_Real_e32e64_vi<op>, VOP2_SDWA_Real<op>, VOP2_SDWA9_Real<op> { 953 954 foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in 955 def _dpp_vi : 956 VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.VI>, 957 VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp")>; 958} 959 960defm V_CNDMASK_B32 : VOP2_Real_e32e64_vi <0x0>; 961defm V_ADD_F32 : VOP2_Real_e32e64_vi <0x1>; 962defm V_SUB_F32 : VOP2_Real_e32e64_vi <0x2>; 963defm V_SUBREV_F32 : VOP2_Real_e32e64_vi <0x3>; 964defm V_MUL_LEGACY_F32 : VOP2_Real_e32e64_vi <0x4>; 965defm V_MUL_F32 : VOP2_Real_e32e64_vi <0x5>; 966defm V_MUL_I32_I24 : VOP2_Real_e32e64_vi <0x6>; 967defm V_MUL_HI_I32_I24 : VOP2_Real_e32e64_vi <0x7>; 968defm V_MUL_U32_U24 : VOP2_Real_e32e64_vi <0x8>; 969defm V_MUL_HI_U32_U24 : VOP2_Real_e32e64_vi <0x9>; 970defm V_MIN_F32 : VOP2_Real_e32e64_vi <0xa>; 971defm V_MAX_F32 : VOP2_Real_e32e64_vi <0xb>; 972defm V_MIN_I32 : VOP2_Real_e32e64_vi <0xc>; 973defm V_MAX_I32 : VOP2_Real_e32e64_vi <0xd>; 974defm V_MIN_U32 : VOP2_Real_e32e64_vi <0xe>; 975defm V_MAX_U32 : VOP2_Real_e32e64_vi <0xf>; 976defm V_LSHRREV_B32 : VOP2_Real_e32e64_vi <0x10>; 977defm V_ASHRREV_I32 : VOP2_Real_e32e64_vi <0x11>; 978defm V_LSHLREV_B32 : VOP2_Real_e32e64_vi <0x12>; 979defm V_AND_B32 : VOP2_Real_e32e64_vi <0x13>; 980defm V_OR_B32 : VOP2_Real_e32e64_vi <0x14>; 981defm V_XOR_B32 : VOP2_Real_e32e64_vi <0x15>; 982defm V_MAC_F32 : VOP2_Real_e32e64_vi <0x16>; 983defm V_MADMK_F32 : VOP2_Real_MADK_vi <0x17>; 984defm V_MADAK_F32 : VOP2_Real_MADK_vi <0x18>; 985 986defm V_ADD_U32 : VOP2be_Real_e32e64_vi_only <0x19, "V_ADD_I32", "v_add_u32">; 987defm V_SUB_U32 : VOP2be_Real_e32e64_vi_only <0x1a, "V_SUB_I32", "v_sub_u32">; 988defm V_SUBREV_U32 : VOP2be_Real_e32e64_vi_only <0x1b, "V_SUBREV_I32", "v_subrev_u32">; 989defm V_ADDC_U32 : VOP2be_Real_e32e64_vi_only <0x1c, "V_ADDC_U32", "v_addc_u32">; 990defm V_SUBB_U32 : VOP2be_Real_e32e64_vi_only <0x1d, "V_SUBB_U32", "v_subb_u32">; 991defm V_SUBBREV_U32 : VOP2be_Real_e32e64_vi_only <0x1e, "V_SUBBREV_U32", "v_subbrev_u32">; 992 993defm V_ADD_CO_U32 : VOP2be_Real_e32e64_gfx9 <0x19, "V_ADD_I32", "v_add_co_u32">; 994defm V_SUB_CO_U32 : VOP2be_Real_e32e64_gfx9 <0x1a, "V_SUB_I32", "v_sub_co_u32">; 995defm V_SUBREV_CO_U32 : VOP2be_Real_e32e64_gfx9 <0x1b, "V_SUBREV_I32", "v_subrev_co_u32">; 996defm V_ADDC_CO_U32 : VOP2be_Real_e32e64_gfx9 <0x1c, "V_ADDC_U32", "v_addc_co_u32">; 997defm V_SUBB_CO_U32 : VOP2be_Real_e32e64_gfx9 <0x1d, "V_SUBB_U32", "v_subb_co_u32">; 998defm V_SUBBREV_CO_U32 : VOP2be_Real_e32e64_gfx9 <0x1e, "V_SUBBREV_U32", "v_subbrev_co_u32">; 999 1000defm V_ADD_U32 : VOP2_Real_e32e64_gfx9 <0x34>; 1001defm V_SUB_U32 : VOP2_Real_e32e64_gfx9 <0x35>; 1002defm V_SUBREV_U32 : VOP2_Real_e32e64_gfx9 <0x36>; 1003 1004defm V_BFM_B32 : VOP2_Real_e64only_vi <0x293>; 1005defm V_BCNT_U32_B32 : VOP2_Real_e64only_vi <0x28b>; 1006defm V_MBCNT_LO_U32_B32 : VOP2_Real_e64only_vi <0x28c>; 1007defm V_MBCNT_HI_U32_B32 : VOP2_Real_e64only_vi <0x28d>; 1008defm V_LDEXP_F32 : VOP2_Real_e64only_vi <0x288>; 1009defm V_CVT_PKACCUM_U8_F32 : VOP2_Real_e64only_vi <0x1f0>; 1010defm V_CVT_PKNORM_I16_F32 : VOP2_Real_e64only_vi <0x294>; 1011defm V_CVT_PKNORM_U16_F32 : VOP2_Real_e64only_vi <0x295>; 1012defm V_CVT_PKRTZ_F16_F32 : VOP2_Real_e64only_vi <0x296>; 1013defm V_CVT_PK_U16_U32 : VOP2_Real_e64only_vi <0x297>; 1014defm V_CVT_PK_I16_I32 : VOP2_Real_e64only_vi <0x298>; 1015 1016defm V_ADD_F16 : VOP2_Real_e32e64_vi <0x1f>; 1017defm V_SUB_F16 : VOP2_Real_e32e64_vi <0x20>; 1018defm V_SUBREV_F16 : VOP2_Real_e32e64_vi <0x21>; 1019defm V_MUL_F16 : VOP2_Real_e32e64_vi <0x22>; 1020defm V_MAC_F16 : VOP2_Real_e32e64_vi <0x23>; 1021defm V_MADMK_F16 : VOP2_Real_MADK_vi <0x24>; 1022defm V_MADAK_F16 : VOP2_Real_MADK_vi <0x25>; 1023defm V_ADD_U16 : VOP2_Real_e32e64_vi <0x26>; 1024defm V_SUB_U16 : VOP2_Real_e32e64_vi <0x27>; 1025defm V_SUBREV_U16 : VOP2_Real_e32e64_vi <0x28>; 1026defm V_MUL_LO_U16 : VOP2_Real_e32e64_vi <0x29>; 1027defm V_LSHLREV_B16 : VOP2_Real_e32e64_vi <0x2a>; 1028defm V_LSHRREV_B16 : VOP2_Real_e32e64_vi <0x2b>; 1029defm V_ASHRREV_I16 : VOP2_Real_e32e64_vi <0x2c>; 1030defm V_MAX_F16 : VOP2_Real_e32e64_vi <0x2d>; 1031defm V_MIN_F16 : VOP2_Real_e32e64_vi <0x2e>; 1032defm V_MAX_U16 : VOP2_Real_e32e64_vi <0x2f>; 1033defm V_MAX_I16 : VOP2_Real_e32e64_vi <0x30>; 1034defm V_MIN_U16 : VOP2_Real_e32e64_vi <0x31>; 1035defm V_MIN_I16 : VOP2_Real_e32e64_vi <0x32>; 1036defm V_LDEXP_F16 : VOP2_Real_e32e64_vi <0x33>; 1037 1038let SubtargetPredicate = isVI in { 1039 1040// Aliases to simplify matching of floating-point instructions that 1041// are VOP2 on SI and VOP3 on VI. 1042class SI2_VI3Alias <string name, VOP3_Real inst> : InstAlias < 1043 name#" $dst, $src0, $src1", 1044 !if(inst.Pfl.HasOMod, 1045 (inst VGPR_32:$dst, 0, VCSrc_f32:$src0, 0, VCSrc_f32:$src1, 0, 0), 1046 (inst VGPR_32:$dst, 0, VCSrc_f32:$src0, 0, VCSrc_f32:$src1, 0)) 1047>, PredicateControl { 1048 let UseInstAsmMatchConverter = 0; 1049 let AsmVariantName = AMDGPUAsmVariants.VOP3; 1050} 1051 1052def : SI2_VI3Alias <"v_ldexp_f32", V_LDEXP_F32_e64_vi>; 1053def : SI2_VI3Alias <"v_cvt_pkaccum_u8_f32", V_CVT_PKACCUM_U8_F32_e64_vi>; 1054def : SI2_VI3Alias <"v_cvt_pknorm_i16_f32", V_CVT_PKNORM_I16_F32_e64_vi>; 1055def : SI2_VI3Alias <"v_cvt_pknorm_u16_f32", V_CVT_PKNORM_U16_F32_e64_vi>; 1056def : SI2_VI3Alias <"v_cvt_pkrtz_f16_f32", V_CVT_PKRTZ_F16_F32_e64_vi>; 1057 1058} // End SubtargetPredicate = isVI 1059 1060let SubtargetPredicate = HasDLInsts in { 1061 1062defm V_FMAC_F32 : VOP2_Real_e32e64_vi <0x3b>; 1063defm V_XNOR_B32 : VOP2_Real_e32e64_vi <0x3d>; 1064 1065} // End SubtargetPredicate = HasDLInsts 1066