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