2281 lines · plain
1//===-- VOPInstructions.td - Vector Instruction Definitions ---------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9// dummies for outer let10class LetDummies {11 bit TRANS;12 bit ReadsModeReg;13 bit mayRaiseFPException;14 bit isCommutable;15 bit isConvertibleToThreeAddress;16 bit isMoveImm;17 bit isReMaterializable;18 bit isConvergent;19 bit isAsCheapAsAMove;20 bit FPDPRounding;21 Predicate SubtargetPredicate;22 string Constraints;23 string DisableEncoding;24 list<SchedReadWrite> SchedRW;25 list<Register> Uses;26 list<Register> Defs;27 list<Predicate> OtherPredicates;28 Predicate AssemblerPredicate;29 string DecoderNamespace;30}31 32class VOP <string opName> {33 string OpName = opName;34}35 36// First 13 insts from VOPDY are also VOPDX. DOT2ACC_F32_BF16 is omitted37defvar VOPDX_Max_Index = 12;38defvar VOPD3X_Max_Index = 36;39 40class VOPD_Component<bits<6> OpIn, string vOPDName> {41 Instruction BaseVOP = !cast<Instruction>(NAME);42 string VOPDName = "v_dual_" # !substr(vOPDName, 2);43 bits<6> VOPDOp = OpIn;44 bit CanBeVOPDX = !le(VOPDOp, VOPDX_Max_Index);45 bit CanBeVOPD3X = !and(!le(VOPDOp, VOPD3X_Max_Index),46 !and(!ne(vOPDName, "v_bitop2_b32"),47 !and(!ne(vOPDName, "v_max_i32"),48 !ne(vOPDName, "v_min_i32"))));49}50 51class VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> :52 InstSI <outs, ins, asm, pattern> {53 54 let mayLoad = 0;55 let mayStore = 0;56 let hasSideEffects = 0;57 let UseNamedOperandTable = 1;58 let VALU = 1;59 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);60}61 62class VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins,63 string asm, list<dag> pattern> :64 InstSI <outs, ins, asm, pattern>,65 VOP <opName>,66 SIMCInstr <opName#suffix, SIEncodingFamily.NONE> {67 let isPseudo = 1;68 let isCodeGenOnly = 1;69 let UseNamedOperandTable = 1;70 71 string Mnemonic = opName;72 Instruction Opcode = !cast<Instruction>(NAME);73 bit IsTrue16 = P.IsTrue16;74 VOPProfile Pfl = P;75 76 string AsmOperands;77}78 79class VOP3Common <dag outs, dag ins, string asm = "",80 list<dag> pattern = [], bit HasMods = 0> :81 VOPAnyCommon <outs, ins, asm, pattern> {82 83 // Using complex patterns gives VOP3 patterns a very high complexity rating,84 // but standalone patterns are almost always preferred, so we need to adjust the85 // priority lower. The goal is to use a high number to reduce complexity to86 // zero (or less than zero).87 let AddedComplexity = -1000;88 89 let VOP3 = 1;90 91 let AsmVariantName = AMDGPUAsmVariants.VOP3;92 let AsmMatchConverter = !if(HasMods, "cvtVOP3", "");93 94 let isCodeGenOnly = 0;95 96 int Size = 8;97 98 // Because SGPRs may be allowed if there are multiple operands, we99 // need a post-isel hook to insert copies in order to avoid100 // violating constant bus requirements.101 let hasPostISelHook = 1;102}103 104class VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [],105 bit isVOP3P = 0, bit isVop3OpSel = 0> :106 VOP_Pseudo <opName, "_e64", P, P.Outs64,107 !if(isVop3OpSel,108 P.InsVOP3OpSel,109 !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)),110 "", pattern> {111 112 let VOP3_OPSEL = isVop3OpSel;113 let IsPacked = P.IsPacked;114 let IsMAI = P.IsMAI;115 let IsWMMA = P.IsWMMA;116 let IsSWMMAC = P.IsSWMMAC;117 118 bit HasFP8DstByteSel = P.HasFP8DstByteSel;119 bit HasFP4DstByteSel = P.HasFP4DstByteSel;120 121 let AsmOperands = !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64);122 123 let Size = 8;124 let mayLoad = 0;125 let mayStore = 0;126 let hasSideEffects = 0;127 128 // Because SGPRs may be allowed if there are multiple operands, we129 // need a post-isel hook to insert copies in order to avoid130 // violating constant bus requirements.131 let hasPostISelHook = 1;132 133 // Using complex patterns gives VOP3 patterns a very high complexity rating,134 // but standalone patterns are almost always preferred, so we need to adjust the135 // priority lower. The goal is to use a high number to reduce complexity to136 // zero (or less than zero).137 let AddedComplexity = -1000;138 139 let VOP3 = 1;140 let VALU = 1;141 let FPClamp = P.HasFPClamp;142 let IntClamp = P.HasIntClamp;143 let ClampLo = P.HasClampLo;144 let ClampHi = P.HasClampHi;145 146 let ReadsModeReg = !or(P.DstVT.isFP, P.Src0VT.isFP);147 148 let mayRaiseFPException = ReadsModeReg;149 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);150 151 let AsmVariantName = AMDGPUAsmVariants.VOP3;152 let AsmMatchConverter =153 !if(isVOP3P,154 "cvtVOP3P",155 !if(!or(P.HasModifiers, P.HasOMod, P.HasClamp),156 "cvtVOP3",157 ""));158}159 160class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> :161 VOP3_Pseudo<opName, P, pattern, 1> {162 let VOP3P = 1;163 let IsDOT = P.IsDOT;164}165 166class VOP_Real<VOP_Pseudo ps> {167 Instruction Opcode = !cast<Instruction>(NAME);168 bit IsSingle = ps.Pfl.IsSingle;169}170 171class VOP3_Real <VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :172 VOP_Real <ps>,173 InstSI <ps.OutOperandList, ps.InOperandList, asm_name # ps.AsmOperands, []>,174 SIMCInstr <ps.PseudoInstr, EncodingFamily> {175 176 let VALU = 1;177 let VOP3 = 1;178 let isPseudo = 0;179 let isCodeGenOnly = 0;180 let UseNamedOperandTable = 1;181 182 // copy relevant pseudo op flags183 let SubtargetPredicate = ps.SubtargetPredicate;184 let WaveSizePredicate = ps.WaveSizePredicate;185 let OtherPredicates = ps.OtherPredicates;186 let True16Predicate = ps.True16Predicate;187 let AsmMatchConverter = ps.AsmMatchConverter;188 let AsmVariantName = ps.AsmVariantName;189 let Constraints = ps.Constraints;190 let TSFlags = ps.TSFlags;191 let UseNamedOperandTable = ps.UseNamedOperandTable;192 let Uses = ps.Uses;193 let Defs = ps.Defs;194 let SchedRW = ps.SchedRW;195 let mayLoad = ps.mayLoad;196 let mayStore = ps.mayStore;197 let TRANS = ps.TRANS;198 let isConvergent = ps.isConvergent;199 200 VOPProfile Pfl = ps.Pfl;201}202 203class VOP3_Real_Gen <VOP_Pseudo ps, GFXGen Gen, string asm_name = ps.Mnemonic> :204 VOP3_Real <ps, Gen.Subtarget, asm_name> {205 let AssemblerPredicate = Gen.AssemblerPredicate;206 let True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);207 let DecoderNamespace = Gen.DecoderNamespace#208 !if(ps.Pfl.IsRealTrue16, "", "_FAKE16");209}210 211// XXX - Is there any reason to distinguish this from regular VOP3212// here?213class VOP3P_Real<VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :214 VOP3_Real<ps, EncodingFamily, asm_name> {215 216 // The v_wmma pseudos have extra constraints that we do not want to impose on the real instruction.217 let Constraints = !if(!eq(!substr(ps.Mnemonic,0,6), "v_wmma"), "", ps.Constraints);218}219 220class VOP3P_Real_Gen<VOP_Pseudo ps, GFXGen Gen, string asm_name = ps.Mnemonic> :221 VOP3P_Real<ps, Gen.Subtarget, asm_name> {222 let AssemblerPredicate = Gen.AssemblerPredicate;223 let DecoderNamespace = Gen.DecoderNamespace;224}225 226class VOP3a<VOPProfile P> : Enc64 {227 bits<4> src0_modifiers;228 bits<9> src0;229 bits<3> src1_modifiers;230 bits<9> src1;231 bits<3> src2_modifiers;232 bits<9> src2;233 bits<1> clamp;234 bits<2> omod;235 236 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);237 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);238 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);239 240 let Inst{31-26} = 0x34; //encoding241 let Inst{40-32} = !if(P.HasSrc0, src0, 0);242 let Inst{49-41} = !if(P.HasSrc1, src1, 0);243 let Inst{58-50} = !if(P.HasSrc2, src2, 0);244 let Inst{60-59} = !if(P.HasOMod, omod, 0);245 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);246 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);247 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);248}249 250// To avoid having different version of every type of operand depending on if251// they are part of a True16 instruction or not, the operand encoding should be252// the same for SGPR, imm, and VGPR_32 whether the instruction is True16 or not.253class VOP3a_t16<VOPProfile P> : Enc64 {254 bits<11> vdst;255 bits<4> src0_modifiers;256 bits<11> src0;257 bits<3> src1_modifiers;258 bits<11> src1;259 bits<3> src2_modifiers;260 bits<11> src2;261 bits<1> clamp;262 bits<2> omod;263 264 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);265 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);266 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);267 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);268 // 16-bit select fields which can be interpreted as OpSel or hi/lo suffix269 let Inst{11} = !if(P.HasSrc0Mods, src0_modifiers{2}, 0);270 let Inst{12} = !if(P.HasSrc1Mods, src1_modifiers{2}, 0);271 let Inst{13} = !if(P.HasSrc2Mods, src2_modifiers{2}, 0);272 let Inst{14} = !if(!and(P.HasDst, P.HasSrc0Mods), src0_modifiers{3}, 0);273 let Inst{15} = !if(P.HasClamp, clamp{0}, 0);274 275 let Inst{31-26} = 0x35;276 let Inst{40-32} = !if(P.HasSrc0, src0{8-0}, 0);277 let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0);278 let Inst{58-50} = !if(P.HasSrc2, src2{8-0}, 0);279 let Inst{60-59} = !if(P.HasOMod, omod, 0);280 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);281 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);282 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);283}284 285class VOP3a_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a<p> {286 let Inst{11} = !if(p.HasClamp, clamp{0}, 0);287 let Inst{25-17} = op;288}289 290class VOP3a_gfx10<bits<10> op, VOPProfile p> : VOP3a<p> {291 let Inst{15} = !if(p.HasClamp, clamp{0}, 0);292 let Inst{25-16} = op;293 let Inst{31-26} = 0x35;294}295 296class VOP3a_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p>;297 298class VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> {299 let Inst{25-16} = op;300 let Inst{15} = !if(P.HasClamp, clamp{0}, 0);301}302 303class VOP3e_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a_gfx6_gfx7<op, p> {304 bits<8> vdst;305 let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0);306}307 308class VOP3e_gfx10<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p> {309 bits<8> vdst;310 let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0);311}312 313class VOP3e_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p>;314 315class VOP3e_t16_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3a_t16<p> {316 let Inst{25-16} = op;317}318 319class VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> {320 bits<8> vdst;321 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);322}323 324class VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {325 let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0);326 let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0);327 let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0);328 let Inst{14} = !if(P.HasDst, src0_modifiers{3}, 0);329}330 331// Special case for v_permlane16_swap_b32/v_permlane32_swap_b32332// op_sel[0]/op_sel[1] are treated as bound_ctrl and fi dpp operands.333class VOP3OpSelIsDPP_base {334 bits<1> fi;335 bits<1> bound_ctrl;336}337 338class VOP3OpSelIsDPP_gfx9 <bits<10> op, VOPProfile P> : VOP3OpSelIsDPP_base, VOP3e_vi <op, P> {339 // OPSEL[0] specifies FI340 let Inst{11} = fi;341 // OPSEL[1] specifies BOUND_CTRL342 let Inst{12} = bound_ctrl;343}344 345class VOP3OpSelIsDPP_gfx12 <bits<10> op, VOPProfile P> : VOP3OpSelIsDPP_base, VOP3e_gfx11_gfx12 <op, P> {346 // OPSEL[0] specifies FI347 let Inst{11} = fi;348 // OPSEL[1] specifies BOUND_CTRL349 let Inst{12} = bound_ctrl;350}351 352class VOP3OpSel_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {353 let Inst{11} = !if(p.HasSrc0, src0_modifiers{2}, 0);354 let Inst{12} = !if(p.HasSrc1, src1_modifiers{2}, 0);355 let Inst{13} = !if(p.HasSrc2, src2_modifiers{2}, 0);356 let Inst{14} = !if(p.HasDst, src0_modifiers{3}, 0);357}358 359class VOP3OpSel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3OpSel_gfx10<op, p>;360 361class VOP3FP8OpSel_src_bytesel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {362 bits<2> byte_sel;363 let Inst{11-12} = byte_sel; // NB: bit order is intentionally reversed!364 let Inst{13} = !if(!and(p.HasOpSel, p.HasSrc2), src2_modifiers{2}, 0);365 let Inst{14} = !if(!and(p.HasOpSel, p.HasDst), src0_modifiers{3}, 0);366}367 368class VOP3FP8OpSel_dst_bytesel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {369 bits<2> byte_sel;370 371 let Inst{11} = !if(!and(p.HasOpSel, p.HasSrc0Mods), src0_modifiers{2}, 0); // op_sel0372 let Inst{12} = !if(!and(p.HasOpSel, p.HasSrc1Mods), src1_modifiers{2}, 0); // op_sel1373 let Inst{14-13} = byte_sel; // op_sel2/3374}375 376class VOP3DotOpSel_gfx11_gfx12<bits<10> op, VOPProfile p> :377 VOP3e_t16_gfx11_gfx12<op, p>{378 let Inst{11} = ?;379 let Inst{12} = ?;380 let Inst{13} = !if(p.HasSrc2Mods, src2_modifiers{2}, 0);381 let Inst{14} = !if(!and(p.HasDst, p.HasSrc0Mods), src0_modifiers{3}, 0);382}383 384// NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa385class VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {386 bits<2> attrchan;387 bits<6> attr;388 bits<1> high;389 390 let Inst{8} = 0; // No modifiers for src0391 let Inst{61} = 0;392 393 let Inst{9} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);394 let Inst{62} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);395 396 let Inst{37-32} = attr;397 let Inst{39-38} = attrchan;398 let Inst{40} = !if(P.HasHigh, high, 0);399 400 let Inst{49-41} = src0;401}402 403class VOP3a_BITOP3_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx11_gfx12<op, p> {404 bits<8> bitop3;405 406 let Inst{60-59} = bitop3{7-6};407 let Inst{10-8} = bitop3{5-3};408 let Inst{63-61} = bitop3{2-0};409 410 let Inst{11} = !if(p.HasOpSel, src0_modifiers{2}, 0);411 let Inst{12} = !if(p.HasOpSel, src1_modifiers{2}, 0);412 let Inst{13} = !if(p.HasOpSel, src2_modifiers{2}, 0);413 let Inst{14} = !if(p.HasOpSel, src0_modifiers{3}, 0);414}415 416class VOP3a_ScaleSel_gfx1250<bits<10> op, VOPProfile p> : VOP3e_gfx11_gfx12<op, p> {417 bits<4> scale_sel;418 419 let Inst{14-11} = scale_sel;420}421 422class VOP3Interp_OpSel_gfx9<bits<10> op, VOPProfile p> : VOP3Interp_vi<op, p> {423 let Inst{11} = src0_modifiers{2};424 // There's no src1425 let Inst{13} = src2_modifiers{2};426 let Inst{14} = !if(p.HasDst, src0_modifiers{3}, 0);427}428 429class VOP3Interp_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {430 bits<6> attr;431 bits<2> attrchan;432 bits<1> high;433 434 let Inst{8} = 0;435 let Inst{9} = !if(p.HasSrc0Mods, src0_modifiers{1}, 0);436 let Inst{37-32} = attr;437 let Inst{39-38} = attrchan;438 let Inst{40} = !if(p.HasHigh, high, 0);439 let Inst{49-41} = src0;440 let Inst{61} = 0;441 let Inst{62} = !if(p.HasSrc0Mods, src0_modifiers{0}, 0);442}443 444class VOP3Interp_gfx11<bits<10> op, VOPProfile p> : VOP3Interp_gfx10<op, p>;445 446class VOP3be <VOPProfile P> : Enc64 {447 bits<8> vdst;448 bits<2> src0_modifiers;449 bits<9> src0;450 bits<2> src1_modifiers;451 bits<9> src1;452 bits<2> src2_modifiers;453 bits<9> src2;454 bits<7> sdst;455 bits<2> omod;456 457 let Inst{7-0} = vdst;458 let Inst{14-8} = sdst;459 let Inst{31-26} = 0x34; //encoding460 let Inst{40-32} = !if(P.HasSrc0, src0, 0);461 let Inst{49-41} = !if(P.HasSrc1, src1, 0);462 let Inst{58-50} = !if(P.HasSrc2, src2, 0);463 let Inst{60-59} = !if(P.HasOMod, omod, 0);464 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);465 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);466 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);467}468 469class VOP3Pe_Base {470 bits<8> vdst;471 bits<4> src0_modifiers;472 bits<9> src0;473 bits<4> src1_modifiers;474 bits<9> src1;475 bits<4> src2_modifiers;476 bits<9> src2;477 bits<1> clamp;478 bits<2> index_key_8bit;479 bits<1> index_key_16bit;480 bits<1> index_key_32bit;481 bits<3> matrix_a_fmt;482 bits<3> matrix_b_fmt;483 bits<1> matrix_a_scale;484 bits<1> matrix_b_scale;485 bits<2> matrix_a_scale_fmt;486 bits<2> matrix_b_scale_fmt;487 bits<1> matrix_a_reuse;488 bits<1> matrix_b_reuse;489}490 491class VOP3Pe <VOPProfile P> : Enc64, VOP3Pe_Base {492 let Inst{7-0} = !if(P.HasDst, vdst, 0);493 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1},494 !if(P.HasMatrixScale, matrix_b_scale_fmt{0}, 0)); // neg_hi src0495 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1},496 !if(P.HasMatrixScale, matrix_b_scale_fmt{1}, 0)); // neg_hi src1497 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2498 499 let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2},500 !if(P.HasMatrixScale, matrix_a_scale{0}, 0)); // op_sel(0)501 let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)502 let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2},503 !if(P.HasMatrixReuse, matrix_a_reuse, 0)); // op_sel(2)504 505 let Inst{14} = !cond(!and(P.HasSrc2, P.HasOpSel) : src2_modifiers{3},506 P.IsDOT : 1,507 P.HasMatrixReuse : matrix_b_reuse,508 1: ?); // op_sel_hi(2)509 510 let Inst{15} = !if(P.HasClamp, clamp{0}, 0);511 512 let Inst{40-32} = !if(P.HasSrc0, src0, 0);513 let Inst{49-41} = !if(P.HasSrc1, src1, 0);514 let Inst{58-50} = !if(P.HasSrc2, src2, 0);515 let Inst{59} = !cond(!and(P.HasSrc0, P.HasOpSel) : src0_modifiers{3},516 P.IsDOT : 1,517 P.HasMatrixScale : matrix_b_scale{0},518 1: ?); // op_sel_hi(0)519 let Inst{60} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3},520 !if(P.HasMatrixScale, 0,521 !if(P.IsDOT, 1, ?))); // op_sel_hi(1)522 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0},523 !if(P.HasMatrixScale, matrix_a_scale_fmt{0}, 0)); // neg (lo)524 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0},525 !if(P.HasMatrixScale, matrix_a_scale_fmt{1}, 0)); // neg (lo)526 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)527}528 529class VOP3Pe_MAI_Base {530 bits<8> vdst;531 bits<10> src0;532 bits<10> src1;533 bits<9> src2;534 bits<3> blgp;535 bits<3> cbsz;536 bits<4> abid;537}538 539class VOP3Pe_MAI <bits<7> op, VOPProfile P, bit acc_cd = 0> : Enc64, VOP3Pe_MAI_Base {540 let Inst{7-0} = vdst;541 542 let Inst{10-8} = !if(P.HasSrc1, cbsz, 0);543 let Inst{14-11} = !if(P.HasAbid, abid, 0);544 545 let Inst{15} = acc_cd;546 547 let Inst{22-16} = op;548 let Inst{31-23} = 0x1a7; //encoding549 let Inst{40-32} = !if(P.HasSrc0, src0{8-0}, 0);550 let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0);551 let Inst{58-50} = !if(P.HasSrc2, src2, 0);552 553 let Inst{59} = !if(P.HasSrc0, src0{9}, 0); // acc(0)554 let Inst{60} = !if(P.HasSrc1, src1{9}, 0); // acc(1)555 556 let Inst{63-61} = !if(P.HasSrc1, blgp, 0);557}558 559class VOP3Pe_SMFMAC <bits<7> op> : Enc64 {560 bits<10> vdst; // VGPR or AGPR, but not SGPR. vdst{8} is not encoded in the instruction.561 bits<10> src0;562 bits<10> src1;563 bits<9> idx;564 bits<3> blgp;565 bits<3> cbsz;566 bits<4> abid;567 568 let blgp = 0;569 570 let Inst{7-0} = vdst{7-0};571 572 let Inst{10-8} = cbsz;573 let Inst{14-11} = abid;574 575 let Inst{15} = vdst{9}; // acc(vdst)576 577 let Inst{22-16} = op;578 let Inst{31-23} = 0x1a7; // encoding579 let Inst{40-32} = src0{8-0};580 let Inst{49-41} = src1{8-0};581 let Inst{58-50} = idx;582 583 let Inst{59} = src0{9}; // acc(0)584 let Inst{60} = src1{9}; // acc(1)585 586 let Inst{63-61} = blgp;587}588 589class VOP3PXe <bits<7> op, VOPProfile MFMAPfl, bit acc_cd = 0> : Enc128, VOP3Pe_MAI_Base {590 bits<9> scale_src0;591 bits<9> scale_src1;592 593 //MFMALdScaleModifierOp transforms 2 bit opsel input to 4 bit value594 //where opsel and opselHi are in 3rd and 4th bit.595 bits<4> src0_modifiers;596 bits<4> src1_modifiers;597 598 // Inst{7-0} = unused599 // Inst{10-8} = neg_hi;600 // Inst{13-11} = op_sel601 let Inst{11} = src0_modifiers{2}; //opsel[0]602 let Inst{12} = src1_modifiers{2}; //opsel[1]603 // Inst{13} = unused op_sel604 // Inst{14} = unused op_sel_hi2605 606 let Inst{31-16} = 0b1101001110101100;607 let Inst{40-32} = scale_src0;608 let Inst{49-41} = scale_src1;609 // Inst{50-58} = unused610 // Inst{60-59} = op_sel_hi;611 let Inst{59} = src0_modifiers{3}; //opsel_hi[0]612 let Inst{60} = src1_modifiers{3}; //opsel_hi[1]613 // Inst{63-61} = neg;614 615 // The high half of the encoding is the unscaled mfma op.616 //617 // FIXME: Defining the encoding in terms of the base instruction618 // seems to not work, results in all 0 encoding, so replicate all619 // the fields from VOP3Pe_MAI, shifted up by 64620 //621 // defvar Hi = VOP3Pe_MAI<op, MFMAPfl, acc_cd>;622 // let Inst{127-64} = Hi.Inst;623 624 let Inst{71-64} = vdst;625 let Inst{74-72} = !if(MFMAPfl.HasSrc1, cbsz, 0);626 627 // abid must be 1 to use a scale.628 let Inst{78-75} = 0b0001; // abid629 630 let Inst{79} = acc_cd;631 632 let Inst{86-80} = op;633 let Inst{95-87} = 0x1a7; //encoding634 let Inst{104-96} = !if(MFMAPfl.HasSrc0, src0{8-0}, 0);635 let Inst{113-105} = !if(MFMAPfl.HasSrc1, src1{8-0}, 0);636 let Inst{122-114} = !if(MFMAPfl.HasSrc2, src2, 0);637 638 let Inst{123} = !if(MFMAPfl.HasSrc0, src0{9}, 0); // acc(0)639 let Inst{124} = !if(MFMAPfl.HasSrc1, src1{9}, 0); // acc(1)640 641 let Inst{127-125} = !if(MFMAPfl.HasSrc1, blgp, 0);642}643 644class VOP3Pe_vi <bits<7> op, VOPProfile P> : VOP3Pe<P> {645 let Inst{22-16} = op;646 let Inst{31-23} = 0x1a7; //encoding647}648 649class VOP3Pe_gfx10 <bits<8> op, VOPProfile P> : VOP3Pe<P> {650 let Inst{23-16} = op;651 let Inst{31-24} = 0xcc; //encoding652}653 654class VOP3Pe_gfx11_gfx12<bits<8> op, VOPProfile P> : VOP3Pe_gfx10<op, P>;655 656class VOP3be_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3be<p> {657 let Inst{25-17} = op;658}659 660class VOP3be_gfx10<bits<10> op, VOPProfile p> : VOP3be<p> {661 bits<1> clamp;662 let Inst{15} = !if(p.HasClamp, clamp{0}, 0);663 let Inst{25-16} = op;664 let Inst{31-26} = 0x35;665}666 667class VOP3be_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3be_gfx10<op, p>;668 669class VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> {670 bits<1> clamp;671 let Inst{25-16} = op;672 let Inst{15} = !if(P.HasClamp, clamp{0}, 0);673}674 675def SDWA {676 // sdwa_sel677 int BYTE_0 = 0;678 int BYTE_1 = 1;679 int BYTE_2 = 2;680 int BYTE_3 = 3;681 int WORD_0 = 4;682 int WORD_1 = 5;683 int DWORD = 6;684 685 // dst_unused686 int UNUSED_PAD = 0;687 int UNUSED_SEXT = 1;688 int UNUSED_PRESERVE = 2;689}690 691class VOP_SDWAe<VOPProfile P> : Enc64 {692 bits<8> src0;693 bits<3> src0_sel;694 bits<5> src0_modifiers; // float: {abs,neg}, int {sext}695 bits<3> src1_sel;696 bits<5> src1_modifiers;697 bits<3> dst_sel;698 bits<2> dst_unused;699 bits<1> clamp;700 701 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);702 let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?);703 let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?);704 let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0);705 let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0);706 let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{4}, 0);707 let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);708 let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0);709 let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{4}, 0);710 let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);711}712 713// GFX9 adds two features to SDWA:714// 1. Add 3 fields to the SDWA microcode word: S0, S1 and OMOD.715// a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather716// than VGPRs (at most 1 can be an SGPR);717// b. OMOD is the standard output modifier (result *2, *4, /2)718// 2. Add a new version of the SDWA microcode word for VOPC: SDWAB. This719// replaces OMOD and the dest fields with SD and SDST (SGPR destination)720// field.721// a. When SD=1, the SDST is used as the destination for the compare result;722// b. When SD=0, VCC is used.723//724// In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA725 726// gfx9 SDWA basic encoding727class VOP_SDWA9e<VOPProfile P> : Enc64 {728 bits<9> src0; // {src0_sgpr{0}, src0{7-0}}729 bits<3> src0_sel;730 bits<5> src0_modifiers; // float: {abs,neg}, int {sext}731 bits<3> src1_sel;732 bits<5> src1_modifiers;733 bits<1> src1_sgpr;734 735 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);736 let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0);737 let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{4}, 0);738 let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);739 let Inst{55} = !if(P.HasSrc0, src0{8}, 0);740 let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0);741 let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{4}, 0);742 let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);743 let Inst{63} = 0; // src1_sgpr - should be specified in subclass744}745 746// gfx9 SDWA-A747class VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> {748 bits<3> dst_sel;749 bits<2> dst_unused;750 bits<1> clamp;751 bits<2> omod;752 753 let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?);754 let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?);755 let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0);756 let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0);757}758 759// gfx9 SDWA-B760class VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> {761 bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}}762 763 let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, ?);764 let Inst{47} = !if(P.EmitDst, sdst{7}, 0);765}766 767class VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> :768 InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>,769 VOP <opName>,770 SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE> {771 772 let isPseudo = 1;773 let isCodeGenOnly = 1;774 let UseNamedOperandTable = 1;775 776 string Mnemonic = opName;777 string AsmOperands = P.AsmSDWA;778 string AsmOperands9 = P.AsmSDWA9;779 780 let Size = 8;781 let mayLoad = 0;782 let mayStore = 0;783 let hasSideEffects = 0;784 785 let VALU = 1;786 let SDWA = 1;787 788 let ReadsModeReg = !or(P.DstVT.isFP, P.Src0VT.isFP);789 790 let mayRaiseFPException = ReadsModeReg;791 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);792 793 let SubtargetPredicate = HasSDWA;794 let AsmVariantName = !if(P.HasExtSDWA, AMDGPUAsmVariants.SDWA,795 AMDGPUAsmVariants.Disable);796 let DecoderNamespace = "GFX8";797 798 VOPProfile Pfl = P;799}800 801class VOP_SDWA8_Real <VOP_SDWA_Pseudo ps> :802 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,803 SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> {804 805 let VALU = 1;806 let SDWA = 1;807 let isPseudo = 0;808 let isCodeGenOnly = 0;809 810 let Defs = ps.Defs;811 let Uses = ps.Uses;812 let hasSideEffects = ps.hasSideEffects;813 814 let Constraints = ps.Constraints;815 816 // Copy relevant pseudo op flags817 let SubtargetPredicate = ps.SubtargetPredicate;818 let AssemblerPredicate = HasSDWA8;819 let AsmMatchConverter = ps.AsmMatchConverter;820 let AsmVariantName = ps.AsmVariantName;821 let UseNamedOperandTable = ps.UseNamedOperandTable;822 let DecoderNamespace = ps.DecoderNamespace;823 let Constraints = ps.Constraints;824 let TSFlags = ps.TSFlags;825 let Uses = ps.Uses;826 let Defs = ps.Defs;827 let SchedRW = ps.SchedRW;828 let mayLoad = ps.mayLoad;829 let mayStore = ps.mayStore;830 let TRANS = ps.TRANS;831 let isConvergent = ps.isConvergent;832}833 834class Base_VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :835 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []> {836 837 let VALU = 1;838 let SDWA = 1;839 let isPseudo = 0;840 let isCodeGenOnly = 0;841 842 let Defs = ps.Defs;843 let Uses = ps.Uses;844 let hasSideEffects = ps.hasSideEffects;845 846 let Constraints = ps.Constraints;847 848 let SubtargetPredicate = ps.SubtargetPredicate;849 let AssemblerPredicate = HasSDWA9;850 let OtherPredicates = ps.OtherPredicates;851 let AsmVariantName = !if(ps.Pfl.HasExtSDWA9, AMDGPUAsmVariants.SDWA9,852 AMDGPUAsmVariants.Disable);853 let DecoderNamespace = "GFX9";854 855 // Copy relevant pseudo op flags856 let AsmMatchConverter = ps.AsmMatchConverter;857 let UseNamedOperandTable = ps.UseNamedOperandTable;858 let Constraints = ps.Constraints;859 let TSFlags = ps.TSFlags;860 let Uses = ps.Uses;861 let Defs = ps.Defs;862 let SchedRW = ps.SchedRW;863 let mayLoad = ps.mayLoad;864 let mayStore = ps.mayStore;865 let TRANS = ps.TRANS;866 let isConvergent = ps.isConvergent;867}868 869class VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :870 Base_VOP_SDWA9_Real <ps >,871 SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9>;872 873class Base_VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : Base_VOP_SDWA9_Real<ps> {874 let SubtargetPredicate = ps.SubtargetPredicate;875 let AssemblerPredicate = HasSDWA10;876 let DecoderNamespace = "GFX10";877}878 879class VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> :880 Base_VOP_SDWA10_Real<ps>, SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SDWA10>;881 882class VOP_DPPe<VOPProfile P, bit IsDPP16=0> : Enc64 {883 bits<2> src0_modifiers;884 bits<8> src0;885 bits<2> src1_modifiers;886 bits<9> dpp_ctrl;887 bits<1> bound_ctrl;888 bits<4> bank_mask;889 bits<4> row_mask;890 bit fi;891 892 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);893 let Inst{48-40} = dpp_ctrl;894 let Inst{50} = !if(IsDPP16, fi, ?);895 let Inst{51} = bound_ctrl;896 let Inst{52} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg897 let Inst{53} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs898 let Inst{54} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg899 let Inst{55} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs900 let Inst{59-56} = bank_mask;901 let Inst{63-60} = row_mask;902}903 904class VOP3_DPPe_Fields_Base {905 bits<9> dpp_ctrl;906 bits<1> bound_ctrl;907 bits<4> bank_mask;908 bits<4> row_mask;909 bit fi;910}911class VOP3_DPPe_Fields : VOP3_DPPe_Fields_Base {912 bits<8> src0;913}914 915class VOP3_DPPe_Fields_t16 : VOP3_DPPe_Fields_Base {916 bits<11> src0;917}918 919// Common refers to common between DPP and DPP8920// Base refers to a shared base between T16 and regular instructions921class VOP3_DPPe_Common_Base<bits<10> op, VOPProfile P> : Enc96 {922 bits<4> src0_modifiers;923 bits<3> src1_modifiers;924 bits<3> src2_modifiers;925 bits<1> clamp;926 bits<2> omod;927 bits<2> byte_sel;928 929 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);930 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);931 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);932 // 16-bit select fields which can be interpreted as OpSel or hi/lo suffix933 let Inst{11} = !if(P.HasFP8SrcByteSel, byte_sel{1},934 !if(P.HasOpSel, !if(P.HasSrc0Mods, src0_modifiers{2}, 0), ?));935 let Inst{12} = !if(P.HasFP8SrcByteSel, byte_sel{0},936 !if(P.HasOpSel, !if(P.HasSrc1Mods, src1_modifiers{2}, 0), ?));937 let Inst{13} = !if(P.HasFP8DstByteSel, byte_sel{0},938 !if(P.HasOpSel, !if(P.HasSrc2Mods, src2_modifiers{2}, 0), ?));939 let Inst{14} = !if(P.HasFP8DstByteSel, byte_sel{1},940 !if(P.HasOpSel, !if(P.HasSrc0Mods, src0_modifiers{3}, 0), ?));941 let Inst{15} = !if(P.HasClamp, clamp, 0);942 let Inst{25-16} = op;943 let Inst{31-26} = 0x35;944 945 let Inst{60-59} = !if(P.HasOMod, omod, 0);946 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);947 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);948 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);949}950 951class VOP3_DPPe_Common<bits<10> op, VOPProfile P> : VOP3_DPPe_Common_Base<op, P> {952 bits<8> vdst;953 bits<9> src1;954 bits<9> src2;955 956 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);957 let Inst{49-41} = !if(P.HasSrc1, src1, 0);958 let Inst{58-50} = !if(P.HasSrc2, src2, 0);959}960 961class VOP3_DPPe_Common_t16<bits<10> op, VOPProfile P> : VOP3_DPPe_Common_Base<op, P> {962 bits<11> vdst;963 bits<11> src1;964 bits<11> src2;965 966 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);967 let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0);968 let Inst{58-50} = !if(P.HasSrc2, src2{8-0}, 0);969}970 971class VOP3P_DPPe_Common_Base<bits<8> op, VOPProfile P> : Enc96 {972 bits<4> src0_modifiers;973 bits<4> src1_modifiers;974 bits<4> src2_modifiers;975 bits<1> clamp;976 977 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0978 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1979 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2980 // OPSEL must be set such that the low result only uses low inputs, and the high result only uses high inputs.981 let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0)982 let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)983 let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2)984 let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(2)985 let Inst{15} = !if(P.HasClamp, clamp{0}, 0);986 let Inst{23-16} = op;987 let Inst{31-24} = 0xcc; // encoding988 let Inst{59} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(0)989 let Inst{60} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(1)990 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo)991 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo)992 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)993}994 995class VOP3P_DPPe_Common<bits<8> op, VOPProfile P> : VOP3P_DPPe_Common_Base<op, P> {996 bits<8> vdst;997 bits<9> src1;998 bits<9> src2;999 1000 let Inst{7-0} = vdst;1001 let Inst{49-41} = !if(P.HasSrc1, src1, 0);1002 let Inst{58-50} = !if(P.HasSrc2, src2, 0);1003}1004 1005class VOP3P_DPPe_Common_t16<bits<8> op, VOPProfile P> : VOP3P_DPPe_Common_Base<op, P> {1006 bits<11> vdst;1007 bits<11> src1;1008 bits<11> src2;1009 1010 let Inst{7-0} = vdst{7-0};1011 let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0);1012 let Inst{58-50} = !if(P.HasSrc2, src2{8-0}, 0);1013}1014 1015class VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[],1016 dag Ins = P.InsDPP, string asmOps = P.AsmDPP> :1017 VOP_Pseudo<OpName, "_dpp", P, P.OutsDPP, Ins, asmOps, pattern> {1018 1019 let mayLoad = 0;1020 let mayStore = 0;1021 let hasSideEffects = 0;1022 1023 let VALU = 1;1024 let DPP = 1;1025 let Size = 8;1026 let IsPacked = P.IsPacked;1027 1028 let ReadsModeReg = !or(P.DstVT.isFP, P.Src0VT.isFP);1029 1030 let mayRaiseFPException = ReadsModeReg;1031 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);1032 let isConvergent = 1;1033 1034 string AsmOperands = asmOps;1035 1036 let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", "");1037 let AssemblerPredicate = !if(P.HasExt64BitDPP, HasDPALU_DPP, HasDPP);1038 let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP,1039 AMDGPUAsmVariants.Disable);1040 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");1041 let DecoderNamespace = "GFX8";1042}1043 1044class VOP3_DPP_Pseudo <string OpName, VOPProfile P> :1045 VOP_DPP_Pseudo <OpName, P, [], P.InsVOP3DPP, P.AsmVOP3DPP> {1046 let PseudoInstr = OpName#"_e64"#"_dpp";1047 let OutOperandList = P.OutsVOP3DPP;1048 let Size = 12;1049 let VOP3 = 1;1050 let AsmMatchConverter = "cvtVOP3DPP";1051 let AsmVariantName = !if(!or(P.HasExtVOP3DPP, P.HasExt64BitDPP),1052 AMDGPUAsmVariants.VOP3_DPP,1053 AMDGPUAsmVariants.Disable);1054}1055 1056class VOP_DPP_Real <VOP_DPP_Pseudo ps, int EncodingFamily> :1057 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,1058 SIMCInstr <ps.PseudoInstr, EncodingFamily> {1059 1060 let VALU = 1;1061 let DPP = 1;1062 let isPseudo = 0;1063 let isCodeGenOnly = 0;1064 1065 let Defs = ps.Defs;1066 let Uses = ps.Uses;1067 let hasSideEffects = ps.hasSideEffects;1068 1069 let Constraints = ps.Constraints;1070 1071 // Copy relevant pseudo op flags1072 let isConvergent = ps.isConvergent;1073 let SubtargetPredicate = ps.SubtargetPredicate;1074 let True16Predicate = ps.True16Predicate;1075 let AssemblerPredicate = ps.AssemblerPredicate;1076 let OtherPredicates = ps.OtherPredicates;1077 let AsmMatchConverter = ps.AsmMatchConverter;1078 let AsmVariantName = ps.AsmVariantName;1079 let UseNamedOperandTable = ps.UseNamedOperandTable;1080 let DecoderNamespace = ps.DecoderNamespace;1081 let Constraints = ps.Constraints;1082 let TSFlags = ps.TSFlags;1083 let Uses = ps.Uses;1084 let Defs = ps.Defs;1085 let SchedRW = ps.SchedRW;1086 let mayLoad = ps.mayLoad;1087 let mayStore = ps.mayStore;1088 let TRANS = ps.TRANS;1089 let isConvergent = ps.isConvergent;1090}1091 1092class VOP_DPP_Base <string OpName, VOPProfile P,1093 dag InsDPP,1094 string AsmDPP > :1095 InstSI <P.OutsDPP, InsDPP, OpName#AsmDPP, []> {1096 1097 let mayLoad = 0;1098 let mayStore = 0;1099 let hasSideEffects = 0;1100 let UseNamedOperandTable = 1;1101 1102 let VALU = 1;1103 let DPP = 1;1104 let Size = 8;1105 1106 let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", "");1107 let AssemblerPredicate = !if(P.HasExt64BitDPP, HasDPALU_DPP, HasDPP);1108 let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP,1109 AMDGPUAsmVariants.Disable);1110 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");1111 let DecoderNamespace = "GFX8";1112}1113 1114class VOP_DPP <string OpName, VOPProfile P, bit IsDPP16,1115 dag InsDPP = !if(IsDPP16, P.InsDPP16, P.InsDPP),1116 string AsmDPP = !if(IsDPP16, P.AsmDPP16, P.AsmDPP)> :1117 VOP_DPP_Base<OpName, P, InsDPP, AsmDPP>, VOP_DPPe<P, IsDPP16>;1118 1119class VOP3_DPP_Base <string OpName, VOPProfile P, bit IsDPP16,1120 dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),1121 string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :1122 VOP_DPP_Base<OpName, P, InsDPP, AsmDPP> {1123 let OutOperandList = P.OutsVOP3DPP;1124 let AsmMatchConverter = "cvtVOP3DPP";1125 let VOP3 = 1;1126 let AsmVariantName = !if(!or(P.HasExtVOP3DPP, P.HasExt64BitDPP),1127 AMDGPUAsmVariants.VOP3_DPP,1128 AMDGPUAsmVariants.Disable);1129 let Size = 12;1130}1131 1132class VOP3_DPP_Enc <bits<10> op, VOPProfile P, bit IsDPP16> :1133 VOP3_DPPe_Common<op, P>,1134 VOP3_DPPe_Fields {1135 1136 let Inst{40-32} = 0xfa;1137 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);1138 let Inst{80-72} = dpp_ctrl;1139 let Inst{82} = !if(IsDPP16, fi, ?);1140 let Inst{83} = bound_ctrl;1141 1142 // Inst{87-84} ignored by hw1143 let Inst{91-88} = bank_mask;1144 let Inst{95-92} = row_mask;1145}1146 1147class VOP3_DPP <bits<10> op, string OpName, VOPProfile P, bit IsDPP16,1148 dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),1149 string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :1150 VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3_DPP_Enc<op, P, IsDPP16>;1151 1152class VOP3_DPP_Enc_t16<bits<10> op, VOPProfile P, bit IsDPP16 >1153 : VOP3_DPPe_Common_t16<op, P>,1154 VOP3_DPPe_Fields_t16 {1155 1156 let Inst{40-32} = 0xfa;1157 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);1158 let Inst{80-72} = dpp_ctrl;1159 let Inst{82} = !if(IsDPP16, fi, ?);1160 let Inst{83} = bound_ctrl;1161 1162 // Inst{87-84} ignored by hw1163 let Inst{91-88} = bank_mask;1164 let Inst{95-92} = row_mask;1165}1166 1167class VOP3_DPP_t16<bits<10> op, string OpName, VOPProfile P, bit IsDPP16,1168 dag InsDPP = !if (IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),1169 string AsmDPP = !if (IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)>1170 : VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>,1171 VOP3_DPP_Enc_t16<op, P, IsDPP16> {1172}1173 1174class VOP3P_DPP <bits<8> op, string OpName, VOPProfile P, bit IsDPP16,1175 dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),1176 string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :1177 VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3P_DPPe_Common<op, P>,1178 VOP3_DPPe_Fields {1179 1180 let VOP3P = 1;1181 1182 let Inst{40-32} = 0xfa;1183 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);1184 let Inst{80-72} = dpp_ctrl;1185 let Inst{82} = !if(IsDPP16, fi, ?);1186 let Inst{83} = bound_ctrl;1187 1188 // Inst{87-84} ignored by hw1189 let Inst{91-88} = bank_mask;1190 let Inst{95-92} = row_mask;1191}1192 1193class VOP_DPP8e<VOPProfile P> : Enc64 {1194 bits<8> src0;1195 bits<24> dpp8;1196 bits<9> fi;1197 1198 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);1199 let Inst{63-40} = dpp8{23-0};1200}1201 1202class VOP3_DPP8e_Fields {1203 bits<8> src0;1204 bits<24> dpp8;1205 bits<9> fi;1206}1207 1208class VOP3_DPP8e_Fields_t16 {1209 bits<11> src0;1210 bits<24> dpp8;1211 bits<9> fi;1212}1213 1214class VOP_DPP8_Base<string OpName, VOPProfile P, dag InsDPP8 = P.InsDPP8, string AsmDPP8 = P.AsmDPP8> :1215 InstSI<P.OutsDPP8, InsDPP8, OpName#AsmDPP8, []> {1216 1217 let mayLoad = 0;1218 let mayStore = 0;1219 let hasSideEffects = 0;1220 let UseNamedOperandTable = 1;1221 1222 let VALU = 1;1223 let DPP = 1;1224 let Size = 8;1225 1226 let AsmMatchConverter = "cvtDPP8";1227 let AssemblerPredicate = HasDPP8;1228 let AsmVariantName = AMDGPUAsmVariants.DPP;1229 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");1230}1231 1232class VOP_DPP8<string OpName, VOPProfile P> :1233 VOP_DPP8_Base<OpName, P>, VOP_DPP8e<P>;1234 1235class VOP3_DPP8_Base<string OpName, VOPProfile P> :1236 VOP_DPP8_Base<OpName, P, P.InsVOP3DPP8, P.AsmVOP3DPP8> {1237 let OutOperandList = P.OutsVOP3DPP8;1238 let AsmMatchConverter = "cvtVOP3DPP8";1239 let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,1240 AMDGPUAsmVariants.Disable);1241 let VOP3 = 1;1242 let Size = 12;1243}1244 1245class VOP3_DPP8_Enc <bits<10> op, VOPProfile P> :1246 VOP3_DPPe_Common<op, P>,1247 VOP3_DPP8e_Fields {1248 let Inst{40-32} = fi;1249 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);1250 let Inst{95-72} = dpp8{23-0};1251}1252 1253class VOP3_DPP8<bits<10> op, string OpName, VOPProfile P> :1254 VOP3_DPP8_Base<OpName, P>, VOP3_DPP8_Enc<op, P>;1255 1256class VOP3_DPP8_Enc_t16 <bits<10> op, VOPProfile P> :1257 VOP3_DPPe_Common_t16<op, P>,1258 VOP3_DPP8e_Fields_t16 {1259 let Inst{40-32} = fi;1260 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);1261 let Inst{95-72} = dpp8{23-0};1262}1263 1264class VOP3_DPP8_t16<bits<10> op, string OpName, VOPProfile P> :1265 VOP3_DPP8_Base<OpName, P>, VOP3_DPP8_Enc_t16<op, P>;1266 1267class VOP3P_DPP8<bits<8> op, string OpName, VOPProfile P> :1268 VOP3_DPP8_Base<OpName, P>, VOP3P_DPPe_Common<op, P>,1269 VOP3_DPP8e_Fields {1270 1271 let VOP3P = 1;1272 let Inst{40-32} = fi;1273 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);1274 let Inst{95-72} = dpp8{23-0};1275}1276 1277def DPP8Mode {1278 int FI_0 = 0xE9;1279 int FI_1 = 0xEA;1280}1281 1282class getNumNodeArgs<SDPatternOperator Op> {1283 SDNode N = !cast<SDNode>(Op);1284 SDTypeProfile TP = N.TypeProfile;1285 int ret = TP.NumOperands;1286}1287 1288class getDivergentFrag<SDPatternOperator Op> {1289 assert !or(!isa<SDNode>(Op), !isa<PatFrags>(Op)), "Expected SDNode or PatFrags";1290 1291 int NumSrcArgs = !if(!isa<SDNode>(Op), getNumNodeArgs<Op>.ret,1292 !size(!cast<PatFrags>(Op).Operands));1293 PatFrag ret = PatFrag <1294 !if(!eq(NumSrcArgs, 1),1295 (ops node:$src0),1296 !if(!eq(NumSrcArgs, 2),1297 (ops node:$src0, node:$src1),1298 (ops node:$src0, node:$src1, node:$src2))),1299 !if(!eq(NumSrcArgs, 1),1300 (Op $src0),1301 !if(!eq(NumSrcArgs, 2),1302 (Op $src0, $src1),1303 (Op $src0, $src1, $src2))),1304 [{ return N->isDivergent(); }]1305 >;1306}1307 1308class VOPPatGen<SDPatternOperator Op, VOPProfile P> {1309 PatFrag Operator = getDivergentFrag < Op >.ret;1310 1311 dag Ins = !foreach(tmp, P.Ins32, !subst(ins, Operator,1312 !subst(P.Src0RC32, P.Src0VT,1313 !subst(P.Src1RC32, P.Src1VT, tmp))));1314 1315 dag Outs = !foreach(tmp, P.Outs32, !subst(outs, set,1316 !subst(P.DstRC, P.DstVT, tmp)));1317 1318 list<dag> ret = [!con(Outs, (set Ins))];1319}1320 1321class DivergentUnaryFrag<SDPatternOperator Op> : PatFrag <1322 (ops node:$src0),1323 (Op $src0),1324 [{ return N->isDivergent(); }]> {1325 // This check is unnecessary as it's captured by the result register1326 // bank constraint.1327 //1328 // FIXME: Should add a way for the emitter to recognize this is a1329 // trivially true predicate to eliminate the check.1330 let GISelPredicateCode = [{return true;}];1331}1332 1333class VOPPatOrNull<SDPatternOperator Op, VOPProfile P> {1334 list<dag> ret = !if(!ne(P.NeedPatGen,PatGenMode.NoPattern), VOPPatGen<Op, P>.ret, []);1335}1336 1337class DivergentFragOrOp<SDPatternOperator Op, VOPProfile P> {1338 SDPatternOperator ret = !if(!eq(P.NeedPatGen,PatGenMode.Pattern),1339 !if(!isa<SDNode>(Op), getDivergentFrag<Op>.ret, Op), Op);1340}1341 1342class getVSrcOp<ValueType vt> {1343 RegisterOperand ret = !if(!eq(vt.Size, 32), VSrc_b32, VSrc_b16);1344}1345 1346// Class for binary integer operations with the clamp bit set for saturation1347// TODO: Add sub with negated inline constant pattern.1348class VOPBinOpClampPat<SDPatternOperator node, Instruction inst, ValueType vt> :1349 GCNPat<(node vt:$src0, vt:$src1),1350 (inst getVSrcOp<vt>.ret:$src0, getVSrcOp<vt>.ret:$src1,1351 DSTCLAMP.ENABLE)1352>;1353 1354//===----------------------------------------------------------------------===//1355// VOP3 Classes1356//===----------------------------------------------------------------------===//1357 1358class getVOP3ModPat<VOPProfile P, SDPatternOperator node> {1359 dag src0 = !if(P.HasOMod,1360 !if(P.HasClamp,1361 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod),1362 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i32:$omod)),1363 !if(P.HasClamp,1364 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp),1365 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers)));1366 1367 list<dag> ret3 = [(set P.DstVT:$vdst,1368 (DivergentFragOrOp<node, P>.ret (P.Src0VT src0),1369 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),1370 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))];1371 1372 list<dag> ret2 = [(set P.DstVT:$vdst,1373 (DivergentFragOrOp<node, P>.ret (P.Src0VT src0),1374 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))];1375 1376 list<dag> ret1 = [(set P.DstVT:$vdst,1377 (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))];1378 1379 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,1380 !if(!eq(P.NumSrcArgs, 2), ret2,1381 ret1));1382}1383 1384class getVOP3PModPat<VOPProfile P, SDPatternOperator node, bit HasExplicitClamp,1385 bit IsDOT = 0,1386 ComplexPattern SrcPat = !if(IsDOT, VOP3PModsDOT, VOP3PMods)> {1387 dag src0_dag = (P.Src0VT (SrcPat P.Src0VT:$src0, i32:$src0_modifiers));1388 dag src1_dag = (P.Src1VT (SrcPat P.Src1VT:$src1, i32:$src1_modifiers));1389 dag src2_dag = (P.Src2VT (SrcPat P.Src2VT:$src2, i32:$src2_modifiers));1390 dag clamp_dag = (i1 timm:$clamp);1391 1392 list<dag> ret3 = [(set P.DstVT:$vdst,1393 !if(HasExplicitClamp,1394 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag, clamp_dag),1395 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag)))];1396 1397 list<dag> ret2 = [(set P.DstVT:$vdst,1398 !if(HasExplicitClamp,1399 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, clamp_dag),1400 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag)))];1401 1402 list<dag> ret1 = [(set P.DstVT:$vdst,1403 !if(HasExplicitClamp,1404 (DivergentFragOrOp<node, P>.ret src0_dag, clamp_dag),1405 (DivergentFragOrOp<node, P>.ret src0_dag)))];1406 1407 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,1408 !if(!eq(P.NumSrcArgs, 2), ret2,1409 ret1));1410}1411 1412class getVOP3OpSelPat<VOPProfile P, SDPatternOperator node> {1413 list<dag> ret3 = [(set P.DstVT:$vdst,1414 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)),1415 (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers)),1416 (P.Src2VT (VOP3OpSel P.Src2VT:$src2, i32:$src2_modifiers))))];1417 1418 list<dag> ret2 = [(set P.DstVT:$vdst,1419 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)),1420 (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers))))];1421 1422 list<dag> ret1 = [(set P.DstVT:$vdst,1423 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers))))];1424 1425 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,1426 !if(!eq(P.NumSrcArgs, 2), ret2,1427 ret1));1428}1429 1430class getVOP3OpSelModPat<VOPProfile P, SDPatternOperator node> {1431 list<dag> ret3 = [(set P.DstVT:$vdst,1432 (DivergentFragOrOp<node, P>.ret (P.Src0VT !if(P.HasClamp, (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers),1433 (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))),1434 (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers)),1435 (P.Src2VT (VOP3OpSelMods P.Src2VT:$src2, i32:$src2_modifiers))))];1436 1437 list<dag> ret2 = [(set P.DstVT:$vdst,1438 (DivergentFragOrOp<node, P>.ret !if(P.HasClamp, (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers)),1439 (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))),1440 (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers))))];1441 1442 list<dag> ret1 = [(set P.DstVT:$vdst,1443 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))))];1444 1445 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,1446 !if(!eq(P.NumSrcArgs, 2), ret2,1447 ret1));1448}1449 1450class getVOP3FromVOP2Pat<VOPProfile P, SDPatternOperator node> {1451 list<dag> ret = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))];1452}1453// In VOP1, we can have clamp and omod even if !HasModifiers1454class getVOP3Pat<VOPProfile P, SDPatternOperator node> {1455 dag src0 =1456 !if(P.HasOMod,1457 !if(P.HasClamp,1458 (VOP3Mods0 P.Src0VT:$src0, i1:$clamp, i32:$omod),1459 (VOP3Mods0 P.Src0VT:$src0, i32:$omod)), // impossible?1460 !if(P.HasClamp,1461 (VOP3Mods0 P.Src0VT:$src0, i1:$clamp),1462 (VOP3Mods0 P.Src0VT:$src0))1463 );1464 list<dag> ret3 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1, P.Src2VT:$src2))];1465 1466 list<dag> ret2 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1))];1467 1468 list<dag> ret1 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))];1469 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,1470 !if(!eq(P.NumSrcArgs, 2), ret2,1471 ret1));1472}1473 1474class getVOP3ClampPat<VOPProfile P, SDPatternOperator node> {1475 list<dag> ret3 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i1:$clamp))];1476 list<dag> ret2 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, i1:$clamp))];1477 list<dag> ret1 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, i1:$clamp))];1478 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,1479 !if(!eq(P.NumSrcArgs, 2), ret2,1480 ret1));1481}1482 1483class getVOP3MAIPat<VOPProfile P, SDPatternOperator node> {1484 list<dag> mfma_with_abid = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2,1485 timm:$cbsz, timm:$abid, timm:$blgp))];1486 list<dag> mfma_no_abid = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2,1487 timm:$cbsz, timm:$blgp))];1488 1489 list<dag> ret = !if(!not(P.IsSMFMAC),1490 // mfma1491 !if(P.HasAbid, mfma_with_abid, mfma_no_abid),1492 1493 // smfmac1494 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i32:$idx,1495 timm:$cbsz, timm:$abid))]);1496}1497 1498class getVOP3MAIScaledPat<VOPProfile P, SDPatternOperator node> {1499 list<dag> ret = !if(!not(P.IsSMFMAC),1500 // mfma1501 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2,1502 timm:$cbsz, timm:$blgp,1503 MFMALdScaleModifierOp:$src0_modifiers,1504 i32:$scale_src0,1505 MFMALdScaleModifierOp:$src1_modifiers,1506 i32:$scale_src11507 ))],1508 // smfmac1509 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i32:$idx,1510 timm:$cbsz, timm:$abid,1511 MFMALdScaleModifierOp:$src0_modifiers,1512 i32:$scale_src0,1513 MFMALdScaleModifierOp:$src1_modifiers,1514 i32:$scale_src1))]);1515}1516 1517class VOP3Features<bit Clamp, bit OpSel, bit Packed, bit MAI> {1518 bit HasClamp = Clamp;1519 bit HasOpSel = OpSel;1520 bit IsPacked = Packed;1521 bit IsMAI = MAI;1522}1523 1524def VOP3_REGULAR : VOP3Features<0, 0, 0, 0>;1525def VOP3_CLAMP : VOP3Features<1, 0, 0, 0>;1526def VOP3_OPSEL : VOP3Features<1, 1, 0, 0>;1527def VOP3_PACKED : VOP3Features<1, 1, 1, 0>;1528def VOP3_PACKED_NO_OPSEL : VOP3Features<1, 0, 1, 0>;1529def VOP3_MAI : VOP3Features<0, 0, 0, 1>;1530def VOP3_OPSEL_ONLY : VOP3Features<0, 1, 0, 0>;1531 1532// Packed is misleading, but it enables the appropriate op_sel1533// modifiers.1534def VOP3P_LD_SCALE : VOP3Features<0, 1, 1, 0>;1535 1536class VOP3_Profile_Base<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProfile<P.ArgVT> {1537 1538 let HasClamp = !if(Features.HasClamp, 1, P.HasClamp);1539 let HasOpSel = !if(Features.HasOpSel, 1, P.HasOpSel);1540 let IsMAI = !if(Features.IsMAI, 1, P.IsMAI);1541 let IsPacked = !if(Features.IsPacked, 1, P.IsPacked);1542 let HasFP8SrcByteSel = P.HasFP8SrcByteSel;1543 let HasFP8DstByteSel = P.HasFP8DstByteSel;1544 let HasOMod = P.HasOMod;1545 let HasBitOp3 = P.HasBitOp3;1546 1547 let HasModifiers =1548 !if (Features.IsMAI, 0,1549 !or(Features.IsPacked, P.HasModifiers));1550}1551 1552class VOP3_Profile<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOP3_Profile_Base<P, Features> {1553 let IsSingle = 1;1554 1555}1556 1557class VOP3_Profile_True16<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProfile_True16<P> {1558 let HasClamp = !if(Features.HasClamp, 1, P.HasClamp);1559 let HasOpSel = !if(Features.HasOpSel, 1, P.HasOpSel);1560 let IsMAI = !if(Features.IsMAI, 1, P.IsMAI);1561 let IsPacked = !if(Features.IsPacked, 1, P.IsPacked);1562 let HasFP8SrcByteSel = P.HasFP8SrcByteSel;1563 let HasFP8DstByteSel = P.HasFP8DstByteSel;1564 let HasOMod = P.HasOMod;1565 let HasBitOp3 = P.HasBitOp3;1566 1567 let HasModifiers =1568 !if (Features.IsMAI, 0,1569 !or(Features.IsPacked, Features.HasOpSel, P.HasModifiers));1570 let IsSingle = 1;1571}1572 1573class VOP3_Profile_Fake16<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProfile_Fake16<P> {1574 let HasClamp = !if(Features.HasClamp, 1, P.HasClamp);1575 let HasOpSel = !if(Features.HasOpSel, 1, P.HasOpSel);1576 let IsMAI = !if(Features.IsMAI, 1, P.IsMAI);1577 let IsPacked = !if(Features.IsPacked, 1, P.IsPacked);1578 let HasFP8SrcByteSel = P.HasFP8SrcByteSel;1579 let HasFP8DstByteSel = P.HasFP8DstByteSel;1580 let HasOMod = P.HasOMod;1581 let HasBitOp3 = P.HasBitOp3;1582 1583 let HasModifiers =1584 !if (Features.IsMAI, 0,1585 !or(Features.IsPacked, Features.HasOpSel, P.HasModifiers));1586 let IsSingle = 1;1587}1588 1589// consistently gives instructions a _e64 suffix1590multiclass VOP3Inst_Pseudo_Wrapper<string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> {1591 def _e64 : VOP3_Pseudo<opName, P, pattern, VOP3Only>;1592}1593 1594class VOP3InstBase<string OpName, VOPProfile P, SDPatternOperator node = null_frag, bit IsVOP2 = 0, bit MAIScaled = false> :1595 VOP3_Pseudo<OpName, P,1596 !if(P.HasOpSel,1597 !if(P.HasModifiers,1598 getVOP3OpSelModPat<P, node>.ret,1599 getVOP3OpSelPat<P, node>.ret),1600 !if(P.HasModifiers,1601 getVOP3ModPat<P, node>.ret,1602 !if(IsVOP2,1603 getVOP3FromVOP2Pat<P, node>.ret,1604 !if(P.HasIntClamp,1605 getVOP3ClampPat<P, node>.ret,1606 !if (P.IsMAI,1607 !if(MAIScaled, getVOP3MAIScaledPat<P, node>.ret, getVOP3MAIPat<P, node>.ret),1608 getVOP3Pat<P, node>.ret))))),1609 0, P.HasOpSel> {1610 1611 let IntClamp = P.HasIntClamp;1612 let AsmMatchConverter =1613 !if(P.HasOpSel,1614 "cvtVOP3OpSel",1615 !if(!or(P.HasModifiers, P.HasOMod, P.HasIntClamp),1616 "cvtVOP3",1617 ""));1618}1619 1620multiclass VOP3Inst<string OpName, VOPProfile P, SDPatternOperator node = null_frag,1621 list<Predicate> predicates = []> {1622 def _e64 : VOP3InstBase<OpName, P, node>;1623 if P.HasExtVOP3DPP then1624 def _e64_dpp : VOP3_DPP_Pseudo <OpName, P> {1625 let SubtargetPredicate = isGFX11Plus;1626 }1627 else if P.HasExt64BitDPP then1628 def _e64_dpp : VOP3_DPP_Pseudo <OpName, P> {1629 let OtherPredicates = !listconcat(predicates, [HasDPALU_DPP]);1630 }1631}1632 1633class UniformUnaryFragOrOp<SDPatternOperator Op> {1634 SDPatternOperator ret = !if(!or(!isa<SDNode>(Op), !isa<PatFrags>(Op)),1635 UniformUnaryFrag<Op>, Op);1636}1637 1638multiclass VOP3PseudoScalarInst<string OpName, VOPProfile P,1639 SDPatternOperator node = null_frag> {1640 def _e64 : VOP3_Pseudo<OpName, P, [(set P.DstVT:$vdst,1641 (UniformUnaryFragOrOp<node>.ret1642 (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp,1643 i32:$omod))))]>;1644}1645 1646multiclass VOP3Inst_t16_with_profiles<string OpName, VOPProfile P, VOPProfile P_t16,1647 VOPProfile P_fake16,1648 SDPatternOperator node = null_frag,1649 SDPatternOperator node_t16 = node> {1650 let True16Predicate = NotHasTrue16BitInsts in {1651 defm NAME : VOP3Inst<OpName, P, node>;1652 }1653 let True16Predicate = UseRealTrue16Insts in {1654 defm _t16 : VOP3Inst<OpName # "_t16", P_t16, node_t16>;1655 }1656 let True16Predicate = UseFakeTrue16Insts in {1657 defm _fake16 : VOP3Inst<OpName # "_fake16", P_fake16, node>;1658 }1659}1660 1661multiclass VOP3Inst_t16<string OpName, VOPProfile P,1662 SDPatternOperator node = null_frag,1663 SDPatternOperator node_t16 = node>1664 : VOP3Inst_t16_with_profiles<OpName, VOP3_Profile<P, VOP3_OPSEL>,1665 VOP3_Profile_True16<P, VOP3_OPSEL>, VOP3_Profile_Fake16<P, VOP3_OPSEL>,1666 node, node_t16>;1667 1668//===----------------------------------------------------------------------===//1669// VOP3 DPP1670//===----------------------------------------------------------------------===//1671 1672class VOP3_DPP16_Helper<bits<10> op, VOP_DPP_Pseudo ps, string opName = ps.OpName>1673 : VOP3_DPP<op, opName, ps.Pfl, 1> {1674 let VOP3_OPSEL = ps.Pfl.HasOpSel;1675 let IsDOT = ps.IsDOT;1676 let hasSideEffects = ps.hasSideEffects;1677 let Defs = ps.Defs;1678 let SchedRW = ps.SchedRW;1679 let Uses = ps.Uses;1680 let AssemblerPredicate = HasDPP16;1681 let SubtargetPredicate = ps.SubtargetPredicate;1682 let OtherPredicates = ps.OtherPredicates;1683}1684 1685class VOP3_DPP16_t16_Helper<bits<10> op, VOP_DPP_Pseudo ps,1686 string opName = ps.OpName>1687 : VOP3_DPP_t16<op, opName, ps.Pfl, 1> {1688 let VOP3_OPSEL = ps.Pfl.HasOpSel;1689 let IsDOT = ps.IsDOT;1690 let hasSideEffects = ps.hasSideEffects;1691 let Defs = ps.Defs;1692 let SchedRW = ps.SchedRW;1693 let Uses = ps.Uses;1694 let AssemblerPredicate = HasDPP16;1695 let SubtargetPredicate = ps.SubtargetPredicate;1696 let OtherPredicates = ps.OtherPredicates;1697}1698 1699class VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, int subtarget,1700 string opName = ps.OpName>1701 : VOP3_DPP16_Helper<op, ps, opName>, SIMCInstr<ps.PseudoInstr, subtarget>;1702 1703class VOP3_DPP16_t16<bits<10> op, VOP_DPP_Pseudo ps, int subtarget,1704 string opName = ps.OpName>1705 : VOP3_DPP16_t16_Helper<op, ps, opName>, SIMCInstr<ps.PseudoInstr, subtarget>;1706 1707class VOP3_DPP16_Gen<bits<10> op, VOP_DPP_Pseudo ps, GFXGen Gen,1708 string opName = ps.OpName>1709 : VOP3_DPP16<op, ps, Gen.Subtarget, opName> {1710 let AssemblerPredicate = Gen.AssemblerPredicate;1711 let DecoderNamespace = Gen.DecoderNamespace;1712}1713 1714class VOP3_DPP16_Gen_t16<bits<10> op, VOP_DPP_Pseudo ps, GFXGen Gen,1715 string opName = ps.OpName>1716 : VOP3_DPP16_t16<op, ps, Gen.Subtarget, opName> {1717 let True16Predicate =1718 !if (ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);1719 let AssemblerPredicate = Gen.AssemblerPredicate;1720 let DecoderNamespace =1721 Gen.DecoderNamespace #!if (ps.Pfl.IsRealTrue16, "", "_FAKE16");1722}1723 1724class Base_VOP3_DPP8<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>1725 : VOP3_DPP8<op, opName, ps.Pfl> {1726 let VOP3_OPSEL = ps.Pfl.HasOpSel;1727 let IsDOT = ps.IsDOT;1728 let hasSideEffects = ps.hasSideEffects;1729 let Defs = ps.Defs;1730 let SchedRW = ps.SchedRW;1731 let Uses = ps.Uses;1732 1733 let SubtargetPredicate = ps.SubtargetPredicate;1734 let OtherPredicates = ps.OtherPredicates;1735 let True16Predicate = ps.True16Predicate;1736}1737 1738class Base_VOP3_DPP8_t16<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>1739 : VOP3_DPP8_t16<op, opName, ps.Pfl> {1740 let VOP3_OPSEL = ps.Pfl.HasOpSel;1741 let IsDOT = ps.IsDOT;1742 let hasSideEffects = ps.hasSideEffects;1743 let Defs = ps.Defs;1744 let SchedRW = ps.SchedRW;1745 let Uses = ps.Uses;1746 1747 let SubtargetPredicate = ps.SubtargetPredicate;1748 let OtherPredicates = ps.OtherPredicates;1749 let True16Predicate = ps.True16Predicate;1750}1751 1752class Base_VOP3b_DPP16<bits<10> op, VOP_DPP_Pseudo ps,1753 string opName = ps.OpName>1754 : VOP3_DPP16_Helper<op, ps, opName> {1755 bits<7> sdst;1756 let Inst{14 - 8} = sdst;1757}1758 1759class VOP3b_DPP8_Base<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>1760 : Base_VOP3_DPP8<op, ps, opName> {1761 bits<7> sdst;1762 let Inst{14 - 8} = sdst;1763}1764 1765class VOP3_BITOP3_DPP16_Gen<bits<10> op, VOP_DPP_Pseudo p, GFXGen Gen, string asmName>1766 : VOP3_DPP16_Gen_t16<op, p, Gen, asmName> {1767 bits<8> bitop3;1768 1769 let Inst{60-59} = bitop3{7-6};1770 let Inst{10-8} = bitop3{5-3};1771 let Inst{63-61} = bitop3{2-0};1772 1773 let Inst{11} = !if(p.Pfl.HasOpSel, src0_modifiers{2}, 0);1774 let Inst{12} = !if(p.Pfl.HasOpSel, src1_modifiers{2}, 0);1775 let Inst{13} = !if(p.Pfl.HasOpSel, src2_modifiers{2}, 0);1776 let Inst{14} = !if(p.Pfl.HasOpSel, src0_modifiers{3}, 0);1777}1778 1779class VOP3_BITOP3_DPP8<bits<10> op, VOP_Pseudo p, string asmName>1780 : Base_VOP3_DPP8_t16<op, p, asmName> {1781 bits<8> bitop3;1782 1783 let Inst{60-59} = bitop3{7-6};1784 let Inst{10-8} = bitop3{5-3};1785 let Inst{63-61} = bitop3{2-0};1786 1787 let Inst{11} = !if(p.Pfl.HasOpSel, src0_modifiers{2}, 0);1788 let Inst{12} = !if(p.Pfl.HasOpSel, src1_modifiers{2}, 0);1789 let Inst{13} = !if(p.Pfl.HasOpSel, src2_modifiers{2}, 0);1790 let Inst{14} = !if(p.Pfl.HasOpSel, src0_modifiers{3}, 0);1791}1792 1793class VOP3b_DPP8_Base_t16<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>1794 : Base_VOP3_DPP8<op, ps, opName> {1795 bits<8> sdst;1796 let Inst{14 - 8} = sdst{7-1};1797}1798 1799//===----------------------------------------------------------------------===//1800// VOP3 GFX11, GFX121801//===----------------------------------------------------------------------===//1802 1803multiclass VOP3_Real_Base<GFXGen Gen, bits<10> op, string opName = NAME,1804 bit isSingle = 0> {1805 defvar ps = !cast<VOP_Pseudo>(opName#"_e64");1806 let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {1807 if ps.Pfl.HasFP8SrcByteSel then {1808 def _e64#Gen.Suffix :1809 VOP3_Real_Gen<ps, Gen>,1810 VOP3FP8OpSel_src_bytesel_gfx11_gfx12<op, ps.Pfl>;1811 } else if ps.Pfl.HasFP8DstByteSel then {1812 def _e64#Gen.Suffix :1813 VOP3_Real_Gen<ps, Gen>,1814 VOP3FP8OpSel_dst_bytesel_gfx11_gfx12<op, ps.Pfl>;1815 } else if ps.Pfl.HasOpSel then {1816 def _e64#Gen.Suffix :1817 VOP3_Real_Gen<ps, Gen>,1818 VOP3OpSel_gfx11_gfx12<op, ps.Pfl>;1819 } else {1820 def _e64#Gen.Suffix :1821 VOP3_Real_Gen<ps, Gen>,1822 VOP3e_gfx11_gfx12<op, ps.Pfl>;1823 }1824 }1825}1826 1827multiclass VOP3Dot_Real_Base<GFXGen Gen, bits<10> op, string asmName, string opName = NAME,1828 bit isSingle = 0> {1829 defvar ps = !cast<VOP_Pseudo>(opName#"_e64");1830 let AsmString = asmName # ps.AsmOperands,1831 DecoderNamespace = Gen.DecoderNamespace # !if(ps.Pfl.IsRealTrue16, "", "_FAKE16"),1832 IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {1833 def _e64#Gen.Suffix :1834 VOP3_Real_Gen<ps, Gen>,1835 VOP3DotOpSel_gfx11_gfx12<op, ps.Pfl>;1836 }1837}1838 1839multiclass VOP3_Real_with_name<GFXGen Gen, bits<10> op, string opName,1840 string asmName, string pseudo_mnemonic = "", bit isSingle = 0> {1841 defvar ps = !cast<VOP_Pseudo>(opName#"_e64");1842 let AsmString = asmName # ps.AsmOperands,1843 IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {1844 // FIXME-TRUE16 support FP8 instructions properly1845 if ps.Pfl.HasFP8SrcByteSel then {1846 def _e64#Gen.Suffix :1847 VOP3_Real_Gen<ps, Gen>,1848 VOP3FP8OpSel_src_bytesel_gfx11_gfx12<op, ps.Pfl>;1849 } else if ps.Pfl.HasFP8DstByteSel then {1850 def _e64#Gen.Suffix :1851 VOP3_Real_Gen<ps, Gen>,1852 VOP3FP8OpSel_dst_bytesel_gfx11_gfx12<op, ps.Pfl>;1853 } else {1854 if ps.Pfl.IsRealTrue16 then {1855 def _e64#Gen.Suffix :1856 VOP3_Real_Gen<ps, Gen>,1857 VOP3e_t16_gfx11_gfx12<op, ps.Pfl>;1858 } else {1859 if ps.Pfl.HasOpSel then {1860 def _e64#Gen.Suffix :1861 VOP3_Real_Gen<ps, Gen>,1862 VOP3OpSel_gfx11_gfx12<op, ps.Pfl>;1863 } else {1864 def _e64#Gen.Suffix :1865 VOP3_Real_Gen<ps, Gen>,1866 VOP3e_gfx11_gfx12<op, ps.Pfl>;1867 }1868 }1869 }1870 }1871 if !ne(ps.Mnemonic, asmName) then {1872 def Gen.Suffix#"_VOP3_alias" : LetDummies,1873 AMDGPUMnemonicAlias<!if(!empty(pseudo_mnemonic),1874 ps.Mnemonic, pseudo_mnemonic), asmName, ""> {1875 let AssemblerPredicate = Gen.AssemblerPredicate;1876 }1877 }1878}1879 1880// for READLANE/WRITELANE1881multiclass VOP3_Real_No_Suffix<GFXGen Gen, bits<10> op, string opName = NAME> {1882 defvar ps = !cast<VOP_Pseudo>(opName);1883 def _e64#Gen.Suffix :1884 VOP3_Real_Gen<ps, Gen>,1885 VOP3e_gfx11_gfx12<op, ps.Pfl>;1886}1887 1888multiclass VOP3_Real_dpp_Base<GFXGen Gen, bits<10> op, string opName = NAME> {1889 defvar ps = !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp");1890 if ps.Pfl.IsTrue16 then1891 def _e64_dpp#Gen.Suffix :1892 VOP3_DPP16_Gen_t16<op, ps, Gen>;1893 else1894 def _e64_dpp#Gen.Suffix :1895 VOP3_DPP16_Gen<op, ps, Gen>;1896}1897 1898multiclass VOP3Dot_Real_dpp_Base<GFXGen Gen, bits<10> op, string asmName, string opName = NAME> {1899 defvar ps = !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp");1900 def _e64_dpp#Gen.Suffix :1901 VOP3_DPP16_Gen_t16<op, ps, Gen> {1902 let AsmString = asmName # ps.Pfl.AsmVOP3DPP16;1903 let DecoderNamespace = Gen.DecoderNamespace1904 # !if(ps.Pfl.IsRealTrue16, "", "_FAKE16");1905 let Inst{11} = ?;1906 let Inst{12} = ?;1907 }1908}1909 1910multiclass VOP3_Real_dpp_with_name<GFXGen Gen, bits<10> op, string opName,1911 string asmName> {1912 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");1913 let AsmString = asmName # ps.Pfl.AsmVOP3DPP16 in {1914 defm NAME : VOP3_Real_dpp_Base<Gen, op, opName>;1915 }1916}1917 1918multiclass VOP3_Real_dpp8_Base<GFXGen Gen, bits<10> op, string opName = NAME> {1919 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");1920 if !not(ps.Pfl.HasExt64BitDPP) then1921 def _e64_dpp8#Gen.Suffix : Base_VOP3_DPP8<op, ps> {1922 let DecoderNamespace = Gen.DecoderNamespace;1923 let AssemblerPredicate = Gen.AssemblerPredicate;1924 }1925}1926 1927multiclass VOP3Dot_Real_dpp8_Base<GFXGen Gen, bits<10> op, string asmName, string opName = NAME> {1928 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");1929 if !not(ps.Pfl.HasExt64BitDPP) then1930 def _e64_dpp8#Gen.Suffix : Base_VOP3_DPP8<op, ps> {1931 let Inst{11} = ?;1932 let Inst{12} = ?;1933 let AsmString = asmName # ps.Pfl.AsmVOP3DPP8;1934 let DecoderNamespace = Gen.DecoderNamespace1935 # !if(ps.Pfl.IsRealTrue16, "", "_FAKE16");1936 let AssemblerPredicate = Gen.AssemblerPredicate;1937 }1938}1939 1940multiclass VOP3_Real_dpp8_with_name<GFXGen Gen, bits<10> op, string opName,1941 string asmName> {1942 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");1943 if !not(ps.Pfl.HasExt64BitDPP) then1944 let AsmString = asmName # ps.Pfl.AsmVOP3DPP8,1945 DecoderNamespace = Gen.DecoderNamespace#1946 !if(ps.Pfl.IsRealTrue16, "", "_FAKE16"),1947 True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts,1948 NoTrue16Predicate) in {1949 defm NAME : VOP3_Real_dpp8_Base<Gen, op, opName>;1950 }1951}1952 1953multiclass VOP3be_Real<GFXGen Gen, bits<10> op, string opName, string asmName,1954 bit isSingle = 0> {1955 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");1956 let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in1957 def _e64#Gen.Suffix :1958 VOP3_Real_Gen<ps, Gen, asmName>,1959 VOP3be_gfx11_gfx12<op, ps.Pfl> ;1960}1961 1962multiclass VOP3be_Real_dpp<GFXGen Gen, bits<10> op, string opName,1963 string asmName> {1964 defvar ps = !cast<VOP3_Pseudo>(opName #"_e64");1965 defvar dpp_ps = !cast<VOP_DPP_Pseudo>(opName #"_e64" #"_dpp");1966 def _e64_dpp#Gen.Suffix : Base_VOP3b_DPP16<op, dpp_ps, asmName>,1967 SIMCInstr<dpp_ps.PseudoInstr, Gen.Subtarget> {1968 let DecoderNamespace = Gen.DecoderNamespace;1969 let AssemblerPredicate = Gen.AssemblerPredicate;1970 }1971}1972 1973multiclass VOP3be_Real_dpp8<GFXGen Gen, bits<10> op, string opName,1974 string asmName> {1975 defvar ps = !cast<VOP3_Pseudo>(opName #"_e64");1976 if !not(ps.Pfl.HasExt64BitDPP) then1977 def _e64_dpp8#Gen.Suffix : VOP3b_DPP8_Base<op, ps, asmName> {1978 let DecoderNamespace = Gen.DecoderNamespace;1979 let AssemblerPredicate = Gen.AssemblerPredicate;1980 }1981}1982 1983// VOP1 and VOP2 depend on these triple defs1984multiclass VOP3_Realtriple<GFXGen Gen, bits<10> op, bit isSingle = 0,1985 string opName = NAME> :1986 VOP3_Real_Base<Gen, op, opName, isSingle>,1987 VOP3_Real_dpp_Base<Gen, op, opName>,1988 VOP3_Real_dpp8_Base<Gen, op, opName>;1989 1990multiclass VOP3Dot_Realtriple<GFXGen Gen, bits<10> op, string asmName, bit isSingle = 0,1991 string opName = NAME> :1992 VOP3Dot_Real_Base<Gen, op, asmName, opName, isSingle>,1993 VOP3Dot_Real_dpp_Base<Gen, op, asmName, opName>,1994 VOP3Dot_Real_dpp8_Base<Gen, op, asmName, opName>;1995 1996multiclass VOP3Only_Realtriple<GFXGen Gen, bits<10> op> :1997 VOP3_Realtriple<Gen, op, 1>;1998 1999multiclass VOP3_Realtriple_with_name<GFXGen Gen, bits<10> op, string opName,2000 string asmName, string pseudo_mnemonic = "", bit isSingle = 0> :2001 VOP3_Real_with_name<Gen, op, opName, asmName, pseudo_mnemonic, isSingle>,2002 VOP3_Real_dpp_with_name<Gen, op, opName, asmName>,2003 VOP3_Real_dpp8_with_name<Gen, op, opName, asmName>;2004 2005multiclass VOP3Only_Realtriple_with_name<GFXGen Gen, bits<10> op, string opName,2006 string asmName> :2007 VOP3_Realtriple_with_name<Gen, op, opName, asmName, "", 1>;2008 2009multiclass VOP3be_Realtriple<2010 GFXGen Gen, bits<10> op, bit isSingle = 0, string opName = NAME,2011 string asmName = !cast<VOP_Pseudo>(opName#"_e64").Mnemonic> :2012 VOP3be_Real<Gen, op, opName, asmName, isSingle>,2013 VOP3be_Real_dpp<Gen, op, opName, asmName>,2014 VOP3be_Real_dpp8<Gen, op, opName, asmName>;2015 2016multiclass VOP3beOnly_Realtriple<GFXGen Gen, bits<10> op> :2017 VOP3be_Realtriple<Gen, op, 1>;2018 2019multiclass VOP3_BITOP3_Real_dpp_Base<GFXGen Gen, bits<10> op, string asmName> {2020 def _e64_dpp#Gen.Suffix :2021 VOP3_BITOP3_DPP16_Gen<op, !cast<VOP_DPP_Pseudo>(NAME#"_e64"#"_dpp"), Gen, asmName>;2022}2023 2024multiclass VOP3_BITOP3_Real_dpp8_Base<GFXGen Gen, bits<10> op, string asmName> {2025 defvar ps = !cast<VOP3_Pseudo>(NAME#"_e64");2026 def _e64_dpp8#Gen.Suffix : VOP3_BITOP3_DPP8<op, ps, asmName> {2027 let DecoderNamespace =2028 Gen.DecoderNamespace #!if (ps.Pfl.IsRealTrue16, "", "_FAKE16");2029 let AssemblerPredicate = Gen.AssemblerPredicate;2030 }2031}2032 2033multiclass VOP3_BITOP3_Real_Base<GFXGen Gen, bits<10> op, string asmName> {2034 defvar ps = !cast<VOP_Pseudo>(NAME#"_e64");2035 let IsSingle = ps.Pfl.IsSingle, AsmString = asmName # ps.AsmOperands in {2036 def _e64#Gen.Suffix :2037 VOP3_Real_Gen<ps, Gen>,2038 VOP3a_BITOP3_gfx12<op, ps.Pfl>;2039 }2040}2041 2042multiclass VOP3Only_ScaleSel_Real_gfx1250<bits<10> op> {2043 defvar ps = !cast<VOP_Pseudo>(NAME#"_e64");2044 def _e64_gfx1250 :2045 VOP3_Real_Gen<ps, GFX1250Gen>,2046 VOP3a_ScaleSel_gfx1250<op, ps.Pfl>;2047}2048 2049multiclass VOP3Only_Realtriple_t16_gfx11_gfx12_not_gfx1250<bits<10> op, string asmName, string opName = NAME,2050 string pseudo_mnemonic = "", bit isSingle = 0> :2051 VOP3_Realtriple_with_name<GFX11Gen, op, opName, asmName, pseudo_mnemonic, isSingle>,2052 VOP3_Realtriple_with_name<GFX12Not12_50Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2053 2054multiclass VOP3Only_Realtriple_t16_and_fake16_gfx11_gfx12_not_gfx1250<bits<10> op, string asmName,2055 string opName = NAME, string pseudo_mnemonic = ""> {2056 defm _t16 : VOP3Only_Realtriple_t16_gfx11_gfx12_not_gfx1250<op, asmName, opName#"_t16", pseudo_mnemonic, 1>;2057 defm _fake16 : VOP3Only_Realtriple_t16_gfx11_gfx12_not_gfx1250<op, asmName, opName#"_fake16", pseudo_mnemonic, 1>;2058}2059 2060multiclass VOP3_Realtriple_with_name_gfx11_gfx12_not_gfx1250<bits<10> op, string opName,2061 string asmName, string pseudo_mnemonic = "",2062 bit isSingle = 0> :2063 VOP3_Realtriple_with_name<GFX11Gen, op, opName, asmName, pseudo_mnemonic, isSingle>,2064 VOP3_Realtriple_with_name<GFX12Not12_50Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2065 2066//===----------------------------------------------------------------------===//2067// VOP3 GFX112068//===----------------------------------------------------------------------===//2069 2070// VOP1 and VOP2 depend on these triple defs2071 2072multiclass VOP3_Realtriple_t16_gfx11<bits<10> op, string asmName, string opName = NAME,2073 string pseudo_mnemonic = "", bit isSingle = 0> :2074 VOP3_Realtriple_with_name<GFX11Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2075 2076multiclass VOP3_Realtriple_t16_and_fake16_gfx11<bits<10> op, string asmName, string opName = NAME,2077 string pseudo_mnemonic = "", bit isSingle = 0> {2078 defm _t16: VOP3_Realtriple_t16_gfx11<op, asmName, opName#"_t16", pseudo_mnemonic, isSingle>;2079 defm _fake16: VOP3_Realtriple_t16_gfx11<op, asmName, opName#"_fake16", pseudo_mnemonic, isSingle>;2080}2081 2082multiclass VOP3Only_Realtriple_t16_gfx11<bits<10> op, string asmName,2083 string opName = NAME, string pseudo_mnemonic = "">2084 : VOP3_Realtriple_t16_gfx11<op, asmName, opName, pseudo_mnemonic, 1>;2085 2086multiclass VOP3Only_Realtriple_t16_and_fake16_gfx11<bits<10> op, string asmName,2087 string opName = NAME, string pseudo_mnemonic = ""> {2088 defm _t16: VOP3_Realtriple_t16_gfx11<op, asmName, opName#"_t16", pseudo_mnemonic, 1>;2089 defm _fake16: VOP3_Realtriple_t16_gfx11<op, asmName, opName#"_fake16", pseudo_mnemonic, 1>;2090}2091 2092multiclass VOP3be_Real_gfx11<bits<10> op, string opName, string asmName,2093 bit isSingle = 0> :2094 VOP3be_Real<GFX11Gen, op, opName, asmName, isSingle>;2095 2096multiclass VOP3_Real_Base_gfx11<bits<10> op, string opName = NAME,2097 bit isSingle = 0> :2098 VOP3_Real_Base<GFX11Gen, op, opName, isSingle>;2099 2100multiclass VOP3_Realtriple_gfx11<bits<10> op, bit isSingle = 0,2101 string opName = NAME> :2102 VOP3_Realtriple<GFX11Gen, op, isSingle, opName>;2103 2104//===----------------------------------------------------------------------===//2105// VOP3 GFX122106//===----------------------------------------------------------------------===//2107 2108multiclass VOP3Only_Realtriple_gfx12<bits<10> op, bit isSingle = 0> :2109 VOP3_Realtriple<GFX12Gen, op, isSingle>;2110 2111// IsSingle is captured from the vopprofile for these instructions, but the2112// following alternative is more explicit2113multiclass VOP3Only_Real_Base_gfx12<bits<10> op> :2114 VOP3_Real_Base<GFX12Gen, op, NAME, 1/*IsSingle*/>;2115 2116multiclass VOP3Only_Realtriple_with_name_gfx12_not_gfx1250<bits<10> op, string opName,2117 string asmName, string pseudo_mnemonic = "",2118 bit isSingle = 0> :2119 VOP3_Realtriple_with_name<GFX12Not12_50Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2120 2121multiclass VOP3Only_Real_Base_gfx1250<bits<10> op> :2122 VOP3_Real_Base<GFX1250Gen, op, NAME, 1/*IsSingle*/>;2123 2124multiclass VOP3Only_Realtriple_gfx1250<bits<10> op, bit isSingle = 0> :2125 VOP3_Realtriple<GFX1250Gen, op, isSingle>;2126 2127multiclass VOP3Only_Realtriple_gfx12_not_gfx1250<bits<10> op, bit isSingle = 0> :2128 VOP3_Realtriple<GFX12Not12_50Gen, op, isSingle>;2129 2130multiclass VOP3Only_Realtriple_with_name_gfx1250<bits<10> op, string opName,2131 string asmName, string pseudo_mnemonic = "",2132 bit isSingle = 0> :2133 VOP3_Realtriple_with_name<GFX1250Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2134 2135multiclass VOP3Only_Realtriple_t16_gfx1250<bits<10> op, string asmName = !cast<VOP3_Pseudo>(NAME#"_e64").Mnemonic,2136 string opName = NAME, string pseudo_mnemonic = "", bit isSingle = 0> :2137 VOP3Only_Realtriple_with_name_gfx1250<op, opName, asmName, pseudo_mnemonic, isSingle>;2138 2139multiclass VOP3_Realtriple_t16_gfx12<bits<10> op, string asmName, string opName = NAME,2140 string pseudo_mnemonic = "", bit isSingle = 0> :2141 VOP3_Realtriple_with_name<GFX12Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2142 2143multiclass VOP3_Realtriple_t16_and_fake16_gfx12<bits<10> op, string asmName, string opName = NAME,2144 string pseudo_mnemonic = "", bit isSingle = 0> {2145 defm _t16:VOP3_Realtriple_t16_gfx12<op, asmName, opName#"_t16", pseudo_mnemonic, isSingle>;2146 defm _fake16:VOP3_Realtriple_t16_gfx12<op, asmName, opName#"_fake16", pseudo_mnemonic, isSingle>;2147}2148 2149multiclass VOP3Only_Realtriple_t16_gfx12<bits<10> op, string asmName,2150 string opName = NAME, string pseudo_mnemonic = "">2151 : VOP3_Realtriple_t16_gfx12<op, asmName, opName, pseudo_mnemonic, 1>;2152 2153multiclass VOP3Only_Realtriple_t16_and_fake16_gfx12<bits<10> op, string asmName,2154 string opName = NAME, string pseudo_mnemonic = ""> {2155 defm _t16 : VOP3Only_Realtriple_t16_gfx12<op, asmName, opName#"_t16", pseudo_mnemonic>;2156 defm _fake16 : VOP3Only_Realtriple_t16_gfx12<op, asmName, opName#"_fake16", pseudo_mnemonic>;2157}2158 2159multiclass VOP3Only_Realtriple_t16_and_fake16_gfx1250<bits<10> op,2160 string asmName = !cast<VOP3_Pseudo>(NAME#"_e64").Mnemonic,2161 string opName = NAME, string pseudo_mnemonic = ""> {2162 defm _t16 : VOP3Only_Realtriple_t16_gfx1250<op, asmName, opName#"_t16", pseudo_mnemonic>;2163 defm _fake16 : VOP3Only_Realtriple_t16_gfx1250<op, asmName, opName#"_fake16", pseudo_mnemonic>;2164}2165 2166multiclass VOP3be_Real_with_name_gfx12<bits<10> op, string opName,2167 string asmName, bit isSingle = 0> {2168 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");2169 defm NAME : VOP3be_Realtriple<GFX12Gen, op, !or(isSingle, ps.Pfl.IsSingle),2170 opName, asmName>;2171 def : AMDGPUMnemonicAlias<ps.Mnemonic, asmName> {2172 let AssemblerPredicate = GFX12Gen.AssemblerPredicate;2173 }2174}2175 2176multiclass VOP3_Realtriple_with_name_gfx12<bits<10> op, string opName,2177 string asmName, string pseudo_mnemonic = "", bit isSingle = 0> :2178 VOP3_Realtriple_with_name<GFX12Gen, op, opName, asmName, pseudo_mnemonic, isSingle>;2179 2180multiclass VOP3Only_Realtriple_with_name_gfx11_gfx12<bits<10> op, string opName,2181 string asmName> :2182 VOP3Only_Realtriple_with_name<GFX11Gen, op, opName, asmName>,2183 VOP3Only_Realtriple_with_name<GFX12Gen, op, opName, asmName>;2184 2185multiclass VOP3_Real_BITOP3_gfx1250<bits<10> op, string asmName = !cast<VOP3_Pseudo>(NAME#"_e64").Mnemonic> :2186 VOP3_BITOP3_Real_Base<GFX1250Gen, op, asmName>,2187 VOP3_BITOP3_Real_dpp_Base<GFX1250Gen, op, asmName>,2188 VOP3_BITOP3_Real_dpp8_Base<GFX1250Gen, op, asmName>;2189 2190multiclass VOP3_Real_BITOP3_t16_and_fake16_gfx1250<bits<10> op, string asmName = !cast<VOP3_Pseudo>(NAME#"_e64").Mnemonic> {2191 defm _t16 : VOP3_Real_BITOP3_gfx1250<op, asmName>;2192 defm _fake16: VOP3_Real_BITOP3_gfx1250<op, asmName>;2193}2194 2195multiclass VOP3Dot_Realtriple_gfx11_gfx12<bits<10> op, string asmName, bit isSingle = 0,2196 string opName = NAME> :2197 VOP3Dot_Realtriple<GFX11Gen, op, asmName, isSingle, opName>,2198 VOP3Dot_Realtriple<GFX12Gen, op, asmName, isSingle, opName>;2199 2200 2201//===----------------------------------------------------------------------===//2202 2203include "VOPCInstructions.td"2204include "VOP1Instructions.td"2205include "VOP2Instructions.td"2206include "VOP3Instructions.td"2207include "VOP3PInstructions.td"2208include "VOPDInstructions.td"2209 2210class ClassPat<Instruction inst, ValueType vt> : GCNPat <2211 (i1 (is_fpclass (vt (VOP3ModsNonCanonicalizing vt:$src0, i32:$src0_mods)), (i32 timm:$mask))),2212 (inst i32:$src0_mods, vt:$src0, (V_MOV_B32_e32 timm:$mask))2213>;2214 2215class ClassPat_t16<Instruction inst, ValueType vt> : GCNPat <2216 (i1 (is_fpclass (vt (VOP3ModsNonCanonicalizing vt:$src0, i32:$src0_mods)), (i32 timm:$mask))),2217 (inst i32:$src0_mods, vt:$src0, SRCMODS.NONE, (V_MOV_B32_e32 timm:$mask))2218>;2219 2220def : ClassPat<V_CMP_CLASS_F16_e64, f16> {2221 let OtherPredicates = [Has16BitInsts];2222 let True16Predicate = NotHasTrue16BitInsts;2223}2224 2225def : ClassPat_t16<V_CMP_CLASS_F16_t16_e64, f16> {2226 let True16Predicate = UseRealTrue16Insts;2227}2228 2229def : ClassPat_t16<V_CMP_CLASS_F16_fake16_e64, f16> {2230 let True16Predicate = UseFakeTrue16Insts;2231}2232 2233def : ClassPat<V_CMP_CLASS_F32_e64, f32>;2234def : ClassPat<V_CMP_CLASS_F64_e64, f64>;2235 2236class VOPInfoTable <string Format> : GenericTable {2237 let FilterClass = Format # "_Real";2238 let CppTypeName = "VOPInfo";2239 let Fields = ["Opcode", "IsSingle"];2240 2241 let PrimaryKey = ["Opcode"];2242 let PrimaryKeyName = "get" # Format # "OpcodeHelper";2243}2244 2245def VOP1InfoTable : VOPInfoTable<"VOP1">;2246def VOP2InfoTable : VOPInfoTable<"VOP2">;2247def VOP3InfoTable : VOPInfoTable<"VOP3">;2248 2249class VOPC64Table <string Format> : GenericTable {2250 let FilterClass = "VOPC64_" # Format;2251 let CppTypeName = "VOPC64DPPInfo";2252 let Fields = ["Opcode"];2253 2254 let PrimaryKey = ["Opcode"];2255 let PrimaryKeyName = "isVOPC64" # Format # "OpcodeHelper";2256}2257 2258def VOPC64DPPTable : VOPC64Table<"DPP">;2259def VOPC64DPP8Table : VOPC64Table<"DPP8">;2260 2261class AsmOnlyInfoTable <string Format, string Class>: GenericTable {2262 let FilterClass = Class;2263 let FilterClassField = "isAsmParserOnly";2264 let CppTypeName = Format # "DPPAsmOnlyInfo";2265 let Fields = ["Opcode"];2266 2267 let PrimaryKey = ["Opcode"];2268 let PrimaryKeyName = "is" # Format # "AsmOnlyOpcodeHelper";2269}2270 2271def VOPCAsmOnlyInfoTable : AsmOnlyInfoTable <"VOPC", "VOPC_DPPe_Common">;2272 2273def VOPTrue16Table : GenericTable {2274 let FilterClass = "VOP_Pseudo";2275 let CppTypeName = "VOPTrue16Info";2276 let Fields = ["Opcode", "IsTrue16"];2277 2278 let PrimaryKey = ["Opcode"];2279 let PrimaryKeyName = "getTrue16OpcodeHelper";2280}2281