xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/VOPInstructions.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric//===-- VOPInstructions.td - Vector Instruction Definitions ---------------===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric// dummies for outer let
100b57cec5SDimitry Andricclass LetDummies {
11e8d8bef9SDimitry Andric  bit TRANS;
125ffd83dbSDimitry Andric  bit ReadsModeReg;
135ffd83dbSDimitry Andric  bit mayRaiseFPException;
140b57cec5SDimitry Andric  bit isCommutable;
150b57cec5SDimitry Andric  bit isConvertibleToThreeAddress;
160b57cec5SDimitry Andric  bit isMoveImm;
170b57cec5SDimitry Andric  bit isReMaterializable;
180b57cec5SDimitry Andric  bit isAsCheapAsAMove;
198bcb0991SDimitry Andric  bit FPDPRounding;
20*0fca6ea1SDimitry Andric  bit IsInvalidSingleUseConsumer;
21*0fca6ea1SDimitry Andric  bit IsInvalidSingleUseProducer;
220b57cec5SDimitry Andric  Predicate SubtargetPredicate;
230b57cec5SDimitry Andric  string Constraints;
240b57cec5SDimitry Andric  string DisableEncoding;
250b57cec5SDimitry Andric  list<SchedReadWrite> SchedRW;
260b57cec5SDimitry Andric  list<Register> Uses;
270b57cec5SDimitry Andric  list<Register> Defs;
28bdd1243dSDimitry Andric  list<Predicate> OtherPredicates;
29bdd1243dSDimitry Andric  Predicate AssemblerPredicate;
30bdd1243dSDimitry Andric  string DecoderNamespace;
310b57cec5SDimitry Andric}
320b57cec5SDimitry Andric
330b57cec5SDimitry Andricclass VOP <string opName> {
340b57cec5SDimitry Andric  string OpName = opName;
350b57cec5SDimitry Andric}
360b57cec5SDimitry Andric
3781ad6265SDimitry Andric// First 13 insts from VOPDY are also VOPDX. DOT2ACC_F32_BF16 is omitted
3881ad6265SDimitry Andricdefvar VOPDX_Max_Index = 12;
3981ad6265SDimitry Andric
4081ad6265SDimitry Andricclass VOPD_Component<bits<5> OpIn, string vOPDName> {
4181ad6265SDimitry Andric  Instruction BaseVOP = !cast<Instruction>(NAME);
4281ad6265SDimitry Andric  string VOPDName = "v_dual_" # !substr(vOPDName, 2);
4381ad6265SDimitry Andric  bits<5> VOPDOp = OpIn;
4481ad6265SDimitry Andric  bit CanBeVOPDX = !le(VOPDOp, VOPDX_Max_Index);
4581ad6265SDimitry Andric}
4681ad6265SDimitry Andric
470b57cec5SDimitry Andricclass VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> :
480b57cec5SDimitry Andric    InstSI <outs, ins, asm, pattern> {
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric  let mayLoad = 0;
510b57cec5SDimitry Andric  let mayStore = 0;
520b57cec5SDimitry Andric  let hasSideEffects = 0;
530b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
540b57cec5SDimitry Andric  let VALU = 1;
555ffd83dbSDimitry Andric  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
560b57cec5SDimitry Andric}
570b57cec5SDimitry Andric
580b57cec5SDimitry Andricclass VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins,
590b57cec5SDimitry Andric                  string asm, list<dag> pattern> :
600b57cec5SDimitry Andric  InstSI <outs, ins, asm, pattern>,
610b57cec5SDimitry Andric  VOP <opName>,
628bcb0991SDimitry Andric  SIMCInstr <opName#suffix, SIEncodingFamily.NONE> {
630b57cec5SDimitry Andric  let isPseudo = 1;
640b57cec5SDimitry Andric  let isCodeGenOnly = 1;
650b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric  string Mnemonic = opName;
68bdd1243dSDimitry Andric  Instruction Opcode = !cast<Instruction>(NAME);
69bdd1243dSDimitry Andric  bit IsTrue16 = P.IsTrue16;
70*0fca6ea1SDimitry Andric  bit IsInvalidSingleUseConsumer = P.IsInvalidSingleUseConsumer;
71*0fca6ea1SDimitry Andric  bit IsInvalidSingleUseProducer = P.IsInvalidSingleUseProducer;
720b57cec5SDimitry Andric  VOPProfile Pfl = P;
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric  string AsmOperands;
750b57cec5SDimitry Andric}
760b57cec5SDimitry Andric
770b57cec5SDimitry Andricclass VOP3Common <dag outs, dag ins, string asm = "",
78349cc55cSDimitry Andric                  list<dag> pattern = [], bit HasMods = 0> :
790b57cec5SDimitry Andric  VOPAnyCommon <outs, ins, asm, pattern> {
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric  // Using complex patterns gives VOP3 patterns a very high complexity rating,
820b57cec5SDimitry Andric  // but standalone patterns are almost always preferred, so we need to adjust the
830b57cec5SDimitry Andric  // priority lower.  The goal is to use a high number to reduce complexity to
840b57cec5SDimitry Andric  // zero (or less than zero).
850b57cec5SDimitry Andric  let AddedComplexity = -1000;
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric  let VOP3 = 1;
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric  let AsmVariantName = AMDGPUAsmVariants.VOP3;
90e8d8bef9SDimitry Andric  let AsmMatchConverter = !if(HasMods, "cvtVOP3", "");
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric  let isCodeGenOnly = 0;
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric  int Size = 8;
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric  // Because SGPRs may be allowed if there are multiple operands, we
970b57cec5SDimitry Andric  // need a post-isel hook to insert copies in order to avoid
980b57cec5SDimitry Andric  // violating constant bus requirements.
990b57cec5SDimitry Andric  let hasPostISelHook = 1;
1000b57cec5SDimitry Andric}
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andricclass VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [],
103349cc55cSDimitry Andric                   bit isVOP3P = 0, bit isVop3OpSel = 0> :
1040b57cec5SDimitry Andric  VOP_Pseudo <opName, "_e64", P, P.Outs64,
1050b57cec5SDimitry Andric              !if(isVop3OpSel,
1060b57cec5SDimitry Andric                  P.InsVOP3OpSel,
1070b57cec5SDimitry Andric                  !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)),
1080b57cec5SDimitry Andric              "", pattern> {
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric  let VOP3_OPSEL = isVop3OpSel;
1110b57cec5SDimitry Andric  let IsPacked = P.IsPacked;
1120b57cec5SDimitry Andric  let IsMAI = P.IsMAI;
11381ad6265SDimitry Andric  let IsWMMA = P.IsWMMA;
114b3edf446SDimitry Andric  let IsSWMMAC = P.IsSWMMAC;
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andric  let AsmOperands = !if(isVop3OpSel,
1170b57cec5SDimitry Andric                        P.AsmVOP3OpSel,
1180b57cec5SDimitry Andric                        !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64));
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric  let Size = 8;
1210b57cec5SDimitry Andric  let mayLoad = 0;
1220b57cec5SDimitry Andric  let mayStore = 0;
1230b57cec5SDimitry Andric  let hasSideEffects = 0;
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andric  // Because SGPRs may be allowed if there are multiple operands, we
1260b57cec5SDimitry Andric  // need a post-isel hook to insert copies in order to avoid
1270b57cec5SDimitry Andric  // violating constant bus requirements.
1280b57cec5SDimitry Andric  let hasPostISelHook = 1;
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andric  // Using complex patterns gives VOP3 patterns a very high complexity rating,
1310b57cec5SDimitry Andric  // but standalone patterns are almost always preferred, so we need to adjust the
1320b57cec5SDimitry Andric  // priority lower.  The goal is to use a high number to reduce complexity to
1330b57cec5SDimitry Andric  // zero (or less than zero).
1340b57cec5SDimitry Andric  let AddedComplexity = -1000;
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric  let VOP3 = 1;
1370b57cec5SDimitry Andric  let VALU = 1;
1380b57cec5SDimitry Andric  let FPClamp = P.HasFPClamp;
1390b57cec5SDimitry Andric  let IntClamp = P.HasIntClamp;
1400b57cec5SDimitry Andric  let ClampLo = P.HasClampLo;
1410b57cec5SDimitry Andric  let ClampHi = P.HasClampHi;
1420b57cec5SDimitry Andric
1437a6dacacSDimitry Andric  let ReadsModeReg = !or(P.DstVT.isFP, P.Src0VT.isFP);
1445ffd83dbSDimitry Andric
1455ffd83dbSDimitry Andric  let mayRaiseFPException = ReadsModeReg;
1465ffd83dbSDimitry Andric  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
1470b57cec5SDimitry Andric
1480b57cec5SDimitry Andric  let AsmVariantName = AMDGPUAsmVariants.VOP3;
1490b57cec5SDimitry Andric  let AsmMatchConverter =
1500b57cec5SDimitry Andric    !if(isVOP3P,
1510b57cec5SDimitry Andric        "cvtVOP3P",
152*0fca6ea1SDimitry Andric        !if(!or(P.HasModifiers, P.HasOMod, P.HasClamp),
1530b57cec5SDimitry Andric            "cvtVOP3",
1540b57cec5SDimitry Andric            ""));
1550b57cec5SDimitry Andric}
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andricclass VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> :
158349cc55cSDimitry Andric  VOP3_Pseudo<opName, P, pattern, 1> {
1590b57cec5SDimitry Andric  let VOP3P = 1;
1607a6dacacSDimitry Andric  let IsDOT = P.IsDOT;
1610b57cec5SDimitry Andric}
1620b57cec5SDimitry Andric
163fe6060f1SDimitry Andricclass VOP_Real<VOP_Pseudo ps> {
164fe6060f1SDimitry Andric  Instruction Opcode = !cast<Instruction>(NAME);
165fe6060f1SDimitry Andric  bit IsSingle = ps.Pfl.IsSingle;
166*0fca6ea1SDimitry Andric  bit IsInvalidSingleUseConsumer = ps.Pfl.IsInvalidSingleUseConsumer;
167*0fca6ea1SDimitry Andric  bit IsInvalidSingleUseProducer = ps.Pfl.IsInvalidSingleUseProducer;
168fe6060f1SDimitry Andric}
169fe6060f1SDimitry Andric
17081ad6265SDimitry Andricclass VOP3_Real <VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :
171fe6060f1SDimitry Andric  VOP_Real <ps>,
17281ad6265SDimitry Andric  InstSI <ps.OutOperandList, ps.InOperandList, asm_name # ps.AsmOperands, []>,
1730b57cec5SDimitry Andric  SIMCInstr <ps.PseudoInstr, EncodingFamily> {
1740b57cec5SDimitry Andric
175fe6060f1SDimitry Andric  let VALU = 1;
176fe6060f1SDimitry Andric  let VOP3 = 1;
1770b57cec5SDimitry Andric  let isPseudo = 0;
1780b57cec5SDimitry Andric  let isCodeGenOnly = 0;
1790b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric  // copy relevant pseudo op flags
1820b57cec5SDimitry Andric  let SubtargetPredicate = ps.SubtargetPredicate;
183*0fca6ea1SDimitry Andric  let WaveSizePredicate  = ps.WaveSizePredicate;
1848bcb0991SDimitry Andric  let OtherPredicates    = ps.OtherPredicates;
1850b57cec5SDimitry Andric  let AsmMatchConverter  = ps.AsmMatchConverter;
1860b57cec5SDimitry Andric  let AsmVariantName     = ps.AsmVariantName;
1870b57cec5SDimitry Andric  let Constraints        = ps.Constraints;
1880b57cec5SDimitry Andric  let DisableEncoding    = ps.DisableEncoding;
1890b57cec5SDimitry Andric  let TSFlags            = ps.TSFlags;
1900b57cec5SDimitry Andric  let UseNamedOperandTable = ps.UseNamedOperandTable;
1910b57cec5SDimitry Andric  let Uses                 = ps.Uses;
1920b57cec5SDimitry Andric  let Defs                 = ps.Defs;
193fe6060f1SDimitry Andric  let SchedRW              = ps.SchedRW;
194fe6060f1SDimitry Andric  let mayLoad              = ps.mayLoad;
195fe6060f1SDimitry Andric  let mayStore             = ps.mayStore;
196fe6060f1SDimitry Andric  let TRANS                = ps.TRANS;
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric  VOPProfile Pfl = ps.Pfl;
1990b57cec5SDimitry Andric}
2000b57cec5SDimitry Andric
2015f757f3fSDimitry Andricclass VOP3_Real_Gen <VOP_Pseudo ps, GFXGen Gen, string asm_name = ps.Mnemonic> :
2025f757f3fSDimitry Andric  VOP3_Real <ps, Gen.Subtarget, asm_name> {
203297eecfbSDimitry Andric  let AssemblerPredicate = Gen.AssemblerPredicate;
204*0fca6ea1SDimitry Andric  let True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);
2055f757f3fSDimitry Andric  let DecoderNamespace = Gen.DecoderNamespace#
2065f757f3fSDimitry Andric                         !if(ps.Pfl.IsRealTrue16, "", "_FAKE16");
2075f757f3fSDimitry Andric}
2085f757f3fSDimitry Andric
2095ffd83dbSDimitry Andric// XXX - Is there any reason to distinguish this from regular VOP3
2100b57cec5SDimitry Andric// here?
21181ad6265SDimitry Andricclass VOP3P_Real<VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :
21281ad6265SDimitry Andric  VOP3_Real<ps, EncodingFamily, asm_name> {
21381ad6265SDimitry Andric
21481ad6265SDimitry Andric  // The v_wmma pseudos have extra constraints that we do not want to impose on the real instruction.
21581ad6265SDimitry Andric  let Constraints        = !if(!eq(!substr(ps.Mnemonic,0,6), "v_wmma"), "", ps.Constraints);
21681ad6265SDimitry Andric}
2170b57cec5SDimitry Andric
2185f757f3fSDimitry Andricclass VOP3P_Real_Gen<VOP_Pseudo ps, GFXGen Gen, string asm_name = ps.Mnemonic> :
2195f757f3fSDimitry Andric  VOP3P_Real<ps, Gen.Subtarget, asm_name> {
2205f757f3fSDimitry Andric  let AssemblerPredicate = Gen.AssemblerPredicate;
2215f757f3fSDimitry Andric  let DecoderNamespace = Gen.DecoderNamespace;
2225f757f3fSDimitry Andric}
2235f757f3fSDimitry Andric
2240b57cec5SDimitry Andricclass VOP3a<VOPProfile P> : Enc64 {
2250b57cec5SDimitry Andric  bits<4> src0_modifiers;
2260b57cec5SDimitry Andric  bits<9> src0;
2270b57cec5SDimitry Andric  bits<3> src1_modifiers;
2280b57cec5SDimitry Andric  bits<9> src1;
2290b57cec5SDimitry Andric  bits<3> src2_modifiers;
2300b57cec5SDimitry Andric  bits<9> src2;
2310b57cec5SDimitry Andric  bits<1> clamp;
2320b57cec5SDimitry Andric  bits<2> omod;
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric  let Inst{8}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
2350b57cec5SDimitry Andric  let Inst{9}     = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);
2360b57cec5SDimitry Andric  let Inst{10}    = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric  let Inst{31-26} = 0x34; //encoding
2390b57cec5SDimitry Andric  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
2400b57cec5SDimitry Andric  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
2410b57cec5SDimitry Andric  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
2420b57cec5SDimitry Andric  let Inst{60-59} = !if(P.HasOMod, omod, 0);
2430b57cec5SDimitry Andric  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
2440b57cec5SDimitry Andric  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
2450b57cec5SDimitry Andric  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
2460b57cec5SDimitry Andric}
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andricclass VOP3a_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a<p> {
2490b57cec5SDimitry Andric  let Inst{11}    = !if(p.HasClamp, clamp{0}, 0);
2500b57cec5SDimitry Andric  let Inst{25-17} = op;
2510b57cec5SDimitry Andric}
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andricclass VOP3a_gfx10<bits<10> op, VOPProfile p> : VOP3a<p> {
2540b57cec5SDimitry Andric  let Inst{15}    = !if(p.HasClamp, clamp{0}, 0);
2550b57cec5SDimitry Andric  let Inst{25-16} = op;
2560b57cec5SDimitry Andric  let Inst{31-26} = 0x35;
2570b57cec5SDimitry Andric}
2580b57cec5SDimitry Andric
2595f757f3fSDimitry Andricclass VOP3a_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p>;
26081ad6265SDimitry Andric
2610b57cec5SDimitry Andricclass VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> {
2620b57cec5SDimitry Andric  let Inst{25-16} = op;
2630b57cec5SDimitry Andric  let Inst{15}    = !if(P.HasClamp, clamp{0}, 0);
2640b57cec5SDimitry Andric}
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andricclass VOP3e_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a_gfx6_gfx7<op, p> {
2670b57cec5SDimitry Andric  bits<8> vdst;
2680b57cec5SDimitry Andric  let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0);
2690b57cec5SDimitry Andric}
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andricclass VOP3e_gfx10<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p> {
2720b57cec5SDimitry Andric  bits<8> vdst;
2730b57cec5SDimitry Andric  let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0);
2740b57cec5SDimitry Andric}
2750b57cec5SDimitry Andric
2765f757f3fSDimitry Andricclass VOP3e_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p>;
27781ad6265SDimitry Andric
2780b57cec5SDimitry Andricclass VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> {
2790b57cec5SDimitry Andric  bits<8> vdst;
2800b57cec5SDimitry Andric  let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);
2810b57cec5SDimitry Andric}
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andricclass VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {
2840b57cec5SDimitry Andric  let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0);
2850b57cec5SDimitry Andric  let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0);
2860b57cec5SDimitry Andric  let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0);
2870b57cec5SDimitry Andric  let Inst{14} = !if(P.HasDst,  src0_modifiers{3}, 0);
2880b57cec5SDimitry Andric}
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andricclass VOP3OpSel_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {
2910b57cec5SDimitry Andric  let Inst{11} = !if(p.HasSrc0, src0_modifiers{2}, 0);
2920b57cec5SDimitry Andric  let Inst{12} = !if(p.HasSrc1, src1_modifiers{2}, 0);
2930b57cec5SDimitry Andric  let Inst{13} = !if(p.HasSrc2, src2_modifiers{2}, 0);
2940b57cec5SDimitry Andric  let Inst{14} = !if(p.HasDst,  src0_modifiers{3}, 0);
2950b57cec5SDimitry Andric}
2960b57cec5SDimitry Andric
2975f757f3fSDimitry Andricclass VOP3OpSel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3OpSel_gfx10<op, p>;
29881ad6265SDimitry Andric
299*0fca6ea1SDimitry Andricclass VOP3FP8OpSel_src_bytesel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {
300*0fca6ea1SDimitry Andric  bits<2> byte_sel;
301*0fca6ea1SDimitry Andric  let Inst{11-12} = byte_sel; // NB: bit order is intentionally reversed!
302*0fca6ea1SDimitry Andric  let Inst{14-13} = 0;  // op_sel2/3
303*0fca6ea1SDimitry Andric}
304*0fca6ea1SDimitry Andric
305*0fca6ea1SDimitry Andric class VOP3FP8OpSel_dst_bytesel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {
306*0fca6ea1SDimitry Andric   bits<2> byte_sel;
307*0fca6ea1SDimitry Andric
308*0fca6ea1SDimitry Andric   let Inst{11} = 0; // op_sel0
309*0fca6ea1SDimitry Andric   let Inst{12} = 0; // op_sel1
310*0fca6ea1SDimitry Andric   let Inst{14-13} = byte_sel;  // op_sel2/3
311b3edf446SDimitry Andric }
312b3edf446SDimitry Andric
3135f757f3fSDimitry Andricclass VOP3DotOpSel_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3OpSel_gfx11_gfx12<op, p>{
314fcaf7f86SDimitry Andric  let Inst{11} = ?;
315fcaf7f86SDimitry Andric  let Inst{12} = ?;
316fcaf7f86SDimitry Andric}
31781ad6265SDimitry Andric
3180b57cec5SDimitry Andric// NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa
3190b57cec5SDimitry Andricclass VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {
3200b57cec5SDimitry Andric  bits<2> attrchan;
3210b57cec5SDimitry Andric  bits<6> attr;
3220b57cec5SDimitry Andric  bits<1> high;
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric  let Inst{8}     = 0; // No modifiers for src0
3250b57cec5SDimitry Andric  let Inst{61}    = 0;
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric  let Inst{9}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
3280b57cec5SDimitry Andric  let Inst{62}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric  let Inst{37-32} = attr;
3310b57cec5SDimitry Andric  let Inst{39-38} = attrchan;
3320b57cec5SDimitry Andric  let Inst{40}    = !if(P.HasHigh, high, 0);
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric  let Inst{49-41} = src0;
3350b57cec5SDimitry Andric}
3360b57cec5SDimitry Andric
3370b57cec5SDimitry Andricclass VOP3Interp_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {
3380b57cec5SDimitry Andric  bits<6> attr;
3390b57cec5SDimitry Andric  bits<2> attrchan;
3400b57cec5SDimitry Andric  bits<1> high;
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric  let Inst{8}     = 0;
3430b57cec5SDimitry Andric  let Inst{9}     = !if(p.HasSrc0Mods, src0_modifiers{1}, 0);
3440b57cec5SDimitry Andric  let Inst{37-32} = attr;
3450b57cec5SDimitry Andric  let Inst{39-38} = attrchan;
3460b57cec5SDimitry Andric  let Inst{40}    = !if(p.HasHigh, high, 0);
3470b57cec5SDimitry Andric  let Inst{49-41} = src0;
3480b57cec5SDimitry Andric  let Inst{61}    = 0;
3490b57cec5SDimitry Andric  let Inst{62}    = !if(p.HasSrc0Mods, src0_modifiers{0}, 0);
3500b57cec5SDimitry Andric}
3510b57cec5SDimitry Andric
35281ad6265SDimitry Andricclass VOP3Interp_gfx11<bits<10> op, VOPProfile p> : VOP3Interp_gfx10<op, p>;
35381ad6265SDimitry Andric
3540b57cec5SDimitry Andricclass VOP3be <VOPProfile P> : Enc64 {
3550b57cec5SDimitry Andric  bits<8> vdst;
3560b57cec5SDimitry Andric  bits<2> src0_modifiers;
3570b57cec5SDimitry Andric  bits<9> src0;
3580b57cec5SDimitry Andric  bits<2> src1_modifiers;
3590b57cec5SDimitry Andric  bits<9> src1;
3600b57cec5SDimitry Andric  bits<2> src2_modifiers;
3610b57cec5SDimitry Andric  bits<9> src2;
3620b57cec5SDimitry Andric  bits<7> sdst;
3630b57cec5SDimitry Andric  bits<2> omod;
3640b57cec5SDimitry Andric
3650b57cec5SDimitry Andric  let Inst{7-0}   = vdst;
3660b57cec5SDimitry Andric  let Inst{14-8}  = sdst;
3670b57cec5SDimitry Andric  let Inst{31-26} = 0x34; //encoding
3680b57cec5SDimitry Andric  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
3690b57cec5SDimitry Andric  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
3700b57cec5SDimitry Andric  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
3710b57cec5SDimitry Andric  let Inst{60-59} = !if(P.HasOMod, omod, 0);
3720b57cec5SDimitry Andric  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
3730b57cec5SDimitry Andric  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
3740b57cec5SDimitry Andric  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
3750b57cec5SDimitry Andric}
3760b57cec5SDimitry Andric
377e8d8bef9SDimitry Andricclass VOP3Pe <bits<7> op, VOPProfile P> : Enc64 {
3780b57cec5SDimitry Andric  bits<8> vdst;
3790b57cec5SDimitry Andric  bits<4> src0_modifiers;
3800b57cec5SDimitry Andric  bits<9> src0;
3810b57cec5SDimitry Andric  bits<4> src1_modifiers;
3820b57cec5SDimitry Andric  bits<9> src1;
3830b57cec5SDimitry Andric  bits<4> src2_modifiers;
3840b57cec5SDimitry Andric  bits<9> src2;
3850b57cec5SDimitry Andric  bits<1> clamp;
386b3edf446SDimitry Andric  bits<2> index_key_8bit;
387b3edf446SDimitry Andric  bits<1> index_key_16bit;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric  let Inst{7-0} = vdst;
3900b57cec5SDimitry Andric  let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0
3910b57cec5SDimitry Andric  let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1
3920b57cec5SDimitry Andric  let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andric  let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0)
3950b57cec5SDimitry Andric  let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)
3960b57cec5SDimitry Andric  let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2)
3970b57cec5SDimitry Andric
3987a6dacacSDimitry Andric  let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(2)
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric  let Inst{15} = !if(P.HasClamp, clamp{0}, 0);
4010b57cec5SDimitry Andric
402e8d8bef9SDimitry Andric  let Inst{22-16} = op;
403e8d8bef9SDimitry Andric  let Inst{31-23} = 0x1a7; //encoding
4040b57cec5SDimitry Andric  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
4050b57cec5SDimitry Andric  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
4060b57cec5SDimitry Andric  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
4077a6dacacSDimitry Andric  let Inst{59}    = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(0)
4087a6dacacSDimitry Andric  let Inst{60}    = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(1)
4090b57cec5SDimitry Andric  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo)
4100b57cec5SDimitry Andric  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo)
4110b57cec5SDimitry Andric  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)
4120b57cec5SDimitry Andric}
4130b57cec5SDimitry Andric
414fe6060f1SDimitry Andricclass VOP3Pe_MAI <bits<7> op, VOPProfile P, bit acc_cd = 0> : Enc64 {
4150b57cec5SDimitry Andric  bits<8> vdst;
4160b57cec5SDimitry Andric  bits<10> src0;
4170b57cec5SDimitry Andric  bits<10> src1;
4180b57cec5SDimitry Andric  bits<9> src2;
4190b57cec5SDimitry Andric  bits<3> blgp;
4200b57cec5SDimitry Andric  bits<3> cbsz;
4210b57cec5SDimitry Andric  bits<4> abid;
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric  let Inst{7-0} = vdst;
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andric  let Inst{10-8}  = !if(P.HasSrc1, cbsz, 0);
4260b57cec5SDimitry Andric  let Inst{14-11} = !if(P.HasSrc1, abid, 0);
4270b57cec5SDimitry Andric
428fe6060f1SDimitry Andric  let Inst{15} = acc_cd;
4290b57cec5SDimitry Andric
430e8d8bef9SDimitry Andric  let Inst{22-16} = op;
431e8d8bef9SDimitry Andric  let Inst{31-23} = 0x1a7; //encoding
4320b57cec5SDimitry Andric  let Inst{40-32} = !if(P.HasSrc0, src0{8-0}, 0);
4330b57cec5SDimitry Andric  let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0);
4340b57cec5SDimitry Andric  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
4350b57cec5SDimitry Andric
4360b57cec5SDimitry Andric  let Inst{59}    = !if(P.HasSrc0, src0{9}, 0); // acc(0)
4370b57cec5SDimitry Andric  let Inst{60}    = !if(P.HasSrc1, src1{9}, 0); // acc(1)
4380b57cec5SDimitry Andric
4390b57cec5SDimitry Andric  let Inst{63-61} = !if(P.HasSrc1, blgp, 0);
4400b57cec5SDimitry Andric}
4410b57cec5SDimitry Andric
44281ad6265SDimitry Andricclass VOP3Pe_SMFMAC <bits<7> op> : Enc64 {
44381ad6265SDimitry Andric  bits<10> vdst; // VGPR or AGPR, but not SGPR. vdst{8} is not encoded in the instruction.
44481ad6265SDimitry Andric  bits<10> src0;
44581ad6265SDimitry Andric  bits<10> src1;
44681ad6265SDimitry Andric  bits<9> idx;
44781ad6265SDimitry Andric  bits<3> blgp;
44881ad6265SDimitry Andric  bits<3> cbsz;
44981ad6265SDimitry Andric  bits<4> abid;
45081ad6265SDimitry Andric
45181ad6265SDimitry Andric  let blgp = 0;
45281ad6265SDimitry Andric
45381ad6265SDimitry Andric  let Inst{7-0} = vdst{7-0};
45481ad6265SDimitry Andric
45581ad6265SDimitry Andric  let Inst{10-8}  = cbsz;
45681ad6265SDimitry Andric  let Inst{14-11} = abid;
45781ad6265SDimitry Andric
45881ad6265SDimitry Andric  let Inst{15} = vdst{9}; // acc(vdst)
45981ad6265SDimitry Andric
46081ad6265SDimitry Andric  let Inst{22-16} = op;
46181ad6265SDimitry Andric  let Inst{31-23} = 0x1a7; // encoding
46281ad6265SDimitry Andric  let Inst{40-32} = src0{8-0};
46381ad6265SDimitry Andric  let Inst{49-41} = src1{8-0};
46481ad6265SDimitry Andric  let Inst{58-50} = idx;
46581ad6265SDimitry Andric
46681ad6265SDimitry Andric  let Inst{59}    = src0{9}; // acc(0)
46781ad6265SDimitry Andric  let Inst{60}    = src1{9}; // acc(1)
46881ad6265SDimitry Andric
46981ad6265SDimitry Andric  let Inst{63-61} = blgp;
47081ad6265SDimitry Andric}
4710b57cec5SDimitry Andric
472e8d8bef9SDimitry Andricclass VOP3Pe_gfx10 <bits<7> op, VOPProfile P> : VOP3Pe<op, P> {
473e8d8bef9SDimitry Andric  let Inst{31-23} = 0x198; //encoding
4740b57cec5SDimitry Andric}
4750b57cec5SDimitry Andric
4765f757f3fSDimitry Andricclass VOP3Pe_gfx11_gfx12<bits<7> op, VOPProfile P> : VOP3Pe_gfx10<op, P>;
47781ad6265SDimitry Andric
4780b57cec5SDimitry Andricclass VOP3be_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3be<p> {
4790b57cec5SDimitry Andric  let Inst{25-17} = op;
4800b57cec5SDimitry Andric}
4810b57cec5SDimitry Andric
4820b57cec5SDimitry Andricclass VOP3be_gfx10<bits<10> op, VOPProfile p> : VOP3be<p> {
4830b57cec5SDimitry Andric  bits<1> clamp;
4840b57cec5SDimitry Andric  let Inst{15}    = !if(p.HasClamp, clamp{0}, 0);
4850b57cec5SDimitry Andric  let Inst{25-16} = op;
4860b57cec5SDimitry Andric  let Inst{31-26} = 0x35;
4870b57cec5SDimitry Andric}
4880b57cec5SDimitry Andric
4895f757f3fSDimitry Andricclass VOP3be_gfx11_gfx12<bits<10> op, VOPProfile p> : VOP3be_gfx10<op, p>;
49081ad6265SDimitry Andric
4910b57cec5SDimitry Andricclass VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> {
4920b57cec5SDimitry Andric  bits<1> clamp;
4930b57cec5SDimitry Andric  let Inst{25-16} = op;
4940b57cec5SDimitry Andric  let Inst{15}    = !if(P.HasClamp, clamp{0}, 0);
4950b57cec5SDimitry Andric}
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andricdef SDWA {
4980b57cec5SDimitry Andric  // sdwa_sel
4990b57cec5SDimitry Andric  int BYTE_0 = 0;
5000b57cec5SDimitry Andric  int BYTE_1 = 1;
5010b57cec5SDimitry Andric  int BYTE_2 = 2;
5020b57cec5SDimitry Andric  int BYTE_3 = 3;
5030b57cec5SDimitry Andric  int WORD_0 = 4;
5040b57cec5SDimitry Andric  int WORD_1 = 5;
5050b57cec5SDimitry Andric  int DWORD = 6;
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andric  // dst_unused
5080b57cec5SDimitry Andric  int UNUSED_PAD = 0;
5090b57cec5SDimitry Andric  int UNUSED_SEXT = 1;
5100b57cec5SDimitry Andric  int UNUSED_PRESERVE = 2;
5110b57cec5SDimitry Andric}
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andricclass VOP_SDWAe<VOPProfile P> : Enc64 {
5140b57cec5SDimitry Andric  bits<8> src0;
5150b57cec5SDimitry Andric  bits<3> src0_sel;
5160b57cec5SDimitry Andric  bits<2> src0_modifiers; // float: {abs,neg}, int {sext}
5170b57cec5SDimitry Andric  bits<3> src1_sel;
5180b57cec5SDimitry Andric  bits<2> src1_modifiers;
5190b57cec5SDimitry Andric  bits<3> dst_sel;
5200b57cec5SDimitry Andric  bits<2> dst_unused;
5210b57cec5SDimitry Andric  bits<1> clamp;
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
524fe6060f1SDimitry Andric  let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?);
525fe6060f1SDimitry Andric  let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?);
5260b57cec5SDimitry Andric  let Inst{45}    = !if(P.HasSDWAClamp, clamp{0}, 0);
5270b57cec5SDimitry Andric  let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0);
5280b57cec5SDimitry Andric  let Inst{51}    = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0);
5290b57cec5SDimitry Andric  let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);
5300b57cec5SDimitry Andric  let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0);
5310b57cec5SDimitry Andric  let Inst{59}    = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0);
5320b57cec5SDimitry Andric  let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);
5330b57cec5SDimitry Andric}
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric// GFX9 adds two features to SDWA:
5360b57cec5SDimitry Andric// 1.	Add 3 fields to the SDWA microcode word: S0, S1 and OMOD.
5370b57cec5SDimitry Andric//    a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather
5380b57cec5SDimitry Andric//       than VGPRs (at most 1 can be an SGPR);
5390b57cec5SDimitry Andric//    b. OMOD is the standard output modifier (result *2, *4, /2)
5400b57cec5SDimitry Andric// 2.	Add a new version of the SDWA microcode word for VOPC: SDWAB. This
5410b57cec5SDimitry Andric//    replaces OMOD and the dest fields with SD and SDST (SGPR destination)
5420b57cec5SDimitry Andric//    field.
5430b57cec5SDimitry Andric//    a. When SD=1, the SDST is used as the destination for the compare result;
5440b57cec5SDimitry Andric//    b. When SD=0, VCC is used.
5450b57cec5SDimitry Andric//
5460b57cec5SDimitry Andric// In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andric// gfx9 SDWA basic encoding
5490b57cec5SDimitry Andricclass VOP_SDWA9e<VOPProfile P> : Enc64 {
5500b57cec5SDimitry Andric  bits<9> src0; // {src0_sgpr{0}, src0{7-0}}
5510b57cec5SDimitry Andric  bits<3> src0_sel;
5520b57cec5SDimitry Andric  bits<2> src0_modifiers; // float: {abs,neg}, int {sext}
5530b57cec5SDimitry Andric  bits<3> src1_sel;
5540b57cec5SDimitry Andric  bits<2> src1_modifiers;
5550b57cec5SDimitry Andric  bits<1> src1_sgpr;
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
5580b57cec5SDimitry Andric  let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0);
5590b57cec5SDimitry Andric  let Inst{51}    = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0);
5600b57cec5SDimitry Andric  let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);
5610b57cec5SDimitry Andric  let Inst{55}    = !if(P.HasSrc0, src0{8}, 0);
5620b57cec5SDimitry Andric  let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0);
5630b57cec5SDimitry Andric  let Inst{59}    = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0);
5640b57cec5SDimitry Andric  let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);
5650b57cec5SDimitry Andric  let Inst{63}    = 0; // src1_sgpr - should be specified in subclass
5660b57cec5SDimitry Andric}
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andric// gfx9 SDWA-A
5690b57cec5SDimitry Andricclass VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> {
5700b57cec5SDimitry Andric  bits<3> dst_sel;
5710b57cec5SDimitry Andric  bits<2> dst_unused;
5720b57cec5SDimitry Andric  bits<1> clamp;
5730b57cec5SDimitry Andric  bits<2> omod;
5740b57cec5SDimitry Andric
575fe6060f1SDimitry Andric  let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?);
576fe6060f1SDimitry Andric  let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?);
5770b57cec5SDimitry Andric  let Inst{45}    = !if(P.HasSDWAClamp, clamp{0}, 0);
5780b57cec5SDimitry Andric  let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0);
5790b57cec5SDimitry Andric}
5800b57cec5SDimitry Andric
5810b57cec5SDimitry Andric// gfx9 SDWA-B
5820b57cec5SDimitry Andricclass VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> {
5830b57cec5SDimitry Andric  bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}}
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric  let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, ?);
5860b57cec5SDimitry Andric  let Inst{47} = !if(P.EmitDst, sdst{7}, 0);
5870b57cec5SDimitry Andric}
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andricclass VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> :
5900b57cec5SDimitry Andric  InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>,
5910b57cec5SDimitry Andric  VOP <opName>,
5928bcb0991SDimitry Andric  SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE> {
5930b57cec5SDimitry Andric
5940b57cec5SDimitry Andric  let isPseudo = 1;
5950b57cec5SDimitry Andric  let isCodeGenOnly = 1;
5960b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
5970b57cec5SDimitry Andric
5980b57cec5SDimitry Andric  string Mnemonic = opName;
5990b57cec5SDimitry Andric  string AsmOperands = P.AsmSDWA;
6000b57cec5SDimitry Andric  string AsmOperands9 = P.AsmSDWA9;
6010b57cec5SDimitry Andric
6020b57cec5SDimitry Andric  let Size = 8;
6030b57cec5SDimitry Andric  let mayLoad = 0;
6040b57cec5SDimitry Andric  let mayStore = 0;
6050b57cec5SDimitry Andric  let hasSideEffects = 0;
6060b57cec5SDimitry Andric
6070b57cec5SDimitry Andric  let VALU = 1;
6080b57cec5SDimitry Andric  let SDWA = 1;
6090b57cec5SDimitry Andric
6107a6dacacSDimitry Andric  let ReadsModeReg = !or(P.DstVT.isFP, P.Src0VT.isFP);
6115ffd83dbSDimitry Andric
6125ffd83dbSDimitry Andric  let mayRaiseFPException = ReadsModeReg;
6135ffd83dbSDimitry Andric  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
6145ffd83dbSDimitry Andric
6155ffd83dbSDimitry Andric  let SubtargetPredicate = HasSDWA;
6165ffd83dbSDimitry Andric  let AssemblerPredicate = HasSDWA;
6170b57cec5SDimitry Andric  let AsmVariantName = !if(P.HasExtSDWA, AMDGPUAsmVariants.SDWA,
6180b57cec5SDimitry Andric                                         AMDGPUAsmVariants.Disable);
619*0fca6ea1SDimitry Andric  let DecoderNamespace = "GFX8";
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric  VOPProfile Pfl = P;
6220b57cec5SDimitry Andric}
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andricclass VOP_SDWA_Real <VOP_SDWA_Pseudo ps> :
6250b57cec5SDimitry Andric  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
6260b57cec5SDimitry Andric  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> {
6270b57cec5SDimitry Andric
628fe6060f1SDimitry Andric  let VALU = 1;
629fe6060f1SDimitry Andric  let SDWA = 1;
6300b57cec5SDimitry Andric  let isPseudo = 0;
6310b57cec5SDimitry Andric  let isCodeGenOnly = 0;
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andric  let Defs = ps.Defs;
6340b57cec5SDimitry Andric  let Uses = ps.Uses;
6350b57cec5SDimitry Andric  let hasSideEffects = ps.hasSideEffects;
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andric  let Constraints     = ps.Constraints;
6380b57cec5SDimitry Andric  let DisableEncoding = ps.DisableEncoding;
6390b57cec5SDimitry Andric
6400b57cec5SDimitry Andric  // Copy relevant pseudo op flags
6410b57cec5SDimitry Andric  let SubtargetPredicate   = ps.SubtargetPredicate;
6420b57cec5SDimitry Andric  let AssemblerPredicate   = ps.AssemblerPredicate;
6430b57cec5SDimitry Andric  let AsmMatchConverter    = ps.AsmMatchConverter;
6440b57cec5SDimitry Andric  let AsmVariantName       = ps.AsmVariantName;
6450b57cec5SDimitry Andric  let UseNamedOperandTable = ps.UseNamedOperandTable;
6460b57cec5SDimitry Andric  let DecoderNamespace     = ps.DecoderNamespace;
6470b57cec5SDimitry Andric  let Constraints          = ps.Constraints;
6480b57cec5SDimitry Andric  let DisableEncoding      = ps.DisableEncoding;
6490b57cec5SDimitry Andric  let TSFlags              = ps.TSFlags;
650*0fca6ea1SDimitry Andric  let Uses                 = ps.Uses;
651*0fca6ea1SDimitry Andric  let Defs                 = ps.Defs;
652fe6060f1SDimitry Andric  let SchedRW              = ps.SchedRW;
653fe6060f1SDimitry Andric  let mayLoad              = ps.mayLoad;
654fe6060f1SDimitry Andric  let mayStore             = ps.mayStore;
655fe6060f1SDimitry Andric  let TRANS                = ps.TRANS;
6560b57cec5SDimitry Andric}
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andricclass Base_VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :
6590b57cec5SDimitry Andric  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []> {
6600b57cec5SDimitry Andric
661fe6060f1SDimitry Andric  let VALU = 1;
662fe6060f1SDimitry Andric  let SDWA = 1;
6630b57cec5SDimitry Andric  let isPseudo = 0;
6640b57cec5SDimitry Andric  let isCodeGenOnly = 0;
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andric  let Defs = ps.Defs;
6670b57cec5SDimitry Andric  let Uses = ps.Uses;
6680b57cec5SDimitry Andric  let hasSideEffects = ps.hasSideEffects;
6690b57cec5SDimitry Andric
6700b57cec5SDimitry Andric  let Constraints     = ps.Constraints;
6710b57cec5SDimitry Andric  let DisableEncoding = ps.DisableEncoding;
6720b57cec5SDimitry Andric
6735ffd83dbSDimitry Andric  let SubtargetPredicate = HasSDWA9;
6745ffd83dbSDimitry Andric  let AssemblerPredicate = HasSDWA9;
675*0fca6ea1SDimitry Andric  let OtherPredicates    = ps.OtherPredicates;
6760b57cec5SDimitry Andric  let AsmVariantName = !if(ps.Pfl.HasExtSDWA9, AMDGPUAsmVariants.SDWA9,
6770b57cec5SDimitry Andric                                               AMDGPUAsmVariants.Disable);
678*0fca6ea1SDimitry Andric  let DecoderNamespace = "GFX9";
6790b57cec5SDimitry Andric
6800b57cec5SDimitry Andric  // Copy relevant pseudo op flags
6810b57cec5SDimitry Andric  let AsmMatchConverter    = ps.AsmMatchConverter;
6820b57cec5SDimitry Andric  let UseNamedOperandTable = ps.UseNamedOperandTable;
6830b57cec5SDimitry Andric  let Constraints          = ps.Constraints;
6840b57cec5SDimitry Andric  let DisableEncoding      = ps.DisableEncoding;
6850b57cec5SDimitry Andric  let TSFlags              = ps.TSFlags;
686*0fca6ea1SDimitry Andric  let Uses                 = ps.Uses;
687*0fca6ea1SDimitry Andric  let Defs                 = ps.Defs;
688fe6060f1SDimitry Andric  let SchedRW              = ps.SchedRW;
689fe6060f1SDimitry Andric  let mayLoad              = ps.mayLoad;
690fe6060f1SDimitry Andric  let mayStore             = ps.mayStore;
691fe6060f1SDimitry Andric  let TRANS                = ps.TRANS;
6920b57cec5SDimitry Andric}
6930b57cec5SDimitry Andric
6940b57cec5SDimitry Andricclass VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :
6950b57cec5SDimitry Andric  Base_VOP_SDWA9_Real <ps >,
6960b57cec5SDimitry Andric  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9>;
6970b57cec5SDimitry Andric
6980b57cec5SDimitry Andricclass Base_VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : Base_VOP_SDWA9_Real<ps> {
6995ffd83dbSDimitry Andric  let SubtargetPredicate = HasSDWA10;
7005ffd83dbSDimitry Andric  let AssemblerPredicate = HasSDWA10;
701*0fca6ea1SDimitry Andric  let DecoderNamespace = "GFX10";
7020b57cec5SDimitry Andric}
7030b57cec5SDimitry Andric
7040b57cec5SDimitry Andricclass VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> :
7050b57cec5SDimitry Andric  Base_VOP_SDWA10_Real<ps>, SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SDWA10>;
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andricclass VOP_DPPe<VOPProfile P, bit IsDPP16=0> : Enc64 {
7080b57cec5SDimitry Andric  bits<2> src0_modifiers;
7090b57cec5SDimitry Andric  bits<8> src0;
7100b57cec5SDimitry Andric  bits<2> src1_modifiers;
7110b57cec5SDimitry Andric  bits<9> dpp_ctrl;
7120b57cec5SDimitry Andric  bits<1> bound_ctrl;
7130b57cec5SDimitry Andric  bits<4> bank_mask;
7140b57cec5SDimitry Andric  bits<4> row_mask;
7150b57cec5SDimitry Andric  bit     fi;
7160b57cec5SDimitry Andric
7170b57cec5SDimitry Andric  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
7180b57cec5SDimitry Andric  let Inst{48-40} = dpp_ctrl;
7190b57cec5SDimitry Andric  let Inst{50}    = !if(IsDPP16, fi, ?);
7200b57cec5SDimitry Andric  let Inst{51}    = bound_ctrl;
7210b57cec5SDimitry Andric  let Inst{52}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg
7220b57cec5SDimitry Andric  let Inst{53}    = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs
7230b57cec5SDimitry Andric  let Inst{54}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg
7240b57cec5SDimitry Andric  let Inst{55}    = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs
7250b57cec5SDimitry Andric  let Inst{59-56} = bank_mask;
7260b57cec5SDimitry Andric  let Inst{63-60} = row_mask;
7270b57cec5SDimitry Andric}
7280b57cec5SDimitry Andric
72981ad6265SDimitry Andricclass VOP3_DPPe_Fields_Base {
73081ad6265SDimitry Andric  bits<9> dpp_ctrl;
73181ad6265SDimitry Andric  bits<1> bound_ctrl;
73281ad6265SDimitry Andric  bits<4> bank_mask;
73381ad6265SDimitry Andric  bits<4> row_mask;
73481ad6265SDimitry Andric  bit     fi;
73581ad6265SDimitry Andric}
73681ad6265SDimitry Andricclass VOP3_DPPe_Fields : VOP3_DPPe_Fields_Base {
73781ad6265SDimitry Andric  bits<8> src0;
73881ad6265SDimitry Andric}
73981ad6265SDimitry Andric
74081ad6265SDimitry Andric// Common refers to common between DPP and DPP8
74181ad6265SDimitry Andricclass VOP3_DPPe_Common_Base<bits<10> op, VOPProfile P> : Enc96 {
74281ad6265SDimitry Andric  bits<4> src0_modifiers;
74381ad6265SDimitry Andric  bits<3> src1_modifiers;
74481ad6265SDimitry Andric  bits<3> src2_modifiers;
74581ad6265SDimitry Andric  bits<1> clamp;
74681ad6265SDimitry Andric  bits<2> omod;
747*0fca6ea1SDimitry Andric  bits<2> byte_sel;
74881ad6265SDimitry Andric
74981ad6265SDimitry Andric  let Inst{8}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
75081ad6265SDimitry Andric  let Inst{9}     = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);
75181ad6265SDimitry Andric  let Inst{10}    = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);
75281ad6265SDimitry Andric  // OPSEL must be set such that the low result only uses low inputs, and the high result only uses high inputs.
753*0fca6ea1SDimitry Andric  let Inst{11} = !if(P.HasOpSel, !if(P.HasSrc0Mods, src0_modifiers{2}, 0),
754*0fca6ea1SDimitry Andric                                 !if(P.IsFP8SrcByteSel, byte_sel{1}, ?));
755*0fca6ea1SDimitry Andric  let Inst{12} = !if(P.HasOpSel, !if(P.HasSrc1Mods, src1_modifiers{2}, 0),
756*0fca6ea1SDimitry Andric                                 !if(P.IsFP8SrcByteSel, byte_sel{0}, ?));
757*0fca6ea1SDimitry Andric  let Inst{13} = !if(P.HasOpSel, !if(P.HasSrc2Mods, src2_modifiers{2}, 0),
758*0fca6ea1SDimitry Andric                                 !if(P.IsFP8DstByteSel, byte_sel{0}, ?));
759*0fca6ea1SDimitry Andric  let Inst{14} = !if(P.HasOpSel, !if(P.HasSrc0Mods, src0_modifiers{3}, 0),
760*0fca6ea1SDimitry Andric                                 !if(P.IsFP8DstByteSel, byte_sel{1}, ?));
76181ad6265SDimitry Andric  let Inst{15}    = !if(P.HasClamp, clamp, 0);
76281ad6265SDimitry Andric  let Inst{25-16} = op;
76381ad6265SDimitry Andric  let Inst{31-26} = 0x35;
76481ad6265SDimitry Andric
76581ad6265SDimitry Andric  let Inst{60-59} = !if(P.HasOMod, omod, 0);
76681ad6265SDimitry Andric  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
76781ad6265SDimitry Andric  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
76881ad6265SDimitry Andric  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
76981ad6265SDimitry Andric}
77081ad6265SDimitry Andric
77181ad6265SDimitry Andricclass VOP3_DPPe_Common<bits<10> op, VOPProfile P> : VOP3_DPPe_Common_Base<op, P> {
77281ad6265SDimitry Andric  bits<8> vdst;
77381ad6265SDimitry Andric  bits<9> src1;
77481ad6265SDimitry Andric  bits<9> src2;
77581ad6265SDimitry Andric
77681ad6265SDimitry Andric  let Inst{7-0}   = !if(P.EmitDst, vdst{7-0}, 0);
77781ad6265SDimitry Andric  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
77881ad6265SDimitry Andric  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
77981ad6265SDimitry Andric}
78081ad6265SDimitry Andric
78181ad6265SDimitry Andricclass VOP3P_DPPe_Common_Base<bits<7> op, VOPProfile P> : Enc96 {
78281ad6265SDimitry Andric  bits<4> src0_modifiers;
78381ad6265SDimitry Andric  bits<4> src1_modifiers;
78481ad6265SDimitry Andric  bits<4> src2_modifiers;
78581ad6265SDimitry Andric  bits<1> clamp;
78681ad6265SDimitry Andric
78781ad6265SDimitry Andric  let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0
78881ad6265SDimitry Andric  let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1
78981ad6265SDimitry Andric  let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2
79081ad6265SDimitry Andric  let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0)
79181ad6265SDimitry Andric  let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)
79281ad6265SDimitry Andric  let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2)
7937a6dacacSDimitry Andric  let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(2)
79481ad6265SDimitry Andric  let Inst{15} = !if(P.HasClamp, clamp{0}, 0);
79581ad6265SDimitry Andric  let Inst{22-16} = op;
79681ad6265SDimitry Andric  let Inst{31-23} = 0x198; // encoding
7977a6dacacSDimitry Andric  let Inst{59}    = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(0)
7987a6dacacSDimitry Andric  let Inst{60}    = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, !if(P.IsDOT, 1, ?)); // op_sel_hi(1)
79981ad6265SDimitry Andric  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo)
80081ad6265SDimitry Andric  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo)
80181ad6265SDimitry Andric  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)
80281ad6265SDimitry Andric}
80381ad6265SDimitry Andric
80481ad6265SDimitry Andricclass VOP3P_DPPe_Common<bits<7> op, VOPProfile P> : VOP3P_DPPe_Common_Base<op, P> {
80581ad6265SDimitry Andric  bits<8> vdst;
80681ad6265SDimitry Andric  bits<9> src1;
80781ad6265SDimitry Andric  bits<9> src2;
80881ad6265SDimitry Andric
80981ad6265SDimitry Andric  let Inst{7-0} = vdst;
81081ad6265SDimitry Andric  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
81181ad6265SDimitry Andric  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
81281ad6265SDimitry Andric}
81381ad6265SDimitry Andric
81481ad6265SDimitry Andricclass VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[],
81581ad6265SDimitry Andric  dag Ins = P.InsDPP, string asmOps = P.AsmDPP> :
816*0fca6ea1SDimitry Andric  VOP_Pseudo<OpName, "_dpp", P, P.OutsDPP, Ins, asmOps, pattern> {
8170b57cec5SDimitry Andric
8180b57cec5SDimitry Andric  let mayLoad = 0;
8190b57cec5SDimitry Andric  let mayStore = 0;
8200b57cec5SDimitry Andric  let hasSideEffects = 0;
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric  let VALU = 1;
8230b57cec5SDimitry Andric  let DPP = 1;
8240b57cec5SDimitry Andric  let Size = 8;
825*0fca6ea1SDimitry Andric  let IsPacked = P.IsPacked;
8265ffd83dbSDimitry Andric
8277a6dacacSDimitry Andric  let ReadsModeReg = !or(P.DstVT.isFP, P.Src0VT.isFP);
8285ffd83dbSDimitry Andric
8295ffd83dbSDimitry Andric  let mayRaiseFPException = ReadsModeReg;
8305ffd83dbSDimitry Andric  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
8310b57cec5SDimitry Andric  let isConvergent = 1;
8320b57cec5SDimitry Andric
83381ad6265SDimitry Andric  string AsmOperands = asmOps;
8340b57cec5SDimitry Andric
835e8d8bef9SDimitry Andric  let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", "");
8365f757f3fSDimitry Andric  let AssemblerPredicate = !if(P.HasExt64BitDPP, HasDPALU_DPP, HasDPP);
8370b57cec5SDimitry Andric  let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP,
8380b57cec5SDimitry Andric                                        AMDGPUAsmVariants.Disable);
8390b57cec5SDimitry Andric  let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");
8400b57cec5SDimitry Andric  let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
841*0fca6ea1SDimitry Andric  let DecoderNamespace = "GFX8";
8420b57cec5SDimitry Andric
843*0fca6ea1SDimitry Andric  let IsInvalidSingleUseConsumer = !not(VINTERP);
844*0fca6ea1SDimitry Andric  let IsInvalidSingleUseProducer = !not(VINTERP);
8450b57cec5SDimitry Andric}
8460b57cec5SDimitry Andric
84781ad6265SDimitry Andricclass VOP3_DPP_Pseudo <string OpName, VOPProfile P> :
84881ad6265SDimitry Andric  VOP_DPP_Pseudo <OpName, P, [], P.InsVOP3DPP, P.AsmVOP3DPP> {
84981ad6265SDimitry Andric  let PseudoInstr = OpName#"_e64"#"_dpp";
85081ad6265SDimitry Andric  let OutOperandList = P.OutsVOP3DPP;
85181ad6265SDimitry Andric  let Size = 12;
85281ad6265SDimitry Andric  let VOP3 = 1;
85381ad6265SDimitry Andric  let AsmMatchConverter = "cvtVOP3DPP";
85481ad6265SDimitry Andric  let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,
85581ad6265SDimitry Andric                                            AMDGPUAsmVariants.Disable);
85681ad6265SDimitry Andric}
85781ad6265SDimitry Andric
8580b57cec5SDimitry Andricclass VOP_DPP_Real <VOP_DPP_Pseudo ps, int EncodingFamily> :
8590b57cec5SDimitry Andric  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
8600b57cec5SDimitry Andric  SIMCInstr <ps.PseudoInstr, EncodingFamily> {
8610b57cec5SDimitry Andric
862fe6060f1SDimitry Andric  let VALU = 1;
863fe6060f1SDimitry Andric  let DPP = 1;
8640b57cec5SDimitry Andric  let isPseudo = 0;
8650b57cec5SDimitry Andric  let isCodeGenOnly = 0;
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andric  let Defs = ps.Defs;
8680b57cec5SDimitry Andric  let Uses = ps.Uses;
8690b57cec5SDimitry Andric  let hasSideEffects = ps.hasSideEffects;
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andric  let Constraints     = ps.Constraints;
8720b57cec5SDimitry Andric  let DisableEncoding = ps.DisableEncoding;
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andric  // Copy relevant pseudo op flags
8750b57cec5SDimitry Andric  let isConvergent         = ps.isConvergent;
8760b57cec5SDimitry Andric  let SubtargetPredicate   = ps.SubtargetPredicate;
8770b57cec5SDimitry Andric  let AssemblerPredicate   = ps.AssemblerPredicate;
87881ad6265SDimitry Andric  let OtherPredicates      = ps.OtherPredicates;
8790b57cec5SDimitry Andric  let AsmMatchConverter    = ps.AsmMatchConverter;
8800b57cec5SDimitry Andric  let AsmVariantName       = ps.AsmVariantName;
8810b57cec5SDimitry Andric  let UseNamedOperandTable = ps.UseNamedOperandTable;
8820b57cec5SDimitry Andric  let DecoderNamespace     = ps.DecoderNamespace;
8830b57cec5SDimitry Andric  let Constraints          = ps.Constraints;
8840b57cec5SDimitry Andric  let DisableEncoding      = ps.DisableEncoding;
8850b57cec5SDimitry Andric  let TSFlags              = ps.TSFlags;
886*0fca6ea1SDimitry Andric  let Uses                 = ps.Uses;
887*0fca6ea1SDimitry Andric  let Defs                 = ps.Defs;
888fe6060f1SDimitry Andric  let SchedRW              = ps.SchedRW;
889fe6060f1SDimitry Andric  let mayLoad              = ps.mayLoad;
890fe6060f1SDimitry Andric  let mayStore             = ps.mayStore;
891fe6060f1SDimitry Andric  let TRANS                = ps.TRANS;
8920b57cec5SDimitry Andric}
8930b57cec5SDimitry Andric
89481ad6265SDimitry Andricclass VOP_DPP_Base <string OpName, VOPProfile P,
89581ad6265SDimitry Andric               dag InsDPP,
89681ad6265SDimitry Andric               string AsmDPP > :
89781ad6265SDimitry Andric  InstSI <P.OutsDPP, InsDPP, OpName#AsmDPP, []> {
8980b57cec5SDimitry Andric
8990b57cec5SDimitry Andric  let mayLoad = 0;
9000b57cec5SDimitry Andric  let mayStore = 0;
9010b57cec5SDimitry Andric  let hasSideEffects = 0;
9020b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
9030b57cec5SDimitry Andric
9040b57cec5SDimitry Andric  let VALU = 1;
9050b57cec5SDimitry Andric  let DPP = 1;
9060b57cec5SDimitry Andric  let Size = 8;
9070b57cec5SDimitry Andric
908e8d8bef9SDimitry Andric  let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", "");
9095f757f3fSDimitry Andric  let AssemblerPredicate = !if(P.HasExt64BitDPP, HasDPALU_DPP, HasDPP);
9100b57cec5SDimitry Andric  let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP,
9110b57cec5SDimitry Andric                                        AMDGPUAsmVariants.Disable);
9120b57cec5SDimitry Andric  let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");
9130b57cec5SDimitry Andric  let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
914*0fca6ea1SDimitry Andric  let DecoderNamespace = "GFX8";
9150b57cec5SDimitry Andric}
9160b57cec5SDimitry Andric
91781ad6265SDimitry Andricclass VOP_DPP <string OpName, VOPProfile P, bit IsDPP16,
91881ad6265SDimitry Andric               dag InsDPP = !if(IsDPP16, P.InsDPP16, P.InsDPP),
91981ad6265SDimitry Andric               string AsmDPP = !if(IsDPP16, P.AsmDPP16, P.AsmDPP)> :
92081ad6265SDimitry Andric  VOP_DPP_Base<OpName, P, InsDPP, AsmDPP>, VOP_DPPe<P, IsDPP16>;
92181ad6265SDimitry Andric
92281ad6265SDimitry Andricclass VOP3_DPP_Base <string OpName, VOPProfile P, bit IsDPP16,
92381ad6265SDimitry Andric               dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),
92481ad6265SDimitry Andric               string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :
92581ad6265SDimitry Andric  VOP_DPP_Base<OpName, P, InsDPP, AsmDPP> {
92681ad6265SDimitry Andric  let OutOperandList = P.OutsVOP3DPP;
92781ad6265SDimitry Andric  let AsmMatchConverter = "cvtVOP3DPP";
92881ad6265SDimitry Andric  let VOP3 = 1;
92981ad6265SDimitry Andric  let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,
93081ad6265SDimitry Andric                                            AMDGPUAsmVariants.Disable);
93181ad6265SDimitry Andric  let Size = 12;
93281ad6265SDimitry Andric}
93381ad6265SDimitry Andric
93481ad6265SDimitry Andricclass VOP3_DPP <bits<10> op, string OpName, VOPProfile P, bit IsDPP16,
93581ad6265SDimitry Andric               dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),
93681ad6265SDimitry Andric               string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :
93781ad6265SDimitry Andric  VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3_DPPe_Common<op, P>,
93881ad6265SDimitry Andric  VOP3_DPPe_Fields {
93981ad6265SDimitry Andric
94081ad6265SDimitry Andric  let Inst{40-32} = 0xfa;
94181ad6265SDimitry Andric  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
94281ad6265SDimitry Andric  let Inst{80-72} = dpp_ctrl;
94381ad6265SDimitry Andric  let Inst{82}    = !if(IsDPP16, fi, ?);
94481ad6265SDimitry Andric  let Inst{83}    = bound_ctrl;
94581ad6265SDimitry Andric
94681ad6265SDimitry Andric  // Inst{87-84} ignored by hw
94781ad6265SDimitry Andric  let Inst{91-88} = bank_mask;
94881ad6265SDimitry Andric  let Inst{95-92} = row_mask;
94981ad6265SDimitry Andric}
95081ad6265SDimitry Andric
95181ad6265SDimitry Andricclass VOP3P_DPP <bits<7> op, string OpName, VOPProfile P, bit IsDPP16,
95281ad6265SDimitry Andric               dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),
95381ad6265SDimitry Andric               string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :
95481ad6265SDimitry Andric  VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3P_DPPe_Common<op, P>,
95581ad6265SDimitry Andric  VOP3_DPPe_Fields {
95681ad6265SDimitry Andric
95781ad6265SDimitry Andric  let VOP3P = 1;
95881ad6265SDimitry Andric
95981ad6265SDimitry Andric  let Inst{40-32} = 0xfa;
96081ad6265SDimitry Andric  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
96181ad6265SDimitry Andric  let Inst{80-72} = dpp_ctrl;
96281ad6265SDimitry Andric  let Inst{82}    = !if(IsDPP16, fi, ?);
96381ad6265SDimitry Andric  let Inst{83}    = bound_ctrl;
96481ad6265SDimitry Andric
96581ad6265SDimitry Andric  // Inst{87-84} ignored by hw
96681ad6265SDimitry Andric  let Inst{91-88} = bank_mask;
96781ad6265SDimitry Andric  let Inst{95-92} = row_mask;
96881ad6265SDimitry Andric}
96981ad6265SDimitry Andric
9700b57cec5SDimitry Andricclass VOP_DPP8e<VOPProfile P> : Enc64 {
9710b57cec5SDimitry Andric  bits<8> src0;
9720b57cec5SDimitry Andric  bits<24> dpp8;
9730b57cec5SDimitry Andric  bits<9> fi;
9740b57cec5SDimitry Andric
9750b57cec5SDimitry Andric  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
9760b57cec5SDimitry Andric  let Inst{63-40} = dpp8{23-0};
9770b57cec5SDimitry Andric}
9780b57cec5SDimitry Andric
97981ad6265SDimitry Andricclass VOP3_DPP8e_Fields {
98081ad6265SDimitry Andric  bits<8> src0;
98181ad6265SDimitry Andric  bits<24> dpp8;
98281ad6265SDimitry Andric  bits<9> fi;
98381ad6265SDimitry Andric}
98481ad6265SDimitry Andric
98581ad6265SDimitry Andricclass VOP_DPP8_Base<string OpName, VOPProfile P, dag InsDPP8 = P.InsDPP8, string AsmDPP8 = P.AsmDPP8> :
98681ad6265SDimitry Andric  InstSI<P.OutsDPP8, InsDPP8, OpName#AsmDPP8, []> {
9870b57cec5SDimitry Andric
9880b57cec5SDimitry Andric  let mayLoad = 0;
9890b57cec5SDimitry Andric  let mayStore = 0;
9900b57cec5SDimitry Andric  let hasSideEffects = 0;
9910b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
9920b57cec5SDimitry Andric
9930b57cec5SDimitry Andric  let VALU = 1;
9940b57cec5SDimitry Andric  let DPP = 1;
9950b57cec5SDimitry Andric  let Size = 8;
9960b57cec5SDimitry Andric
9970b57cec5SDimitry Andric  let AsmMatchConverter = "cvtDPP8";
9985ffd83dbSDimitry Andric  let AssemblerPredicate = HasDPP8;
99981ad6265SDimitry Andric  let AsmVariantName = AMDGPUAsmVariants.DPP;
10000b57cec5SDimitry Andric  let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");
10010b57cec5SDimitry Andric  let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
10020b57cec5SDimitry Andric}
10030b57cec5SDimitry Andric
100481ad6265SDimitry Andricclass VOP_DPP8<string OpName, VOPProfile P> :
100581ad6265SDimitry Andric  VOP_DPP8_Base<OpName, P>, VOP_DPP8e<P>;
100681ad6265SDimitry Andric
100781ad6265SDimitry Andricclass VOP3_DPP8_Base<string OpName, VOPProfile P> :
100881ad6265SDimitry Andric  VOP_DPP8_Base<OpName, P, P.InsVOP3DPP8, P.AsmVOP3DPP8> {
100981ad6265SDimitry Andric  let OutOperandList = P.OutsVOP3DPP8;
101081ad6265SDimitry Andric  let AsmMatchConverter = "cvtVOP3DPP8";
101181ad6265SDimitry Andric  let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,
101281ad6265SDimitry Andric                                            AMDGPUAsmVariants.Disable);
101381ad6265SDimitry Andric  let VOP3 = 1;
101481ad6265SDimitry Andric  let Size = 12;
101581ad6265SDimitry Andric}
101681ad6265SDimitry Andric
101781ad6265SDimitry Andric
101881ad6265SDimitry Andricclass VOP3_DPP8<bits<10> op, string OpName, VOPProfile P> :
101981ad6265SDimitry Andric  VOP3_DPP8_Base<OpName, P>, VOP3_DPPe_Common<op, P>,
102081ad6265SDimitry Andric  VOP3_DPP8e_Fields {
102181ad6265SDimitry Andric
102281ad6265SDimitry Andric  let Inst{40-32} = fi;
102381ad6265SDimitry Andric  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
102481ad6265SDimitry Andric  let Inst{95-72} = dpp8{23-0};
102581ad6265SDimitry Andric}
102681ad6265SDimitry Andric
102781ad6265SDimitry Andricclass VOP3P_DPP8<bits<7> op, string OpName, VOPProfile P> :
102881ad6265SDimitry Andric  VOP3_DPP8_Base<OpName, P>, VOP3P_DPPe_Common<op, P>,
102981ad6265SDimitry Andric  VOP3_DPP8e_Fields {
103081ad6265SDimitry Andric
103181ad6265SDimitry Andric  let VOP3P = 1;
103281ad6265SDimitry Andric  let Inst{40-32} = fi;
103381ad6265SDimitry Andric  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
103481ad6265SDimitry Andric  let Inst{95-72} = dpp8{23-0};
103581ad6265SDimitry Andric}
103681ad6265SDimitry Andric
10370b57cec5SDimitry Andricdef DPP8Mode {
10380b57cec5SDimitry Andric  int FI_0 = 0xE9;
10390b57cec5SDimitry Andric  int FI_1 = 0xEA;
10400b57cec5SDimitry Andric}
10410b57cec5SDimitry Andric
10420b57cec5SDimitry Andricclass getNumNodeArgs<SDPatternOperator Op> {
10430b57cec5SDimitry Andric  SDNode N = !cast<SDNode>(Op);
10440b57cec5SDimitry Andric  SDTypeProfile TP = N.TypeProfile;
10450b57cec5SDimitry Andric  int ret = TP.NumOperands;
10460b57cec5SDimitry Andric}
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andricclass getDivergentFrag<SDPatternOperator Op> {
1049349cc55cSDimitry Andric  assert !or(!isa<SDNode>(Op), !isa<PatFrags>(Op)), "Expected SDNode or PatFrags";
10500b57cec5SDimitry Andric
1051349cc55cSDimitry Andric  int NumSrcArgs = !if(!isa<SDNode>(Op), getNumNodeArgs<Op>.ret,
1052349cc55cSDimitry Andric    !size(!cast<PatFrags>(Op).Operands));
10530b57cec5SDimitry Andric  PatFrag ret = PatFrag <
10540b57cec5SDimitry Andric    !if(!eq(NumSrcArgs, 1),
10550b57cec5SDimitry Andric             (ops node:$src0),
10560b57cec5SDimitry Andric             !if(!eq(NumSrcArgs, 2),
10570b57cec5SDimitry Andric               (ops node:$src0, node:$src1),
10580b57cec5SDimitry Andric               (ops node:$src0, node:$src1, node:$src2))),
10590b57cec5SDimitry Andric    !if(!eq(NumSrcArgs, 1),
10600b57cec5SDimitry Andric             (Op $src0),
10610b57cec5SDimitry Andric             !if(!eq(NumSrcArgs, 2),
10620b57cec5SDimitry Andric               (Op $src0, $src1),
10630b57cec5SDimitry Andric               (Op $src0, $src1, $src2))),
10640b57cec5SDimitry Andric    [{ return N->isDivergent(); }]
10650b57cec5SDimitry Andric  >;
10660b57cec5SDimitry Andric}
10670b57cec5SDimitry Andric
10680b57cec5SDimitry Andricclass VOPPatGen<SDPatternOperator Op, VOPProfile P> {
10690b57cec5SDimitry Andric  PatFrag Operator = getDivergentFrag < Op >.ret;
10700b57cec5SDimitry Andric
10710b57cec5SDimitry Andric  dag Ins = !foreach(tmp, P.Ins32, !subst(ins, Operator,
10720b57cec5SDimitry Andric                                         !subst(P.Src0RC32, P.Src0VT,
10730b57cec5SDimitry Andric                                               !subst(P.Src1RC32, P.Src1VT, tmp))));
10740b57cec5SDimitry Andric
10750b57cec5SDimitry Andric  dag Outs = !foreach(tmp, P.Outs32, !subst(outs, set,
10760b57cec5SDimitry Andric                                           !subst(P.DstRC, P.DstVT, tmp)));
10770b57cec5SDimitry Andric
10780b57cec5SDimitry Andric  list<dag> ret =  [!con(Outs, (set Ins))];
10790b57cec5SDimitry Andric}
10800b57cec5SDimitry Andric
10810eae32dcSDimitry Andricclass DivergentUnaryFrag<SDPatternOperator Op> : PatFrag <
10820eae32dcSDimitry Andric  (ops node:$src0),
10830eae32dcSDimitry Andric  (Op $src0),
10840eae32dcSDimitry Andric  [{ return N->isDivergent(); }]> {
10850eae32dcSDimitry Andric  // This check is unnecessary as it's captured by the result register
10860eae32dcSDimitry Andric  // bank constraint.
10870eae32dcSDimitry Andric  //
10880eae32dcSDimitry Andric  // FIXME: Should add a way for the emitter to recognize this is a
10890eae32dcSDimitry Andric  // trivially true predicate to eliminate the check.
10900eae32dcSDimitry Andric  let GISelPredicateCode = [{return true;}];
10910eae32dcSDimitry Andric}
10920eae32dcSDimitry Andric
10930b57cec5SDimitry Andricclass VOPPatOrNull<SDPatternOperator Op, VOPProfile P> {
10940b57cec5SDimitry Andric  list<dag> ret = !if(!ne(P.NeedPatGen,PatGenMode.NoPattern), VOPPatGen<Op, P>.ret, []);
10950b57cec5SDimitry Andric}
10960b57cec5SDimitry Andric
10970b57cec5SDimitry Andricclass DivergentFragOrOp<SDPatternOperator Op, VOPProfile P> {
10980b57cec5SDimitry Andric  SDPatternOperator ret = !if(!eq(P.NeedPatGen,PatGenMode.Pattern),
10990b57cec5SDimitry Andric   !if(!isa<SDNode>(Op), getDivergentFrag<Op>.ret, Op), Op);
11000b57cec5SDimitry Andric}
11010b57cec5SDimitry Andric
1102e8d8bef9SDimitry Andricclass getVSrcOp<ValueType vt> {
1103e8d8bef9SDimitry Andric  RegisterOperand ret = !if(!eq(vt.Size, 32), VSrc_b32, VSrc_b16);
1104e8d8bef9SDimitry Andric}
1105e8d8bef9SDimitry Andric
1106e8d8bef9SDimitry Andric// Class for binary integer operations with the clamp bit set for saturation
1107e8d8bef9SDimitry Andric// TODO: Add sub with negated inline constant pattern.
1108e8d8bef9SDimitry Andricclass VOPBinOpClampPat<SDPatternOperator node, Instruction inst, ValueType vt> :
1109e8d8bef9SDimitry Andric  GCNPat<(node vt:$src0, vt:$src1),
1110e8d8bef9SDimitry Andric         (inst getVSrcOp<vt>.ret:$src0, getVSrcOp<vt>.ret:$src1,
1111e8d8bef9SDimitry Andric               DSTCLAMP.ENABLE)
1112e8d8bef9SDimitry Andric>;
1113e8d8bef9SDimitry Andric
111481ad6265SDimitry Andric//===----------------------------------------------------------------------===//
111581ad6265SDimitry Andric// VOP3 Classes
111681ad6265SDimitry Andric//===----------------------------------------------------------------------===//
111781ad6265SDimitry Andric
111881ad6265SDimitry Andricclass getVOP3ModPat<VOPProfile P, SDPatternOperator node> {
111981ad6265SDimitry Andric  dag src0 = !if(P.HasOMod,
112081ad6265SDimitry Andric    (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod),
112181ad6265SDimitry Andric    (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp));
112281ad6265SDimitry Andric
112381ad6265SDimitry Andric  list<dag> ret3 = [(set P.DstVT:$vdst,
112481ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT src0),
112581ad6265SDimitry Andric          (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
112681ad6265SDimitry Andric          (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))];
112781ad6265SDimitry Andric
112881ad6265SDimitry Andric  list<dag> ret2 = [(set P.DstVT:$vdst,
112981ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT src0),
113081ad6265SDimitry Andric          (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))];
113181ad6265SDimitry Andric
113281ad6265SDimitry Andric  list<dag> ret1 = [(set P.DstVT:$vdst,
113381ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))];
113481ad6265SDimitry Andric
113581ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
113681ad6265SDimitry Andric                  !if(!eq(P.NumSrcArgs, 2), ret2,
113781ad6265SDimitry Andric                  ret1));
113881ad6265SDimitry Andric}
113981ad6265SDimitry Andric
114081ad6265SDimitry Andricclass getVOP3PModPat<VOPProfile P, SDPatternOperator node, bit HasExplicitClamp,
114181ad6265SDimitry Andric                     bit IsDOT = 0,
114281ad6265SDimitry Andric                     ComplexPattern SrcPat = !if(IsDOT, VOP3PModsDOT, VOP3PMods)> {
114381ad6265SDimitry Andric  dag src0_dag = (P.Src0VT (SrcPat P.Src0VT:$src0, i32:$src0_modifiers));
114481ad6265SDimitry Andric  dag src1_dag = (P.Src1VT (SrcPat P.Src1VT:$src1, i32:$src1_modifiers));
114581ad6265SDimitry Andric  dag src2_dag = (P.Src2VT (SrcPat P.Src2VT:$src2, i32:$src2_modifiers));
114681ad6265SDimitry Andric  dag clamp_dag = (i1 timm:$clamp);
114781ad6265SDimitry Andric
114881ad6265SDimitry Andric  list<dag> ret3 = [(set P.DstVT:$vdst,
114981ad6265SDimitry Andric    !if(HasExplicitClamp,
115081ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag, clamp_dag),
115181ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag)))];
115281ad6265SDimitry Andric
115381ad6265SDimitry Andric  list<dag> ret2 = [(set P.DstVT:$vdst,
115481ad6265SDimitry Andric    !if(HasExplicitClamp,
115581ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, clamp_dag),
115681ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag)))];
115781ad6265SDimitry Andric
115881ad6265SDimitry Andric  list<dag> ret1 = [(set P.DstVT:$vdst,
115981ad6265SDimitry Andric    !if(HasExplicitClamp,
116081ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret src0_dag, clamp_dag),
116181ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret src0_dag)))];
116281ad6265SDimitry Andric
116381ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
116481ad6265SDimitry Andric                  !if(!eq(P.NumSrcArgs, 2), ret2,
116581ad6265SDimitry Andric                  ret1));
116681ad6265SDimitry Andric}
116781ad6265SDimitry Andric
116881ad6265SDimitry Andricclass getVOP3OpSelPat<VOPProfile P, SDPatternOperator node> {
116981ad6265SDimitry Andric  list<dag> ret3 = [(set P.DstVT:$vdst,
117081ad6265SDimitry Andric        (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)),
117181ad6265SDimitry Andric          (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers)),
117281ad6265SDimitry Andric          (P.Src2VT (VOP3OpSel P.Src2VT:$src2, i32:$src2_modifiers))))];
117381ad6265SDimitry Andric
117481ad6265SDimitry Andric  list<dag> ret2 = [(set P.DstVT:$vdst,
117581ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)),
117681ad6265SDimitry Andric                                    (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers))))];
117781ad6265SDimitry Andric
117881ad6265SDimitry Andric  list<dag> ret1 = [(set P.DstVT:$vdst,
117981ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers))))];
118081ad6265SDimitry Andric
118181ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
118281ad6265SDimitry Andric                  !if(!eq(P.NumSrcArgs, 2), ret2,
118381ad6265SDimitry Andric                  ret1));
118481ad6265SDimitry Andric}
118581ad6265SDimitry Andric
118681ad6265SDimitry Andricclass getVOP3OpSelModPat<VOPProfile P, SDPatternOperator node> {
118781ad6265SDimitry Andric  list<dag> ret3 = [(set P.DstVT:$vdst,
118881ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT !if(P.HasClamp, (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers),
118981ad6265SDimitry Andric                                    (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))),
119081ad6265SDimitry Andric          (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers)),
119181ad6265SDimitry Andric          (P.Src2VT (VOP3OpSelMods P.Src2VT:$src2, i32:$src2_modifiers))))];
119281ad6265SDimitry Andric
119381ad6265SDimitry Andric  list<dag> ret2 = [(set P.DstVT:$vdst,
119481ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret !if(P.HasClamp, (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers)),
119581ad6265SDimitry Andric                          (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))),
119681ad6265SDimitry Andric          (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers))))];
119781ad6265SDimitry Andric
119881ad6265SDimitry Andric  list<dag> ret1 = [(set P.DstVT:$vdst,
119981ad6265SDimitry Andric    (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))))];
120081ad6265SDimitry Andric
120181ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
120281ad6265SDimitry Andric                  !if(!eq(P.NumSrcArgs, 2), ret2,
120381ad6265SDimitry Andric                  ret1));
120481ad6265SDimitry Andric}
120581ad6265SDimitry Andric
120681ad6265SDimitry Andricclass getVOP3FromVOP2Pat<VOPProfile P, SDPatternOperator node> {
120781ad6265SDimitry Andric  list<dag> ret = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))];
120881ad6265SDimitry Andric}
120981ad6265SDimitry Andric// In VOP1, we can have clamp and omod even if !HasModifiers
121081ad6265SDimitry Andricclass getVOP3Pat<VOPProfile P, SDPatternOperator node> {
121181ad6265SDimitry Andric  dag src0 =
121281ad6265SDimitry Andric    !if(P.HasOMod,
121381ad6265SDimitry Andric      !if(P.HasClamp,
121481ad6265SDimitry Andric          (VOP3Mods0 P.Src0VT:$src0, i1:$clamp, i32:$omod),
121581ad6265SDimitry Andric          (VOP3Mods0 P.Src0VT:$src0, i32:$omod)), // impossible?
121681ad6265SDimitry Andric      !if(P.HasClamp,
121781ad6265SDimitry Andric          (VOP3Mods0 P.Src0VT:$src0, i1:$clamp),
121881ad6265SDimitry Andric          (VOP3Mods0 P.Src0VT:$src0))
121981ad6265SDimitry Andric    );
122081ad6265SDimitry Andric  list<dag> ret3 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1, P.Src2VT:$src2))];
122181ad6265SDimitry Andric
122281ad6265SDimitry Andric  list<dag> ret2 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1))];
122381ad6265SDimitry Andric
122481ad6265SDimitry Andric  list<dag> ret1 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))];
122581ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
122681ad6265SDimitry Andric                  !if(!eq(P.NumSrcArgs, 2), ret2,
122781ad6265SDimitry Andric                  ret1));
122881ad6265SDimitry Andric}
122981ad6265SDimitry Andric
123081ad6265SDimitry Andricclass getVOP3ClampPat<VOPProfile P, SDPatternOperator node> {
123181ad6265SDimitry Andric  list<dag> ret3 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i1:$clamp))];
123281ad6265SDimitry Andric  list<dag> ret2 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, i1:$clamp))];
123381ad6265SDimitry Andric  list<dag> ret1 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, i1:$clamp))];
123481ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
123581ad6265SDimitry Andric                  !if(!eq(P.NumSrcArgs, 2), ret2,
123681ad6265SDimitry Andric                  ret1));
123781ad6265SDimitry Andric}
123881ad6265SDimitry Andric
123981ad6265SDimitry Andricclass getVOP3MAIPat<VOPProfile P, SDPatternOperator node> {
124081ad6265SDimitry Andric  list<dag> ret = !if(!eq(P.Src0VT, P.Src1VT),
124181ad6265SDimitry Andric                      // mfma
124281ad6265SDimitry Andric                      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2,
124381ad6265SDimitry Andric                                            timm:$cbsz, timm:$abid, timm:$blgp))],
124481ad6265SDimitry Andric                      // smfmac
124581ad6265SDimitry Andric                      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i32:$idx,
124681ad6265SDimitry Andric                                            timm:$cbsz, timm:$abid))]);
124781ad6265SDimitry Andric}
124881ad6265SDimitry Andric
124981ad6265SDimitry Andricclass VOP3Features<bit Clamp, bit OpSel, bit Packed, bit MAI> {
125081ad6265SDimitry Andric  bit HasClamp = Clamp;
125181ad6265SDimitry Andric  bit HasOpSel = OpSel;
125281ad6265SDimitry Andric  bit IsPacked = Packed;
125381ad6265SDimitry Andric  bit IsMAI = MAI;
125481ad6265SDimitry Andric}
125581ad6265SDimitry Andric
125681ad6265SDimitry Andricdef VOP3_REGULAR : VOP3Features<0, 0, 0, 0>;
125781ad6265SDimitry Andricdef VOP3_CLAMP   : VOP3Features<1, 0, 0, 0>;
125881ad6265SDimitry Andricdef VOP3_OPSEL   : VOP3Features<1, 1, 0, 0>;
125981ad6265SDimitry Andricdef VOP3_PACKED  : VOP3Features<1, 1, 1, 0>;
126081ad6265SDimitry Andricdef VOP3_MAI     : VOP3Features<0, 0, 0, 1>;
126181ad6265SDimitry Andric
126281ad6265SDimitry Andricclass VOP3_Profile_Base<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProfile<P.ArgVT> {
126381ad6265SDimitry Andric
126481ad6265SDimitry Andric  let HasClamp = !if(Features.HasClamp, 1, P.HasClamp);
126581ad6265SDimitry Andric  let HasOpSel = !if(Features.HasOpSel, 1, P.HasOpSel);
126681ad6265SDimitry Andric  let IsMAI    = !if(Features.IsMAI,    1, P.IsMAI);
126781ad6265SDimitry Andric  let IsPacked = !if(Features.IsPacked, 1, P.IsPacked);
126881ad6265SDimitry Andric
1269753f127fSDimitry Andric  let HasModifiers =
1270753f127fSDimitry Andric      !if (Features.IsMAI, 0,
1271753f127fSDimitry Andric           !or(Features.IsPacked, Features.HasOpSel, P.HasModifiers));
127281ad6265SDimitry Andric}
127381ad6265SDimitry Andric
127481ad6265SDimitry Andricclass VOP3_Profile<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOP3_Profile_Base<P, Features> {
127581ad6265SDimitry Andric  let IsSingle = 1;
127681ad6265SDimitry Andric
127781ad6265SDimitry Andric}
127881ad6265SDimitry Andric
127981ad6265SDimitry Andric// consistently gives instructions a _e64 suffix
128081ad6265SDimitry Andricmulticlass VOP3Inst_Pseudo_Wrapper<string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> {
128181ad6265SDimitry Andric    def _e64 : VOP3_Pseudo<opName, P, pattern, VOP3Only>;
128281ad6265SDimitry Andric}
128381ad6265SDimitry Andric
128481ad6265SDimitry Andricclass VOP3InstBase<string OpName, VOPProfile P, SDPatternOperator node = null_frag, bit IsVOP2 = 0> :
128581ad6265SDimitry Andric  VOP3_Pseudo<OpName, P,
128681ad6265SDimitry Andric    !if(P.HasOpSel,
128781ad6265SDimitry Andric        !if(P.HasModifiers,
128881ad6265SDimitry Andric            getVOP3OpSelModPat<P, node>.ret,
128981ad6265SDimitry Andric            getVOP3OpSelPat<P, node>.ret),
129081ad6265SDimitry Andric        !if(P.HasModifiers,
129181ad6265SDimitry Andric            getVOP3ModPat<P, node>.ret,
129281ad6265SDimitry Andric            !if(IsVOP2,
129381ad6265SDimitry Andric              getVOP3FromVOP2Pat<P, node>.ret,
129481ad6265SDimitry Andric              !if(P.HasIntClamp,
129581ad6265SDimitry Andric                  getVOP3ClampPat<P, node>.ret,
129681ad6265SDimitry Andric                  !if (P.IsMAI,
129781ad6265SDimitry Andric                      getVOP3MAIPat<P, node>.ret,
129881ad6265SDimitry Andric                      getVOP3Pat<P, node>.ret))))),
129981ad6265SDimitry Andric    0, P.HasOpSel> {
130081ad6265SDimitry Andric
130181ad6265SDimitry Andric  let IntClamp = P.HasIntClamp;
130281ad6265SDimitry Andric  let AsmMatchConverter =
130381ad6265SDimitry Andric    !if(P.HasOpSel,
130481ad6265SDimitry Andric        "cvtVOP3OpSel",
130581ad6265SDimitry Andric        !if(!or(P.HasModifiers, P.HasOMod, P.HasIntClamp),
130681ad6265SDimitry Andric            "cvtVOP3",
130781ad6265SDimitry Andric            ""));
130881ad6265SDimitry Andric}
130981ad6265SDimitry Andric
131081ad6265SDimitry Andricmulticlass VOP3Inst<string OpName, VOPProfile P, SDPatternOperator node = null_frag> {
131181ad6265SDimitry Andric  def _e64 : VOP3InstBase<OpName, P, node>;
131281ad6265SDimitry Andric  let SubtargetPredicate = isGFX11Plus in {
131306c3fb27SDimitry Andric    if P.HasExtVOP3DPP then
131481ad6265SDimitry Andric      def _e64_dpp : VOP3_DPP_Pseudo <OpName, P>;
131581ad6265SDimitry Andric  } // end SubtargetPredicate = isGFX11Plus
131681ad6265SDimitry Andric}
131781ad6265SDimitry Andric
13185f757f3fSDimitry Andricclass UniformUnaryFragOrOp<SDPatternOperator Op> {
13195f757f3fSDimitry Andric  SDPatternOperator ret = !if(!or(!isa<SDNode>(Op), !isa<PatFrags>(Op)),
13205f757f3fSDimitry Andric                              UniformUnaryFrag<Op>, Op);
13215f757f3fSDimitry Andric}
13225f757f3fSDimitry Andric
13235f757f3fSDimitry Andricmulticlass VOP3PseudoScalarInst<string OpName, VOPProfile P,
13245f757f3fSDimitry Andric                                SDPatternOperator node = null_frag> {
13255f757f3fSDimitry Andric  def _e64 : VOP3_Pseudo<OpName, P, [(set P.DstVT:$vdst,
13265f757f3fSDimitry Andric      (UniformUnaryFragOrOp<node>.ret
13275f757f3fSDimitry Andric          (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp,
13285f757f3fSDimitry Andric                               i32:$omod))))]>;
13295f757f3fSDimitry Andric}
13305f757f3fSDimitry Andric
133181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
133281ad6265SDimitry Andric// VOP3 DPP
133381ad6265SDimitry Andric//===----------------------------------------------------------------------===//
133481ad6265SDimitry Andric
133581ad6265SDimitry Andricclass Base_VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, string opName = ps.OpName>
133681ad6265SDimitry Andric    : VOP3_DPP<op, opName, ps.Pfl, 1> {
1337fcaf7f86SDimitry Andric  let VOP3_OPSEL = ps.Pfl.HasOpSel;
1338fcaf7f86SDimitry Andric  let IsDOT = ps.IsDOT;
133981ad6265SDimitry Andric  let hasSideEffects = ps.hasSideEffects;
134081ad6265SDimitry Andric  let Defs = ps.Defs;
134181ad6265SDimitry Andric  let SchedRW = ps.SchedRW;
134281ad6265SDimitry Andric  let Uses = ps.Uses;
134381ad6265SDimitry Andric  let AssemblerPredicate = HasDPP16;
1344*0fca6ea1SDimitry Andric  let SubtargetPredicate = ps.SubtargetPredicate;
134581ad6265SDimitry Andric  let OtherPredicates = ps.OtherPredicates;
134681ad6265SDimitry Andric}
134781ad6265SDimitry Andric
134881ad6265SDimitry Andricclass VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, int subtarget,
134981ad6265SDimitry Andric                 string opName = ps.OpName>
135081ad6265SDimitry Andric    : Base_VOP3_DPP16<op, ps, opName>, SIMCInstr<ps.PseudoInstr, subtarget>;
135181ad6265SDimitry Andric
13525f757f3fSDimitry Andricclass VOP3_DPP16_Gen<bits<10> op, VOP_DPP_Pseudo ps, GFXGen Gen,
13535f757f3fSDimitry Andric                     string opName = ps.OpName> :
13545f757f3fSDimitry Andric  VOP3_DPP16 <op, ps, Gen.Subtarget, opName> {
1355297eecfbSDimitry Andric  let AssemblerPredicate = Gen.AssemblerPredicate;
1356*0fca6ea1SDimitry Andric  let True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);
1357*0fca6ea1SDimitry Andric  let DecoderNamespace = Gen.DecoderNamespace#
13585f757f3fSDimitry Andric                         !if(ps.Pfl.IsRealTrue16, "", "_FAKE16");
13595f757f3fSDimitry Andric}
13605f757f3fSDimitry Andric
136181ad6265SDimitry Andricclass Base_VOP3_DPP8<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>
136281ad6265SDimitry Andric    : VOP3_DPP8<op, opName, ps.Pfl> {
1363fcaf7f86SDimitry Andric  let VOP3_OPSEL = ps.Pfl.HasOpSel;
1364fcaf7f86SDimitry Andric  let IsDOT = ps.IsDOT;
136581ad6265SDimitry Andric  let hasSideEffects = ps.hasSideEffects;
136681ad6265SDimitry Andric  let Defs = ps.Defs;
136781ad6265SDimitry Andric  let SchedRW = ps.SchedRW;
136881ad6265SDimitry Andric  let Uses = ps.Uses;
136981ad6265SDimitry Andric
1370*0fca6ea1SDimitry Andric  let SubtargetPredicate = ps.SubtargetPredicate;
137181ad6265SDimitry Andric  let OtherPredicates = ps.OtherPredicates;
137281ad6265SDimitry Andric}
137381ad6265SDimitry Andric
137481ad6265SDimitry Andricclass Base_VOP3b_DPP16<bits<10> op, VOP_DPP_Pseudo ps,
137581ad6265SDimitry Andric                       string opName = ps.OpName>
137681ad6265SDimitry Andric    : Base_VOP3_DPP16<op, ps, opName> {
137781ad6265SDimitry Andric  bits<7> sdst;
137881ad6265SDimitry Andric  let Inst{14 - 8} = sdst;
137981ad6265SDimitry Andric}
138081ad6265SDimitry Andric
138181ad6265SDimitry Andricclass VOP3b_DPP8_Base<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>
138281ad6265SDimitry Andric    : Base_VOP3_DPP8<op, ps, opName> {
138381ad6265SDimitry Andric  bits<7> sdst;
138481ad6265SDimitry Andric  let Inst{14 - 8} = sdst;
138581ad6265SDimitry Andric}
138681ad6265SDimitry Andric
138781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
13885f757f3fSDimitry Andric// VOP3 GFX11, GFX12
138981ad6265SDimitry Andric//===----------------------------------------------------------------------===//
139081ad6265SDimitry Andric
13915f757f3fSDimitry Andricmulticlass VOP3_Real_Base<GFXGen Gen, bits<10> op, string opName = NAME,
139281ad6265SDimitry Andric                          bit isSingle = 0> {
139381ad6265SDimitry Andric  defvar ps = !cast<VOP_Pseudo>(opName#"_e64");
139481ad6265SDimitry Andric  let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {
1395*0fca6ea1SDimitry Andric    if ps.Pfl.IsFP8SrcByteSel then {
1396*0fca6ea1SDimitry Andric      def _e64#Gen.Suffix :
1397*0fca6ea1SDimitry Andric        VOP3_Real_Gen<ps, Gen>,
1398*0fca6ea1SDimitry Andric        VOP3FP8OpSel_src_bytesel_gfx11_gfx12<op, ps.Pfl>;
1399*0fca6ea1SDimitry Andric    } else if ps.Pfl.IsFP8DstByteSel then {
1400*0fca6ea1SDimitry Andric      def _e64#Gen.Suffix :
1401*0fca6ea1SDimitry Andric        VOP3_Real_Gen<ps, Gen>,
1402*0fca6ea1SDimitry Andric        VOP3FP8OpSel_dst_bytesel_gfx11_gfx12<op, ps.Pfl>;
1403*0fca6ea1SDimitry Andric    } else if ps.Pfl.HasOpSel then {
14045f757f3fSDimitry Andric      def _e64#Gen.Suffix :
14055f757f3fSDimitry Andric        VOP3_Real_Gen<ps, Gen>,
14065f757f3fSDimitry Andric        VOP3OpSel_gfx11_gfx12<op, ps.Pfl>;
1407*0fca6ea1SDimitry Andric    } else {
14085f757f3fSDimitry Andric      def _e64#Gen.Suffix :
14095f757f3fSDimitry Andric        VOP3_Real_Gen<ps, Gen>,
14105f757f3fSDimitry Andric        VOP3e_gfx11_gfx12<op, ps.Pfl>;
141181ad6265SDimitry Andric    }
141281ad6265SDimitry Andric  }
1413*0fca6ea1SDimitry Andric}
14145f757f3fSDimitry Andric
14155f757f3fSDimitry Andricmulticlass VOP3Dot_Real_Base<GFXGen Gen, bits<10> op, string opName = NAME,
1416fcaf7f86SDimitry Andric                             bit isSingle = 0> {
1417fcaf7f86SDimitry Andric  defvar ps = !cast<VOP_Pseudo>(opName#"_e64");
1418fcaf7f86SDimitry Andric  let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {
14195f757f3fSDimitry Andric    def _e64#Gen.Suffix :
14205f757f3fSDimitry Andric      VOP3_Real_Gen<ps, Gen>,
14215f757f3fSDimitry Andric      VOP3DotOpSel_gfx11_gfx12<op, ps.Pfl>;
1422fcaf7f86SDimitry Andric  }
1423fcaf7f86SDimitry Andric}
14245f757f3fSDimitry Andric
14255f757f3fSDimitry Andricmulticlass VOP3_Real_with_name<GFXGen Gen, bits<10> op, string opName,
142681ad6265SDimitry Andric                               string asmName, bit isSingle = 0> {
142781ad6265SDimitry Andric  defvar ps = !cast<VOP_Pseudo>(opName#"_e64");
142881ad6265SDimitry Andric  let AsmString = asmName # ps.AsmOperands,
142981ad6265SDimitry Andric      IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {
1430*0fca6ea1SDimitry Andric    if ps.Pfl.IsFP8SrcByteSel then {
1431b3edf446SDimitry Andric      def _e64#Gen.Suffix :
1432b3edf446SDimitry Andric        VOP3_Real_Gen<ps, Gen>,
1433*0fca6ea1SDimitry Andric        VOP3FP8OpSel_src_bytesel_gfx11_gfx12<op, ps.Pfl>;
1434*0fca6ea1SDimitry Andric    } else if ps.Pfl.IsFP8DstByteSel then {
1435*0fca6ea1SDimitry Andric      def _e64#Gen.Suffix :
1436*0fca6ea1SDimitry Andric        VOP3_Real_Gen<ps, Gen>,
1437*0fca6ea1SDimitry Andric        VOP3FP8OpSel_dst_bytesel_gfx11_gfx12<op, ps.Pfl>;
1438*0fca6ea1SDimitry Andric    } else if ps.Pfl.HasOpSel then {
14395f757f3fSDimitry Andric      def _e64#Gen.Suffix :
14405f757f3fSDimitry Andric        VOP3_Real_Gen<ps, Gen>,
14415f757f3fSDimitry Andric        VOP3OpSel_gfx11_gfx12<op, ps.Pfl>;
1442*0fca6ea1SDimitry Andric    } else {
14435f757f3fSDimitry Andric      def _e64#Gen.Suffix :
14445f757f3fSDimitry Andric        VOP3_Real_Gen<ps, Gen>,
14455f757f3fSDimitry Andric        VOP3e_gfx11_gfx12<op, ps.Pfl>;
144681ad6265SDimitry Andric    }
1447b3edf446SDimitry Andric  }
1448*0fca6ea1SDimitry Andric  def Gen.Suffix#"_VOP3_alias" : LetDummies, AMDGPUMnemonicAlias<ps.Mnemonic, asmName> {
1449*0fca6ea1SDimitry Andric    let AssemblerPredicate = Gen.AssemblerPredicate;
1450*0fca6ea1SDimitry Andric  }
145181ad6265SDimitry Andric}
14525f757f3fSDimitry Andric
145381ad6265SDimitry Andric// for READLANE/WRITELANE
14545f757f3fSDimitry Andricmulticlass VOP3_Real_No_Suffix<GFXGen Gen, bits<10> op, string opName = NAME> {
145581ad6265SDimitry Andric  defvar ps = !cast<VOP_Pseudo>(opName);
14565f757f3fSDimitry Andric    def _e64#Gen.Suffix :
14575f757f3fSDimitry Andric      VOP3_Real_Gen<ps, Gen>,
14585f757f3fSDimitry Andric      VOP3e_gfx11_gfx12<op, ps.Pfl>;
145981ad6265SDimitry Andric}
1460fcaf7f86SDimitry Andric
14615f757f3fSDimitry Andricmulticlass VOP3_Real_dpp_Base<GFXGen Gen, bits<10> op, string opName = NAME> {
14625f757f3fSDimitry Andric  def _e64_dpp#Gen.Suffix :
14635f757f3fSDimitry Andric    VOP3_DPP16_Gen<op, !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp"), Gen>;
14645f757f3fSDimitry Andric}
14655f757f3fSDimitry Andric
14665f757f3fSDimitry Andricmulticlass VOP3Dot_Real_dpp_Base<GFXGen Gen, bits<10> op, string opName = NAME> {
14675f757f3fSDimitry Andric  def _e64_dpp#Gen.Suffix :
14685f757f3fSDimitry Andric    VOP3_DPP16_Gen<op, !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp"), Gen> {
1469fcaf7f86SDimitry Andric      let Inst{11} = ?;
1470fcaf7f86SDimitry Andric      let Inst{12} = ?;
1471fcaf7f86SDimitry Andric    }
1472fcaf7f86SDimitry Andric}
1473fcaf7f86SDimitry Andric
14745f757f3fSDimitry Andricmulticlass VOP3_Real_dpp_with_name<GFXGen Gen, bits<10> op, string opName,
147581ad6265SDimitry Andric                                   string asmName> {
147681ad6265SDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
14775f757f3fSDimitry Andric  let AsmString = asmName # ps.Pfl.AsmVOP3DPP16 in {
14785f757f3fSDimitry Andric    defm NAME : VOP3_Real_dpp_Base<Gen, op, opName>;
147981ad6265SDimitry Andric  }
148081ad6265SDimitry Andric}
1481fcaf7f86SDimitry Andric
14825f757f3fSDimitry Andricmulticlass VOP3_Real_dpp8_Base<GFXGen Gen, bits<10> op, string opName = NAME> {
1483fcaf7f86SDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
14845f757f3fSDimitry Andric  def _e64_dpp8#Gen.Suffix : Base_VOP3_DPP8<op, ps> {
1485*0fca6ea1SDimitry Andric    let DecoderNamespace = Gen.DecoderNamespace;
14865f757f3fSDimitry Andric    let AssemblerPredicate = Gen.AssemblerPredicate;
14875f757f3fSDimitry Andric  }
14885f757f3fSDimitry Andric}
14895f757f3fSDimitry Andric
14905f757f3fSDimitry Andricmulticlass VOP3Dot_Real_dpp8_Base<GFXGen Gen, bits<10> op, string opName = NAME> {
14915f757f3fSDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
14925f757f3fSDimitry Andric  def _e64_dpp8#Gen.Suffix : Base_VOP3_DPP8<op, ps> {
1493fcaf7f86SDimitry Andric    let Inst{11} = ?;
1494fcaf7f86SDimitry Andric    let Inst{12} = ?;
1495*0fca6ea1SDimitry Andric    let DecoderNamespace = Gen.DecoderNamespace;
14965f757f3fSDimitry Andric    let AssemblerPredicate = Gen.AssemblerPredicate;
1497fcaf7f86SDimitry Andric  }
1498fcaf7f86SDimitry Andric}
1499fcaf7f86SDimitry Andric
15005f757f3fSDimitry Andricmulticlass VOP3_Real_dpp8_with_name<GFXGen Gen, bits<10> op, string opName,
150181ad6265SDimitry Andric                                    string asmName> {
150281ad6265SDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
15035f757f3fSDimitry Andric  let AsmString = asmName # ps.Pfl.AsmVOP3DPP8,
1504*0fca6ea1SDimitry Andric      DecoderNamespace = Gen.DecoderNamespace#
15055f757f3fSDimitry Andric                         !if(ps.Pfl.IsRealTrue16, "", "_FAKE16"),
1506*0fca6ea1SDimitry Andric      True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts,
1507*0fca6ea1SDimitry Andric                            NoTrue16Predicate) in {
15085f757f3fSDimitry Andric    defm NAME : VOP3_Real_dpp8_Base<Gen, op, opName>;
150981ad6265SDimitry Andric  }
151081ad6265SDimitry Andric}
15115f757f3fSDimitry Andric
15125f757f3fSDimitry Andricmulticlass VOP3be_Real<GFXGen Gen, bits<10> op, string opName, string asmName,
151381ad6265SDimitry Andric                      bit isSingle = 0> {
151481ad6265SDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
151581ad6265SDimitry Andric  let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in
15165f757f3fSDimitry Andric    def _e64#Gen.Suffix :
15175f757f3fSDimitry Andric      VOP3_Real_Gen<ps, Gen, asmName>,
15185f757f3fSDimitry Andric      VOP3be_gfx11_gfx12<op, ps.Pfl> ;
151981ad6265SDimitry Andric}
15205f757f3fSDimitry Andric
15215f757f3fSDimitry Andricmulticlass VOP3be_Real_dpp<GFXGen Gen, bits<10> op, string opName,
15225f757f3fSDimitry Andric                           string asmName> {
152381ad6265SDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName #"_e64");
152481ad6265SDimitry Andric  defvar dpp_ps = !cast<VOP_DPP_Pseudo>(opName #"_e64" #"_dpp");
15255f757f3fSDimitry Andric  def _e64_dpp#Gen.Suffix : Base_VOP3b_DPP16<op, dpp_ps, asmName>,
15265f757f3fSDimitry Andric                            SIMCInstr<dpp_ps.PseudoInstr, Gen.Subtarget> {
1527*0fca6ea1SDimitry Andric    let DecoderNamespace = Gen.DecoderNamespace;
15285f757f3fSDimitry Andric    let AssemblerPredicate = Gen.AssemblerPredicate;
152981ad6265SDimitry Andric  }
153081ad6265SDimitry Andric}
15315f757f3fSDimitry Andric
15325f757f3fSDimitry Andricmulticlass VOP3be_Real_dpp8<GFXGen Gen, bits<10> op, string opName,
15335f757f3fSDimitry Andric                            string asmName> {
153481ad6265SDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName #"_e64");
15355f757f3fSDimitry Andric  def _e64_dpp8#Gen.Suffix : VOP3b_DPP8_Base<op, ps, asmName> {
1536*0fca6ea1SDimitry Andric    let DecoderNamespace = Gen.DecoderNamespace;
15375f757f3fSDimitry Andric    let AssemblerPredicate = Gen.AssemblerPredicate;
153881ad6265SDimitry Andric  }
153981ad6265SDimitry Andric}
154081ad6265SDimitry Andric
154181ad6265SDimitry Andric// VOP1 and VOP2 depend on these triple defs
15425f757f3fSDimitry Andricmulticlass VOP3_Realtriple<GFXGen Gen, bits<10> op, bit isSingle = 0,
15435f757f3fSDimitry Andric                           string opName = NAME> :
15445f757f3fSDimitry Andric  VOP3_Real_Base<Gen, op, opName, isSingle>,
15455f757f3fSDimitry Andric  VOP3_Real_dpp_Base<Gen, op, opName>,
15465f757f3fSDimitry Andric  VOP3_Real_dpp8_Base<Gen, op, opName>;
154781ad6265SDimitry Andric
15485f757f3fSDimitry Andricmulticlass VOP3Dot_Realtriple<GFXGen Gen, bits<10> op, bit isSingle = 0,
15495f757f3fSDimitry Andric                              string opName = NAME> :
15505f757f3fSDimitry Andric  VOP3Dot_Real_Base<Gen, op, opName, isSingle>,
15515f757f3fSDimitry Andric  VOP3Dot_Real_dpp_Base<Gen, op, opName>,
15525f757f3fSDimitry Andric  VOP3Dot_Real_dpp8_Base<Gen, op, opName>;
1553fcaf7f86SDimitry Andric
15545f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple<GFXGen Gen, bits<10> op> :
15555f757f3fSDimitry Andric  VOP3_Realtriple<Gen, op, 1>;
155681ad6265SDimitry Andric
15575f757f3fSDimitry Andricmulticlass VOP3_Realtriple_with_name<GFXGen Gen, bits<10> op, string opName,
155881ad6265SDimitry Andric                                     string asmName, bit isSingle = 0> :
15595f757f3fSDimitry Andric  VOP3_Real_with_name<Gen, op, opName, asmName, isSingle>,
15605f757f3fSDimitry Andric  VOP3_Real_dpp_with_name<Gen, op, opName, asmName>,
15615f757f3fSDimitry Andric  VOP3_Real_dpp8_with_name<Gen, op, opName, asmName>;
156281ad6265SDimitry Andric
15635f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple_with_name<GFXGen Gen, bits<10> op, string opName,
156481ad6265SDimitry Andric                                         string asmName> :
15655f757f3fSDimitry Andric  VOP3_Realtriple_with_name<Gen, op, opName, asmName, 1>;
15665f757f3fSDimitry Andric
15675f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple_t16<GFXGen Gen, bits<10> op, string asmName,
15685f757f3fSDimitry Andric                                   string opName = NAME>
15695f757f3fSDimitry Andric    : VOP3Only_Realtriple_with_name<Gen, op, opName, asmName>;
15705f757f3fSDimitry Andric
15715f757f3fSDimitry Andricmulticlass VOP3be_Realtriple<
15725f757f3fSDimitry Andric    GFXGen Gen, bits<10> op, bit isSingle = 0, string opName = NAME,
15735f757f3fSDimitry Andric    string asmName = !cast<VOP_Pseudo>(opName#"_e64").Mnemonic> :
15745f757f3fSDimitry Andric  VOP3be_Real<Gen, op, opName, asmName, isSingle>,
15755f757f3fSDimitry Andric  VOP3be_Real_dpp<Gen, op, opName, asmName>,
15765f757f3fSDimitry Andric  VOP3be_Real_dpp8<Gen, op, opName, asmName>;
15775f757f3fSDimitry Andric
15785f757f3fSDimitry Andricmulticlass VOP3beOnly_Realtriple<GFXGen Gen, bits<10> op> :
15795f757f3fSDimitry Andric  VOP3be_Realtriple<Gen, op, 1>;
15805f757f3fSDimitry Andric
15815f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
15825f757f3fSDimitry Andric// VOP3 GFX11
15835f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
15845f757f3fSDimitry Andric
15855f757f3fSDimitry Andricmulticlass VOP3be_Real_gfx11<bits<10> op, string opName, string asmName,
15865f757f3fSDimitry Andric                             bit isSingle = 0> :
15875f757f3fSDimitry Andric  VOP3be_Real<GFX11Gen, op, opName, asmName, isSingle>;
15885f757f3fSDimitry Andric
15895f757f3fSDimitry Andricmulticlass VOP3_Real_Base_gfx11<bits<10> op, string opName = NAME,
15905f757f3fSDimitry Andric                                bit isSingle = 0> :
15915f757f3fSDimitry Andric  VOP3_Real_Base<GFX11Gen, op, opName, isSingle>;
15925f757f3fSDimitry Andric
15935f757f3fSDimitry Andricmulticlass VOP3_Realtriple_gfx11<bits<10> op, bit isSingle = 0,
15945f757f3fSDimitry Andric                                 string opName = NAME> :
15955f757f3fSDimitry Andric  VOP3_Realtriple<GFX11Gen, op, isSingle, opName>;
159681ad6265SDimitry Andric
1597bdd1243dSDimitry Andricmulticlass VOP3Only_Realtriple_t16_gfx11<bits<10> op, string asmName,
1598bdd1243dSDimitry Andric                                     string opName = NAME>
15995f757f3fSDimitry Andric    : VOP3Only_Realtriple_with_name<GFX11Gen, op, opName, asmName>;
1600bdd1243dSDimitry Andric
16015f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
16025f757f3fSDimitry Andric// VOP3 GFX12
16035f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
160481ad6265SDimitry Andric
16055f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple_gfx12<bits<10> op, bit isSingle = 0> :
16065f757f3fSDimitry Andric  VOP3_Realtriple<GFX12Gen, op, isSingle>;
16075f757f3fSDimitry Andric
16085f757f3fSDimitry Andric// IsSingle is captured from the vopprofile for these instructions, but the
16095f757f3fSDimitry Andric// following alternative is more explicit
16105f757f3fSDimitry Andricmulticlass VOP3Only_Real_Base_gfx12<bits<10> op> :
16115f757f3fSDimitry Andric  VOP3_Real_Base<GFX12Gen, op, NAME, 1/*IsSingle*/>;
16125f757f3fSDimitry Andric
16135f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple_t16_gfx12<bits<10> op> :
16145f757f3fSDimitry Andric  VOP3Only_Realtriple<GFX12Gen, op>;
16155f757f3fSDimitry Andric
16165f757f3fSDimitry Andricmulticlass VOP3be_Real_with_name_gfx12<bits<10> op, string opName,
16175f757f3fSDimitry Andric                                       string asmName, bit isSingle = 0> {
16185f757f3fSDimitry Andric  defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
16195f757f3fSDimitry Andric  let AsmString = asmName # ps.AsmOperands,
16205f757f3fSDimitry Andric      IsSingle = !or(isSingle, ps.Pfl.IsSingle) in
16215f757f3fSDimitry Andric    def _e64_gfx12 :
16225f757f3fSDimitry Andric      VOP3_Real_Gen<ps, GFX12Gen, asmName>,
1623*0fca6ea1SDimitry Andric      VOP3be_gfx11_gfx12<op, ps.Pfl>;
1624*0fca6ea1SDimitry Andric  def : AMDGPUMnemonicAlias<ps.Mnemonic, asmName> {
1625*0fca6ea1SDimitry Andric    let AssemblerPredicate = GFX12Gen.AssemblerPredicate;
1626*0fca6ea1SDimitry Andric  }
16275f757f3fSDimitry Andric}
16285f757f3fSDimitry Andric
16295f757f3fSDimitry Andricmulticlass VOP3_Realtriple_with_name_gfx12<bits<10> op, string opName,
16305f757f3fSDimitry Andric                                           string asmName, bit isSingle = 0> :
16315f757f3fSDimitry Andric  VOP3_Realtriple_with_name<GFX12Gen, op, opName, asmName, isSingle>;
16325f757f3fSDimitry Andric
16335f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple_with_name_gfx11_gfx12<bits<10> op, string opName,
16345f757f3fSDimitry Andric                                                     string asmName> :
16355f757f3fSDimitry Andric  VOP3Only_Realtriple_with_name<GFX11Gen, op, opName, asmName>,
16365f757f3fSDimitry Andric  VOP3Only_Realtriple_with_name<GFX12Gen, op, opName, asmName>;
16375f757f3fSDimitry Andric
16385f757f3fSDimitry Andricmulticlass VOP3Only_Realtriple_with_name_t16_gfx12<bits<10> op, string asmName,
16395f757f3fSDimitry Andric                                     string opName = NAME>
16405f757f3fSDimitry Andric    : VOP3Only_Realtriple_with_name<GFX12Gen, op, opName, asmName>;
16415f757f3fSDimitry Andric
16425f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
1643e8d8bef9SDimitry Andric
16440b57cec5SDimitry Andricinclude "VOPCInstructions.td"
16450b57cec5SDimitry Andricinclude "VOP1Instructions.td"
16460b57cec5SDimitry Andricinclude "VOP2Instructions.td"
16470b57cec5SDimitry Andricinclude "VOP3Instructions.td"
16480b57cec5SDimitry Andricinclude "VOP3PInstructions.td"
164981ad6265SDimitry Andricinclude "VOPDInstructions.td"
1650fe6060f1SDimitry Andric
1651bdd1243dSDimitry Andricclass ClassPat<Instruction inst, ValueType vt> : GCNPat <
165206c3fb27SDimitry Andric  (is_fpclass (vt (VOP3ModsNonCanonicalizing vt:$src0, i32:$src0_mods)), (i32 timm:$mask)),
1653bdd1243dSDimitry Andric  (inst i32:$src0_mods, vt:$src0, (V_MOV_B32_e32 timm:$mask))
1654bdd1243dSDimitry Andric>;
1655bdd1243dSDimitry Andric
1656bdd1243dSDimitry Andricdef : ClassPat<V_CMP_CLASS_F16_e64, f16> {
1657bdd1243dSDimitry Andric  let OtherPredicates = [NotHasTrue16BitInsts, Has16BitInsts];
1658bdd1243dSDimitry Andric}
1659bdd1243dSDimitry Andric
1660bdd1243dSDimitry Andricdef : ClassPat<V_CMP_CLASS_F16_t16_e64, f16> {
1661bdd1243dSDimitry Andric  let OtherPredicates = [HasTrue16BitInsts];
1662bdd1243dSDimitry Andric}
1663bdd1243dSDimitry Andric
1664bdd1243dSDimitry Andricdef : ClassPat<V_CMP_CLASS_F32_e64, f32>;
1665bdd1243dSDimitry Andricdef : ClassPat<V_CMP_CLASS_F64_e64, f64>;
1666fe6060f1SDimitry Andric
1667fe6060f1SDimitry Andricclass VOPInfoTable <string Format> : GenericTable {
1668fe6060f1SDimitry Andric  let FilterClass = Format # "_Real";
1669fe6060f1SDimitry Andric  let CppTypeName = "VOPInfo";
1670fe6060f1SDimitry Andric  let Fields = ["Opcode", "IsSingle"];
1671fe6060f1SDimitry Andric
1672fe6060f1SDimitry Andric  let PrimaryKey = ["Opcode"];
1673fe6060f1SDimitry Andric  let PrimaryKeyName = "get" # Format # "OpcodeHelper";
1674fe6060f1SDimitry Andric}
1675fe6060f1SDimitry Andric
1676fe6060f1SDimitry Andricdef VOP1InfoTable : VOPInfoTable<"VOP1">;
1677fe6060f1SDimitry Andricdef VOP2InfoTable : VOPInfoTable<"VOP2">;
1678fe6060f1SDimitry Andricdef VOP3InfoTable : VOPInfoTable<"VOP3">;
167981ad6265SDimitry Andric
168081ad6265SDimitry Andricclass VOPC64Table <string Format> : GenericTable {
168181ad6265SDimitry Andric  let FilterClass = "VOPC64_" # Format # "_Base";
168281ad6265SDimitry Andric  let CppTypeName = "VOPC64DPPInfo";
168381ad6265SDimitry Andric  let Fields = ["Opcode"];
168481ad6265SDimitry Andric
168581ad6265SDimitry Andric  let PrimaryKey = ["Opcode"];
168681ad6265SDimitry Andric  let PrimaryKeyName = "isVOPC64" # Format # "OpcodeHelper";
168781ad6265SDimitry Andric}
168881ad6265SDimitry Andric
168981ad6265SDimitry Andricdef VOPC64DPPTable : VOPC64Table<"DPP">;
169081ad6265SDimitry Andricdef VOPC64DPP8Table : VOPC64Table<"DPP8">;
1691bdd1243dSDimitry Andric
1692*0fca6ea1SDimitry Andricclass AsmOnlyInfoTable <string Format, string Class>: GenericTable {
1693*0fca6ea1SDimitry Andric  let FilterClass = Class;
1694*0fca6ea1SDimitry Andric  let FilterClassField = "isAsmParserOnly";
1695*0fca6ea1SDimitry Andric  let CppTypeName = Format # "DPPAsmOnlyInfo";
1696*0fca6ea1SDimitry Andric  let Fields = ["Opcode"];
1697*0fca6ea1SDimitry Andric
1698*0fca6ea1SDimitry Andric  let PrimaryKey = ["Opcode"];
1699*0fca6ea1SDimitry Andric  let PrimaryKeyName = "is" # Format # "AsmOnlyOpcodeHelper";
1700*0fca6ea1SDimitry Andric}
1701*0fca6ea1SDimitry Andric
1702*0fca6ea1SDimitry Andricdef VOPCAsmOnlyInfoTable : AsmOnlyInfoTable <"VOPC", "VOPC_DPPe_Common">;
1703*0fca6ea1SDimitry Andric
1704bdd1243dSDimitry Andricdef VOPTrue16Table : GenericTable {
1705bdd1243dSDimitry Andric  let FilterClass = "VOP_Pseudo";
1706bdd1243dSDimitry Andric  let CppTypeName = "VOPTrue16Info";
1707bdd1243dSDimitry Andric  let Fields = ["Opcode", "IsTrue16"];
1708bdd1243dSDimitry Andric
1709bdd1243dSDimitry Andric  let PrimaryKey = ["Opcode"];
1710bdd1243dSDimitry Andric  let PrimaryKeyName = "getTrue16OpcodeHelper";
1711bdd1243dSDimitry Andric}
1712*0fca6ea1SDimitry Andric
1713*0fca6ea1SDimitry Andricdef SingleUseExceptionTable : GenericTable {
1714*0fca6ea1SDimitry Andric  let FilterClass = "VOP_Pseudo";
1715*0fca6ea1SDimitry Andric  let CppTypeName = "SingleUseExceptionInfo";
1716*0fca6ea1SDimitry Andric  let Fields = ["Opcode", "IsInvalidSingleUseConsumer", "IsInvalidSingleUseProducer"];
1717*0fca6ea1SDimitry Andric
1718*0fca6ea1SDimitry Andric  let PrimaryKey = ["Opcode"];
1719*0fca6ea1SDimitry Andric  let PrimaryKeyName = "getSingleUseExceptionHelper";
1720*0fca6ea1SDimitry Andric}
1721