1097a140dSpatrick//===-- VOPInstructions.td - Vector Instruction Definitions ---------------===//
209467b48Spatrick//
309467b48Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick// See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick//
709467b48Spatrick//===----------------------------------------------------------------------===//
809467b48Spatrick
909467b48Spatrick// dummies for outer let
1009467b48Spatrickclass LetDummies {
1173471bf0Spatrick  bit TRANS;
12097a140dSpatrick  bit ReadsModeReg;
13097a140dSpatrick  bit mayRaiseFPException;
1409467b48Spatrick  bit isCommutable;
1509467b48Spatrick  bit isConvertibleToThreeAddress;
1609467b48Spatrick  bit isMoveImm;
1709467b48Spatrick  bit isReMaterializable;
1809467b48Spatrick  bit isAsCheapAsAMove;
1909467b48Spatrick  bit VOPAsmPrefer32Bit;
2009467b48Spatrick  bit FPDPRounding;
2109467b48Spatrick  Predicate SubtargetPredicate;
2209467b48Spatrick  string Constraints;
2309467b48Spatrick  string DisableEncoding;
2409467b48Spatrick  list<SchedReadWrite> SchedRW;
2509467b48Spatrick  list<Register> Uses;
2609467b48Spatrick  list<Register> Defs;
27*d415bd75Srobert  list<Predicate> OtherPredicates;
28*d415bd75Srobert  Predicate AssemblerPredicate;
29*d415bd75Srobert  string DecoderNamespace;
3009467b48Spatrick}
3109467b48Spatrick
3209467b48Spatrickclass VOP <string opName> {
3309467b48Spatrick  string OpName = opName;
3409467b48Spatrick}
3509467b48Spatrick
36*d415bd75Srobert// First 13 insts from VOPDY are also VOPDX. DOT2ACC_F32_BF16 is omitted
37*d415bd75Srobertdefvar VOPDX_Max_Index = 12;
38*d415bd75Srobert
39*d415bd75Srobertclass VOPD_Component<bits<5> OpIn, string vOPDName> {
40*d415bd75Srobert  Instruction BaseVOP = !cast<Instruction>(NAME);
41*d415bd75Srobert  string VOPDName = "v_dual_" # !substr(vOPDName, 2);
42*d415bd75Srobert  bits<5> VOPDOp = OpIn;
43*d415bd75Srobert  bit CanBeVOPDX = !le(VOPDOp, VOPDX_Max_Index);
44*d415bd75Srobert}
45*d415bd75Srobert
4609467b48Spatrickclass VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> :
4709467b48Spatrick    InstSI <outs, ins, asm, pattern> {
4809467b48Spatrick
4909467b48Spatrick  let mayLoad = 0;
5009467b48Spatrick  let mayStore = 0;
5109467b48Spatrick  let hasSideEffects = 0;
5209467b48Spatrick  let UseNamedOperandTable = 1;
5309467b48Spatrick  let VALU = 1;
54097a140dSpatrick  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
5509467b48Spatrick}
5609467b48Spatrick
5709467b48Spatrickclass VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins,
5809467b48Spatrick                  string asm, list<dag> pattern> :
5909467b48Spatrick  InstSI <outs, ins, asm, pattern>,
6009467b48Spatrick  VOP <opName>,
6109467b48Spatrick  SIMCInstr <opName#suffix, SIEncodingFamily.NONE> {
6209467b48Spatrick  let isPseudo = 1;
6309467b48Spatrick  let isCodeGenOnly = 1;
6409467b48Spatrick  let UseNamedOperandTable = 1;
6509467b48Spatrick
6609467b48Spatrick  string Mnemonic = opName;
67*d415bd75Srobert  Instruction Opcode = !cast<Instruction>(NAME);
68*d415bd75Srobert  bit IsTrue16 = P.IsTrue16;
6909467b48Spatrick  VOPProfile Pfl = P;
7009467b48Spatrick
7109467b48Spatrick  string AsmOperands;
7209467b48Spatrick}
7309467b48Spatrick
7409467b48Spatrickclass VOP3Common <dag outs, dag ins, string asm = "",
75*d415bd75Srobert                  list<dag> pattern = [], bit HasMods = 0> :
7609467b48Spatrick  VOPAnyCommon <outs, ins, asm, pattern> {
7709467b48Spatrick
7809467b48Spatrick  // Using complex patterns gives VOP3 patterns a very high complexity rating,
7909467b48Spatrick  // but standalone patterns are almost always preferred, so we need to adjust the
8009467b48Spatrick  // priority lower.  The goal is to use a high number to reduce complexity to
8109467b48Spatrick  // zero (or less than zero).
8209467b48Spatrick  let AddedComplexity = -1000;
8309467b48Spatrick
8409467b48Spatrick  let VOP3 = 1;
8509467b48Spatrick
8609467b48Spatrick  let AsmVariantName = AMDGPUAsmVariants.VOP3;
8773471bf0Spatrick  let AsmMatchConverter = !if(HasMods, "cvtVOP3", "");
8809467b48Spatrick
8909467b48Spatrick  let isCodeGenOnly = 0;
9009467b48Spatrick
9109467b48Spatrick  int Size = 8;
9209467b48Spatrick
9309467b48Spatrick  // Because SGPRs may be allowed if there are multiple operands, we
9409467b48Spatrick  // need a post-isel hook to insert copies in order to avoid
9509467b48Spatrick  // violating constant bus requirements.
9609467b48Spatrick  let hasPostISelHook = 1;
9709467b48Spatrick}
9809467b48Spatrick
9909467b48Spatrickclass VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [],
100*d415bd75Srobert                   bit isVOP3P = 0, bit isVop3OpSel = 0> :
10109467b48Spatrick  VOP_Pseudo <opName, "_e64", P, P.Outs64,
10209467b48Spatrick              !if(isVop3OpSel,
10309467b48Spatrick                  P.InsVOP3OpSel,
10409467b48Spatrick                  !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)),
10509467b48Spatrick              "", pattern> {
10609467b48Spatrick
10709467b48Spatrick  let VOP3_OPSEL = isVop3OpSel;
10809467b48Spatrick  let IsPacked = P.IsPacked;
10909467b48Spatrick  let IsMAI = P.IsMAI;
110*d415bd75Srobert  let IsWMMA = P.IsWMMA;
11109467b48Spatrick
11209467b48Spatrick  let AsmOperands = !if(isVop3OpSel,
11309467b48Spatrick                        P.AsmVOP3OpSel,
11409467b48Spatrick                        !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64));
11509467b48Spatrick
11609467b48Spatrick  let Size = 8;
11709467b48Spatrick  let mayLoad = 0;
11809467b48Spatrick  let mayStore = 0;
11909467b48Spatrick  let hasSideEffects = 0;
12009467b48Spatrick
12109467b48Spatrick  // Because SGPRs may be allowed if there are multiple operands, we
12209467b48Spatrick  // need a post-isel hook to insert copies in order to avoid
12309467b48Spatrick  // violating constant bus requirements.
12409467b48Spatrick  let hasPostISelHook = 1;
12509467b48Spatrick
12609467b48Spatrick  // Using complex patterns gives VOP3 patterns a very high complexity rating,
12709467b48Spatrick  // but standalone patterns are almost always preferred, so we need to adjust the
12809467b48Spatrick  // priority lower.  The goal is to use a high number to reduce complexity to
12909467b48Spatrick  // zero (or less than zero).
13009467b48Spatrick  let AddedComplexity = -1000;
13109467b48Spatrick
13209467b48Spatrick  let VOP3 = 1;
13309467b48Spatrick  let VALU = 1;
13409467b48Spatrick  let FPClamp = P.HasFPClamp;
13509467b48Spatrick  let IntClamp = P.HasIntClamp;
13609467b48Spatrick  let ClampLo = P.HasClampLo;
13709467b48Spatrick  let ClampHi = P.HasClampHi;
13809467b48Spatrick
139097a140dSpatrick  let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret);
140097a140dSpatrick
141097a140dSpatrick  let mayRaiseFPException = ReadsModeReg;
142097a140dSpatrick  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
14309467b48Spatrick
14409467b48Spatrick  let AsmVariantName = AMDGPUAsmVariants.VOP3;
14509467b48Spatrick  let AsmMatchConverter =
14609467b48Spatrick    !if(isVOP3P,
14709467b48Spatrick        "cvtVOP3P",
14873471bf0Spatrick        !if(!or(P.HasModifiers, P.HasOMod, P.HasIntClamp),
14909467b48Spatrick            "cvtVOP3",
15009467b48Spatrick            ""));
15109467b48Spatrick}
15209467b48Spatrick
15309467b48Spatrickclass VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> :
154*d415bd75Srobert  VOP3_Pseudo<opName, P, pattern, 1> {
15509467b48Spatrick  let VOP3P = 1;
15609467b48Spatrick}
15709467b48Spatrick
15873471bf0Spatrickclass VOP_Real<VOP_Pseudo ps> {
15973471bf0Spatrick  Instruction Opcode = !cast<Instruction>(NAME);
16073471bf0Spatrick  bit IsSingle = ps.Pfl.IsSingle;
16173471bf0Spatrick}
16273471bf0Spatrick
163*d415bd75Srobertclass VOP3_Real <VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :
16473471bf0Spatrick  VOP_Real <ps>,
165*d415bd75Srobert  InstSI <ps.OutOperandList, ps.InOperandList, asm_name # ps.AsmOperands, []>,
16609467b48Spatrick  SIMCInstr <ps.PseudoInstr, EncodingFamily> {
16709467b48Spatrick
16873471bf0Spatrick  let VALU = 1;
16973471bf0Spatrick  let VOP3 = 1;
17009467b48Spatrick  let isPseudo = 0;
17109467b48Spatrick  let isCodeGenOnly = 0;
17209467b48Spatrick  let UseNamedOperandTable = 1;
17309467b48Spatrick
17409467b48Spatrick  // copy relevant pseudo op flags
17509467b48Spatrick  let SubtargetPredicate = ps.SubtargetPredicate;
17609467b48Spatrick  let OtherPredicates    = ps.OtherPredicates;
17709467b48Spatrick  let AsmMatchConverter  = ps.AsmMatchConverter;
17809467b48Spatrick  let AsmVariantName     = ps.AsmVariantName;
17909467b48Spatrick  let Constraints        = ps.Constraints;
18009467b48Spatrick  let DisableEncoding    = ps.DisableEncoding;
18109467b48Spatrick  let TSFlags            = ps.TSFlags;
18209467b48Spatrick  let UseNamedOperandTable = ps.UseNamedOperandTable;
18309467b48Spatrick  let Uses                 = ps.Uses;
18409467b48Spatrick  let Defs                 = ps.Defs;
18573471bf0Spatrick  let SchedRW              = ps.SchedRW;
18673471bf0Spatrick  let mayLoad              = ps.mayLoad;
18773471bf0Spatrick  let mayStore             = ps.mayStore;
18873471bf0Spatrick  let TRANS                = ps.TRANS;
18909467b48Spatrick
19009467b48Spatrick  VOPProfile Pfl = ps.Pfl;
19109467b48Spatrick}
19209467b48Spatrick
193097a140dSpatrick// XXX - Is there any reason to distinguish this from regular VOP3
19409467b48Spatrick// here?
195*d415bd75Srobertclass VOP3P_Real<VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :
196*d415bd75Srobert  VOP3_Real<ps, EncodingFamily, asm_name> {
197*d415bd75Srobert
198*d415bd75Srobert  // The v_wmma pseudos have extra constraints that we do not want to impose on the real instruction.
199*d415bd75Srobert  let Constraints        = !if(!eq(!substr(ps.Mnemonic,0,6), "v_wmma"), "", ps.Constraints);
200*d415bd75Srobert}
20109467b48Spatrick
20209467b48Spatrickclass VOP3a<VOPProfile P> : Enc64 {
20309467b48Spatrick  bits<4> src0_modifiers;
20409467b48Spatrick  bits<9> src0;
20509467b48Spatrick  bits<3> src1_modifiers;
20609467b48Spatrick  bits<9> src1;
20709467b48Spatrick  bits<3> src2_modifiers;
20809467b48Spatrick  bits<9> src2;
20909467b48Spatrick  bits<1> clamp;
21009467b48Spatrick  bits<2> omod;
21109467b48Spatrick
21209467b48Spatrick  let Inst{8}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
21309467b48Spatrick  let Inst{9}     = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);
21409467b48Spatrick  let Inst{10}    = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);
21509467b48Spatrick
21609467b48Spatrick  let Inst{31-26} = 0x34; //encoding
21709467b48Spatrick  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
21809467b48Spatrick  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
21909467b48Spatrick  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
22009467b48Spatrick  let Inst{60-59} = !if(P.HasOMod, omod, 0);
22109467b48Spatrick  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
22209467b48Spatrick  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
22309467b48Spatrick  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
22409467b48Spatrick}
22509467b48Spatrick
22609467b48Spatrickclass VOP3a_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a<p> {
22709467b48Spatrick  let Inst{11}    = !if(p.HasClamp, clamp{0}, 0);
22809467b48Spatrick  let Inst{25-17} = op;
22909467b48Spatrick}
23009467b48Spatrick
23109467b48Spatrickclass VOP3a_gfx10<bits<10> op, VOPProfile p> : VOP3a<p> {
23209467b48Spatrick  let Inst{15}    = !if(p.HasClamp, clamp{0}, 0);
23309467b48Spatrick  let Inst{25-16} = op;
23409467b48Spatrick  let Inst{31-26} = 0x35;
23509467b48Spatrick}
23609467b48Spatrick
237*d415bd75Srobertclass VOP3a_gfx11<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p>;
238*d415bd75Srobert
23909467b48Spatrickclass VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> {
24009467b48Spatrick  let Inst{25-16} = op;
24109467b48Spatrick  let Inst{15}    = !if(P.HasClamp, clamp{0}, 0);
24209467b48Spatrick}
24309467b48Spatrick
24409467b48Spatrickclass VOP3e_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a_gfx6_gfx7<op, p> {
24509467b48Spatrick  bits<8> vdst;
24609467b48Spatrick  let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0);
24709467b48Spatrick}
24809467b48Spatrick
24909467b48Spatrickclass VOP3e_gfx10<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p> {
25009467b48Spatrick  bits<8> vdst;
25109467b48Spatrick  let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0);
25209467b48Spatrick}
25309467b48Spatrick
254*d415bd75Srobertclass VOP3e_gfx11<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p>;
255*d415bd75Srobert
25609467b48Spatrickclass VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> {
25709467b48Spatrick  bits<8> vdst;
25809467b48Spatrick  let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);
25909467b48Spatrick}
26009467b48Spatrick
26109467b48Spatrickclass VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {
26209467b48Spatrick  let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0);
26309467b48Spatrick  let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0);
26409467b48Spatrick  let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0);
26509467b48Spatrick  let Inst{14} = !if(P.HasDst,  src0_modifiers{3}, 0);
26609467b48Spatrick}
26709467b48Spatrick
26809467b48Spatrickclass VOP3OpSel_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {
26909467b48Spatrick  let Inst{11} = !if(p.HasSrc0, src0_modifiers{2}, 0);
27009467b48Spatrick  let Inst{12} = !if(p.HasSrc1, src1_modifiers{2}, 0);
27109467b48Spatrick  let Inst{13} = !if(p.HasSrc2, src2_modifiers{2}, 0);
27209467b48Spatrick  let Inst{14} = !if(p.HasDst,  src0_modifiers{3}, 0);
27309467b48Spatrick}
27409467b48Spatrick
275*d415bd75Srobertclass VOP3OpSel_gfx11<bits<10> op, VOPProfile p> : VOP3OpSel_gfx10<op, p>;
276*d415bd75Srobert
277*d415bd75Srobertclass VOP3DotOpSel_gfx11<bits<10> op, VOPProfile p> : VOP3OpSel_gfx11<op, p>{
278*d415bd75Srobert  let Inst{11} = ?;
279*d415bd75Srobert  let Inst{12} = ?;
280*d415bd75Srobert}
281*d415bd75Srobert
28209467b48Spatrick// NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa
28309467b48Spatrickclass VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {
28409467b48Spatrick  bits<2> attrchan;
28509467b48Spatrick  bits<6> attr;
28609467b48Spatrick  bits<1> high;
28709467b48Spatrick
28809467b48Spatrick  let Inst{8}     = 0; // No modifiers for src0
28909467b48Spatrick  let Inst{61}    = 0;
29009467b48Spatrick
29109467b48Spatrick  let Inst{9}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
29209467b48Spatrick  let Inst{62}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
29309467b48Spatrick
29409467b48Spatrick  let Inst{37-32} = attr;
29509467b48Spatrick  let Inst{39-38} = attrchan;
29609467b48Spatrick  let Inst{40}    = !if(P.HasHigh, high, 0);
29709467b48Spatrick
29809467b48Spatrick  let Inst{49-41} = src0;
29909467b48Spatrick}
30009467b48Spatrick
30109467b48Spatrickclass VOP3Interp_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> {
30209467b48Spatrick  bits<6> attr;
30309467b48Spatrick  bits<2> attrchan;
30409467b48Spatrick  bits<1> high;
30509467b48Spatrick
30609467b48Spatrick  let Inst{8}     = 0;
30709467b48Spatrick  let Inst{9}     = !if(p.HasSrc0Mods, src0_modifiers{1}, 0);
30809467b48Spatrick  let Inst{37-32} = attr;
30909467b48Spatrick  let Inst{39-38} = attrchan;
31009467b48Spatrick  let Inst{40}    = !if(p.HasHigh, high, 0);
31109467b48Spatrick  let Inst{49-41} = src0;
31209467b48Spatrick  let Inst{61}    = 0;
31309467b48Spatrick  let Inst{62}    = !if(p.HasSrc0Mods, src0_modifiers{0}, 0);
31409467b48Spatrick}
31509467b48Spatrick
316*d415bd75Srobertclass VOP3Interp_gfx11<bits<10> op, VOPProfile p> : VOP3Interp_gfx10<op, p>;
317*d415bd75Srobert
31809467b48Spatrickclass VOP3be <VOPProfile P> : Enc64 {
31909467b48Spatrick  bits<8> vdst;
32009467b48Spatrick  bits<2> src0_modifiers;
32109467b48Spatrick  bits<9> src0;
32209467b48Spatrick  bits<2> src1_modifiers;
32309467b48Spatrick  bits<9> src1;
32409467b48Spatrick  bits<2> src2_modifiers;
32509467b48Spatrick  bits<9> src2;
32609467b48Spatrick  bits<7> sdst;
32709467b48Spatrick  bits<2> omod;
32809467b48Spatrick
32909467b48Spatrick  let Inst{7-0}   = vdst;
33009467b48Spatrick  let Inst{14-8}  = sdst;
33109467b48Spatrick  let Inst{31-26} = 0x34; //encoding
33209467b48Spatrick  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
33309467b48Spatrick  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
33409467b48Spatrick  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
33509467b48Spatrick  let Inst{60-59} = !if(P.HasOMod, omod, 0);
33609467b48Spatrick  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
33709467b48Spatrick  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
33809467b48Spatrick  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
33909467b48Spatrick}
34009467b48Spatrick
34173471bf0Spatrickclass VOP3Pe <bits<7> op, VOPProfile P> : Enc64 {
34209467b48Spatrick  bits<8> vdst;
34309467b48Spatrick  bits<4> src0_modifiers;
34409467b48Spatrick  bits<9> src0;
34509467b48Spatrick  bits<4> src1_modifiers;
34609467b48Spatrick  bits<9> src1;
34709467b48Spatrick  bits<4> src2_modifiers;
34809467b48Spatrick  bits<9> src2;
34909467b48Spatrick  bits<1> clamp;
35009467b48Spatrick
35109467b48Spatrick  let Inst{7-0} = vdst;
35209467b48Spatrick  let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0
35309467b48Spatrick  let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1
35409467b48Spatrick  let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2
35509467b48Spatrick
35609467b48Spatrick  let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0)
35709467b48Spatrick  let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)
35809467b48Spatrick  let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2)
35909467b48Spatrick
36073471bf0Spatrick  let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, ?); // op_sel_hi(2)
36109467b48Spatrick
36209467b48Spatrick  let Inst{15} = !if(P.HasClamp, clamp{0}, 0);
36309467b48Spatrick
36473471bf0Spatrick  let Inst{22-16} = op;
36573471bf0Spatrick  let Inst{31-23} = 0x1a7; //encoding
36609467b48Spatrick  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
36709467b48Spatrick  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
36809467b48Spatrick  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
36973471bf0Spatrick  let Inst{59}    = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, ?); // op_sel_hi(0)
37073471bf0Spatrick  let Inst{60}    = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, ?); // op_sel_hi(1)
37109467b48Spatrick  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo)
37209467b48Spatrick  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo)
37309467b48Spatrick  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)
37409467b48Spatrick}
37509467b48Spatrick
37673471bf0Spatrickclass VOP3Pe_MAI <bits<7> op, VOPProfile P, bit acc_cd = 0> : Enc64 {
37709467b48Spatrick  bits<8> vdst;
37809467b48Spatrick  bits<10> src0;
37909467b48Spatrick  bits<10> src1;
38009467b48Spatrick  bits<9> src2;
38109467b48Spatrick  bits<3> blgp;
38209467b48Spatrick  bits<3> cbsz;
38309467b48Spatrick  bits<4> abid;
38409467b48Spatrick
38509467b48Spatrick  let Inst{7-0} = vdst;
38609467b48Spatrick
38709467b48Spatrick  let Inst{10-8}  = !if(P.HasSrc1, cbsz, 0);
38809467b48Spatrick  let Inst{14-11} = !if(P.HasSrc1, abid, 0);
38909467b48Spatrick
39073471bf0Spatrick  let Inst{15} = acc_cd;
39109467b48Spatrick
39273471bf0Spatrick  let Inst{22-16} = op;
39373471bf0Spatrick  let Inst{31-23} = 0x1a7; //encoding
39409467b48Spatrick  let Inst{40-32} = !if(P.HasSrc0, src0{8-0}, 0);
39509467b48Spatrick  let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0);
39609467b48Spatrick  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
39709467b48Spatrick
39809467b48Spatrick  let Inst{59}    = !if(P.HasSrc0, src0{9}, 0); // acc(0)
39909467b48Spatrick  let Inst{60}    = !if(P.HasSrc1, src1{9}, 0); // acc(1)
40009467b48Spatrick
40109467b48Spatrick  let Inst{63-61} = !if(P.HasSrc1, blgp, 0);
40209467b48Spatrick}
40309467b48Spatrick
404*d415bd75Srobertclass VOP3Pe_SMFMAC <bits<7> op> : Enc64 {
405*d415bd75Srobert  bits<10> vdst; // VGPR or AGPR, but not SGPR. vdst{8} is not encoded in the instruction.
406*d415bd75Srobert  bits<10> src0;
407*d415bd75Srobert  bits<10> src1;
408*d415bd75Srobert  bits<9> idx;
409*d415bd75Srobert  bits<3> blgp;
410*d415bd75Srobert  bits<3> cbsz;
411*d415bd75Srobert  bits<4> abid;
412*d415bd75Srobert
413*d415bd75Srobert  let blgp = 0;
414*d415bd75Srobert
415*d415bd75Srobert  let Inst{7-0} = vdst{7-0};
416*d415bd75Srobert
417*d415bd75Srobert  let Inst{10-8}  = cbsz;
418*d415bd75Srobert  let Inst{14-11} = abid;
419*d415bd75Srobert
420*d415bd75Srobert  let Inst{15} = vdst{9}; // acc(vdst)
421*d415bd75Srobert
422*d415bd75Srobert  let Inst{22-16} = op;
423*d415bd75Srobert  let Inst{31-23} = 0x1a7; // encoding
424*d415bd75Srobert  let Inst{40-32} = src0{8-0};
425*d415bd75Srobert  let Inst{49-41} = src1{8-0};
426*d415bd75Srobert  let Inst{58-50} = idx;
427*d415bd75Srobert
428*d415bd75Srobert  let Inst{59}    = src0{9}; // acc(0)
429*d415bd75Srobert  let Inst{60}    = src1{9}; // acc(1)
430*d415bd75Srobert
431*d415bd75Srobert  let Inst{63-61} = blgp;
432*d415bd75Srobert}
43309467b48Spatrick
43473471bf0Spatrickclass VOP3Pe_gfx10 <bits<7> op, VOPProfile P> : VOP3Pe<op, P> {
43573471bf0Spatrick  let Inst{31-23} = 0x198; //encoding
43609467b48Spatrick}
43709467b48Spatrick
438*d415bd75Srobertclass VOP3Pe_gfx11<bits<7> op, VOPProfile P> : VOP3Pe_gfx10<op, P>;
439*d415bd75Srobert
44009467b48Spatrickclass VOP3be_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3be<p> {
44109467b48Spatrick  let Inst{25-17} = op;
44209467b48Spatrick}
44309467b48Spatrick
44409467b48Spatrickclass VOP3be_gfx10<bits<10> op, VOPProfile p> : VOP3be<p> {
44509467b48Spatrick  bits<1> clamp;
44609467b48Spatrick  let Inst{15}    = !if(p.HasClamp, clamp{0}, 0);
44709467b48Spatrick  let Inst{25-16} = op;
44809467b48Spatrick  let Inst{31-26} = 0x35;
44909467b48Spatrick}
45009467b48Spatrick
451*d415bd75Srobertclass VOP3be_gfx11<bits<10> op, VOPProfile p> : VOP3be_gfx10<op, p>;
452*d415bd75Srobert
45309467b48Spatrickclass VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> {
45409467b48Spatrick  bits<1> clamp;
45509467b48Spatrick  let Inst{25-16} = op;
45609467b48Spatrick  let Inst{15}    = !if(P.HasClamp, clamp{0}, 0);
45709467b48Spatrick}
45809467b48Spatrick
45909467b48Spatrickdef SDWA {
46009467b48Spatrick  // sdwa_sel
46109467b48Spatrick  int BYTE_0 = 0;
46209467b48Spatrick  int BYTE_1 = 1;
46309467b48Spatrick  int BYTE_2 = 2;
46409467b48Spatrick  int BYTE_3 = 3;
46509467b48Spatrick  int WORD_0 = 4;
46609467b48Spatrick  int WORD_1 = 5;
46709467b48Spatrick  int DWORD = 6;
46809467b48Spatrick
46909467b48Spatrick  // dst_unused
47009467b48Spatrick  int UNUSED_PAD = 0;
47109467b48Spatrick  int UNUSED_SEXT = 1;
47209467b48Spatrick  int UNUSED_PRESERVE = 2;
47309467b48Spatrick}
47409467b48Spatrick
47509467b48Spatrickclass VOP_SDWAe<VOPProfile P> : Enc64 {
47609467b48Spatrick  bits<8> src0;
47709467b48Spatrick  bits<3> src0_sel;
47809467b48Spatrick  bits<2> src0_modifiers; // float: {abs,neg}, int {sext}
47909467b48Spatrick  bits<3> src1_sel;
48009467b48Spatrick  bits<2> src1_modifiers;
48109467b48Spatrick  bits<3> dst_sel;
48209467b48Spatrick  bits<2> dst_unused;
48309467b48Spatrick  bits<1> clamp;
48409467b48Spatrick
48509467b48Spatrick  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
48673471bf0Spatrick  let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?);
48773471bf0Spatrick  let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?);
48809467b48Spatrick  let Inst{45}    = !if(P.HasSDWAClamp, clamp{0}, 0);
48909467b48Spatrick  let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0);
49009467b48Spatrick  let Inst{51}    = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0);
49109467b48Spatrick  let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);
49209467b48Spatrick  let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0);
49309467b48Spatrick  let Inst{59}    = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0);
49409467b48Spatrick  let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);
49509467b48Spatrick}
49609467b48Spatrick
49709467b48Spatrick// GFX9 adds two features to SDWA:
49809467b48Spatrick// 1.	Add 3 fields to the SDWA microcode word: S0, S1 and OMOD.
49909467b48Spatrick//    a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather
50009467b48Spatrick//       than VGPRs (at most 1 can be an SGPR);
50109467b48Spatrick//    b. OMOD is the standard output modifier (result *2, *4, /2)
50209467b48Spatrick// 2.	Add a new version of the SDWA microcode word for VOPC: SDWAB. This
50309467b48Spatrick//    replaces OMOD and the dest fields with SD and SDST (SGPR destination)
50409467b48Spatrick//    field.
50509467b48Spatrick//    a. When SD=1, the SDST is used as the destination for the compare result;
50609467b48Spatrick//    b. When SD=0, VCC is used.
50709467b48Spatrick//
50809467b48Spatrick// In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA
50909467b48Spatrick
51009467b48Spatrick// gfx9 SDWA basic encoding
51109467b48Spatrickclass VOP_SDWA9e<VOPProfile P> : Enc64 {
51209467b48Spatrick  bits<9> src0; // {src0_sgpr{0}, src0{7-0}}
51309467b48Spatrick  bits<3> src0_sel;
51409467b48Spatrick  bits<2> src0_modifiers; // float: {abs,neg}, int {sext}
51509467b48Spatrick  bits<3> src1_sel;
51609467b48Spatrick  bits<2> src1_modifiers;
51709467b48Spatrick  bits<1> src1_sgpr;
51809467b48Spatrick
51909467b48Spatrick  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
52009467b48Spatrick  let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0);
52109467b48Spatrick  let Inst{51}    = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0);
52209467b48Spatrick  let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);
52309467b48Spatrick  let Inst{55}    = !if(P.HasSrc0, src0{8}, 0);
52409467b48Spatrick  let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0);
52509467b48Spatrick  let Inst{59}    = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0);
52609467b48Spatrick  let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);
52709467b48Spatrick  let Inst{63}    = 0; // src1_sgpr - should be specified in subclass
52809467b48Spatrick}
52909467b48Spatrick
53009467b48Spatrick// gfx9 SDWA-A
53109467b48Spatrickclass VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> {
53209467b48Spatrick  bits<3> dst_sel;
53309467b48Spatrick  bits<2> dst_unused;
53409467b48Spatrick  bits<1> clamp;
53509467b48Spatrick  bits<2> omod;
53609467b48Spatrick
53773471bf0Spatrick  let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?);
53873471bf0Spatrick  let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?);
53909467b48Spatrick  let Inst{45}    = !if(P.HasSDWAClamp, clamp{0}, 0);
54009467b48Spatrick  let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0);
54109467b48Spatrick}
54209467b48Spatrick
54309467b48Spatrick// gfx9 SDWA-B
54409467b48Spatrickclass VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> {
54509467b48Spatrick  bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}}
54609467b48Spatrick
54709467b48Spatrick  let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, ?);
54809467b48Spatrick  let Inst{47} = !if(P.EmitDst, sdst{7}, 0);
54909467b48Spatrick}
55009467b48Spatrick
55109467b48Spatrickclass VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> :
55209467b48Spatrick  InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>,
55309467b48Spatrick  VOP <opName>,
55409467b48Spatrick  SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE> {
55509467b48Spatrick
55609467b48Spatrick  let isPseudo = 1;
55709467b48Spatrick  let isCodeGenOnly = 1;
55809467b48Spatrick  let UseNamedOperandTable = 1;
55909467b48Spatrick
56009467b48Spatrick  string Mnemonic = opName;
56109467b48Spatrick  string AsmOperands = P.AsmSDWA;
56209467b48Spatrick  string AsmOperands9 = P.AsmSDWA9;
56309467b48Spatrick
56409467b48Spatrick  let Size = 8;
56509467b48Spatrick  let mayLoad = 0;
56609467b48Spatrick  let mayStore = 0;
56709467b48Spatrick  let hasSideEffects = 0;
56809467b48Spatrick
56909467b48Spatrick  let VALU = 1;
57009467b48Spatrick  let SDWA = 1;
57109467b48Spatrick
572097a140dSpatrick  let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret);
573097a140dSpatrick
574097a140dSpatrick  let mayRaiseFPException = ReadsModeReg;
575097a140dSpatrick  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
576097a140dSpatrick
577097a140dSpatrick  let SubtargetPredicate = HasSDWA;
578097a140dSpatrick  let AssemblerPredicate = HasSDWA;
57909467b48Spatrick  let AsmVariantName = !if(P.HasExtSDWA, AMDGPUAsmVariants.SDWA,
58009467b48Spatrick                                         AMDGPUAsmVariants.Disable);
58109467b48Spatrick  let DecoderNamespace = "SDWA";
58209467b48Spatrick
58309467b48Spatrick  VOPProfile Pfl = P;
58409467b48Spatrick}
58509467b48Spatrick
58609467b48Spatrickclass VOP_SDWA_Real <VOP_SDWA_Pseudo ps> :
58709467b48Spatrick  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
58809467b48Spatrick  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> {
58909467b48Spatrick
59073471bf0Spatrick  let VALU = 1;
59173471bf0Spatrick  let SDWA = 1;
59209467b48Spatrick  let isPseudo = 0;
59309467b48Spatrick  let isCodeGenOnly = 0;
59409467b48Spatrick
59509467b48Spatrick  let Defs = ps.Defs;
59609467b48Spatrick  let Uses = ps.Uses;
59709467b48Spatrick  let hasSideEffects = ps.hasSideEffects;
59809467b48Spatrick
59909467b48Spatrick  let Constraints     = ps.Constraints;
60009467b48Spatrick  let DisableEncoding = ps.DisableEncoding;
60109467b48Spatrick
60209467b48Spatrick  // Copy relevant pseudo op flags
60309467b48Spatrick  let SubtargetPredicate   = ps.SubtargetPredicate;
60409467b48Spatrick  let AssemblerPredicate   = ps.AssemblerPredicate;
60509467b48Spatrick  let AsmMatchConverter    = ps.AsmMatchConverter;
60609467b48Spatrick  let AsmVariantName       = ps.AsmVariantName;
60709467b48Spatrick  let UseNamedOperandTable = ps.UseNamedOperandTable;
60809467b48Spatrick  let DecoderNamespace     = ps.DecoderNamespace;
60909467b48Spatrick  let Constraints          = ps.Constraints;
61009467b48Spatrick  let DisableEncoding      = ps.DisableEncoding;
61109467b48Spatrick  let TSFlags              = ps.TSFlags;
61273471bf0Spatrick  let SchedRW              = ps.SchedRW;
61373471bf0Spatrick  let mayLoad              = ps.mayLoad;
61473471bf0Spatrick  let mayStore             = ps.mayStore;
61573471bf0Spatrick  let TRANS                = ps.TRANS;
61609467b48Spatrick}
61709467b48Spatrick
61809467b48Spatrickclass Base_VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :
61909467b48Spatrick  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []> {
62009467b48Spatrick
62173471bf0Spatrick  let VALU = 1;
62273471bf0Spatrick  let SDWA = 1;
62309467b48Spatrick  let isPseudo = 0;
62409467b48Spatrick  let isCodeGenOnly = 0;
62509467b48Spatrick
62609467b48Spatrick  let Defs = ps.Defs;
62709467b48Spatrick  let Uses = ps.Uses;
62809467b48Spatrick  let hasSideEffects = ps.hasSideEffects;
62909467b48Spatrick
63009467b48Spatrick  let Constraints     = ps.Constraints;
63109467b48Spatrick  let DisableEncoding = ps.DisableEncoding;
63209467b48Spatrick
633097a140dSpatrick  let SubtargetPredicate = HasSDWA9;
634097a140dSpatrick  let AssemblerPredicate = HasSDWA9;
63509467b48Spatrick  let AsmVariantName = !if(ps.Pfl.HasExtSDWA9, AMDGPUAsmVariants.SDWA9,
63609467b48Spatrick                                               AMDGPUAsmVariants.Disable);
63709467b48Spatrick  let DecoderNamespace = "SDWA9";
63809467b48Spatrick
63909467b48Spatrick  // Copy relevant pseudo op flags
64009467b48Spatrick  let AsmMatchConverter    = ps.AsmMatchConverter;
64109467b48Spatrick  let UseNamedOperandTable = ps.UseNamedOperandTable;
64209467b48Spatrick  let Constraints          = ps.Constraints;
64309467b48Spatrick  let DisableEncoding      = ps.DisableEncoding;
64409467b48Spatrick  let TSFlags              = ps.TSFlags;
64573471bf0Spatrick  let SchedRW              = ps.SchedRW;
64673471bf0Spatrick  let mayLoad              = ps.mayLoad;
64773471bf0Spatrick  let mayStore             = ps.mayStore;
64873471bf0Spatrick  let TRANS                = ps.TRANS;
64909467b48Spatrick}
65009467b48Spatrick
65109467b48Spatrickclass VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :
65209467b48Spatrick  Base_VOP_SDWA9_Real <ps >,
65309467b48Spatrick  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9>;
65409467b48Spatrick
65509467b48Spatrickclass Base_VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : Base_VOP_SDWA9_Real<ps> {
656097a140dSpatrick  let SubtargetPredicate = HasSDWA10;
657097a140dSpatrick  let AssemblerPredicate = HasSDWA10;
65809467b48Spatrick  let DecoderNamespace = "SDWA10";
65909467b48Spatrick}
66009467b48Spatrick
66109467b48Spatrickclass VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> :
66209467b48Spatrick  Base_VOP_SDWA10_Real<ps>, SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SDWA10>;
66309467b48Spatrick
66409467b48Spatrickclass VOP_DPPe<VOPProfile P, bit IsDPP16=0> : Enc64 {
66509467b48Spatrick  bits<2> src0_modifiers;
66609467b48Spatrick  bits<8> src0;
66709467b48Spatrick  bits<2> src1_modifiers;
66809467b48Spatrick  bits<9> dpp_ctrl;
66909467b48Spatrick  bits<1> bound_ctrl;
67009467b48Spatrick  bits<4> bank_mask;
67109467b48Spatrick  bits<4> row_mask;
67209467b48Spatrick  bit     fi;
67309467b48Spatrick
67409467b48Spatrick  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
67509467b48Spatrick  let Inst{48-40} = dpp_ctrl;
67609467b48Spatrick  let Inst{50}    = !if(IsDPP16, fi, ?);
67709467b48Spatrick  let Inst{51}    = bound_ctrl;
67809467b48Spatrick  let Inst{52}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg
67909467b48Spatrick  let Inst{53}    = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs
68009467b48Spatrick  let Inst{54}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg
68109467b48Spatrick  let Inst{55}    = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs
68209467b48Spatrick  let Inst{59-56} = bank_mask;
68309467b48Spatrick  let Inst{63-60} = row_mask;
68409467b48Spatrick}
68509467b48Spatrick
686*d415bd75Srobertclass VOP3_DPPe_Fields_Base {
687*d415bd75Srobert  bits<9> dpp_ctrl;
688*d415bd75Srobert  bits<1> bound_ctrl;
689*d415bd75Srobert  bits<4> bank_mask;
690*d415bd75Srobert  bits<4> row_mask;
691*d415bd75Srobert  bit     fi;
692*d415bd75Srobert}
693*d415bd75Srobertclass VOP3_DPPe_Fields : VOP3_DPPe_Fields_Base {
694*d415bd75Srobert  bits<8> src0;
695*d415bd75Srobert}
696*d415bd75Srobert
697*d415bd75Srobert// Common refers to common between DPP and DPP8
698*d415bd75Srobertclass VOP3_DPPe_Common_Base<bits<10> op, VOPProfile P> : Enc96 {
699*d415bd75Srobert  bits<4> src0_modifiers;
700*d415bd75Srobert  bits<3> src1_modifiers;
701*d415bd75Srobert  bits<3> src2_modifiers;
702*d415bd75Srobert  bits<1> clamp;
703*d415bd75Srobert  bits<2> omod;
704*d415bd75Srobert
705*d415bd75Srobert  let Inst{8}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
706*d415bd75Srobert  let Inst{9}     = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);
707*d415bd75Srobert  let Inst{10}    = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);
708*d415bd75Srobert  // OPSEL must be set such that the low result only uses low inputs, and the high result only uses high inputs.
709*d415bd75Srobert  let Inst{11} = !if(P.HasOpSel,!if(P.HasSrc0Mods, src0_modifiers{2}, 0),?);
710*d415bd75Srobert  let Inst{12} = !if(P.HasOpSel,!if(P.HasSrc1Mods, src1_modifiers{2}, 0),?);
711*d415bd75Srobert  let Inst{13} = !if(P.HasOpSel,!if(P.HasSrc2Mods, src2_modifiers{2}, 0),?);
712*d415bd75Srobert  let Inst{14} = !if(P.HasOpSel,!if(P.HasSrc0Mods, src0_modifiers{3}, 0),?);
713*d415bd75Srobert  let Inst{15}    = !if(P.HasClamp, clamp, 0);
714*d415bd75Srobert  let Inst{25-16} = op;
715*d415bd75Srobert  let Inst{31-26} = 0x35;
716*d415bd75Srobert
717*d415bd75Srobert  let Inst{60-59} = !if(P.HasOMod, omod, 0);
718*d415bd75Srobert  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
719*d415bd75Srobert  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
720*d415bd75Srobert  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
721*d415bd75Srobert}
722*d415bd75Srobert
723*d415bd75Srobertclass VOP3_DPPe_Common<bits<10> op, VOPProfile P> : VOP3_DPPe_Common_Base<op, P> {
724*d415bd75Srobert  bits<8> vdst;
725*d415bd75Srobert  bits<9> src1;
726*d415bd75Srobert  bits<9> src2;
727*d415bd75Srobert
728*d415bd75Srobert  let Inst{7-0}   = !if(P.EmitDst, vdst{7-0}, 0);
729*d415bd75Srobert  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
730*d415bd75Srobert  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
731*d415bd75Srobert}
732*d415bd75Srobert
733*d415bd75Srobertclass VOP3P_DPPe_Common_Base<bits<7> op, VOPProfile P> : Enc96 {
734*d415bd75Srobert  bits<4> src0_modifiers;
735*d415bd75Srobert  bits<4> src1_modifiers;
736*d415bd75Srobert  bits<4> src2_modifiers;
737*d415bd75Srobert  bits<1> clamp;
738*d415bd75Srobert
739*d415bd75Srobert  let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0
740*d415bd75Srobert  let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1
741*d415bd75Srobert  let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2
742*d415bd75Srobert  let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0)
743*d415bd75Srobert  let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)
744*d415bd75Srobert  let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2)
745*d415bd75Srobert  let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, ?); // op_sel_hi(2)
746*d415bd75Srobert  let Inst{15} = !if(P.HasClamp, clamp{0}, 0);
747*d415bd75Srobert  let Inst{22-16} = op;
748*d415bd75Srobert  let Inst{31-23} = 0x198; // encoding
749*d415bd75Srobert  let Inst{59}    = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, ?); // op_sel_hi(0)
750*d415bd75Srobert  let Inst{60}    = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, ?); // op_sel_hi(1)
751*d415bd75Srobert  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo)
752*d415bd75Srobert  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo)
753*d415bd75Srobert  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)
754*d415bd75Srobert}
755*d415bd75Srobert
756*d415bd75Srobertclass VOP3P_DPPe_Common<bits<7> op, VOPProfile P> : VOP3P_DPPe_Common_Base<op, P> {
757*d415bd75Srobert  bits<8> vdst;
758*d415bd75Srobert  bits<9> src1;
759*d415bd75Srobert  bits<9> src2;
760*d415bd75Srobert
761*d415bd75Srobert  let Inst{7-0} = vdst;
762*d415bd75Srobert  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
763*d415bd75Srobert  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
764*d415bd75Srobert}
765*d415bd75Srobert
766*d415bd75Srobertclass VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[],
767*d415bd75Srobert  dag Ins = P.InsDPP, string asmOps = P.AsmDPP> :
768*d415bd75Srobert  InstSI <P.OutsDPP, Ins, OpName#asmOps, pattern>,
76909467b48Spatrick  VOP <OpName>,
77009467b48Spatrick  SIMCInstr <OpName#"_dpp", SIEncodingFamily.NONE> {
77109467b48Spatrick
77209467b48Spatrick  let isPseudo = 1;
77309467b48Spatrick  let isCodeGenOnly = 1;
77409467b48Spatrick
77509467b48Spatrick  let mayLoad = 0;
77609467b48Spatrick  let mayStore = 0;
77709467b48Spatrick  let hasSideEffects = 0;
77809467b48Spatrick  let UseNamedOperandTable = 1;
77909467b48Spatrick
78009467b48Spatrick  let VALU = 1;
78109467b48Spatrick  let DPP = 1;
78209467b48Spatrick  let Size = 8;
783097a140dSpatrick
784097a140dSpatrick  let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret);
785097a140dSpatrick
786097a140dSpatrick  let mayRaiseFPException = ReadsModeReg;
787097a140dSpatrick  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
78809467b48Spatrick  let isConvergent = 1;
78909467b48Spatrick
79009467b48Spatrick  string Mnemonic = OpName;
791*d415bd75Srobert  string AsmOperands = asmOps;
79209467b48Spatrick
79373471bf0Spatrick  let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", "");
79473471bf0Spatrick  let SubtargetPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP);
79573471bf0Spatrick  let AssemblerPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP);
79609467b48Spatrick  let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP,
79709467b48Spatrick                                        AMDGPUAsmVariants.Disable);
79809467b48Spatrick  let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");
79909467b48Spatrick  let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
80009467b48Spatrick  let DecoderNamespace = "DPP";
80109467b48Spatrick
80209467b48Spatrick  VOPProfile Pfl = P;
80309467b48Spatrick}
80409467b48Spatrick
805*d415bd75Srobertclass VOP3_DPP_Pseudo <string OpName, VOPProfile P> :
806*d415bd75Srobert  VOP_DPP_Pseudo <OpName, P, [], P.InsVOP3DPP, P.AsmVOP3DPP> {
807*d415bd75Srobert  let PseudoInstr = OpName#"_e64"#"_dpp";
808*d415bd75Srobert  let OutOperandList = P.OutsVOP3DPP;
809*d415bd75Srobert  let Size = 12;
810*d415bd75Srobert  let VOP3 = 1;
811*d415bd75Srobert  let AsmMatchConverter = "cvtVOP3DPP";
812*d415bd75Srobert  let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,
813*d415bd75Srobert                                            AMDGPUAsmVariants.Disable);
814*d415bd75Srobert}
815*d415bd75Srobert
81609467b48Spatrickclass VOP_DPP_Real <VOP_DPP_Pseudo ps, int EncodingFamily> :
81709467b48Spatrick  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
81809467b48Spatrick  SIMCInstr <ps.PseudoInstr, EncodingFamily> {
81909467b48Spatrick
82073471bf0Spatrick  let VALU = 1;
82173471bf0Spatrick  let DPP = 1;
82209467b48Spatrick  let isPseudo = 0;
82309467b48Spatrick  let isCodeGenOnly = 0;
82409467b48Spatrick
82509467b48Spatrick  let Defs = ps.Defs;
82609467b48Spatrick  let Uses = ps.Uses;
82709467b48Spatrick  let hasSideEffects = ps.hasSideEffects;
82809467b48Spatrick
82909467b48Spatrick  let Constraints     = ps.Constraints;
83009467b48Spatrick  let DisableEncoding = ps.DisableEncoding;
83109467b48Spatrick
83209467b48Spatrick  // Copy relevant pseudo op flags
83309467b48Spatrick  let isConvergent         = ps.isConvergent;
83409467b48Spatrick  let SubtargetPredicate   = ps.SubtargetPredicate;
83509467b48Spatrick  let AssemblerPredicate   = ps.AssemblerPredicate;
836*d415bd75Srobert  let OtherPredicates      = ps.OtherPredicates;
83709467b48Spatrick  let AsmMatchConverter    = ps.AsmMatchConverter;
83809467b48Spatrick  let AsmVariantName       = ps.AsmVariantName;
83909467b48Spatrick  let UseNamedOperandTable = ps.UseNamedOperandTable;
84009467b48Spatrick  let DecoderNamespace     = ps.DecoderNamespace;
84109467b48Spatrick  let Constraints          = ps.Constraints;
84209467b48Spatrick  let DisableEncoding      = ps.DisableEncoding;
84309467b48Spatrick  let TSFlags              = ps.TSFlags;
84473471bf0Spatrick  let SchedRW              = ps.SchedRW;
84573471bf0Spatrick  let mayLoad              = ps.mayLoad;
84673471bf0Spatrick  let mayStore             = ps.mayStore;
84773471bf0Spatrick  let TRANS                = ps.TRANS;
84809467b48Spatrick}
84909467b48Spatrick
850*d415bd75Srobertclass VOP_DPP_Base <string OpName, VOPProfile P,
851*d415bd75Srobert               dag InsDPP,
852*d415bd75Srobert               string AsmDPP > :
853*d415bd75Srobert  InstSI <P.OutsDPP, InsDPP, OpName#AsmDPP, []> {
85409467b48Spatrick
85509467b48Spatrick  let mayLoad = 0;
85609467b48Spatrick  let mayStore = 0;
85709467b48Spatrick  let hasSideEffects = 0;
85809467b48Spatrick  let UseNamedOperandTable = 1;
85909467b48Spatrick
86009467b48Spatrick  let VALU = 1;
86109467b48Spatrick  let DPP = 1;
86209467b48Spatrick  let Size = 8;
86309467b48Spatrick
86473471bf0Spatrick  let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", "");
86573471bf0Spatrick  let SubtargetPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP);
86673471bf0Spatrick  let AssemblerPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP);
86709467b48Spatrick  let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP,
86809467b48Spatrick                                        AMDGPUAsmVariants.Disable);
86909467b48Spatrick  let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");
87009467b48Spatrick  let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
87109467b48Spatrick  let DecoderNamespace = "DPP";
87209467b48Spatrick}
87309467b48Spatrick
874*d415bd75Srobertclass VOP_DPP <string OpName, VOPProfile P, bit IsDPP16,
875*d415bd75Srobert               dag InsDPP = !if(IsDPP16, P.InsDPP16, P.InsDPP),
876*d415bd75Srobert               string AsmDPP = !if(IsDPP16, P.AsmDPP16, P.AsmDPP)> :
877*d415bd75Srobert  VOP_DPP_Base<OpName, P, InsDPP, AsmDPP>, VOP_DPPe<P, IsDPP16>;
878*d415bd75Srobert
879*d415bd75Srobertclass VOP3_DPP_Base <string OpName, VOPProfile P, bit IsDPP16,
880*d415bd75Srobert               dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),
881*d415bd75Srobert               string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :
882*d415bd75Srobert  VOP_DPP_Base<OpName, P, InsDPP, AsmDPP> {
883*d415bd75Srobert  let OutOperandList = P.OutsVOP3DPP;
884*d415bd75Srobert  let AsmMatchConverter = "cvtVOP3DPP";
885*d415bd75Srobert  let VOP3 = 1;
886*d415bd75Srobert  let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,
887*d415bd75Srobert                                            AMDGPUAsmVariants.Disable);
888*d415bd75Srobert  let Size = 12;
889*d415bd75Srobert}
890*d415bd75Srobert
891*d415bd75Srobertclass VOP3_DPP <bits<10> op, string OpName, VOPProfile P, bit IsDPP16,
892*d415bd75Srobert               dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),
893*d415bd75Srobert               string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :
894*d415bd75Srobert  VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3_DPPe_Common<op, P>,
895*d415bd75Srobert  VOP3_DPPe_Fields {
896*d415bd75Srobert
897*d415bd75Srobert  let Inst{40-32} = 0xfa;
898*d415bd75Srobert  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
899*d415bd75Srobert  let Inst{80-72} = dpp_ctrl;
900*d415bd75Srobert  let Inst{82}    = !if(IsDPP16, fi, ?);
901*d415bd75Srobert  let Inst{83}    = bound_ctrl;
902*d415bd75Srobert
903*d415bd75Srobert  // Inst{87-84} ignored by hw
904*d415bd75Srobert  let Inst{91-88} = bank_mask;
905*d415bd75Srobert  let Inst{95-92} = row_mask;
906*d415bd75Srobert}
907*d415bd75Srobert
908*d415bd75Srobertclass VOP3P_DPP <bits<7> op, string OpName, VOPProfile P, bit IsDPP16,
909*d415bd75Srobert               dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP),
910*d415bd75Srobert               string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> :
911*d415bd75Srobert  VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3P_DPPe_Common<op, P>,
912*d415bd75Srobert  VOP3_DPPe_Fields {
913*d415bd75Srobert
914*d415bd75Srobert  let VOP3P = 1;
915*d415bd75Srobert
916*d415bd75Srobert  let Inst{40-32} = 0xfa;
917*d415bd75Srobert  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
918*d415bd75Srobert  let Inst{80-72} = dpp_ctrl;
919*d415bd75Srobert  let Inst{82}    = !if(IsDPP16, fi, ?);
920*d415bd75Srobert  let Inst{83}    = bound_ctrl;
921*d415bd75Srobert
922*d415bd75Srobert  // Inst{87-84} ignored by hw
923*d415bd75Srobert  let Inst{91-88} = bank_mask;
924*d415bd75Srobert  let Inst{95-92} = row_mask;
925*d415bd75Srobert}
926*d415bd75Srobert
92709467b48Spatrickclass VOP_DPP8e<VOPProfile P> : Enc64 {
92809467b48Spatrick  bits<8> src0;
92909467b48Spatrick  bits<24> dpp8;
93009467b48Spatrick  bits<9> fi;
93109467b48Spatrick
93209467b48Spatrick  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
93309467b48Spatrick  let Inst{63-40} = dpp8{23-0};
93409467b48Spatrick}
93509467b48Spatrick
936*d415bd75Srobertclass VOP3_DPP8e_Fields {
937*d415bd75Srobert  bits<8> src0;
938*d415bd75Srobert  bits<24> dpp8;
939*d415bd75Srobert  bits<9> fi;
940*d415bd75Srobert}
941*d415bd75Srobert
942*d415bd75Srobertclass VOP_DPP8_Base<string OpName, VOPProfile P, dag InsDPP8 = P.InsDPP8, string AsmDPP8 = P.AsmDPP8> :
943*d415bd75Srobert  InstSI<P.OutsDPP8, InsDPP8, OpName#AsmDPP8, []> {
94409467b48Spatrick
94509467b48Spatrick  let mayLoad = 0;
94609467b48Spatrick  let mayStore = 0;
94709467b48Spatrick  let hasSideEffects = 0;
94809467b48Spatrick  let UseNamedOperandTable = 1;
94909467b48Spatrick
95009467b48Spatrick  let VALU = 1;
95109467b48Spatrick  let DPP = 1;
95209467b48Spatrick  let Size = 8;
95309467b48Spatrick
95409467b48Spatrick  let AsmMatchConverter = "cvtDPP8";
95509467b48Spatrick  let SubtargetPredicate = HasDPP8;
956097a140dSpatrick  let AssemblerPredicate = HasDPP8;
957*d415bd75Srobert  let AsmVariantName = AMDGPUAsmVariants.DPP;
95809467b48Spatrick  let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", "");
95909467b48Spatrick  let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
96009467b48Spatrick}
96109467b48Spatrick
962*d415bd75Srobertclass VOP_DPP8<string OpName, VOPProfile P> :
963*d415bd75Srobert  VOP_DPP8_Base<OpName, P>, VOP_DPP8e<P>;
964*d415bd75Srobert
965*d415bd75Srobertclass VOP3_DPP8_Base<string OpName, VOPProfile P> :
966*d415bd75Srobert  VOP_DPP8_Base<OpName, P, P.InsVOP3DPP8, P.AsmVOP3DPP8> {
967*d415bd75Srobert  let OutOperandList = P.OutsVOP3DPP8;
968*d415bd75Srobert  let AsmMatchConverter = "cvtVOP3DPP8";
969*d415bd75Srobert  let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP,
970*d415bd75Srobert                                            AMDGPUAsmVariants.Disable);
971*d415bd75Srobert  let VOP3 = 1;
972*d415bd75Srobert  let Size = 12;
973*d415bd75Srobert}
974*d415bd75Srobert
975*d415bd75Srobert
976*d415bd75Srobertclass VOP3_DPP8<bits<10> op, string OpName, VOPProfile P> :
977*d415bd75Srobert  VOP3_DPP8_Base<OpName, P>, VOP3_DPPe_Common<op, P>,
978*d415bd75Srobert  VOP3_DPP8e_Fields {
979*d415bd75Srobert
980*d415bd75Srobert  let Inst{40-32} = fi;
981*d415bd75Srobert  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
982*d415bd75Srobert  let Inst{95-72} = dpp8{23-0};
983*d415bd75Srobert}
984*d415bd75Srobert
985*d415bd75Srobertclass VOP3P_DPP8<bits<7> op, string OpName, VOPProfile P> :
986*d415bd75Srobert  VOP3_DPP8_Base<OpName, P>, VOP3P_DPPe_Common<op, P>,
987*d415bd75Srobert  VOP3_DPP8e_Fields {
988*d415bd75Srobert
989*d415bd75Srobert  let VOP3P = 1;
990*d415bd75Srobert  let Inst{40-32} = fi;
991*d415bd75Srobert  let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0);
992*d415bd75Srobert  let Inst{95-72} = dpp8{23-0};
993*d415bd75Srobert}
994*d415bd75Srobert
99509467b48Spatrickdef DPP8Mode {
99609467b48Spatrick  int FI_0 = 0xE9;
99709467b48Spatrick  int FI_1 = 0xEA;
99809467b48Spatrick}
99909467b48Spatrick
100009467b48Spatrickclass getNumNodeArgs<SDPatternOperator Op> {
100109467b48Spatrick  SDNode N = !cast<SDNode>(Op);
100209467b48Spatrick  SDTypeProfile TP = N.TypeProfile;
100309467b48Spatrick  int ret = TP.NumOperands;
100409467b48Spatrick}
100509467b48Spatrick
100609467b48Spatrickclass getDivergentFrag<SDPatternOperator Op> {
1007*d415bd75Srobert  assert !or(!isa<SDNode>(Op), !isa<PatFrags>(Op)), "Expected SDNode or PatFrags";
100809467b48Spatrick
1009*d415bd75Srobert  int NumSrcArgs = !if(!isa<SDNode>(Op), getNumNodeArgs<Op>.ret,
1010*d415bd75Srobert    !size(!cast<PatFrags>(Op).Operands));
101109467b48Spatrick  PatFrag ret = PatFrag <
101209467b48Spatrick    !if(!eq(NumSrcArgs, 1),
101309467b48Spatrick             (ops node:$src0),
101409467b48Spatrick             !if(!eq(NumSrcArgs, 2),
101509467b48Spatrick               (ops node:$src0, node:$src1),
101609467b48Spatrick               (ops node:$src0, node:$src1, node:$src2))),
101709467b48Spatrick    !if(!eq(NumSrcArgs, 1),
101809467b48Spatrick             (Op $src0),
101909467b48Spatrick             !if(!eq(NumSrcArgs, 2),
102009467b48Spatrick               (Op $src0, $src1),
102109467b48Spatrick               (Op $src0, $src1, $src2))),
102209467b48Spatrick    [{ return N->isDivergent(); }]
102309467b48Spatrick  >;
102409467b48Spatrick}
102509467b48Spatrick
102609467b48Spatrickclass VOPPatGen<SDPatternOperator Op, VOPProfile P> {
102709467b48Spatrick  PatFrag Operator = getDivergentFrag < Op >.ret;
102809467b48Spatrick
102909467b48Spatrick  dag Ins = !foreach(tmp, P.Ins32, !subst(ins, Operator,
103009467b48Spatrick                                         !subst(P.Src0RC32, P.Src0VT,
103109467b48Spatrick                                               !subst(P.Src1RC32, P.Src1VT, tmp))));
103209467b48Spatrick
103309467b48Spatrick  dag Outs = !foreach(tmp, P.Outs32, !subst(outs, set,
103409467b48Spatrick                                           !subst(P.DstRC, P.DstVT, tmp)));
103509467b48Spatrick
103609467b48Spatrick  list<dag> ret =  [!con(Outs, (set Ins))];
103709467b48Spatrick}
103809467b48Spatrick
1039*d415bd75Srobertclass DivergentUnaryFrag<SDPatternOperator Op> : PatFrag <
1040*d415bd75Srobert  (ops node:$src0),
1041*d415bd75Srobert  (Op $src0),
1042*d415bd75Srobert  [{ return N->isDivergent(); }]> {
1043*d415bd75Srobert  // This check is unnecessary as it's captured by the result register
1044*d415bd75Srobert  // bank constraint.
1045*d415bd75Srobert  //
1046*d415bd75Srobert  // FIXME: Should add a way for the emitter to recognize this is a
1047*d415bd75Srobert  // trivially true predicate to eliminate the check.
1048*d415bd75Srobert  let GISelPredicateCode = [{return true;}];
1049*d415bd75Srobert}
1050*d415bd75Srobert
105109467b48Spatrickclass VOPPatOrNull<SDPatternOperator Op, VOPProfile P> {
105209467b48Spatrick  list<dag> ret = !if(!ne(P.NeedPatGen,PatGenMode.NoPattern), VOPPatGen<Op, P>.ret, []);
105309467b48Spatrick}
105409467b48Spatrick
105509467b48Spatrickclass DivergentFragOrOp<SDPatternOperator Op, VOPProfile P> {
105609467b48Spatrick  SDPatternOperator ret = !if(!eq(P.NeedPatGen,PatGenMode.Pattern),
105709467b48Spatrick   !if(!isa<SDNode>(Op), getDivergentFrag<Op>.ret, Op), Op);
105809467b48Spatrick}
105909467b48Spatrick
106073471bf0Spatrickclass getVSrcOp<ValueType vt> {
106173471bf0Spatrick  RegisterOperand ret = !if(!eq(vt.Size, 32), VSrc_b32, VSrc_b16);
106273471bf0Spatrick}
106373471bf0Spatrick
106473471bf0Spatrick// Class for binary integer operations with the clamp bit set for saturation
106573471bf0Spatrick// TODO: Add sub with negated inline constant pattern.
106673471bf0Spatrickclass VOPBinOpClampPat<SDPatternOperator node, Instruction inst, ValueType vt> :
106773471bf0Spatrick  GCNPat<(node vt:$src0, vt:$src1),
106873471bf0Spatrick         (inst getVSrcOp<vt>.ret:$src0, getVSrcOp<vt>.ret:$src1,
106973471bf0Spatrick               DSTCLAMP.ENABLE)
107073471bf0Spatrick>;
107173471bf0Spatrick
1072*d415bd75Srobert//===----------------------------------------------------------------------===//
1073*d415bd75Srobert// VOP3 Classes
1074*d415bd75Srobert//===----------------------------------------------------------------------===//
1075*d415bd75Srobert
1076*d415bd75Srobertclass getVOP3ModPat<VOPProfile P, SDPatternOperator node> {
1077*d415bd75Srobert  dag src0 = !if(P.HasOMod,
1078*d415bd75Srobert    (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod),
1079*d415bd75Srobert    (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp));
1080*d415bd75Srobert
1081*d415bd75Srobert  list<dag> ret3 = [(set P.DstVT:$vdst,
1082*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT src0),
1083*d415bd75Srobert          (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1084*d415bd75Srobert          (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))];
1085*d415bd75Srobert
1086*d415bd75Srobert  list<dag> ret2 = [(set P.DstVT:$vdst,
1087*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT src0),
1088*d415bd75Srobert          (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))];
1089*d415bd75Srobert
1090*d415bd75Srobert  list<dag> ret1 = [(set P.DstVT:$vdst,
1091*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))];
1092*d415bd75Srobert
1093*d415bd75Srobert  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
1094*d415bd75Srobert                  !if(!eq(P.NumSrcArgs, 2), ret2,
1095*d415bd75Srobert                  ret1));
1096*d415bd75Srobert}
1097*d415bd75Srobert
1098*d415bd75Srobertclass getVOP3PModPat<VOPProfile P, SDPatternOperator node, bit HasExplicitClamp,
1099*d415bd75Srobert                     bit IsDOT = 0,
1100*d415bd75Srobert                     ComplexPattern SrcPat = !if(IsDOT, VOP3PModsDOT, VOP3PMods)> {
1101*d415bd75Srobert  dag src0_dag = (P.Src0VT (SrcPat P.Src0VT:$src0, i32:$src0_modifiers));
1102*d415bd75Srobert  dag src1_dag = (P.Src1VT (SrcPat P.Src1VT:$src1, i32:$src1_modifiers));
1103*d415bd75Srobert  dag src2_dag = (P.Src2VT (SrcPat P.Src2VT:$src2, i32:$src2_modifiers));
1104*d415bd75Srobert  dag clamp_dag = (i1 timm:$clamp);
1105*d415bd75Srobert
1106*d415bd75Srobert  list<dag> ret3 = [(set P.DstVT:$vdst,
1107*d415bd75Srobert    !if(HasExplicitClamp,
1108*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag, clamp_dag),
1109*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag)))];
1110*d415bd75Srobert
1111*d415bd75Srobert  list<dag> ret2 = [(set P.DstVT:$vdst,
1112*d415bd75Srobert    !if(HasExplicitClamp,
1113*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, clamp_dag),
1114*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag)))];
1115*d415bd75Srobert
1116*d415bd75Srobert  list<dag> ret1 = [(set P.DstVT:$vdst,
1117*d415bd75Srobert    !if(HasExplicitClamp,
1118*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret src0_dag, clamp_dag),
1119*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret src0_dag)))];
1120*d415bd75Srobert
1121*d415bd75Srobert  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
1122*d415bd75Srobert                  !if(!eq(P.NumSrcArgs, 2), ret2,
1123*d415bd75Srobert                  ret1));
1124*d415bd75Srobert}
1125*d415bd75Srobert
1126*d415bd75Srobertclass getVOP3OpSelPat<VOPProfile P, SDPatternOperator node> {
1127*d415bd75Srobert  list<dag> ret3 = [(set P.DstVT:$vdst,
1128*d415bd75Srobert        (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)),
1129*d415bd75Srobert          (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers)),
1130*d415bd75Srobert          (P.Src2VT (VOP3OpSel P.Src2VT:$src2, i32:$src2_modifiers))))];
1131*d415bd75Srobert
1132*d415bd75Srobert  list<dag> ret2 = [(set P.DstVT:$vdst,
1133*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)),
1134*d415bd75Srobert                                    (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers))))];
1135*d415bd75Srobert
1136*d415bd75Srobert  list<dag> ret1 = [(set P.DstVT:$vdst,
1137*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers))))];
1138*d415bd75Srobert
1139*d415bd75Srobert  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
1140*d415bd75Srobert                  !if(!eq(P.NumSrcArgs, 2), ret2,
1141*d415bd75Srobert                  ret1));
1142*d415bd75Srobert}
1143*d415bd75Srobert
1144*d415bd75Srobertclass getVOP3OpSelModPat<VOPProfile P, SDPatternOperator node> {
1145*d415bd75Srobert  list<dag> ret3 = [(set P.DstVT:$vdst,
1146*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT !if(P.HasClamp, (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers),
1147*d415bd75Srobert                                    (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))),
1148*d415bd75Srobert          (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers)),
1149*d415bd75Srobert          (P.Src2VT (VOP3OpSelMods P.Src2VT:$src2, i32:$src2_modifiers))))];
1150*d415bd75Srobert
1151*d415bd75Srobert  list<dag> ret2 = [(set P.DstVT:$vdst,
1152*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret !if(P.HasClamp, (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers)),
1153*d415bd75Srobert                          (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))),
1154*d415bd75Srobert          (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers))))];
1155*d415bd75Srobert
1156*d415bd75Srobert  list<dag> ret1 = [(set P.DstVT:$vdst,
1157*d415bd75Srobert    (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))))];
1158*d415bd75Srobert
1159*d415bd75Srobert  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
1160*d415bd75Srobert                  !if(!eq(P.NumSrcArgs, 2), ret2,
1161*d415bd75Srobert                  ret1));
1162*d415bd75Srobert}
1163*d415bd75Srobert
1164*d415bd75Srobertclass getVOP3FromVOP2Pat<VOPProfile P, SDPatternOperator node> {
1165*d415bd75Srobert  list<dag> ret = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))];
1166*d415bd75Srobert}
1167*d415bd75Srobert// In VOP1, we can have clamp and omod even if !HasModifiers
1168*d415bd75Srobertclass getVOP3Pat<VOPProfile P, SDPatternOperator node> {
1169*d415bd75Srobert  dag src0 =
1170*d415bd75Srobert    !if(P.HasOMod,
1171*d415bd75Srobert      !if(P.HasClamp,
1172*d415bd75Srobert          (VOP3Mods0 P.Src0VT:$src0, i1:$clamp, i32:$omod),
1173*d415bd75Srobert          (VOP3Mods0 P.Src0VT:$src0, i32:$omod)), // impossible?
1174*d415bd75Srobert      !if(P.HasClamp,
1175*d415bd75Srobert          (VOP3Mods0 P.Src0VT:$src0, i1:$clamp),
1176*d415bd75Srobert          (VOP3Mods0 P.Src0VT:$src0))
1177*d415bd75Srobert    );
1178*d415bd75Srobert  list<dag> ret3 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1, P.Src2VT:$src2))];
1179*d415bd75Srobert
1180*d415bd75Srobert  list<dag> ret2 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1))];
1181*d415bd75Srobert
1182*d415bd75Srobert  list<dag> ret1 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))];
1183*d415bd75Srobert  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
1184*d415bd75Srobert                  !if(!eq(P.NumSrcArgs, 2), ret2,
1185*d415bd75Srobert                  ret1));
1186*d415bd75Srobert}
1187*d415bd75Srobert
1188*d415bd75Srobertclass getVOP3ClampPat<VOPProfile P, SDPatternOperator node> {
1189*d415bd75Srobert  list<dag> ret3 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i1:$clamp))];
1190*d415bd75Srobert  list<dag> ret2 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, i1:$clamp))];
1191*d415bd75Srobert  list<dag> ret1 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, i1:$clamp))];
1192*d415bd75Srobert  list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3,
1193*d415bd75Srobert                  !if(!eq(P.NumSrcArgs, 2), ret2,
1194*d415bd75Srobert                  ret1));
1195*d415bd75Srobert}
1196*d415bd75Srobert
1197*d415bd75Srobertclass getVOP3MAIPat<VOPProfile P, SDPatternOperator node> {
1198*d415bd75Srobert  list<dag> ret = !if(!eq(P.Src0VT, P.Src1VT),
1199*d415bd75Srobert                      // mfma
1200*d415bd75Srobert                      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2,
1201*d415bd75Srobert                                            timm:$cbsz, timm:$abid, timm:$blgp))],
1202*d415bd75Srobert                      // smfmac
1203*d415bd75Srobert                      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i32:$idx,
1204*d415bd75Srobert                                            timm:$cbsz, timm:$abid))]);
1205*d415bd75Srobert}
1206*d415bd75Srobert
1207*d415bd75Srobertclass VOP3Features<bit Clamp, bit OpSel, bit Packed, bit MAI> {
1208*d415bd75Srobert  bit HasClamp = Clamp;
1209*d415bd75Srobert  bit HasOpSel = OpSel;
1210*d415bd75Srobert  bit IsPacked = Packed;
1211*d415bd75Srobert  bit IsMAI = MAI;
1212*d415bd75Srobert}
1213*d415bd75Srobert
1214*d415bd75Srobertdef VOP3_REGULAR : VOP3Features<0, 0, 0, 0>;
1215*d415bd75Srobertdef VOP3_CLAMP   : VOP3Features<1, 0, 0, 0>;
1216*d415bd75Srobertdef VOP3_OPSEL   : VOP3Features<1, 1, 0, 0>;
1217*d415bd75Srobertdef VOP3_PACKED  : VOP3Features<1, 1, 1, 0>;
1218*d415bd75Srobertdef VOP3_MAI     : VOP3Features<0, 0, 0, 1>;
1219*d415bd75Srobert
1220*d415bd75Srobertclass VOP3_Profile_Base<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProfile<P.ArgVT> {
1221*d415bd75Srobert
1222*d415bd75Srobert  let HasClamp = !if(Features.HasClamp, 1, P.HasClamp);
1223*d415bd75Srobert  let HasOpSel = !if(Features.HasOpSel, 1, P.HasOpSel);
1224*d415bd75Srobert  let IsMAI    = !if(Features.IsMAI,    1, P.IsMAI);
1225*d415bd75Srobert  let IsPacked = !if(Features.IsPacked, 1, P.IsPacked);
1226*d415bd75Srobert
1227*d415bd75Srobert  let HasModifiers =
1228*d415bd75Srobert      !if (Features.IsMAI, 0,
1229*d415bd75Srobert           !or(Features.IsPacked, Features.HasOpSel, P.HasModifiers));
1230*d415bd75Srobert}
1231*d415bd75Srobert
1232*d415bd75Srobertclass VOP3_Profile<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOP3_Profile_Base<P, Features> {
1233*d415bd75Srobert  let IsSingle = 1;
1234*d415bd75Srobert
1235*d415bd75Srobert}
1236*d415bd75Srobert
1237*d415bd75Srobert// consistently gives instructions a _e64 suffix
1238*d415bd75Srobertmulticlass VOP3Inst_Pseudo_Wrapper<string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> {
1239*d415bd75Srobert    def _e64 : VOP3_Pseudo<opName, P, pattern, VOP3Only>;
1240*d415bd75Srobert}
1241*d415bd75Srobert
1242*d415bd75Srobertclass VOP3InstBase<string OpName, VOPProfile P, SDPatternOperator node = null_frag, bit IsVOP2 = 0> :
1243*d415bd75Srobert  VOP3_Pseudo<OpName, P,
1244*d415bd75Srobert    !if(P.HasOpSel,
1245*d415bd75Srobert        !if(P.HasModifiers,
1246*d415bd75Srobert            getVOP3OpSelModPat<P, node>.ret,
1247*d415bd75Srobert            getVOP3OpSelPat<P, node>.ret),
1248*d415bd75Srobert        !if(P.HasModifiers,
1249*d415bd75Srobert            getVOP3ModPat<P, node>.ret,
1250*d415bd75Srobert            !if(IsVOP2,
1251*d415bd75Srobert              getVOP3FromVOP2Pat<P, node>.ret,
1252*d415bd75Srobert              !if(P.HasIntClamp,
1253*d415bd75Srobert                  getVOP3ClampPat<P, node>.ret,
1254*d415bd75Srobert                  !if (P.IsMAI,
1255*d415bd75Srobert                      getVOP3MAIPat<P, node>.ret,
1256*d415bd75Srobert                      getVOP3Pat<P, node>.ret))))),
1257*d415bd75Srobert    0, P.HasOpSel> {
1258*d415bd75Srobert
1259*d415bd75Srobert  let IntClamp = P.HasIntClamp;
1260*d415bd75Srobert  let AsmMatchConverter =
1261*d415bd75Srobert    !if(P.HasOpSel,
1262*d415bd75Srobert        "cvtVOP3OpSel",
1263*d415bd75Srobert        !if(!or(P.HasModifiers, P.HasOMod, P.HasIntClamp),
1264*d415bd75Srobert            "cvtVOP3",
1265*d415bd75Srobert            ""));
1266*d415bd75Srobert}
1267*d415bd75Srobert
1268*d415bd75Srobertmulticlass VOP3Inst<string OpName, VOPProfile P, SDPatternOperator node = null_frag> {
1269*d415bd75Srobert  def _e64 : VOP3InstBase<OpName, P, node>;
1270*d415bd75Srobert  let SubtargetPredicate = isGFX11Plus in {
1271*d415bd75Srobert    foreach _ = BoolToList<P.HasExtVOP3DPP>.ret in
1272*d415bd75Srobert      def _e64_dpp : VOP3_DPP_Pseudo <OpName, P>;
1273*d415bd75Srobert  } // end SubtargetPredicate = isGFX11Plus
1274*d415bd75Srobert}
1275*d415bd75Srobert
1276*d415bd75Srobert//===----------------------------------------------------------------------===//
1277*d415bd75Srobert// VOP3 DPP
1278*d415bd75Srobert//===----------------------------------------------------------------------===//
1279*d415bd75Srobert
1280*d415bd75Srobertclass Base_VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, string opName = ps.OpName>
1281*d415bd75Srobert    : VOP3_DPP<op, opName, ps.Pfl, 1> {
1282*d415bd75Srobert  let VOP3_OPSEL = ps.Pfl.HasOpSel;
1283*d415bd75Srobert  let IsDOT = ps.IsDOT;
1284*d415bd75Srobert  let hasSideEffects = ps.hasSideEffects;
1285*d415bd75Srobert  let Defs = ps.Defs;
1286*d415bd75Srobert  let SchedRW = ps.SchedRW;
1287*d415bd75Srobert  let Uses = ps.Uses;
1288*d415bd75Srobert  let AssemblerPredicate = HasDPP16;
1289*d415bd75Srobert  let SubtargetPredicate = HasDPP16;
1290*d415bd75Srobert  let OtherPredicates = ps.OtherPredicates;
1291*d415bd75Srobert}
1292*d415bd75Srobert
1293*d415bd75Srobertclass VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, int subtarget,
1294*d415bd75Srobert                 string opName = ps.OpName>
1295*d415bd75Srobert    : Base_VOP3_DPP16<op, ps, opName>, SIMCInstr<ps.PseudoInstr, subtarget>;
1296*d415bd75Srobert
1297*d415bd75Srobertclass Base_VOP3_DPP8<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>
1298*d415bd75Srobert    : VOP3_DPP8<op, opName, ps.Pfl> {
1299*d415bd75Srobert  let VOP3_OPSEL = ps.Pfl.HasOpSel;
1300*d415bd75Srobert  let IsDOT = ps.IsDOT;
1301*d415bd75Srobert  let hasSideEffects = ps.hasSideEffects;
1302*d415bd75Srobert  let Defs = ps.Defs;
1303*d415bd75Srobert  let SchedRW = ps.SchedRW;
1304*d415bd75Srobert  let Uses = ps.Uses;
1305*d415bd75Srobert
1306*d415bd75Srobert  let OtherPredicates = ps.OtherPredicates;
1307*d415bd75Srobert}
1308*d415bd75Srobert
1309*d415bd75Srobertclass Base_VOP3b_DPP16<bits<10> op, VOP_DPP_Pseudo ps,
1310*d415bd75Srobert                       string opName = ps.OpName>
1311*d415bd75Srobert    : Base_VOP3_DPP16<op, ps, opName> {
1312*d415bd75Srobert  bits<7> sdst;
1313*d415bd75Srobert  let Inst{14 - 8} = sdst;
1314*d415bd75Srobert}
1315*d415bd75Srobert
1316*d415bd75Srobertclass VOP3b_DPP8_Base<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName>
1317*d415bd75Srobert    : Base_VOP3_DPP8<op, ps, opName> {
1318*d415bd75Srobert  bits<7> sdst;
1319*d415bd75Srobert  let Inst{14 - 8} = sdst;
1320*d415bd75Srobert}
1321*d415bd75Srobert
1322*d415bd75Srobert//===----------------------------------------------------------------------===//
1323*d415bd75Srobert// VOP3 GFX11
1324*d415bd75Srobert//===----------------------------------------------------------------------===//
1325*d415bd75Srobert
1326*d415bd75Srobertlet AssemblerPredicate = isGFX11Only,
1327*d415bd75Srobert    DecoderNamespace = "GFX11" in {
1328*d415bd75Srobert  multiclass VOP3_Real_Base_gfx11<bits<10> op, string opName = NAME,
1329*d415bd75Srobert                                  bit isSingle = 0> {
1330*d415bd75Srobert    defvar ps = !cast<VOP_Pseudo>(opName#"_e64");
1331*d415bd75Srobert    let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {
1332*d415bd75Srobert    foreach _ = BoolToList<ps.Pfl.HasOpSel>.ret in
1333*d415bd75Srobert      def _e64_gfx11 :
1334*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11>,
1335*d415bd75Srobert        VOP3OpSel_gfx11<op, ps.Pfl>;
1336*d415bd75Srobert    foreach _ = BoolToList<!not(ps.Pfl.HasOpSel)>.ret in
1337*d415bd75Srobert      def _e64_gfx11 :
1338*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11>,
1339*d415bd75Srobert        VOP3e_gfx11<op, ps.Pfl>;
1340*d415bd75Srobert    }
1341*d415bd75Srobert  }
1342*d415bd75Srobert  multiclass VOP3Dot_Real_Base_gfx11<bits<10> op, string opName = NAME,
1343*d415bd75Srobert                                     bit isSingle = 0> {
1344*d415bd75Srobert    defvar ps = !cast<VOP_Pseudo>(opName#"_e64");
1345*d415bd75Srobert    let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {
1346*d415bd75Srobert      def _e64_gfx11 :
1347*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11>,
1348*d415bd75Srobert        VOP3DotOpSel_gfx11<op, ps.Pfl>;
1349*d415bd75Srobert    }
1350*d415bd75Srobert  }
1351*d415bd75Srobert  multiclass VOP3_Real_with_name_gfx11<bits<10> op, string opName,
1352*d415bd75Srobert                                       string asmName, bit isSingle = 0> {
1353*d415bd75Srobert    defvar ps = !cast<VOP_Pseudo>(opName#"_e64");
1354*d415bd75Srobert    let AsmString = asmName # ps.AsmOperands,
1355*d415bd75Srobert        IsSingle = !or(isSingle, ps.Pfl.IsSingle) in {
1356*d415bd75Srobert    foreach _ = BoolToList<ps.Pfl.HasOpSel>.ret in
1357*d415bd75Srobert      def _e64_gfx11 :
1358*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11>,
1359*d415bd75Srobert        VOP3OpSel_gfx11<op, ps.Pfl>;
1360*d415bd75Srobert    foreach _ = BoolToList<!not(ps.Pfl.HasOpSel)>.ret in
1361*d415bd75Srobert      def _e64_gfx11 :
1362*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11>,
1363*d415bd75Srobert        VOP3e_gfx11<op, ps.Pfl>;
1364*d415bd75Srobert    }
1365*d415bd75Srobert    def _gfx11_VOP3_alias : MnemonicAlias<ps.Mnemonic, asmName>, Requires<[isGFX11Plus]>, LetDummies;
1366*d415bd75Srobert  }
1367*d415bd75Srobert  // for READLANE/WRITELANE
1368*d415bd75Srobert  multiclass VOP3_Real_No_Suffix_gfx11<bits<10> op, string opName = NAME> {
1369*d415bd75Srobert    defvar ps = !cast<VOP_Pseudo>(opName);
1370*d415bd75Srobert      def _e64_gfx11 :
1371*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11>,
1372*d415bd75Srobert        VOP3e_gfx11<op, ps.Pfl>;
1373*d415bd75Srobert  }
1374*d415bd75Srobert  multiclass VOP3_Real_dpp_Base_gfx11<bits<10> op, string opName = NAME> {
1375*d415bd75Srobert    def _e64_dpp_gfx11 : VOP3_DPP16<op, !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp"), SIEncodingFamily.GFX11> {
1376*d415bd75Srobert      let DecoderNamespace = "DPPGFX11";
1377*d415bd75Srobert      }
1378*d415bd75Srobert  }
1379*d415bd75Srobert
1380*d415bd75Srobert  multiclass VOP3Dot_Real_dpp_Base_gfx11<bits<10> op, string opName = NAME> {
1381*d415bd75Srobert    def _e64_dpp_gfx11 : VOP3_DPP16<op, !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp"), SIEncodingFamily.GFX11> {
1382*d415bd75Srobert      let Inst{11} = ?;
1383*d415bd75Srobert      let Inst{12} = ?;
1384*d415bd75Srobert      let DecoderNamespace = "DPPGFX11";
1385*d415bd75Srobert      }
1386*d415bd75Srobert  }
1387*d415bd75Srobert
1388*d415bd75Srobert  multiclass VOP3_Real_dpp_with_name_gfx11<bits<10> op, string opName,
1389*d415bd75Srobert                                           string asmName> {
1390*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
1391*d415bd75Srobert    let AsmString = asmName # ps.Pfl.AsmVOP3DPP16, DecoderNamespace = "DPPGFX11" in {
1392*d415bd75Srobert      defm NAME : VOP3_Real_dpp_Base_gfx11<op, opName>;
1393*d415bd75Srobert    }
1394*d415bd75Srobert  }
1395*d415bd75Srobert  multiclass VOP3_Real_dpp8_Base_gfx11<bits<10> op, string opName = NAME> {
1396*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
1397*d415bd75Srobert    def _e64_dpp8_gfx11 : Base_VOP3_DPP8<op, ps> {
1398*d415bd75Srobert      let DecoderNamespace = "DPP8GFX11";
1399*d415bd75Srobert    }
1400*d415bd75Srobert  }
1401*d415bd75Srobert
1402*d415bd75Srobert  multiclass VOP3Dot_Real_dpp8_Base_gfx11<bits<10> op, string opName = NAME> {
1403*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
1404*d415bd75Srobert    def _e64_dpp8_gfx11 : Base_VOP3_DPP8<op, ps> {
1405*d415bd75Srobert      let Inst{11} = ?;
1406*d415bd75Srobert      let Inst{12} = ?;
1407*d415bd75Srobert      let DecoderNamespace = "DPP8GFX11";
1408*d415bd75Srobert    }
1409*d415bd75Srobert  }
1410*d415bd75Srobert
1411*d415bd75Srobert  multiclass VOP3_Real_dpp8_with_name_gfx11<bits<10> op, string opName,
1412*d415bd75Srobert                                           string asmName> {
1413*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
1414*d415bd75Srobert    let AsmString = asmName # ps.Pfl.AsmVOP3DPP8, DecoderNamespace = "DPP8GFX11"  in {
1415*d415bd75Srobert      defm NAME : VOP3_Real_dpp8_Base_gfx11<op, opName>;
1416*d415bd75Srobert    }
1417*d415bd75Srobert  }
1418*d415bd75Srobert  multiclass VOP3be_Real_gfx11<bits<10> op, string opName, string asmName,
1419*d415bd75Srobert                               bit isSingle = 0> {
1420*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
1421*d415bd75Srobert    let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in
1422*d415bd75Srobert      def _e64_gfx11 :
1423*d415bd75Srobert        VOP3_Real<ps, SIEncodingFamily.GFX11, asmName>,
1424*d415bd75Srobert        VOP3be_gfx11<op, ps.Pfl> ;
1425*d415bd75Srobert  }
1426*d415bd75Srobert  multiclass VOP3be_Real_dpp_gfx11<bits<10> op, string opName, string asmName> {
1427*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName #"_e64");
1428*d415bd75Srobert    defvar dpp_ps = !cast<VOP_DPP_Pseudo>(opName #"_e64" #"_dpp");
1429*d415bd75Srobert    def _e64_dpp_gfx11 : Base_VOP3b_DPP16<op, dpp_ps, asmName>,
1430*d415bd75Srobert                         SIMCInstr<dpp_ps.PseudoInstr, SIEncodingFamily.GFX11> {
1431*d415bd75Srobert      let DecoderNamespace = "DPPGFX11";
1432*d415bd75Srobert    }
1433*d415bd75Srobert  }
1434*d415bd75Srobert  multiclass VOP3be_Real_dpp8_gfx11<bits<10> op, string opName, string asmName> {
1435*d415bd75Srobert    defvar ps = !cast<VOP3_Pseudo>(opName #"_e64");
1436*d415bd75Srobert    def _e64_dpp8_gfx11 : VOP3b_DPP8_Base<op, ps, asmName> {
1437*d415bd75Srobert      let DecoderNamespace = "DPP8GFX11";
1438*d415bd75Srobert    }
1439*d415bd75Srobert  }
1440*d415bd75Srobert} // End AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11"
1441*d415bd75Srobert
1442*d415bd75Srobert// VOP1 and VOP2 depend on these triple defs
1443*d415bd75Srobertmulticlass VOP3_Realtriple_gfx11<bits<10> op,
1444*d415bd75Srobert                                 bit isSingle = 0, string opName = NAME> :
1445*d415bd75Srobert  VOP3_Real_Base_gfx11<op, opName, isSingle>,
1446*d415bd75Srobert  VOP3_Real_dpp_Base_gfx11<op, opName>,
1447*d415bd75Srobert  VOP3_Real_dpp8_Base_gfx11<op, opName>;
1448*d415bd75Srobert
1449*d415bd75Srobertmulticlass VOP3Dot_Realtriple_gfx11<bits<10> op,
1450*d415bd75Srobert                                 bit isSingle = 0, string opName = NAME> :
1451*d415bd75Srobert  VOP3Dot_Real_Base_gfx11<op, opName, isSingle>,
1452*d415bd75Srobert  VOP3Dot_Real_dpp_Base_gfx11<op, opName>,
1453*d415bd75Srobert  VOP3Dot_Real_dpp8_Base_gfx11<op, opName>;
1454*d415bd75Srobert
1455*d415bd75Srobertmulticlass VOP3Only_Realtriple_gfx11<bits<10> op> :
1456*d415bd75Srobert  VOP3_Realtriple_gfx11<op, 1>;
1457*d415bd75Srobert
1458*d415bd75Srobertmulticlass VOP3_Realtriple_with_name_gfx11<bits<10> op, string opName,
1459*d415bd75Srobert                                           string asmName, bit isSingle = 0> :
1460*d415bd75Srobert  VOP3_Real_with_name_gfx11<op, opName, asmName, isSingle>,
1461*d415bd75Srobert  VOP3_Real_dpp_with_name_gfx11<op, opName, asmName>,
1462*d415bd75Srobert  VOP3_Real_dpp8_with_name_gfx11<op, opName, asmName>;
1463*d415bd75Srobert
1464*d415bd75Srobertmulticlass VOP3Only_Realtriple_with_name_gfx11<bits<10> op, string opName,
1465*d415bd75Srobert                                               string asmName> :
1466*d415bd75Srobert  VOP3_Realtriple_with_name_gfx11<op, opName, asmName, 1>;
1467*d415bd75Srobert
1468*d415bd75Srobertmulticlass VOP3Only_Realtriple_t16_gfx11<bits<10> op, string asmName,
1469*d415bd75Srobert                                     string opName = NAME>
1470*d415bd75Srobert    : VOP3Only_Realtriple_with_name_gfx11<op, opName, asmName>;
1471*d415bd75Srobert
1472*d415bd75Srobertmulticlass VOP3be_Realtriple_gfx11<
1473*d415bd75Srobert    bits<10> op, bit isSingle = 0, string opName = NAME,
1474*d415bd75Srobert    string asmName = !cast<VOP_Pseudo>(opName#"_e64").Mnemonic> :
1475*d415bd75Srobert  VOP3be_Real_gfx11<op, opName, asmName, isSingle>,
1476*d415bd75Srobert  VOP3be_Real_dpp_gfx11<op, opName, asmName>,
1477*d415bd75Srobert  VOP3be_Real_dpp8_gfx11<op, opName, asmName>;
1478*d415bd75Srobert
1479*d415bd75Srobertmulticlass VOP3beOnly_Realtriple_gfx11<bits<10> op> :
1480*d415bd75Srobert  VOP3be_Realtriple_gfx11<op, 1>;
148173471bf0Spatrick
148209467b48Spatrickinclude "VOPCInstructions.td"
148309467b48Spatrickinclude "VOP1Instructions.td"
148409467b48Spatrickinclude "VOP2Instructions.td"
148509467b48Spatrickinclude "VOP3Instructions.td"
148609467b48Spatrickinclude "VOP3PInstructions.td"
1487*d415bd75Srobertinclude "VOPDInstructions.td"
148873471bf0Spatrick
1489*d415bd75Srobertclass ClassPat<Instruction inst, ValueType vt> : GCNPat <
1490*d415bd75Srobert  (is_fpclass (vt (VOP3Mods vt:$src0, i32:$src0_mods)), (i32 timm:$mask)),
1491*d415bd75Srobert  (inst i32:$src0_mods, vt:$src0, (V_MOV_B32_e32 timm:$mask))
1492*d415bd75Srobert>;
1493*d415bd75Srobert
1494*d415bd75Srobertdef : ClassPat<V_CMP_CLASS_F16_e64, f16> {
1495*d415bd75Srobert  let OtherPredicates = [NotHasTrue16BitInsts, Has16BitInsts];
1496*d415bd75Srobert}
1497*d415bd75Srobert
1498*d415bd75Srobertdef : ClassPat<V_CMP_CLASS_F16_t16_e64, f16> {
1499*d415bd75Srobert  let OtherPredicates = [HasTrue16BitInsts];
1500*d415bd75Srobert}
1501*d415bd75Srobert
1502*d415bd75Srobertdef : ClassPat<V_CMP_CLASS_F32_e64, f32>;
1503*d415bd75Srobertdef : ClassPat<V_CMP_CLASS_F64_e64, f64>;
150473471bf0Spatrick
150573471bf0Spatrickclass VOPInfoTable <string Format> : GenericTable {
150673471bf0Spatrick  let FilterClass = Format # "_Real";
150773471bf0Spatrick  let CppTypeName = "VOPInfo";
150873471bf0Spatrick  let Fields = ["Opcode", "IsSingle"];
150973471bf0Spatrick
151073471bf0Spatrick  let PrimaryKey = ["Opcode"];
151173471bf0Spatrick  let PrimaryKeyName = "get" # Format # "OpcodeHelper";
151273471bf0Spatrick}
151373471bf0Spatrick
151473471bf0Spatrickdef VOP1InfoTable : VOPInfoTable<"VOP1">;
151573471bf0Spatrickdef VOP2InfoTable : VOPInfoTable<"VOP2">;
151673471bf0Spatrickdef VOP3InfoTable : VOPInfoTable<"VOP3">;
1517*d415bd75Srobert
1518*d415bd75Srobertclass VOPC64Table <string Format> : GenericTable {
1519*d415bd75Srobert  let FilterClass = "VOPC64_" # Format # "_Base";
1520*d415bd75Srobert  let CppTypeName = "VOPC64DPPInfo";
1521*d415bd75Srobert  let Fields = ["Opcode"];
1522*d415bd75Srobert
1523*d415bd75Srobert  let PrimaryKey = ["Opcode"];
1524*d415bd75Srobert  let PrimaryKeyName = "isVOPC64" # Format # "OpcodeHelper";
1525*d415bd75Srobert}
1526*d415bd75Srobert
1527*d415bd75Srobertdef VOPC64DPPTable : VOPC64Table<"DPP">;
1528*d415bd75Srobertdef VOPC64DPP8Table : VOPC64Table<"DPP8">;
1529*d415bd75Srobert
1530*d415bd75Srobertdef VOPTrue16Table : GenericTable {
1531*d415bd75Srobert  let FilterClass = "VOP_Pseudo";
1532*d415bd75Srobert  let CppTypeName = "VOPTrue16Info";
1533*d415bd75Srobert  let Fields = ["Opcode", "IsTrue16"];
1534*d415bd75Srobert
1535*d415bd75Srobert  let PrimaryKey = ["Opcode"];
1536*d415bd75Srobert  let PrimaryKeyName = "getTrue16OpcodeHelper";
1537*d415bd75Srobert}
1538