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