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_Pseudo <string opName, VOPProfile P, list<dag> pattern=[], string suffix = "_e32"> : 52 InstSI <P.Outs32, P.Ins32, "", pattern>, 53 VOP <opName>, 54 SIMCInstr <opName#suffix, SIEncodingFamily.NONE>, 55 MnemonicAlias<opName#suffix, opName> { 56 57 let isPseudo = 1; 58 let isCodeGenOnly = 1; 59 let UseNamedOperandTable = 1; 60 61 string Mnemonic = opName; 62 string AsmOperands = P.Asm32; 63 64 let Size = 4; 65 let mayLoad = 0; 66 let mayStore = 0; 67 let hasSideEffects = 0; 68 let SubtargetPredicate = isGCN; 69 70 let VOP2 = 1; 71 let VALU = 1; 72 let Uses = [EXEC]; 73 74 let AsmVariantName = AMDGPUAsmVariants.Default; 75 76 VOPProfile Pfl = P; 77} 78 79class VOP2_Real <VOP2_Pseudo ps, int EncodingFamily> : 80 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 81 SIMCInstr <ps.PseudoInstr, EncodingFamily> { 82 83 let isPseudo = 0; 84 let isCodeGenOnly = 0; 85 86 let Constraints = ps.Constraints; 87 let DisableEncoding = ps.DisableEncoding; 88 89 // copy relevant pseudo op flags 90 let SubtargetPredicate = ps.SubtargetPredicate; 91 let AsmMatchConverter = ps.AsmMatchConverter; 92 let AsmVariantName = ps.AsmVariantName; 93 let Constraints = ps.Constraints; 94 let DisableEncoding = ps.DisableEncoding; 95 let TSFlags = ps.TSFlags; 96} 97 98class VOP2_SDWA_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> : 99 VOP_SDWA_Pseudo <OpName, P, pattern> { 100 let AsmMatchConverter = "cvtSdwaVOP2"; 101} 102 103class getVOP2Pat64 <SDPatternOperator node, VOPProfile P> : LetDummies { 104 list<dag> ret = !if(P.HasModifiers, 105 [(set P.DstVT:$vdst, 106 (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), 107 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], 108 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]); 109} 110 111multiclass VOP2Inst <string opName, 112 VOPProfile P, 113 SDPatternOperator node = null_frag, 114 string revOp = opName> { 115 116 def _e32 : VOP2_Pseudo <opName, P>, 117 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>; 118 119 def _e64 : VOP3_Pseudo <opName, P, getVOP2Pat64<node, P>.ret>, 120 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>; 121 122 def _sdwa : VOP2_SDWA_Pseudo <opName, P>; 123} 124 125// TODO: add SDWA pseudo instructions for VOP2bInst and VOP2eInst 126multiclass VOP2bInst <string opName, 127 VOPProfile P, 128 SDPatternOperator node = null_frag, 129 string revOp = opName, 130 bit useSGPRInput = !eq(P.NumSrcArgs, 3)> { 131 132 let SchedRW = [Write32Bit, WriteSALU] in { 133 let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in { 134 def _e32 : VOP2_Pseudo <opName, P>, 135 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>; 136 137 def _sdwa : VOP2_SDWA_Pseudo <opName, P>; 138 } 139 140 def _e64 : VOP3_Pseudo <opName, P, getVOP2Pat64<node, P>.ret>, 141 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>; 142 } 143} 144 145multiclass VOP2eInst <string opName, 146 VOPProfile P, 147 SDPatternOperator node = null_frag, 148 string revOp = opName, 149 bit useSGPRInput = !eq(P.NumSrcArgs, 3)> { 150 151 let SchedRW = [Write32Bit] in { 152 let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]) in { 153 def _e32 : VOP2_Pseudo <opName, P>, 154 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>; 155 } 156 157 def _e64 : VOP3_Pseudo <opName, P, getVOP2Pat64<node, P>.ret>, 158 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>; 159 } 160} 161 162class VOP_MADAK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> { 163 field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm); 164 field dag Ins32 = (ins VCSrc_f32:$src0, VGPR_32:$src1, ImmOpType:$imm); 165 field string Asm32 = "$vdst, $src0, $src1, $imm"; 166 field bit HasExt = 0; 167} 168 169def VOP_MADAK_F16 : VOP_MADAK <f16>; 170def VOP_MADAK_F32 : VOP_MADAK <f32>; 171 172class VOP_MADMK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> { 173 field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm); 174 field dag Ins32 = (ins VCSrc_f32:$src0, ImmOpType:$imm, VGPR_32:$src1); 175 field string Asm32 = "$vdst, $src0, $imm, $src1"; 176 field bit HasExt = 0; 177} 178 179def VOP_MADMK_F16 : VOP_MADMK <f16>; 180def VOP_MADMK_F32 : VOP_MADMK <f32>; 181 182class VOP_MAC <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> { 183 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2); 184 let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3, 185 HasModifiers, HasOMod, Src0Mod, Src1Mod, Src2Mod>.ret; 186 let InsDPP = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0, 187 Src1ModDPP:$src1_modifiers, Src1DPP:$src1, 188 VGPR_32:$src2, // stub argument 189 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 190 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl); 191 let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0, 192 Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1, 193 VGPR_32:$src2, // stub argument 194 clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused, 195 src0_sel:$src0_sel, src1_sel:$src1_sel); 196 let Asm32 = getAsm32<1, 2, vt>.ret; 197 let Asm64 = getAsm64<1, 2, HasModifiers, HasOMod, vt>.ret; 198 let AsmDPP = getAsmDPP<1, 2, HasModifiers, vt>.ret; 199 let AsmSDWA = getAsmSDWA<1, 2, HasModifiers, vt>.ret; 200 let HasSrc2 = 0; 201 let HasSrc2Mods = 0; 202 let HasExt = 1; 203} 204 205def VOP_MAC_F16 : VOP_MAC <f16> { 206 // FIXME: Move 'Asm64' definition to VOP_MAC, and use 'vt'. Currently it gives 207 // 'not a string initializer' error. 208 let Asm64 = getAsm64<1, 2, HasModifiers, HasOMod, f16>.ret; 209} 210 211def VOP_MAC_F32 : VOP_MAC <f32> { 212 // FIXME: Move 'Asm64' definition to VOP_MAC, and use 'vt'. Currently it gives 213 // 'not a string initializer' error. 214 let Asm64 = getAsm64<1, 2, HasModifiers, HasOMod, f32>.ret; 215} 216 217// Write out to vcc or arbitrary SGPR. 218def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> { 219 let Asm32 = "$vdst, vcc, $src0, $src1"; 220 let Asm64 = "$vdst, $sdst, $src0, $src1"; 221 let AsmSDWA = "$vdst, vcc, $src0_modifiers, $src1_modifiers$clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 222 let AsmDPP = "$vdst, vcc, $src0, $src1 $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 223 let Outs32 = (outs DstRC:$vdst); 224 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 225} 226 227// Write out to vcc or arbitrary SGPR and read in from vcc or 228// arbitrary SGPR. 229def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { 230 // We use VCSrc_b32 to exclude literal constants, even though the 231 // encoding normally allows them since the implicit VCC use means 232 // using one would always violate the constant bus 233 // restriction. SGPRs are still allowed because it should 234 // technically be possible to use VCC again as src0. 235 let Src0RC32 = VCSrc_b32; 236 let Asm32 = "$vdst, vcc, $src0, $src1, vcc"; 237 let Asm64 = "$vdst, $sdst, $src0, $src1, $src2"; 238 let AsmSDWA = "$vdst, vcc, $src0_modifiers, $src1_modifiers, vcc $clamp $dst_sel $dst_unused $src0_sel $src1_sel"; 239 let AsmDPP = "$vdst, vcc, $src0, $src1, vcc $dpp_ctrl$row_mask$bank_mask$bound_ctrl"; 240 let Outs32 = (outs DstRC:$vdst); 241 let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); 242 243 // Suppress src2 implied by type since the 32-bit encoding uses an 244 // implicit VCC use. 245 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); 246 247 let InsSDWA = (ins Src0Mod:$src0_modifiers, Src0SDWA:$src0, 248 Src1Mod:$src1_modifiers, Src1SDWA:$src1, 249 clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused, 250 src0_sel:$src0_sel, src1_sel:$src1_sel); 251 252 let InsDPP = (ins Src0Mod:$src0_modifiers, Src0DPP:$src0, 253 Src1Mod:$src1_modifiers, Src1DPP:$src1, 254 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, 255 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl); 256 let HasExt = 1; 257} 258 259// Read in from vcc or arbitrary SGPR 260def VOP2e_I32_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { 261 let Src0RC32 = VCSrc_b32; // See comment in def VOP2b_I32_I1_I32_I32_I1 above. 262 let Asm32 = "$vdst, $src0, $src1, vcc"; 263 let Asm64 = "$vdst, $src0, $src1, $src2"; 264 let Outs32 = (outs DstRC:$vdst); 265 let Outs64 = (outs DstRC:$vdst); 266 267 // Suppress src2 implied by type since the 32-bit encoding uses an 268 // implicit VCC use. 269 let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); 270} 271 272def VOP_READLANE : VOPProfile<[i32, i32, i32]> { 273 let Outs32 = (outs SReg_32:$vdst); 274 let Outs64 = Outs32; 275 let Ins32 = (ins VGPR_32:$src0, SCSrc_b32:$src1); 276 let Ins64 = Ins32; 277 let Asm32 = " $vdst, $src0, $src1"; 278 let Asm64 = Asm32; 279} 280 281def VOP_WRITELANE : VOPProfile<[i32, i32, i32]> { 282 let Outs32 = (outs VGPR_32:$vdst); 283 let Outs64 = Outs32; 284 let Ins32 = (ins SReg_32:$src0, SCSrc_b32:$src1); 285 let Ins64 = Ins32; 286 let Asm32 = " $vdst, $src0, $src1"; 287 let Asm64 = Asm32; 288} 289 290//===----------------------------------------------------------------------===// 291// VOP2 Instructions 292//===----------------------------------------------------------------------===// 293 294let SubtargetPredicate = isGCN in { 295 296defm V_CNDMASK_B32 : VOP2eInst <"v_cndmask_b32", VOP2e_I32_I32_I32_I1>; 297def V_MADMK_F32 : VOP2_Pseudo <"v_madmk_f32", VOP_MADMK_F32>; 298 299let isCommutable = 1 in { 300defm V_ADD_F32 : VOP2Inst <"v_add_f32", VOP_F32_F32_F32, fadd>; 301defm V_SUB_F32 : VOP2Inst <"v_sub_f32", VOP_F32_F32_F32, fsub>; 302defm V_SUBREV_F32 : VOP2Inst <"v_subrev_f32", VOP_F32_F32_F32, null_frag, "v_sub_f32">; 303defm V_MUL_LEGACY_F32 : VOP2Inst <"v_mul_legacy_f32", VOP_F32_F32_F32, AMDGPUfmul_legacy>; 304defm V_MUL_F32 : VOP2Inst <"v_mul_f32", VOP_F32_F32_F32, fmul>; 305defm V_MUL_I32_I24 : VOP2Inst <"v_mul_i32_i24", VOP_I32_I32_I32, AMDGPUmul_i24>; 306defm V_MUL_HI_I32_I24 : VOP2Inst <"v_mul_hi_i32_i24", VOP_I32_I32_I32, AMDGPUmulhi_i24>; 307defm V_MUL_U32_U24 : VOP2Inst <"v_mul_u32_u24", VOP_I32_I32_I32, AMDGPUmul_u24>; 308defm V_MUL_HI_U32_U24 : VOP2Inst <"v_mul_hi_u32_u24", VOP_I32_I32_I32, AMDGPUmulhi_u24>; 309defm V_MIN_F32 : VOP2Inst <"v_min_f32", VOP_F32_F32_F32, fminnum>; 310defm V_MAX_F32 : VOP2Inst <"v_max_f32", VOP_F32_F32_F32, fmaxnum>; 311defm V_MIN_I32 : VOP2Inst <"v_min_i32", VOP_I32_I32_I32>; 312defm V_MAX_I32 : VOP2Inst <"v_max_i32", VOP_I32_I32_I32>; 313defm V_MIN_U32 : VOP2Inst <"v_min_u32", VOP_I32_I32_I32>; 314defm V_MAX_U32 : VOP2Inst <"v_max_u32", VOP_I32_I32_I32>; 315defm V_LSHRREV_B32 : VOP2Inst <"v_lshrrev_b32", VOP_I32_I32_I32, null_frag, "v_lshr_b32">; 316defm V_ASHRREV_I32 : VOP2Inst <"v_ashrrev_i32", VOP_I32_I32_I32, null_frag, "v_ashr_i32">; 317defm V_LSHLREV_B32 : VOP2Inst <"v_lshlrev_b32", VOP_I32_I32_I32, null_frag, "v_lshl_b32">; 318defm V_AND_B32 : VOP2Inst <"v_and_b32", VOP_I32_I32_I32>; 319defm V_OR_B32 : VOP2Inst <"v_or_b32", VOP_I32_I32_I32>; 320defm V_XOR_B32 : VOP2Inst <"v_xor_b32", VOP_I32_I32_I32>; 321 322let Constraints = "$vdst = $src2", DisableEncoding="$src2", 323 isConvertibleToThreeAddress = 1 in { 324defm V_MAC_F32 : VOP2Inst <"v_mac_f32", VOP_MAC_F32>; 325} 326 327def V_MADAK_F32 : VOP2_Pseudo <"v_madak_f32", VOP_MADAK_F32>; 328 329// No patterns so that the scalar instructions are always selected. 330// The scalar versions will be replaced with vector when needed later. 331 332// V_ADD_I32, V_SUB_I32, and V_SUBREV_I32 where renamed to *_U32 in VI, 333// but the VI instructions behave the same as the SI versions. 334defm V_ADD_I32 : VOP2bInst <"v_add_i32", VOP2b_I32_I1_I32_I32>; 335defm V_SUB_I32 : VOP2bInst <"v_sub_i32", VOP2b_I32_I1_I32_I32>; 336defm V_SUBREV_I32 : VOP2bInst <"v_subrev_i32", VOP2b_I32_I1_I32_I32, null_frag, "v_sub_i32">; 337defm V_ADDC_U32 : VOP2bInst <"v_addc_u32", VOP2b_I32_I1_I32_I32_I1>; 338defm V_SUBB_U32 : VOP2bInst <"v_subb_u32", VOP2b_I32_I1_I32_I32_I1>; 339defm V_SUBBREV_U32 : VOP2bInst <"v_subbrev_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_subb_u32">; 340} // End isCommutable = 1 341 342// These are special and do not read the exec mask. 343let isConvergent = 1, Uses = []<Register> in { 344def V_READLANE_B32 : VOP2_Pseudo<"v_readlane_b32", VOP_READLANE, 345 [(set i32:$vdst, (int_amdgcn_readlane i32:$src0, i32:$src1))], "">; 346 347def V_WRITELANE_B32 : VOP2_Pseudo<"v_writelane_b32", VOP_WRITELANE, [], "">; 348} // End isConvergent = 1 349 350defm V_BFM_B32 : VOP2Inst <"v_bfm_b32", VOP_I32_I32_I32>; 351defm V_BCNT_U32_B32 : VOP2Inst <"v_bcnt_u32_b32", VOP_I32_I32_I32>; 352defm V_MBCNT_LO_U32_B32 : VOP2Inst <"v_mbcnt_lo_u32_b32", VOP_I32_I32_I32, int_amdgcn_mbcnt_lo>; 353defm V_MBCNT_HI_U32_B32 : VOP2Inst <"v_mbcnt_hi_u32_b32", VOP_I32_I32_I32, int_amdgcn_mbcnt_hi>; 354defm V_LDEXP_F32 : VOP2Inst <"v_ldexp_f32", VOP_F32_F32_I32, AMDGPUldexp>; 355defm V_CVT_PKACCUM_U8_F32 : VOP2Inst <"v_cvt_pkaccum_u8_f32", VOP_I32_F32_I32>; // TODO: set "Uses = dst" 356defm V_CVT_PKNORM_I16_F32 : VOP2Inst <"v_cvt_pknorm_i16_f32", VOP_I32_F32_F32>; 357defm V_CVT_PKNORM_U16_F32 : VOP2Inst <"v_cvt_pknorm_u16_f32", VOP_I32_F32_F32>; 358defm V_CVT_PKRTZ_F16_F32 : VOP2Inst <"v_cvt_pkrtz_f16_f32", VOP_I32_F32_F32, AMDGPUpkrtz_f16_f32>; 359defm V_CVT_PK_U16_U32 : VOP2Inst <"v_cvt_pk_u16_u32", VOP_I32_I32_I32>; 360defm V_CVT_PK_I16_I32 : VOP2Inst <"v_cvt_pk_i16_i32", VOP_I32_I32_I32>; 361 362} // End SubtargetPredicate = isGCN 363 364 365// These instructions only exist on SI and CI 366let SubtargetPredicate = isSICI in { 367 368defm V_MIN_LEGACY_F32 : VOP2Inst <"v_min_legacy_f32", VOP_F32_F32_F32, AMDGPUfmin_legacy>; 369defm V_MAX_LEGACY_F32 : VOP2Inst <"v_max_legacy_f32", VOP_F32_F32_F32, AMDGPUfmax_legacy>; 370 371let isCommutable = 1 in { 372defm V_MAC_LEGACY_F32 : VOP2Inst <"v_mac_legacy_f32", VOP_F32_F32_F32>; 373defm V_LSHR_B32 : VOP2Inst <"v_lshr_b32", VOP_I32_I32_I32>; 374defm V_ASHR_I32 : VOP2Inst <"v_ashr_i32", VOP_I32_I32_I32>; 375defm V_LSHL_B32 : VOP2Inst <"v_lshl_b32", VOP_I32_I32_I32>; 376} // End isCommutable = 1 377 378} // End let SubtargetPredicate = SICI 379 380let SubtargetPredicate = isVI in { 381 382def V_MADMK_F16 : VOP2_Pseudo <"v_madmk_f16", VOP_MADMK_F16>; 383defm V_LSHLREV_B16 : VOP2Inst <"v_lshlrev_b16", VOP_I16_I16_I16>; 384defm V_LSHRREV_B16 : VOP2Inst <"v_lshrrev_b16", VOP_I16_I16_I16>; 385defm V_ASHRREV_I16 : VOP2Inst <"v_ashrrev_i16", VOP_I16_I16_I16>; 386defm V_LDEXP_F16 : VOP2Inst <"v_ldexp_f16", VOP_F16_F16_I32, AMDGPUldexp>; 387 388let isCommutable = 1 in { 389defm V_ADD_F16 : VOP2Inst <"v_add_f16", VOP_F16_F16_F16, fadd>; 390defm V_SUB_F16 : VOP2Inst <"v_sub_f16", VOP_F16_F16_F16, fsub>; 391defm V_SUBREV_F16 : VOP2Inst <"v_subrev_f16", VOP_F16_F16_F16, null_frag, "v_sub_f16">; 392defm V_MUL_F16 : VOP2Inst <"v_mul_f16", VOP_F16_F16_F16, fmul>; 393def V_MADAK_F16 : VOP2_Pseudo <"v_madak_f16", VOP_MADAK_F16>; 394defm V_ADD_U16 : VOP2Inst <"v_add_u16", VOP_I16_I16_I16>; 395defm V_SUB_U16 : VOP2Inst <"v_sub_u16" , VOP_I16_I16_I16>; 396defm V_SUBREV_U16 : VOP2Inst <"v_subrev_u16", VOP_I16_I16_I16, null_frag, "v_sub_u16">; 397defm V_MUL_LO_U16 : VOP2Inst <"v_mul_lo_u16", VOP_I16_I16_I16>; 398defm V_MAX_F16 : VOP2Inst <"v_max_f16", VOP_F16_F16_F16, fmaxnum>; 399defm V_MIN_F16 : VOP2Inst <"v_min_f16", VOP_F16_F16_F16, fminnum>; 400defm V_MAX_U16 : VOP2Inst <"v_max_u16", VOP_I16_I16_I16>; 401defm V_MAX_I16 : VOP2Inst <"v_max_i16", VOP_I16_I16_I16>; 402defm V_MIN_U16 : VOP2Inst <"v_min_u16", VOP_I16_I16_I16>; 403defm V_MIN_I16 : VOP2Inst <"v_min_i16", VOP_I16_I16_I16>; 404 405let Constraints = "$vdst = $src2", DisableEncoding="$src2", 406 isConvertibleToThreeAddress = 1 in { 407defm V_MAC_F16 : VOP2Inst <"v_mac_f16", VOP_MAC_F16>; 408} 409} // End isCommutable = 1 410 411} // End SubtargetPredicate = isVI 412 413// Note: 16-bit instructions produce a 0 result in the high 16-bits. 414multiclass Arithmetic_i16_Pats <SDPatternOperator op, Instruction inst> { 415 416def : Pat< 417 (op i16:$src0, i16:$src1), 418 (inst $src0, $src1) 419>; 420 421def : Pat< 422 (i32 (zext (op i16:$src0, i16:$src1))), 423 (inst $src0, $src1) 424>; 425 426def : Pat< 427 (i64 (zext (op i16:$src0, i16:$src1))), 428 (REG_SEQUENCE VReg_64, 429 (inst $src0, $src1), sub0, 430 (V_MOV_B32_e32 (i32 0)), sub1) 431>; 432 433} 434 435multiclass Bits_OpsRev_i16_Pats <SDPatternOperator op, Instruction inst> { 436 437def : Pat< 438 (op i16:$src0, i16:$src1), 439 (inst $src1, $src0) 440>; 441 442def : Pat< 443 (i32 (zext (op i16:$src0, i16:$src1))), 444 (inst $src1, $src0) 445>; 446 447 448def : Pat< 449 (i64 (zext (op i16:$src0, i16:$src1))), 450 (REG_SEQUENCE VReg_64, 451 (inst $src1, $src0), sub0, 452 (V_MOV_B32_e32 (i32 0)), sub1) 453>; 454} 455 456class ZExt_i16_i1_Pat <SDNode ext> : Pat < 457 (i16 (ext i1:$src)), 458 (V_CNDMASK_B32_e64 (i32 0), (i32 1), $src) 459>; 460 461let Predicates = [isVI] in { 462 463defm : Arithmetic_i16_Pats<add, V_ADD_U16_e64>; 464defm : Arithmetic_i16_Pats<mul, V_MUL_LO_U16_e64>; 465defm : Arithmetic_i16_Pats<sub, V_SUB_U16_e64>; 466defm : Arithmetic_i16_Pats<smin, V_MIN_I16_e64>; 467defm : Arithmetic_i16_Pats<smax, V_MAX_I16_e64>; 468defm : Arithmetic_i16_Pats<umin, V_MIN_U16_e64>; 469defm : Arithmetic_i16_Pats<umax, V_MAX_U16_e64>; 470 471def : Pat < 472 (and i16:$src0, i16:$src1), 473 (V_AND_B32_e64 $src0, $src1) 474>; 475 476def : Pat < 477 (or i16:$src0, i16:$src1), 478 (V_OR_B32_e64 $src0, $src1) 479>; 480 481def : Pat < 482 (xor i16:$src0, i16:$src1), 483 (V_XOR_B32_e64 $src0, $src1) 484>; 485 486defm : Bits_OpsRev_i16_Pats<shl, V_LSHLREV_B16_e64>; 487defm : Bits_OpsRev_i16_Pats<srl, V_LSHRREV_B16_e64>; 488defm : Bits_OpsRev_i16_Pats<sra, V_ASHRREV_I16_e64>; 489 490def : ZExt_i16_i1_Pat<zext>; 491def : ZExt_i16_i1_Pat<anyext>; 492 493def : Pat < 494 (i16 (sext i1:$src)), 495 (V_CNDMASK_B32_e64 (i32 0), (i32 -1), $src) 496>; 497 498// Undo sub x, c -> add x, -c canonicalization since c is more likely 499// an inline immediate than -c. 500// TODO: Also do for 64-bit. 501def : Pat< 502 (add i16:$src0, (i16 NegSubInlineConst16:$src1)), 503 (V_SUB_U16_e64 $src0, NegSubInlineConst16:$src1) 504>; 505 506} // End Predicates = [isVI] 507 508//===----------------------------------------------------------------------===// 509// SI 510//===----------------------------------------------------------------------===// 511 512let AssemblerPredicates = [isSICI], DecoderNamespace = "SICI" in { 513 514multiclass VOP2_Real_si <bits<6> op> { 515 def _si : 516 VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.SI>, 517 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>; 518} 519 520multiclass VOP2_Real_MADK_si <bits<6> op> { 521 def _si : VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.SI>, 522 VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>; 523} 524 525multiclass VOP2_Real_e32_si <bits<6> op> { 526 def _e32_si : 527 VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.SI>, 528 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>; 529} 530 531multiclass VOP2_Real_e32e64_si <bits<6> op> : VOP2_Real_e32_si<op> { 532 def _e64_si : 533 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>, 534 VOP3e_si <{1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 535} 536 537multiclass VOP2be_Real_e32e64_si <bits<6> op> : VOP2_Real_e32_si<op> { 538 def _e64_si : 539 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>, 540 VOP3be_si <{1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 541} 542 543} // End AssemblerPredicates = [isSICI], DecoderNamespace = "SICI" 544 545defm V_CNDMASK_B32 : VOP2_Real_e32e64_si <0x0>; 546defm V_ADD_F32 : VOP2_Real_e32e64_si <0x3>; 547defm V_SUB_F32 : VOP2_Real_e32e64_si <0x4>; 548defm V_SUBREV_F32 : VOP2_Real_e32e64_si <0x5>; 549defm V_MUL_LEGACY_F32 : VOP2_Real_e32e64_si <0x7>; 550defm V_MUL_F32 : VOP2_Real_e32e64_si <0x8>; 551defm V_MUL_I32_I24 : VOP2_Real_e32e64_si <0x9>; 552defm V_MUL_HI_I32_I24 : VOP2_Real_e32e64_si <0xa>; 553defm V_MUL_U32_U24 : VOP2_Real_e32e64_si <0xb>; 554defm V_MUL_HI_U32_U24 : VOP2_Real_e32e64_si <0xc>; 555defm V_MIN_F32 : VOP2_Real_e32e64_si <0xf>; 556defm V_MAX_F32 : VOP2_Real_e32e64_si <0x10>; 557defm V_MIN_I32 : VOP2_Real_e32e64_si <0x11>; 558defm V_MAX_I32 : VOP2_Real_e32e64_si <0x12>; 559defm V_MIN_U32 : VOP2_Real_e32e64_si <0x13>; 560defm V_MAX_U32 : VOP2_Real_e32e64_si <0x14>; 561defm V_LSHRREV_B32 : VOP2_Real_e32e64_si <0x16>; 562defm V_ASHRREV_I32 : VOP2_Real_e32e64_si <0x18>; 563defm V_LSHLREV_B32 : VOP2_Real_e32e64_si <0x1a>; 564defm V_AND_B32 : VOP2_Real_e32e64_si <0x1b>; 565defm V_OR_B32 : VOP2_Real_e32e64_si <0x1c>; 566defm V_XOR_B32 : VOP2_Real_e32e64_si <0x1d>; 567defm V_MAC_F32 : VOP2_Real_e32e64_si <0x1f>; 568defm V_MADMK_F32 : VOP2_Real_MADK_si <0x20>; 569defm V_MADAK_F32 : VOP2_Real_MADK_si <0x21>; 570defm V_ADD_I32 : VOP2be_Real_e32e64_si <0x25>; 571defm V_SUB_I32 : VOP2be_Real_e32e64_si <0x26>; 572defm V_SUBREV_I32 : VOP2be_Real_e32e64_si <0x27>; 573defm V_ADDC_U32 : VOP2be_Real_e32e64_si <0x28>; 574defm V_SUBB_U32 : VOP2be_Real_e32e64_si <0x29>; 575defm V_SUBBREV_U32 : VOP2be_Real_e32e64_si <0x2a>; 576 577defm V_READLANE_B32 : VOP2_Real_si <0x01>; 578defm V_WRITELANE_B32 : VOP2_Real_si <0x02>; 579 580defm V_MAC_LEGACY_F32 : VOP2_Real_e32e64_si <0x6>; 581defm V_MIN_LEGACY_F32 : VOP2_Real_e32e64_si <0xd>; 582defm V_MAX_LEGACY_F32 : VOP2_Real_e32e64_si <0xe>; 583defm V_LSHR_B32 : VOP2_Real_e32e64_si <0x15>; 584defm V_ASHR_I32 : VOP2_Real_e32e64_si <0x17>; 585defm V_LSHL_B32 : VOP2_Real_e32e64_si <0x19>; 586 587defm V_BFM_B32 : VOP2_Real_e32e64_si <0x1e>; 588defm V_BCNT_U32_B32 : VOP2_Real_e32e64_si <0x22>; 589defm V_MBCNT_LO_U32_B32 : VOP2_Real_e32e64_si <0x23>; 590defm V_MBCNT_HI_U32_B32 : VOP2_Real_e32e64_si <0x24>; 591defm V_LDEXP_F32 : VOP2_Real_e32e64_si <0x2b>; 592defm V_CVT_PKACCUM_U8_F32 : VOP2_Real_e32e64_si <0x2c>; 593defm V_CVT_PKNORM_I16_F32 : VOP2_Real_e32e64_si <0x2d>; 594defm V_CVT_PKNORM_U16_F32 : VOP2_Real_e32e64_si <0x2e>; 595defm V_CVT_PKRTZ_F16_F32 : VOP2_Real_e32e64_si <0x2f>; 596defm V_CVT_PK_U16_U32 : VOP2_Real_e32e64_si <0x30>; 597defm V_CVT_PK_I16_I32 : VOP2_Real_e32e64_si <0x31>; 598 599 600//===----------------------------------------------------------------------===// 601// VI 602//===----------------------------------------------------------------------===// 603 604class VOP2_DPP <bits<6> op, VOP2_Pseudo ps, VOPProfile P = ps.Pfl> : 605 VOP_DPP <ps.OpName, P> { 606 let Defs = ps.Defs; 607 let Uses = ps.Uses; 608 let SchedRW = ps.SchedRW; 609 let hasSideEffects = ps.hasSideEffects; 610 let Constraints = ps.Constraints; 611 let DisableEncoding = ps.DisableEncoding; 612 613 bits<8> vdst; 614 bits<8> src1; 615 let Inst{8-0} = 0xfa; //dpp 616 let Inst{16-9} = !if(P.HasSrc1, src1{7-0}, 0); 617 let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0); 618 let Inst{30-25} = op; 619 let Inst{31} = 0x0; //encoding 620} 621 622let AssemblerPredicates = [isVI], DecoderNamespace = "VI" in { 623 624multiclass VOP32_Real_vi <bits<10> op> { 625 def _vi : 626 VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.VI>, 627 VOP3e_vi<op, !cast<VOP2_Pseudo>(NAME).Pfl>; 628} 629 630multiclass VOP2_Real_MADK_vi <bits<6> op> { 631 def _vi : VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.VI>, 632 VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>; 633} 634 635multiclass VOP2_Real_e32_vi <bits<6> op> { 636 def _e32_vi : 637 VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.VI>, 638 VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>; 639} 640 641multiclass VOP2_Real_e64_vi <bits<10> op> { 642 def _e64_vi : 643 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>, 644 VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 645} 646 647multiclass Base_VOP2be_Real_e32e64_vi <bits<6> op> : VOP2_Real_e32_vi<op> { 648 def _e64_vi : 649 VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>, 650 VOP3be_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>; 651} 652 653multiclass Base_VOP2_Real_e32e64_vi <bits<6> op> : 654 VOP2_Real_e32_vi<op>, 655 VOP2_Real_e64_vi<{0, 1, 0, 0, op{5-0}}>; 656 657} // End AssemblerPredicates = [isVI], DecoderNamespace = "VI" 658 659multiclass VOP2_SDWA_Real <bits<6> op> { 660 def _sdwa_vi : 661 VOP_SDWA_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>, 662 VOP2_SDWAe <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl>; 663} 664 665multiclass VOP2be_Real_e32e64_vi <bits<6> op> : 666 Base_VOP2be_Real_e32e64_vi<op>, VOP2_SDWA_Real<op> { 667 // For now left dpp only for asm/dasm 668 // TODO: add corresponding pseudo 669 def _dpp : VOP2_DPP<op, !cast<VOP2_Pseudo>(NAME#"_e32")>; 670} 671 672multiclass VOP2_Real_e32e64_vi <bits<6> op> : 673 Base_VOP2_Real_e32e64_vi<op>, VOP2_SDWA_Real<op> { 674 // For now left dpp only for asm/dasm 675 // TODO: add corresponding pseudo 676 def _dpp : VOP2_DPP<op, !cast<VOP2_Pseudo>(NAME#"_e32")>; 677} 678 679defm V_CNDMASK_B32 : Base_VOP2_Real_e32e64_vi <0x0>; 680defm V_ADD_F32 : VOP2_Real_e32e64_vi <0x1>; 681defm V_SUB_F32 : VOP2_Real_e32e64_vi <0x2>; 682defm V_SUBREV_F32 : VOP2_Real_e32e64_vi <0x3>; 683defm V_MUL_LEGACY_F32 : VOP2_Real_e32e64_vi <0x4>; 684defm V_MUL_F32 : VOP2_Real_e32e64_vi <0x5>; 685defm V_MUL_I32_I24 : VOP2_Real_e32e64_vi <0x6>; 686defm V_MUL_HI_I32_I24 : VOP2_Real_e32e64_vi <0x7>; 687defm V_MUL_U32_U24 : VOP2_Real_e32e64_vi <0x8>; 688defm V_MUL_HI_U32_U24 : VOP2_Real_e32e64_vi <0x9>; 689defm V_MIN_F32 : VOP2_Real_e32e64_vi <0xa>; 690defm V_MAX_F32 : VOP2_Real_e32e64_vi <0xb>; 691defm V_MIN_I32 : VOP2_Real_e32e64_vi <0xc>; 692defm V_MAX_I32 : VOP2_Real_e32e64_vi <0xd>; 693defm V_MIN_U32 : VOP2_Real_e32e64_vi <0xe>; 694defm V_MAX_U32 : VOP2_Real_e32e64_vi <0xf>; 695defm V_LSHRREV_B32 : VOP2_Real_e32e64_vi <0x10>; 696defm V_ASHRREV_I32 : VOP2_Real_e32e64_vi <0x11>; 697defm V_LSHLREV_B32 : VOP2_Real_e32e64_vi <0x12>; 698defm V_AND_B32 : VOP2_Real_e32e64_vi <0x13>; 699defm V_OR_B32 : VOP2_Real_e32e64_vi <0x14>; 700defm V_XOR_B32 : VOP2_Real_e32e64_vi <0x15>; 701defm V_MAC_F32 : VOP2_Real_e32e64_vi <0x16>; 702defm V_MADMK_F32 : VOP2_Real_MADK_vi <0x17>; 703defm V_MADAK_F32 : VOP2_Real_MADK_vi <0x18>; 704defm V_ADD_I32 : VOP2be_Real_e32e64_vi <0x19>; 705defm V_SUB_I32 : VOP2be_Real_e32e64_vi <0x1a>; 706defm V_SUBREV_I32 : VOP2be_Real_e32e64_vi <0x1b>; 707defm V_ADDC_U32 : VOP2be_Real_e32e64_vi <0x1c>; 708defm V_SUBB_U32 : VOP2be_Real_e32e64_vi <0x1d>; 709defm V_SUBBREV_U32 : VOP2be_Real_e32e64_vi <0x1e>; 710 711defm V_READLANE_B32 : VOP32_Real_vi <0x289>; 712defm V_WRITELANE_B32 : VOP32_Real_vi <0x28a>; 713 714defm V_BFM_B32 : VOP2_Real_e64_vi <0x293>; 715defm V_BCNT_U32_B32 : VOP2_Real_e64_vi <0x28b>; 716defm V_MBCNT_LO_U32_B32 : VOP2_Real_e64_vi <0x28c>; 717defm V_MBCNT_HI_U32_B32 : VOP2_Real_e64_vi <0x28d>; 718defm V_LDEXP_F32 : VOP2_Real_e64_vi <0x288>; 719defm V_CVT_PKACCUM_U8_F32 : VOP2_Real_e64_vi <0x1f0>; 720defm V_CVT_PKNORM_I16_F32 : VOP2_Real_e64_vi <0x294>; 721defm V_CVT_PKNORM_U16_F32 : VOP2_Real_e64_vi <0x295>; 722defm V_CVT_PKRTZ_F16_F32 : VOP2_Real_e64_vi <0x296>; 723defm V_CVT_PK_U16_U32 : VOP2_Real_e64_vi <0x297>; 724defm V_CVT_PK_I16_I32 : VOP2_Real_e64_vi <0x298>; 725 726defm V_ADD_F16 : VOP2_Real_e32e64_vi <0x1f>; 727defm V_SUB_F16 : VOP2_Real_e32e64_vi <0x20>; 728defm V_SUBREV_F16 : VOP2_Real_e32e64_vi <0x21>; 729defm V_MUL_F16 : VOP2_Real_e32e64_vi <0x22>; 730defm V_MAC_F16 : VOP2_Real_e32e64_vi <0x23>; 731defm V_MADMK_F16 : VOP2_Real_MADK_vi <0x24>; 732defm V_MADAK_F16 : VOP2_Real_MADK_vi <0x25>; 733defm V_ADD_U16 : VOP2_Real_e32e64_vi <0x26>; 734defm V_SUB_U16 : VOP2_Real_e32e64_vi <0x27>; 735defm V_SUBREV_U16 : VOP2_Real_e32e64_vi <0x28>; 736defm V_MUL_LO_U16 : VOP2_Real_e32e64_vi <0x29>; 737defm V_LSHLREV_B16 : VOP2_Real_e32e64_vi <0x2a>; 738defm V_LSHRREV_B16 : VOP2_Real_e32e64_vi <0x2b>; 739defm V_ASHRREV_I16 : VOP2_Real_e32e64_vi <0x2c>; 740defm V_MAX_F16 : VOP2_Real_e32e64_vi <0x2d>; 741defm V_MIN_F16 : VOP2_Real_e32e64_vi <0x2e>; 742defm V_MAX_U16 : VOP2_Real_e32e64_vi <0x2f>; 743defm V_MAX_I16 : VOP2_Real_e32e64_vi <0x30>; 744defm V_MIN_U16 : VOP2_Real_e32e64_vi <0x31>; 745defm V_MIN_I16 : VOP2_Real_e32e64_vi <0x32>; 746defm V_LDEXP_F16 : VOP2_Real_e32e64_vi <0x33>; 747 748let SubtargetPredicate = isVI in { 749 750// Aliases to simplify matching of floating-point instructions that 751// are VOP2 on SI and VOP3 on VI. 752class SI2_VI3Alias <string name, Instruction inst> : InstAlias < 753 name#" $dst, $src0, $src1", 754 (inst VGPR_32:$dst, 0, VCSrc_f32:$src0, 0, VCSrc_f32:$src1, 0, 0) 755>, PredicateControl { 756 let UseInstAsmMatchConverter = 0; 757 let AsmVariantName = AMDGPUAsmVariants.VOP3; 758} 759 760def : SI2_VI3Alias <"v_ldexp_f32", V_LDEXP_F32_e64_vi>; 761def : SI2_VI3Alias <"v_cvt_pkaccum_u8_f32", V_CVT_PKACCUM_U8_F32_e64_vi>; 762def : SI2_VI3Alias <"v_cvt_pknorm_i16_f32", V_CVT_PKNORM_I16_F32_e64_vi>; 763def : SI2_VI3Alias <"v_cvt_pknorm_u16_f32", V_CVT_PKNORM_U16_F32_e64_vi>; 764def : SI2_VI3Alias <"v_cvt_pkrtz_f16_f32", V_CVT_PKRTZ_F16_F32_e64_vi>; 765 766} // End SubtargetPredicate = isVI 767