1//===-- VOPInstructions.td - Vector Instruction Definitions ---------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9// dummies for outer let 10class LetDummies { 11 bit TRANS; 12 bit ReadsModeReg; 13 bit mayRaiseFPException; 14 bit isCommutable; 15 bit isConvertibleToThreeAddress; 16 bit isMoveImm; 17 bit isReMaterializable; 18 bit isAsCheapAsAMove; 19 bit VOPAsmPrefer32Bit; 20 bit FPDPRounding; 21 Predicate SubtargetPredicate; 22 string Constraints; 23 string DisableEncoding; 24 list<SchedReadWrite> SchedRW; 25 list<Register> Uses; 26 list<Register> Defs; 27} 28 29class VOP <string opName> { 30 string OpName = opName; 31} 32 33// First 13 insts from VOPDY are also VOPDX. DOT2ACC_F32_BF16 is omitted 34defvar VOPDX_Max_Index = 12; 35 36class VOPD_Component<bits<5> OpIn, string vOPDName> { 37 Instruction BaseVOP = !cast<Instruction>(NAME); 38 string VOPDName = "v_dual_" # !substr(vOPDName, 2); 39 bits<5> VOPDOp = OpIn; 40 bit CanBeVOPDX = !le(VOPDOp, VOPDX_Max_Index); 41} 42 43class VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> : 44 InstSI <outs, ins, asm, pattern> { 45 46 let mayLoad = 0; 47 let mayStore = 0; 48 let hasSideEffects = 0; 49 let UseNamedOperandTable = 1; 50 let VALU = 1; 51 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 52} 53 54class VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins, 55 string asm, list<dag> pattern> : 56 InstSI <outs, ins, asm, pattern>, 57 VOP <opName>, 58 SIMCInstr <opName#suffix, SIEncodingFamily.NONE> { 59 let isPseudo = 1; 60 let isCodeGenOnly = 1; 61 let UseNamedOperandTable = 1; 62 63 string Mnemonic = opName; 64 VOPProfile Pfl = P; 65 66 string AsmOperands; 67} 68 69class VOP3Common <dag outs, dag ins, string asm = "", 70 list<dag> pattern = [], bit HasMods = 0> : 71 VOPAnyCommon <outs, ins, asm, pattern> { 72 73 // Using complex patterns gives VOP3 patterns a very high complexity rating, 74 // but standalone patterns are almost always preferred, so we need to adjust the 75 // priority lower. The goal is to use a high number to reduce complexity to 76 // zero (or less than zero). 77 let AddedComplexity = -1000; 78 79 let VOP3 = 1; 80 81 let AsmVariantName = AMDGPUAsmVariants.VOP3; 82 let AsmMatchConverter = !if(HasMods, "cvtVOP3", ""); 83 84 let isCodeGenOnly = 0; 85 86 int Size = 8; 87 88 // Because SGPRs may be allowed if there are multiple operands, we 89 // need a post-isel hook to insert copies in order to avoid 90 // violating constant bus requirements. 91 let hasPostISelHook = 1; 92} 93 94class VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [], 95 bit isVOP3P = 0, bit isVop3OpSel = 0> : 96 VOP_Pseudo <opName, "_e64", P, P.Outs64, 97 !if(isVop3OpSel, 98 P.InsVOP3OpSel, 99 !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)), 100 "", pattern> { 101 102 let VOP3_OPSEL = isVop3OpSel; 103 let IsPacked = P.IsPacked; 104 let IsMAI = P.IsMAI; 105 let IsWMMA = P.IsWMMA; 106 107 let AsmOperands = !if(isVop3OpSel, 108 P.AsmVOP3OpSel, 109 !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64)); 110 111 let Size = 8; 112 let mayLoad = 0; 113 let mayStore = 0; 114 let hasSideEffects = 0; 115 116 // Because SGPRs may be allowed if there are multiple operands, we 117 // need a post-isel hook to insert copies in order to avoid 118 // violating constant bus requirements. 119 let hasPostISelHook = 1; 120 121 // Using complex patterns gives VOP3 patterns a very high complexity rating, 122 // but standalone patterns are almost always preferred, so we need to adjust the 123 // priority lower. The goal is to use a high number to reduce complexity to 124 // zero (or less than zero). 125 let AddedComplexity = -1000; 126 127 let VOP3 = 1; 128 let VALU = 1; 129 let FPClamp = P.HasFPClamp; 130 let IntClamp = P.HasIntClamp; 131 let ClampLo = P.HasClampLo; 132 let ClampHi = P.HasClampHi; 133 134 let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret); 135 136 let mayRaiseFPException = ReadsModeReg; 137 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 138 139 let AsmVariantName = AMDGPUAsmVariants.VOP3; 140 let AsmMatchConverter = 141 !if(isVOP3P, 142 "cvtVOP3P", 143 !if(!or(P.HasModifiers, P.HasOMod, P.HasIntClamp), 144 "cvtVOP3", 145 "")); 146} 147 148class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> : 149 VOP3_Pseudo<opName, P, pattern, 1> { 150 let VOP3P = 1; 151} 152 153class VOP_Real<VOP_Pseudo ps> { 154 Instruction Opcode = !cast<Instruction>(NAME); 155 bit IsSingle = ps.Pfl.IsSingle; 156} 157 158class VOP3_Real <VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> : 159 VOP_Real <ps>, 160 InstSI <ps.OutOperandList, ps.InOperandList, asm_name # ps.AsmOperands, []>, 161 SIMCInstr <ps.PseudoInstr, EncodingFamily> { 162 163 let VALU = 1; 164 let VOP3 = 1; 165 let isPseudo = 0; 166 let isCodeGenOnly = 0; 167 let UseNamedOperandTable = 1; 168 169 // copy relevant pseudo op flags 170 let SubtargetPredicate = ps.SubtargetPredicate; 171 let OtherPredicates = ps.OtherPredicates; 172 let AsmMatchConverter = ps.AsmMatchConverter; 173 let AsmVariantName = ps.AsmVariantName; 174 let Constraints = ps.Constraints; 175 let DisableEncoding = ps.DisableEncoding; 176 let TSFlags = ps.TSFlags; 177 let UseNamedOperandTable = ps.UseNamedOperandTable; 178 let Uses = ps.Uses; 179 let Defs = ps.Defs; 180 let SchedRW = ps.SchedRW; 181 let mayLoad = ps.mayLoad; 182 let mayStore = ps.mayStore; 183 let TRANS = ps.TRANS; 184 185 VOPProfile Pfl = ps.Pfl; 186} 187 188// XXX - Is there any reason to distinguish this from regular VOP3 189// here? 190class VOP3P_Real<VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> : 191 VOP3_Real<ps, EncodingFamily, asm_name> { 192 193 // The v_wmma pseudos have extra constraints that we do not want to impose on the real instruction. 194 let Constraints = !if(!eq(!substr(ps.Mnemonic,0,6), "v_wmma"), "", ps.Constraints); 195} 196 197class VOP3a<VOPProfile P> : Enc64 { 198 bits<4> src0_modifiers; 199 bits<9> src0; 200 bits<3> src1_modifiers; 201 bits<9> src1; 202 bits<3> src2_modifiers; 203 bits<9> src2; 204 bits<1> clamp; 205 bits<2> omod; 206 207 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); 208 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); 209 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); 210 211 let Inst{31-26} = 0x34; //encoding 212 let Inst{40-32} = !if(P.HasSrc0, src0, 0); 213 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 214 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 215 let Inst{60-59} = !if(P.HasOMod, omod, 0); 216 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 217 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); 218 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); 219} 220 221class VOP3a_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a<p> { 222 let Inst{11} = !if(p.HasClamp, clamp{0}, 0); 223 let Inst{25-17} = op; 224} 225 226class VOP3a_gfx10<bits<10> op, VOPProfile p> : VOP3a<p> { 227 let Inst{15} = !if(p.HasClamp, clamp{0}, 0); 228 let Inst{25-16} = op; 229 let Inst{31-26} = 0x35; 230} 231 232class VOP3a_gfx11<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p>; 233 234class VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> { 235 let Inst{25-16} = op; 236 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 237} 238 239class VOP3e_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a_gfx6_gfx7<op, p> { 240 bits<8> vdst; 241 let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0); 242} 243 244class VOP3e_gfx10<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p> { 245 bits<8> vdst; 246 let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0); 247} 248 249class VOP3e_gfx11<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p>; 250 251class VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> { 252 bits<8> vdst; 253 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0); 254} 255 256class VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> { 257 let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0); 258 let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0); 259 let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0); 260 let Inst{14} = !if(P.HasDst, src0_modifiers{3}, 0); 261} 262 263class VOP3OpSel_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> { 264 let Inst{11} = !if(p.HasSrc0, src0_modifiers{2}, 0); 265 let Inst{12} = !if(p.HasSrc1, src1_modifiers{2}, 0); 266 let Inst{13} = !if(p.HasSrc2, src2_modifiers{2}, 0); 267 let Inst{14} = !if(p.HasDst, src0_modifiers{3}, 0); 268} 269 270class VOP3OpSel_gfx11<bits<10> op, VOPProfile p> : VOP3OpSel_gfx10<op, p>; 271 272class VOP3DotOpSel_gfx11<bits<10> op, VOPProfile p> : VOP3OpSel_gfx11<op, p>{ 273 let Inst{11} = ?; 274 let Inst{12} = ?; 275} 276 277// NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa 278class VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> { 279 bits<2> attrchan; 280 bits<6> attr; 281 bits<1> high; 282 283 let Inst{8} = 0; // No modifiers for src0 284 let Inst{61} = 0; 285 286 let Inst{9} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); 287 let Inst{62} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 288 289 let Inst{37-32} = attr; 290 let Inst{39-38} = attrchan; 291 let Inst{40} = !if(P.HasHigh, high, 0); 292 293 let Inst{49-41} = src0; 294} 295 296class VOP3Interp_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> { 297 bits<6> attr; 298 bits<2> attrchan; 299 bits<1> high; 300 301 let Inst{8} = 0; 302 let Inst{9} = !if(p.HasSrc0Mods, src0_modifiers{1}, 0); 303 let Inst{37-32} = attr; 304 let Inst{39-38} = attrchan; 305 let Inst{40} = !if(p.HasHigh, high, 0); 306 let Inst{49-41} = src0; 307 let Inst{61} = 0; 308 let Inst{62} = !if(p.HasSrc0Mods, src0_modifiers{0}, 0); 309} 310 311class VOP3Interp_gfx11<bits<10> op, VOPProfile p> : VOP3Interp_gfx10<op, p>; 312 313class VOP3be <VOPProfile P> : Enc64 { 314 bits<8> vdst; 315 bits<2> src0_modifiers; 316 bits<9> src0; 317 bits<2> src1_modifiers; 318 bits<9> src1; 319 bits<2> src2_modifiers; 320 bits<9> src2; 321 bits<7> sdst; 322 bits<2> omod; 323 324 let Inst{7-0} = vdst; 325 let Inst{14-8} = sdst; 326 let Inst{31-26} = 0x34; //encoding 327 let Inst{40-32} = !if(P.HasSrc0, src0, 0); 328 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 329 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 330 let Inst{60-59} = !if(P.HasOMod, omod, 0); 331 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 332 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); 333 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); 334} 335 336class VOP3Pe <bits<7> op, VOPProfile P> : Enc64 { 337 bits<8> vdst; 338 bits<4> src0_modifiers; 339 bits<9> src0; 340 bits<4> src1_modifiers; 341 bits<9> src1; 342 bits<4> src2_modifiers; 343 bits<9> src2; 344 bits<1> clamp; 345 346 let Inst{7-0} = vdst; 347 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0 348 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1 349 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2 350 351 let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0) 352 let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1) 353 let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2) 354 355 let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, ?); // op_sel_hi(2) 356 357 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 358 359 let Inst{22-16} = op; 360 let Inst{31-23} = 0x1a7; //encoding 361 let Inst{40-32} = !if(P.HasSrc0, src0, 0); 362 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 363 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 364 let Inst{59} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, ?); // op_sel_hi(0) 365 let Inst{60} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, ?); // op_sel_hi(1) 366 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo) 367 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo) 368 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo) 369} 370 371class VOP3Pe_MAI <bits<7> op, VOPProfile P, bit acc_cd = 0> : Enc64 { 372 bits<8> vdst; 373 bits<10> src0; 374 bits<10> src1; 375 bits<9> src2; 376 bits<3> blgp; 377 bits<3> cbsz; 378 bits<4> abid; 379 380 let Inst{7-0} = vdst; 381 382 let Inst{10-8} = !if(P.HasSrc1, cbsz, 0); 383 let Inst{14-11} = !if(P.HasSrc1, abid, 0); 384 385 let Inst{15} = acc_cd; 386 387 let Inst{22-16} = op; 388 let Inst{31-23} = 0x1a7; //encoding 389 let Inst{40-32} = !if(P.HasSrc0, src0{8-0}, 0); 390 let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0); 391 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 392 393 let Inst{59} = !if(P.HasSrc0, src0{9}, 0); // acc(0) 394 let Inst{60} = !if(P.HasSrc1, src1{9}, 0); // acc(1) 395 396 let Inst{63-61} = !if(P.HasSrc1, blgp, 0); 397} 398 399class VOP3Pe_SMFMAC <bits<7> op> : Enc64 { 400 bits<10> vdst; // VGPR or AGPR, but not SGPR. vdst{8} is not encoded in the instruction. 401 bits<10> src0; 402 bits<10> src1; 403 bits<9> idx; 404 bits<3> blgp; 405 bits<3> cbsz; 406 bits<4> abid; 407 408 let blgp = 0; 409 410 let Inst{7-0} = vdst{7-0}; 411 412 let Inst{10-8} = cbsz; 413 let Inst{14-11} = abid; 414 415 let Inst{15} = vdst{9}; // acc(vdst) 416 417 let Inst{22-16} = op; 418 let Inst{31-23} = 0x1a7; // encoding 419 let Inst{40-32} = src0{8-0}; 420 let Inst{49-41} = src1{8-0}; 421 let Inst{58-50} = idx; 422 423 let Inst{59} = src0{9}; // acc(0) 424 let Inst{60} = src1{9}; // acc(1) 425 426 let Inst{63-61} = blgp; 427} 428 429class VOP3Pe_gfx10 <bits<7> op, VOPProfile P> : VOP3Pe<op, P> { 430 let Inst{31-23} = 0x198; //encoding 431} 432 433class VOP3Pe_gfx11<bits<7> op, VOPProfile P> : VOP3Pe_gfx10<op, P>; 434 435class VOP3be_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3be<p> { 436 let Inst{25-17} = op; 437} 438 439class VOP3be_gfx10<bits<10> op, VOPProfile p> : VOP3be<p> { 440 bits<1> clamp; 441 let Inst{15} = !if(p.HasClamp, clamp{0}, 0); 442 let Inst{25-16} = op; 443 let Inst{31-26} = 0x35; 444} 445 446class VOP3be_gfx11<bits<10> op, VOPProfile p> : VOP3be_gfx10<op, p>; 447 448class VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> { 449 bits<1> clamp; 450 let Inst{25-16} = op; 451 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 452} 453 454def SDWA { 455 // sdwa_sel 456 int BYTE_0 = 0; 457 int BYTE_1 = 1; 458 int BYTE_2 = 2; 459 int BYTE_3 = 3; 460 int WORD_0 = 4; 461 int WORD_1 = 5; 462 int DWORD = 6; 463 464 // dst_unused 465 int UNUSED_PAD = 0; 466 int UNUSED_SEXT = 1; 467 int UNUSED_PRESERVE = 2; 468} 469 470class VOP_SDWAe<VOPProfile P> : Enc64 { 471 bits<8> src0; 472 bits<3> src0_sel; 473 bits<2> src0_modifiers; // float: {abs,neg}, int {sext} 474 bits<3> src1_sel; 475 bits<2> src1_modifiers; 476 bits<3> dst_sel; 477 bits<2> dst_unused; 478 bits<1> clamp; 479 480 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 481 let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?); 482 let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?); 483 let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0); 484 let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0); 485 let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0); 486 let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0); 487 let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0); 488 let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0); 489 let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0); 490} 491 492// GFX9 adds two features to SDWA: 493// 1. Add 3 fields to the SDWA microcode word: S0, S1 and OMOD. 494// a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather 495// than VGPRs (at most 1 can be an SGPR); 496// b. OMOD is the standard output modifier (result *2, *4, /2) 497// 2. Add a new version of the SDWA microcode word for VOPC: SDWAB. This 498// replaces OMOD and the dest fields with SD and SDST (SGPR destination) 499// field. 500// a. When SD=1, the SDST is used as the destination for the compare result; 501// b. When SD=0, VCC is used. 502// 503// In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA 504 505// gfx9 SDWA basic encoding 506class VOP_SDWA9e<VOPProfile P> : Enc64 { 507 bits<9> src0; // {src0_sgpr{0}, src0{7-0}} 508 bits<3> src0_sel; 509 bits<2> src0_modifiers; // float: {abs,neg}, int {sext} 510 bits<3> src1_sel; 511 bits<2> src1_modifiers; 512 bits<1> src1_sgpr; 513 514 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 515 let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0); 516 let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0); 517 let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0); 518 let Inst{55} = !if(P.HasSrc0, src0{8}, 0); 519 let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0); 520 let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0); 521 let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0); 522 let Inst{63} = 0; // src1_sgpr - should be specified in subclass 523} 524 525// gfx9 SDWA-A 526class VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> { 527 bits<3> dst_sel; 528 bits<2> dst_unused; 529 bits<1> clamp; 530 bits<2> omod; 531 532 let Inst{42-40} = !if(P.EmitDstSel, dst_sel{2-0}, ?); 533 let Inst{44-43} = !if(P.EmitDstSel, dst_unused{1-0}, ?); 534 let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0); 535 let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0); 536} 537 538// gfx9 SDWA-B 539class VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> { 540 bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}} 541 542 let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, ?); 543 let Inst{47} = !if(P.EmitDst, sdst{7}, 0); 544} 545 546class VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> : 547 InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>, 548 VOP <opName>, 549 SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE> { 550 551 let isPseudo = 1; 552 let isCodeGenOnly = 1; 553 let UseNamedOperandTable = 1; 554 555 string Mnemonic = opName; 556 string AsmOperands = P.AsmSDWA; 557 string AsmOperands9 = P.AsmSDWA9; 558 559 let Size = 8; 560 let mayLoad = 0; 561 let mayStore = 0; 562 let hasSideEffects = 0; 563 564 let VALU = 1; 565 let SDWA = 1; 566 567 let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret); 568 569 let mayRaiseFPException = ReadsModeReg; 570 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 571 572 let SubtargetPredicate = HasSDWA; 573 let AssemblerPredicate = HasSDWA; 574 let AsmVariantName = !if(P.HasExtSDWA, AMDGPUAsmVariants.SDWA, 575 AMDGPUAsmVariants.Disable); 576 let DecoderNamespace = "SDWA"; 577 578 VOPProfile Pfl = P; 579} 580 581class VOP_SDWA_Real <VOP_SDWA_Pseudo ps> : 582 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 583 SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> { 584 585 let VALU = 1; 586 let SDWA = 1; 587 let isPseudo = 0; 588 let isCodeGenOnly = 0; 589 590 let Defs = ps.Defs; 591 let Uses = ps.Uses; 592 let hasSideEffects = ps.hasSideEffects; 593 594 let Constraints = ps.Constraints; 595 let DisableEncoding = ps.DisableEncoding; 596 597 // Copy relevant pseudo op flags 598 let SubtargetPredicate = ps.SubtargetPredicate; 599 let AssemblerPredicate = ps.AssemblerPredicate; 600 let AsmMatchConverter = ps.AsmMatchConverter; 601 let AsmVariantName = ps.AsmVariantName; 602 let UseNamedOperandTable = ps.UseNamedOperandTable; 603 let DecoderNamespace = ps.DecoderNamespace; 604 let Constraints = ps.Constraints; 605 let DisableEncoding = ps.DisableEncoding; 606 let TSFlags = ps.TSFlags; 607 let SchedRW = ps.SchedRW; 608 let mayLoad = ps.mayLoad; 609 let mayStore = ps.mayStore; 610 let TRANS = ps.TRANS; 611} 612 613class Base_VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> : 614 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []> { 615 616 let VALU = 1; 617 let SDWA = 1; 618 let isPseudo = 0; 619 let isCodeGenOnly = 0; 620 621 let Defs = ps.Defs; 622 let Uses = ps.Uses; 623 let hasSideEffects = ps.hasSideEffects; 624 625 let Constraints = ps.Constraints; 626 let DisableEncoding = ps.DisableEncoding; 627 628 let SubtargetPredicate = HasSDWA9; 629 let AssemblerPredicate = HasSDWA9; 630 let AsmVariantName = !if(ps.Pfl.HasExtSDWA9, AMDGPUAsmVariants.SDWA9, 631 AMDGPUAsmVariants.Disable); 632 let DecoderNamespace = "SDWA9"; 633 634 // Copy relevant pseudo op flags 635 let AsmMatchConverter = ps.AsmMatchConverter; 636 let UseNamedOperandTable = ps.UseNamedOperandTable; 637 let Constraints = ps.Constraints; 638 let DisableEncoding = ps.DisableEncoding; 639 let TSFlags = ps.TSFlags; 640 let SchedRW = ps.SchedRW; 641 let mayLoad = ps.mayLoad; 642 let mayStore = ps.mayStore; 643 let TRANS = ps.TRANS; 644} 645 646class VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> : 647 Base_VOP_SDWA9_Real <ps >, 648 SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9>; 649 650class Base_VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : Base_VOP_SDWA9_Real<ps> { 651 let SubtargetPredicate = HasSDWA10; 652 let AssemblerPredicate = HasSDWA10; 653 let DecoderNamespace = "SDWA10"; 654} 655 656class VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : 657 Base_VOP_SDWA10_Real<ps>, SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SDWA10>; 658 659class VOP_DPPe<VOPProfile P, bit IsDPP16=0> : Enc64 { 660 bits<2> src0_modifiers; 661 bits<8> src0; 662 bits<2> src1_modifiers; 663 bits<9> dpp_ctrl; 664 bits<1> bound_ctrl; 665 bits<4> bank_mask; 666 bits<4> row_mask; 667 bit fi; 668 669 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 670 let Inst{48-40} = dpp_ctrl; 671 let Inst{50} = !if(IsDPP16, fi, ?); 672 let Inst{51} = bound_ctrl; 673 let Inst{52} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg 674 let Inst{53} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs 675 let Inst{54} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg 676 let Inst{55} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs 677 let Inst{59-56} = bank_mask; 678 let Inst{63-60} = row_mask; 679} 680 681class VOP3_DPPe_Fields_Base { 682 bits<9> dpp_ctrl; 683 bits<1> bound_ctrl; 684 bits<4> bank_mask; 685 bits<4> row_mask; 686 bit fi; 687} 688class VOP3_DPPe_Fields : VOP3_DPPe_Fields_Base { 689 bits<8> src0; 690} 691 692// Common refers to common between DPP and DPP8 693class VOP3_DPPe_Common_Base<bits<10> op, VOPProfile P> : Enc96 { 694 bits<4> src0_modifiers; 695 bits<3> src1_modifiers; 696 bits<3> src2_modifiers; 697 bits<1> clamp; 698 bits<2> omod; 699 700 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); 701 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); 702 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); 703 // OPSEL must be set such that the low result only uses low inputs, and the high result only uses high inputs. 704 let Inst{11} = !if(P.HasOpSel,!if(P.HasSrc0Mods, src0_modifiers{2}, 0),?); 705 let Inst{12} = !if(P.HasOpSel,!if(P.HasSrc1Mods, src1_modifiers{2}, 0),?); 706 let Inst{13} = !if(P.HasOpSel,!if(P.HasSrc2Mods, src2_modifiers{2}, 0),?); 707 let Inst{14} = !if(P.HasOpSel,!if(P.HasSrc0Mods, src0_modifiers{3}, 0),?); 708 let Inst{15} = !if(P.HasClamp, clamp, 0); 709 let Inst{25-16} = op; 710 let Inst{31-26} = 0x35; 711 712 let Inst{60-59} = !if(P.HasOMod, omod, 0); 713 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 714 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); 715 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); 716} 717 718class VOP3_DPPe_Common<bits<10> op, VOPProfile P> : VOP3_DPPe_Common_Base<op, P> { 719 bits<8> vdst; 720 bits<9> src1; 721 bits<9> src2; 722 723 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0); 724 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 725 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 726} 727 728class VOP3P_DPPe_Common_Base<bits<7> op, VOPProfile P> : Enc96 { 729 bits<4> src0_modifiers; 730 bits<4> src1_modifiers; 731 bits<4> src2_modifiers; 732 bits<1> clamp; 733 734 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0 735 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1 736 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2 737 let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0) 738 let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1) 739 let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2) 740 let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, ?); // op_sel_hi(2) 741 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 742 let Inst{22-16} = op; 743 let Inst{31-23} = 0x198; // encoding 744 let Inst{59} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, ?); // op_sel_hi(0) 745 let Inst{60} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, ?); // op_sel_hi(1) 746 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo) 747 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo) 748 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo) 749} 750 751class VOP3P_DPPe_Common<bits<7> op, VOPProfile P> : VOP3P_DPPe_Common_Base<op, P> { 752 bits<8> vdst; 753 bits<9> src1; 754 bits<9> src2; 755 756 let Inst{7-0} = vdst; 757 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 758 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 759} 760 761class VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[], 762 dag Ins = P.InsDPP, string asmOps = P.AsmDPP> : 763 InstSI <P.OutsDPP, Ins, OpName#asmOps, pattern>, 764 VOP <OpName>, 765 SIMCInstr <OpName#"_dpp", SIEncodingFamily.NONE> { 766 767 let isPseudo = 1; 768 let isCodeGenOnly = 1; 769 770 let mayLoad = 0; 771 let mayStore = 0; 772 let hasSideEffects = 0; 773 let UseNamedOperandTable = 1; 774 775 let VALU = 1; 776 let DPP = 1; 777 let Size = 8; 778 779 let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret); 780 781 let mayRaiseFPException = ReadsModeReg; 782 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 783 let isConvergent = 1; 784 785 string Mnemonic = OpName; 786 string AsmOperands = asmOps; 787 788 let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", ""); 789 let SubtargetPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP); 790 let AssemblerPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP); 791 let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP, 792 AMDGPUAsmVariants.Disable); 793 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", ""); 794 let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, ""); 795 let DecoderNamespace = "DPP"; 796 797 VOPProfile Pfl = P; 798} 799 800class VOP3_DPP_Pseudo <string OpName, VOPProfile P> : 801 VOP_DPP_Pseudo <OpName, P, [], P.InsVOP3DPP, P.AsmVOP3DPP> { 802 let PseudoInstr = OpName#"_e64"#"_dpp"; 803 let OutOperandList = P.OutsVOP3DPP; 804 let Size = 12; 805 let VOP3 = 1; 806 let AsmMatchConverter = "cvtVOP3DPP"; 807 let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP, 808 AMDGPUAsmVariants.Disable); 809} 810 811class VOP_DPP_Real <VOP_DPP_Pseudo ps, int EncodingFamily> : 812 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 813 SIMCInstr <ps.PseudoInstr, EncodingFamily> { 814 815 let VALU = 1; 816 let DPP = 1; 817 let isPseudo = 0; 818 let isCodeGenOnly = 0; 819 820 let Defs = ps.Defs; 821 let Uses = ps.Uses; 822 let hasSideEffects = ps.hasSideEffects; 823 824 let Constraints = ps.Constraints; 825 let DisableEncoding = ps.DisableEncoding; 826 827 // Copy relevant pseudo op flags 828 let isConvergent = ps.isConvergent; 829 let SubtargetPredicate = ps.SubtargetPredicate; 830 let AssemblerPredicate = ps.AssemblerPredicate; 831 let OtherPredicates = ps.OtherPredicates; 832 let AsmMatchConverter = ps.AsmMatchConverter; 833 let AsmVariantName = ps.AsmVariantName; 834 let UseNamedOperandTable = ps.UseNamedOperandTable; 835 let DecoderNamespace = ps.DecoderNamespace; 836 let Constraints = ps.Constraints; 837 let DisableEncoding = ps.DisableEncoding; 838 let TSFlags = ps.TSFlags; 839 let SchedRW = ps.SchedRW; 840 let mayLoad = ps.mayLoad; 841 let mayStore = ps.mayStore; 842 let TRANS = ps.TRANS; 843} 844 845class VOP_DPP_Base <string OpName, VOPProfile P, 846 dag InsDPP, 847 string AsmDPP > : 848 InstSI <P.OutsDPP, InsDPP, OpName#AsmDPP, []> { 849 850 let mayLoad = 0; 851 let mayStore = 0; 852 let hasSideEffects = 0; 853 let UseNamedOperandTable = 1; 854 855 let VALU = 1; 856 let DPP = 1; 857 let Size = 8; 858 859 let AsmMatchConverter = !if(P.HasModifiers, "cvtDPP", ""); 860 let SubtargetPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP); 861 let AssemblerPredicate = !if(P.HasExt64BitDPP, Has64BitDPP, HasDPP); 862 let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP, 863 AMDGPUAsmVariants.Disable); 864 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", ""); 865 let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, ""); 866 let DecoderNamespace = "DPP"; 867} 868 869class VOP_DPP <string OpName, VOPProfile P, bit IsDPP16, 870 dag InsDPP = !if(IsDPP16, P.InsDPP16, P.InsDPP), 871 string AsmDPP = !if(IsDPP16, P.AsmDPP16, P.AsmDPP)> : 872 VOP_DPP_Base<OpName, P, InsDPP, AsmDPP>, VOP_DPPe<P, IsDPP16>; 873 874class VOP3_DPP_Base <string OpName, VOPProfile P, bit IsDPP16, 875 dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP), 876 string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> : 877 VOP_DPP_Base<OpName, P, InsDPP, AsmDPP> { 878 let OutOperandList = P.OutsVOP3DPP; 879 let AsmMatchConverter = "cvtVOP3DPP"; 880 let VOP3 = 1; 881 let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP, 882 AMDGPUAsmVariants.Disable); 883 let Size = 12; 884} 885 886class VOP3_DPP <bits<10> op, string OpName, VOPProfile P, bit IsDPP16, 887 dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP), 888 string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> : 889 VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3_DPPe_Common<op, P>, 890 VOP3_DPPe_Fields { 891 892 let Inst{40-32} = 0xfa; 893 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0); 894 let Inst{80-72} = dpp_ctrl; 895 let Inst{82} = !if(IsDPP16, fi, ?); 896 let Inst{83} = bound_ctrl; 897 898 // Inst{87-84} ignored by hw 899 let Inst{91-88} = bank_mask; 900 let Inst{95-92} = row_mask; 901} 902 903class VOP3P_DPP <bits<7> op, string OpName, VOPProfile P, bit IsDPP16, 904 dag InsDPP = !if(IsDPP16, P.InsVOP3DPP16, P.InsVOP3DPP), 905 string AsmDPP = !if(IsDPP16, P.AsmVOP3DPP16, P.AsmVOP3DPP)> : 906 VOP3_DPP_Base<OpName, P, IsDPP16, InsDPP, AsmDPP>, VOP3P_DPPe_Common<op, P>, 907 VOP3_DPPe_Fields { 908 909 let VOP3P = 1; 910 911 let Inst{40-32} = 0xfa; 912 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0); 913 let Inst{80-72} = dpp_ctrl; 914 let Inst{82} = !if(IsDPP16, fi, ?); 915 let Inst{83} = bound_ctrl; 916 917 // Inst{87-84} ignored by hw 918 let Inst{91-88} = bank_mask; 919 let Inst{95-92} = row_mask; 920} 921 922class VOP_DPP8e<VOPProfile P> : Enc64 { 923 bits<8> src0; 924 bits<24> dpp8; 925 bits<9> fi; 926 927 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 928 let Inst{63-40} = dpp8{23-0}; 929} 930 931class VOP3_DPP8e_Fields { 932 bits<8> src0; 933 bits<24> dpp8; 934 bits<9> fi; 935} 936 937class VOP_DPP8_Base<string OpName, VOPProfile P, dag InsDPP8 = P.InsDPP8, string AsmDPP8 = P.AsmDPP8> : 938 InstSI<P.OutsDPP8, InsDPP8, OpName#AsmDPP8, []> { 939 940 let mayLoad = 0; 941 let mayStore = 0; 942 let hasSideEffects = 0; 943 let UseNamedOperandTable = 1; 944 945 let VALU = 1; 946 let DPP = 1; 947 let Size = 8; 948 949 let AsmMatchConverter = "cvtDPP8"; 950 let SubtargetPredicate = HasDPP8; 951 let AssemblerPredicate = HasDPP8; 952 let AsmVariantName = AMDGPUAsmVariants.DPP; 953 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", ""); 954 let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, ""); 955} 956 957class VOP_DPP8<string OpName, VOPProfile P> : 958 VOP_DPP8_Base<OpName, P>, VOP_DPP8e<P>; 959 960class VOP3_DPP8_Base<string OpName, VOPProfile P> : 961 VOP_DPP8_Base<OpName, P, P.InsVOP3DPP8, P.AsmVOP3DPP8> { 962 let OutOperandList = P.OutsVOP3DPP8; 963 let AsmMatchConverter = "cvtVOP3DPP8"; 964 let AsmVariantName = !if(P.HasExtVOP3DPP, AMDGPUAsmVariants.VOP3_DPP, 965 AMDGPUAsmVariants.Disable); 966 let VOP3 = 1; 967 let Size = 12; 968} 969 970 971class VOP3_DPP8<bits<10> op, string OpName, VOPProfile P> : 972 VOP3_DPP8_Base<OpName, P>, VOP3_DPPe_Common<op, P>, 973 VOP3_DPP8e_Fields { 974 975 let Inst{40-32} = fi; 976 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0); 977 let Inst{95-72} = dpp8{23-0}; 978} 979 980class VOP3P_DPP8<bits<7> op, string OpName, VOPProfile P> : 981 VOP3_DPP8_Base<OpName, P>, VOP3P_DPPe_Common<op, P>, 982 VOP3_DPP8e_Fields { 983 984 let VOP3P = 1; 985 let Inst{40-32} = fi; 986 let Inst{71-64} = !if(P.HasSrc0, src0{7-0}, 0); 987 let Inst{95-72} = dpp8{23-0}; 988} 989 990def DPP8Mode { 991 int FI_0 = 0xE9; 992 int FI_1 = 0xEA; 993} 994 995class getNumNodeArgs<SDPatternOperator Op> { 996 SDNode N = !cast<SDNode>(Op); 997 SDTypeProfile TP = N.TypeProfile; 998 int ret = TP.NumOperands; 999} 1000 1001class getDivergentFrag<SDPatternOperator Op> { 1002 assert !or(!isa<SDNode>(Op), !isa<PatFrags>(Op)), "Expected SDNode or PatFrags"; 1003 1004 int NumSrcArgs = !if(!isa<SDNode>(Op), getNumNodeArgs<Op>.ret, 1005 !size(!cast<PatFrags>(Op).Operands)); 1006 PatFrag ret = PatFrag < 1007 !if(!eq(NumSrcArgs, 1), 1008 (ops node:$src0), 1009 !if(!eq(NumSrcArgs, 2), 1010 (ops node:$src0, node:$src1), 1011 (ops node:$src0, node:$src1, node:$src2))), 1012 !if(!eq(NumSrcArgs, 1), 1013 (Op $src0), 1014 !if(!eq(NumSrcArgs, 2), 1015 (Op $src0, $src1), 1016 (Op $src0, $src1, $src2))), 1017 [{ return N->isDivergent(); }] 1018 >; 1019} 1020 1021class VOPPatGen<SDPatternOperator Op, VOPProfile P> { 1022 PatFrag Operator = getDivergentFrag < Op >.ret; 1023 1024 dag Ins = !foreach(tmp, P.Ins32, !subst(ins, Operator, 1025 !subst(P.Src0RC32, P.Src0VT, 1026 !subst(P.Src1RC32, P.Src1VT, tmp)))); 1027 1028 dag Outs = !foreach(tmp, P.Outs32, !subst(outs, set, 1029 !subst(P.DstRC, P.DstVT, tmp))); 1030 1031 list<dag> ret = [!con(Outs, (set Ins))]; 1032} 1033 1034class DivergentUnaryFrag<SDPatternOperator Op> : PatFrag < 1035 (ops node:$src0), 1036 (Op $src0), 1037 [{ return N->isDivergent(); }]> { 1038 // This check is unnecessary as it's captured by the result register 1039 // bank constraint. 1040 // 1041 // FIXME: Should add a way for the emitter to recognize this is a 1042 // trivially true predicate to eliminate the check. 1043 let GISelPredicateCode = [{return true;}]; 1044} 1045 1046class VOPPatOrNull<SDPatternOperator Op, VOPProfile P> { 1047 list<dag> ret = !if(!ne(P.NeedPatGen,PatGenMode.NoPattern), VOPPatGen<Op, P>.ret, []); 1048} 1049 1050class DivergentFragOrOp<SDPatternOperator Op, VOPProfile P> { 1051 SDPatternOperator ret = !if(!eq(P.NeedPatGen,PatGenMode.Pattern), 1052 !if(!isa<SDNode>(Op), getDivergentFrag<Op>.ret, Op), Op); 1053} 1054 1055class getVSrcOp<ValueType vt> { 1056 RegisterOperand ret = !if(!eq(vt.Size, 32), VSrc_b32, VSrc_b16); 1057} 1058 1059// Class for binary integer operations with the clamp bit set for saturation 1060// TODO: Add sub with negated inline constant pattern. 1061class VOPBinOpClampPat<SDPatternOperator node, Instruction inst, ValueType vt> : 1062 GCNPat<(node vt:$src0, vt:$src1), 1063 (inst getVSrcOp<vt>.ret:$src0, getVSrcOp<vt>.ret:$src1, 1064 DSTCLAMP.ENABLE) 1065>; 1066 1067//===----------------------------------------------------------------------===// 1068// VOP3 Classes 1069//===----------------------------------------------------------------------===// 1070 1071class getVOP3ModPat<VOPProfile P, SDPatternOperator node> { 1072 dag src0 = !if(P.HasOMod, 1073 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod), 1074 (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp)); 1075 1076 list<dag> ret3 = [(set P.DstVT:$vdst, 1077 (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), 1078 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), 1079 (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))]; 1080 1081 list<dag> ret2 = [(set P.DstVT:$vdst, 1082 (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), 1083 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))]; 1084 1085 list<dag> ret1 = [(set P.DstVT:$vdst, 1086 (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))]; 1087 1088 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3, 1089 !if(!eq(P.NumSrcArgs, 2), ret2, 1090 ret1)); 1091} 1092 1093class getVOP3PModPat<VOPProfile P, SDPatternOperator node, bit HasExplicitClamp, 1094 bit IsDOT = 0, 1095 ComplexPattern SrcPat = !if(IsDOT, VOP3PModsDOT, VOP3PMods)> { 1096 dag src0_dag = (P.Src0VT (SrcPat P.Src0VT:$src0, i32:$src0_modifiers)); 1097 dag src1_dag = (P.Src1VT (SrcPat P.Src1VT:$src1, i32:$src1_modifiers)); 1098 dag src2_dag = (P.Src2VT (SrcPat P.Src2VT:$src2, i32:$src2_modifiers)); 1099 dag clamp_dag = (i1 timm:$clamp); 1100 1101 list<dag> ret3 = [(set P.DstVT:$vdst, 1102 !if(HasExplicitClamp, 1103 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag, clamp_dag), 1104 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, src2_dag)))]; 1105 1106 list<dag> ret2 = [(set P.DstVT:$vdst, 1107 !if(HasExplicitClamp, 1108 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag, clamp_dag), 1109 (DivergentFragOrOp<node, P>.ret src0_dag, src1_dag)))]; 1110 1111 list<dag> ret1 = [(set P.DstVT:$vdst, 1112 !if(HasExplicitClamp, 1113 (DivergentFragOrOp<node, P>.ret src0_dag, clamp_dag), 1114 (DivergentFragOrOp<node, P>.ret src0_dag)))]; 1115 1116 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3, 1117 !if(!eq(P.NumSrcArgs, 2), ret2, 1118 ret1)); 1119} 1120 1121class getVOP3OpSelPat<VOPProfile P, SDPatternOperator node> { 1122 list<dag> ret3 = [(set P.DstVT:$vdst, 1123 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)), 1124 (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers)), 1125 (P.Src2VT (VOP3OpSel P.Src2VT:$src2, i32:$src2_modifiers))))]; 1126 1127 list<dag> ret2 = [(set P.DstVT:$vdst, 1128 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers)), 1129 (P.Src1VT (VOP3OpSel P.Src1VT:$src1, i32:$src1_modifiers))))]; 1130 1131 list<dag> ret1 = [(set P.DstVT:$vdst, 1132 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSel P.Src0VT:$src0, i32:$src0_modifiers))))]; 1133 1134 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3, 1135 !if(!eq(P.NumSrcArgs, 2), ret2, 1136 ret1)); 1137} 1138 1139class getVOP3OpSelModPat<VOPProfile P, SDPatternOperator node> { 1140 list<dag> ret3 = [(set P.DstVT:$vdst, 1141 (DivergentFragOrOp<node, P>.ret (P.Src0VT !if(P.HasClamp, (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers), 1142 (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))), 1143 (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers)), 1144 (P.Src2VT (VOP3OpSelMods P.Src2VT:$src2, i32:$src2_modifiers))))]; 1145 1146 list<dag> ret2 = [(set P.DstVT:$vdst, 1147 (DivergentFragOrOp<node, P>.ret !if(P.HasClamp, (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers)), 1148 (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))), 1149 (P.Src1VT (VOP3OpSelMods P.Src1VT:$src1, i32:$src1_modifiers))))]; 1150 1151 list<dag> ret1 = [(set P.DstVT:$vdst, 1152 (DivergentFragOrOp<node, P>.ret (P.Src0VT (VOP3OpSelMods P.Src0VT:$src0, i32:$src0_modifiers))))]; 1153 1154 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3, 1155 !if(!eq(P.NumSrcArgs, 2), ret2, 1156 ret1)); 1157} 1158 1159class getVOP3FromVOP2Pat<VOPProfile P, SDPatternOperator node> { 1160 list<dag> ret = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]; 1161} 1162// In VOP1, we can have clamp and omod even if !HasModifiers 1163class getVOP3Pat<VOPProfile P, SDPatternOperator node> { 1164 dag src0 = 1165 !if(P.HasOMod, 1166 !if(P.HasClamp, 1167 (VOP3Mods0 P.Src0VT:$src0, i1:$clamp, i32:$omod), 1168 (VOP3Mods0 P.Src0VT:$src0, i32:$omod)), // impossible? 1169 !if(P.HasClamp, 1170 (VOP3Mods0 P.Src0VT:$src0, i1:$clamp), 1171 (VOP3Mods0 P.Src0VT:$src0)) 1172 ); 1173 list<dag> ret3 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1, P.Src2VT:$src2))]; 1174 1175 list<dag> ret2 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0), P.Src1VT:$src1))]; 1176 1177 list<dag> ret1 = [(set P.DstVT:$vdst, (DivergentFragOrOp<node, P>.ret (P.Src0VT src0)))]; 1178 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3, 1179 !if(!eq(P.NumSrcArgs, 2), ret2, 1180 ret1)); 1181} 1182 1183class getVOP3ClampPat<VOPProfile P, SDPatternOperator node> { 1184 list<dag> ret3 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i1:$clamp))]; 1185 list<dag> ret2 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, i1:$clamp))]; 1186 list<dag> ret1 = [(set P.DstVT:$vdst, (node P.Src0VT:$src0, i1:$clamp))]; 1187 list<dag> ret = !if(!eq(P.NumSrcArgs, 3), ret3, 1188 !if(!eq(P.NumSrcArgs, 2), ret2, 1189 ret1)); 1190} 1191 1192class getVOP3MAIPat<VOPProfile P, SDPatternOperator node> { 1193 list<dag> ret = !if(!eq(P.Src0VT, P.Src1VT), 1194 // mfma 1195 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, 1196 timm:$cbsz, timm:$abid, timm:$blgp))], 1197 // smfmac 1198 [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, i32:$idx, 1199 timm:$cbsz, timm:$abid))]); 1200} 1201 1202class VOP3Features<bit Clamp, bit OpSel, bit Packed, bit MAI> { 1203 bit HasClamp = Clamp; 1204 bit HasOpSel = OpSel; 1205 bit IsPacked = Packed; 1206 bit IsMAI = MAI; 1207} 1208 1209def VOP3_REGULAR : VOP3Features<0, 0, 0, 0>; 1210def VOP3_CLAMP : VOP3Features<1, 0, 0, 0>; 1211def VOP3_OPSEL : VOP3Features<1, 1, 0, 0>; 1212def VOP3_PACKED : VOP3Features<1, 1, 1, 0>; 1213def VOP3_MAI : VOP3Features<0, 0, 0, 1>; 1214 1215class VOP3_Profile_Base<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOPProfile<P.ArgVT> { 1216 1217 let HasClamp = !if(Features.HasClamp, 1, P.HasClamp); 1218 let HasOpSel = !if(Features.HasOpSel, 1, P.HasOpSel); 1219 let IsMAI = !if(Features.IsMAI, 1, P.IsMAI); 1220 let IsPacked = !if(Features.IsPacked, 1, P.IsPacked); 1221 1222 let HasModifiers = 1223 !if (Features.IsMAI, 0, 1224 !or(Features.IsPacked, Features.HasOpSel, P.HasModifiers)); 1225} 1226 1227class VOP3_Profile<VOPProfile P, VOP3Features Features = VOP3_REGULAR> : VOP3_Profile_Base<P, Features> { 1228 let IsSingle = 1; 1229 1230} 1231 1232// consistently gives instructions a _e64 suffix 1233multiclass VOP3Inst_Pseudo_Wrapper<string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> { 1234 def _e64 : VOP3_Pseudo<opName, P, pattern, VOP3Only>; 1235} 1236 1237class VOP3InstBase<string OpName, VOPProfile P, SDPatternOperator node = null_frag, bit IsVOP2 = 0> : 1238 VOP3_Pseudo<OpName, P, 1239 !if(P.HasOpSel, 1240 !if(P.HasModifiers, 1241 getVOP3OpSelModPat<P, node>.ret, 1242 getVOP3OpSelPat<P, node>.ret), 1243 !if(P.HasModifiers, 1244 getVOP3ModPat<P, node>.ret, 1245 !if(IsVOP2, 1246 getVOP3FromVOP2Pat<P, node>.ret, 1247 !if(P.HasIntClamp, 1248 getVOP3ClampPat<P, node>.ret, 1249 !if (P.IsMAI, 1250 getVOP3MAIPat<P, node>.ret, 1251 getVOP3Pat<P, node>.ret))))), 1252 0, P.HasOpSel> { 1253 1254 let IntClamp = P.HasIntClamp; 1255 let AsmMatchConverter = 1256 !if(P.HasOpSel, 1257 "cvtVOP3OpSel", 1258 !if(!or(P.HasModifiers, P.HasOMod, P.HasIntClamp), 1259 "cvtVOP3", 1260 "")); 1261} 1262 1263multiclass VOP3Inst<string OpName, VOPProfile P, SDPatternOperator node = null_frag> { 1264 def _e64 : VOP3InstBase<OpName, P, node>; 1265 let SubtargetPredicate = isGFX11Plus in { 1266 foreach _ = BoolToList<P.HasExtVOP3DPP>.ret in 1267 def _e64_dpp : VOP3_DPP_Pseudo <OpName, P>; 1268 } // end SubtargetPredicate = isGFX11Plus 1269} 1270 1271//===----------------------------------------------------------------------===// 1272// VOP3 DPP 1273//===----------------------------------------------------------------------===// 1274 1275class Base_VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, string opName = ps.OpName> 1276 : VOP3_DPP<op, opName, ps.Pfl, 1> { 1277 let VOP3_OPSEL = ps.Pfl.HasOpSel; 1278 let IsDOT = ps.IsDOT; 1279 let hasSideEffects = ps.hasSideEffects; 1280 let Defs = ps.Defs; 1281 let SchedRW = ps.SchedRW; 1282 let Uses = ps.Uses; 1283 let AssemblerPredicate = HasDPP16; 1284 let SubtargetPredicate = HasDPP16; 1285 let OtherPredicates = ps.OtherPredicates; 1286} 1287 1288class VOP3_DPP16<bits<10> op, VOP_DPP_Pseudo ps, int subtarget, 1289 string opName = ps.OpName> 1290 : Base_VOP3_DPP16<op, ps, opName>, SIMCInstr<ps.PseudoInstr, subtarget>; 1291 1292class Base_VOP3_DPP8<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName> 1293 : VOP3_DPP8<op, opName, ps.Pfl> { 1294 let VOP3_OPSEL = ps.Pfl.HasOpSel; 1295 let IsDOT = ps.IsDOT; 1296 let hasSideEffects = ps.hasSideEffects; 1297 let Defs = ps.Defs; 1298 let SchedRW = ps.SchedRW; 1299 let Uses = ps.Uses; 1300 1301 let OtherPredicates = ps.OtherPredicates; 1302} 1303 1304class Base_VOP3b_DPP16<bits<10> op, VOP_DPP_Pseudo ps, 1305 string opName = ps.OpName> 1306 : Base_VOP3_DPP16<op, ps, opName> { 1307 bits<7> sdst; 1308 let Inst{14 - 8} = sdst; 1309} 1310 1311class VOP3b_DPP8_Base<bits<10> op, VOP_Pseudo ps, string opName = ps.OpName> 1312 : Base_VOP3_DPP8<op, ps, opName> { 1313 bits<7> sdst; 1314 let Inst{14 - 8} = sdst; 1315} 1316 1317//===----------------------------------------------------------------------===// 1318// VOP3 GFX11 1319//===----------------------------------------------------------------------===// 1320 1321let AssemblerPredicate = isGFX11Only, 1322 DecoderNamespace = "GFX11" in { 1323 multiclass VOP3_Real_Base_gfx11<bits<10> op, string opName = NAME, 1324 bit isSingle = 0> { 1325 defvar ps = !cast<VOP_Pseudo>(opName#"_e64"); 1326 let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in { 1327 foreach _ = BoolToList<ps.Pfl.HasOpSel>.ret in 1328 def _e64_gfx11 : 1329 VOP3_Real<ps, SIEncodingFamily.GFX11>, 1330 VOP3OpSel_gfx11<op, ps.Pfl>; 1331 foreach _ = BoolToList<!not(ps.Pfl.HasOpSel)>.ret in 1332 def _e64_gfx11 : 1333 VOP3_Real<ps, SIEncodingFamily.GFX11>, 1334 VOP3e_gfx11<op, ps.Pfl>; 1335 } 1336 } 1337 multiclass VOP3Dot_Real_Base_gfx11<bits<10> op, string opName = NAME, 1338 bit isSingle = 0> { 1339 defvar ps = !cast<VOP_Pseudo>(opName#"_e64"); 1340 let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in { 1341 def _e64_gfx11 : 1342 VOP3_Real<ps, SIEncodingFamily.GFX11>, 1343 VOP3DotOpSel_gfx11<op, ps.Pfl>; 1344 } 1345 } 1346 multiclass VOP3_Real_with_name_gfx11<bits<10> op, string opName, 1347 string asmName, bit isSingle = 0> { 1348 defvar ps = !cast<VOP_Pseudo>(opName#"_e64"); 1349 let AsmString = asmName # ps.AsmOperands, 1350 IsSingle = !or(isSingle, ps.Pfl.IsSingle) in { 1351 foreach _ = BoolToList<ps.Pfl.HasOpSel>.ret in 1352 def _e64_gfx11 : 1353 VOP3_Real<ps, SIEncodingFamily.GFX11>, 1354 VOP3OpSel_gfx11<op, ps.Pfl>, 1355 MnemonicAlias<ps.Mnemonic, asmName>, Requires<[isGFX11Plus]>; 1356 foreach _ = BoolToList<!not(ps.Pfl.HasOpSel)>.ret in 1357 def _e64_gfx11 : 1358 VOP3_Real<ps, SIEncodingFamily.GFX11>, 1359 VOP3e_gfx11<op, ps.Pfl>, 1360 MnemonicAlias<ps.Mnemonic, asmName>, Requires<[isGFX11Plus]>; 1361 } 1362 } 1363 // for READLANE/WRITELANE 1364 multiclass VOP3_Real_No_Suffix_gfx11<bits<10> op, string opName = NAME> { 1365 defvar ps = !cast<VOP_Pseudo>(opName); 1366 def _e64_gfx11 : 1367 VOP3_Real<ps, SIEncodingFamily.GFX11>, 1368 VOP3e_gfx11<op, ps.Pfl>; 1369 } 1370 multiclass VOP3_Real_dpp_Base_gfx11<bits<10> op, string opName = NAME> { 1371 def _e64_dpp_gfx11 : VOP3_DPP16<op, !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp"), SIEncodingFamily.GFX11> { 1372 let DecoderNamespace = "DPPGFX11"; 1373 } 1374 } 1375 1376 multiclass VOP3Dot_Real_dpp_Base_gfx11<bits<10> op, string opName = NAME> { 1377 def _e64_dpp_gfx11 : VOP3_DPP16<op, !cast<VOP_DPP_Pseudo>(opName#"_e64"#"_dpp"), SIEncodingFamily.GFX11> { 1378 let Inst{11} = ?; 1379 let Inst{12} = ?; 1380 let DecoderNamespace = "DPPGFX11"; 1381 } 1382 } 1383 1384 multiclass VOP3_Real_dpp_with_name_gfx11<bits<10> op, string opName, 1385 string asmName> { 1386 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64"); 1387 let AsmString = asmName # ps.Pfl.AsmVOP3DPP16, DecoderNamespace = "DPPGFX11" in { 1388 defm NAME : VOP3_Real_dpp_Base_gfx11<op, opName>; 1389 } 1390 } 1391 multiclass VOP3_Real_dpp8_Base_gfx11<bits<10> op, string opName = NAME> { 1392 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64"); 1393 def _e64_dpp8_gfx11 : Base_VOP3_DPP8<op, ps> { 1394 let DecoderNamespace = "DPP8GFX11"; 1395 } 1396 } 1397 1398 multiclass VOP3Dot_Real_dpp8_Base_gfx11<bits<10> op, string opName = NAME> { 1399 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64"); 1400 def _e64_dpp8_gfx11 : Base_VOP3_DPP8<op, ps> { 1401 let Inst{11} = ?; 1402 let Inst{12} = ?; 1403 let DecoderNamespace = "DPP8GFX11"; 1404 } 1405 } 1406 1407 multiclass VOP3_Real_dpp8_with_name_gfx11<bits<10> op, string opName, 1408 string asmName> { 1409 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64"); 1410 let AsmString = asmName # ps.Pfl.AsmVOP3DPP8, DecoderNamespace = "DPP8GFX11" in { 1411 defm NAME : VOP3_Real_dpp8_Base_gfx11<op, opName>; 1412 } 1413 } 1414 multiclass VOP3be_Real_gfx11<bits<10> op, string opName, string asmName, 1415 bit isSingle = 0> { 1416 defvar ps = !cast<VOP3_Pseudo>(opName#"_e64"); 1417 let IsSingle = !or(isSingle, ps.Pfl.IsSingle) in 1418 def _e64_gfx11 : 1419 VOP3_Real<ps, SIEncodingFamily.GFX11, asmName>, 1420 VOP3be_gfx11<op, ps.Pfl> ; 1421 } 1422 multiclass VOP3be_Real_dpp_gfx11<bits<10> op, string opName, string asmName> { 1423 defvar ps = !cast<VOP3_Pseudo>(opName #"_e64"); 1424 defvar dpp_ps = !cast<VOP_DPP_Pseudo>(opName #"_e64" #"_dpp"); 1425 def _e64_dpp_gfx11 : Base_VOP3b_DPP16<op, dpp_ps, asmName>, 1426 SIMCInstr<dpp_ps.PseudoInstr, SIEncodingFamily.GFX11> { 1427 let DecoderNamespace = "DPPGFX11"; 1428 } 1429 } 1430 multiclass VOP3be_Real_dpp8_gfx11<bits<10> op, string opName, string asmName> { 1431 defvar ps = !cast<VOP3_Pseudo>(opName #"_e64"); 1432 def _e64_dpp8_gfx11 : VOP3b_DPP8_Base<op, ps, asmName> { 1433 let DecoderNamespace = "DPP8GFX11"; 1434 } 1435 } 1436} // End AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11" 1437 1438// VOP1 and VOP2 depend on these triple defs 1439multiclass VOP3_Realtriple_gfx11<bits<10> op, 1440 bit isSingle = 0, string opName = NAME> : 1441 VOP3_Real_Base_gfx11<op, opName, isSingle>, 1442 VOP3_Real_dpp_Base_gfx11<op, opName>, 1443 VOP3_Real_dpp8_Base_gfx11<op, opName>; 1444 1445multiclass VOP3Dot_Realtriple_gfx11<bits<10> op, 1446 bit isSingle = 0, string opName = NAME> : 1447 VOP3Dot_Real_Base_gfx11<op, opName, isSingle>, 1448 VOP3Dot_Real_dpp_Base_gfx11<op, opName>, 1449 VOP3Dot_Real_dpp8_Base_gfx11<op, opName>; 1450 1451multiclass VOP3Only_Realtriple_gfx11<bits<10> op> : 1452 VOP3_Realtriple_gfx11<op, 1>; 1453 1454multiclass VOP3_Realtriple_with_name_gfx11<bits<10> op, string opName, 1455 string asmName, bit isSingle = 0> : 1456 VOP3_Real_with_name_gfx11<op, opName, asmName, isSingle>, 1457 VOP3_Real_dpp_with_name_gfx11<op, opName, asmName>, 1458 VOP3_Real_dpp8_with_name_gfx11<op, opName, asmName>; 1459 1460multiclass VOP3Only_Realtriple_with_name_gfx11<bits<10> op, string opName, 1461 string asmName> : 1462 VOP3_Realtriple_with_name_gfx11<op, opName, asmName, 1>; 1463 1464multiclass VOP3be_Realtriple_gfx11< 1465 bits<10> op, bit isSingle = 0, string opName = NAME, 1466 string asmName = !cast<VOP_Pseudo>(opName#"_e64").Mnemonic> : 1467 VOP3be_Real_gfx11<op, opName, asmName, isSingle>, 1468 VOP3be_Real_dpp_gfx11<op, opName, asmName>, 1469 VOP3be_Real_dpp8_gfx11<op, opName, asmName>; 1470 1471multiclass VOP3beOnly_Realtriple_gfx11<bits<10> op> : 1472 VOP3be_Realtriple_gfx11<op, 1>; 1473 1474include "VOPCInstructions.td" 1475include "VOP1Instructions.td" 1476include "VOP2Instructions.td" 1477include "VOP3Instructions.td" 1478include "VOP3PInstructions.td" 1479include "VOPDInstructions.td" 1480 1481 1482class VOPInfoTable <string Format> : GenericTable { 1483 let FilterClass = Format # "_Real"; 1484 let CppTypeName = "VOPInfo"; 1485 let Fields = ["Opcode", "IsSingle"]; 1486 1487 let PrimaryKey = ["Opcode"]; 1488 let PrimaryKeyName = "get" # Format # "OpcodeHelper"; 1489} 1490 1491def VOP1InfoTable : VOPInfoTable<"VOP1">; 1492def VOP2InfoTable : VOPInfoTable<"VOP2">; 1493def VOP3InfoTable : VOPInfoTable<"VOP3">; 1494 1495class VOPC64Table <string Format> : GenericTable { 1496 let FilterClass = "VOPC64_" # Format # "_Base"; 1497 let CppTypeName = "VOPC64DPPInfo"; 1498 let Fields = ["Opcode"]; 1499 1500 let PrimaryKey = ["Opcode"]; 1501 let PrimaryKeyName = "isVOPC64" # Format # "OpcodeHelper"; 1502} 1503 1504def VOPC64DPPTable : VOPC64Table<"DPP">; 1505def VOPC64DPP8Table : VOPC64Table<"DPP8">; 1506