brintos

brintos / llvm-project-archived public Read only

0
0
Text · 81.1 KiB · ea3edb8 Raw
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