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 ReadsModeReg; 12 bit mayRaiseFPException; 13 bit isCommutable; 14 bit isConvertibleToThreeAddress; 15 bit isMoveImm; 16 bit isReMaterializable; 17 bit isAsCheapAsAMove; 18 bit VOPAsmPrefer32Bit; 19 bit FPDPRounding; 20 Predicate SubtargetPredicate; 21 string Constraints; 22 string DisableEncoding; 23 list<SchedReadWrite> SchedRW; 24 list<Register> Uses; 25 list<Register> Defs; 26} 27 28class VOP <string opName> { 29 string OpName = opName; 30} 31 32class VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> : 33 InstSI <outs, ins, asm, pattern> { 34 35 let mayLoad = 0; 36 let mayStore = 0; 37 let hasSideEffects = 0; 38 let UseNamedOperandTable = 1; 39 let VALU = 1; 40 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 41} 42 43class VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins, 44 string asm, list<dag> pattern> : 45 InstSI <outs, ins, asm, pattern>, 46 VOP <opName>, 47 SIMCInstr <opName#suffix, SIEncodingFamily.NONE> { 48 let isPseudo = 1; 49 let isCodeGenOnly = 1; 50 let UseNamedOperandTable = 1; 51 52 string Mnemonic = opName; 53 VOPProfile Pfl = P; 54 55 string AsmOperands; 56} 57 58class VOP3Common <dag outs, dag ins, string asm = "", 59 list<dag> pattern = [], bit HasMods = 0, 60 bit VOP3Only = 0> : 61 VOPAnyCommon <outs, ins, asm, pattern> { 62 63 // Using complex patterns gives VOP3 patterns a very high complexity rating, 64 // but standalone patterns are almost always preferred, so we need to adjust the 65 // priority lower. The goal is to use a high number to reduce complexity to 66 // zero (or less than zero). 67 let AddedComplexity = -1000; 68 69 let VOP3 = 1; 70 71 let AsmVariantName = AMDGPUAsmVariants.VOP3; 72 let AsmMatchConverter = !if(!eq(HasMods,1), "cvtVOP3", ""); 73 74 let isCodeGenOnly = 0; 75 76 int Size = 8; 77 78 // Because SGPRs may be allowed if there are multiple operands, we 79 // need a post-isel hook to insert copies in order to avoid 80 // violating constant bus requirements. 81 let hasPostISelHook = 1; 82} 83 84class VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [], 85 bit VOP3Only = 0, bit isVOP3P = 0, bit isVop3OpSel = 0> : 86 VOP_Pseudo <opName, "_e64", P, P.Outs64, 87 !if(isVop3OpSel, 88 P.InsVOP3OpSel, 89 !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)), 90 "", pattern> { 91 92 let VOP3_OPSEL = isVop3OpSel; 93 let IsPacked = P.IsPacked; 94 let IsMAI = P.IsMAI; 95 96 let AsmOperands = !if(isVop3OpSel, 97 P.AsmVOP3OpSel, 98 !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64)); 99 100 let Size = 8; 101 let mayLoad = 0; 102 let mayStore = 0; 103 let hasSideEffects = 0; 104 105 // Because SGPRs may be allowed if there are multiple operands, we 106 // need a post-isel hook to insert copies in order to avoid 107 // violating constant bus requirements. 108 let hasPostISelHook = 1; 109 110 // Using complex patterns gives VOP3 patterns a very high complexity rating, 111 // but standalone patterns are almost always preferred, so we need to adjust the 112 // priority lower. The goal is to use a high number to reduce complexity to 113 // zero (or less than zero). 114 let AddedComplexity = -1000; 115 116 let VOP3 = 1; 117 let VALU = 1; 118 let FPClamp = P.HasFPClamp; 119 let IntClamp = P.HasIntClamp; 120 let ClampLo = P.HasClampLo; 121 let ClampHi = P.HasClampHi; 122 123 let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret); 124 125 let mayRaiseFPException = ReadsModeReg; 126 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 127 128 let AsmVariantName = AMDGPUAsmVariants.VOP3; 129 let AsmMatchConverter = 130 !if(isVOP3P, 131 "cvtVOP3P", 132 !if(!or(P.HasModifiers, !or(P.HasOMod, P.HasIntClamp)), 133 "cvtVOP3", 134 "")); 135} 136 137class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> : 138 VOP3_Pseudo<opName, P, pattern, 1, 1> { 139 let VOP3P = 1; 140} 141 142class VOP3_Real <VOP_Pseudo ps, int EncodingFamily> : 143 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 144 SIMCInstr <ps.PseudoInstr, EncodingFamily> { 145 146 let isPseudo = 0; 147 let isCodeGenOnly = 0; 148 let UseNamedOperandTable = 1; 149 150 let Constraints = ps.Constraints; 151 let DisableEncoding = ps.DisableEncoding; 152 153 // copy relevant pseudo op flags 154 let SubtargetPredicate = ps.SubtargetPredicate; 155 let OtherPredicates = ps.OtherPredicates; 156 let AsmMatchConverter = ps.AsmMatchConverter; 157 let AsmVariantName = ps.AsmVariantName; 158 let Constraints = ps.Constraints; 159 let DisableEncoding = ps.DisableEncoding; 160 let TSFlags = ps.TSFlags; 161 let UseNamedOperandTable = ps.UseNamedOperandTable; 162 let Uses = ps.Uses; 163 let Defs = ps.Defs; 164 165 VOPProfile Pfl = ps.Pfl; 166} 167 168// XXX - Is there any reason to distinguish this from regular VOP3 169// here? 170class VOP3P_Real<VOP_Pseudo ps, int EncodingFamily> : 171 VOP3_Real<ps, EncodingFamily>; 172 173class VOP3a<VOPProfile P> : Enc64 { 174 bits<4> src0_modifiers; 175 bits<9> src0; 176 bits<3> src1_modifiers; 177 bits<9> src1; 178 bits<3> src2_modifiers; 179 bits<9> src2; 180 bits<1> clamp; 181 bits<2> omod; 182 183 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); 184 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); 185 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); 186 187 let Inst{31-26} = 0x34; //encoding 188 let Inst{40-32} = !if(P.HasSrc0, src0, 0); 189 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 190 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 191 let Inst{60-59} = !if(P.HasOMod, omod, 0); 192 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 193 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); 194 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); 195} 196 197class VOP3a_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a<p> { 198 let Inst{11} = !if(p.HasClamp, clamp{0}, 0); 199 let Inst{25-17} = op; 200} 201 202class VOP3a_gfx10<bits<10> op, VOPProfile p> : VOP3a<p> { 203 let Inst{15} = !if(p.HasClamp, clamp{0}, 0); 204 let Inst{25-16} = op; 205 let Inst{31-26} = 0x35; 206} 207 208class VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> { 209 let Inst{25-16} = op; 210 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 211} 212 213class VOP3e_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3a_gfx6_gfx7<op, p> { 214 bits<8> vdst; 215 let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0); 216} 217 218class VOP3e_gfx10<bits<10> op, VOPProfile p> : VOP3a_gfx10<op, p> { 219 bits<8> vdst; 220 let Inst{7-0} = !if(p.EmitDst, vdst{7-0}, 0); 221} 222 223class VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> { 224 bits<8> vdst; 225 let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0); 226} 227 228class VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> { 229 let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0); 230 let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0); 231 let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0); 232 let Inst{14} = !if(P.HasDst, src0_modifiers{3}, 0); 233} 234 235class VOP3OpSel_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> { 236 let Inst{11} = !if(p.HasSrc0, src0_modifiers{2}, 0); 237 let Inst{12} = !if(p.HasSrc1, src1_modifiers{2}, 0); 238 let Inst{13} = !if(p.HasSrc2, src2_modifiers{2}, 0); 239 let Inst{14} = !if(p.HasDst, src0_modifiers{3}, 0); 240} 241 242// NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa 243class VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> { 244 bits<2> attrchan; 245 bits<6> attr; 246 bits<1> high; 247 248 let Inst{8} = 0; // No modifiers for src0 249 let Inst{61} = 0; 250 251 let Inst{9} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); 252 let Inst{62} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 253 254 let Inst{37-32} = attr; 255 let Inst{39-38} = attrchan; 256 let Inst{40} = !if(P.HasHigh, high, 0); 257 258 let Inst{49-41} = src0; 259} 260 261class VOP3Interp_gfx10<bits<10> op, VOPProfile p> : VOP3e_gfx10<op, p> { 262 bits<6> attr; 263 bits<2> attrchan; 264 bits<1> high; 265 266 let Inst{8} = 0; 267 let Inst{9} = !if(p.HasSrc0Mods, src0_modifiers{1}, 0); 268 let Inst{37-32} = attr; 269 let Inst{39-38} = attrchan; 270 let Inst{40} = !if(p.HasHigh, high, 0); 271 let Inst{49-41} = src0; 272 let Inst{61} = 0; 273 let Inst{62} = !if(p.HasSrc0Mods, src0_modifiers{0}, 0); 274} 275 276class VOP3be <VOPProfile P> : Enc64 { 277 bits<8> vdst; 278 bits<2> src0_modifiers; 279 bits<9> src0; 280 bits<2> src1_modifiers; 281 bits<9> src1; 282 bits<2> src2_modifiers; 283 bits<9> src2; 284 bits<7> sdst; 285 bits<2> omod; 286 287 let Inst{7-0} = vdst; 288 let Inst{14-8} = sdst; 289 let Inst{31-26} = 0x34; //encoding 290 let Inst{40-32} = !if(P.HasSrc0, src0, 0); 291 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 292 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 293 let Inst{60-59} = !if(P.HasOMod, omod, 0); 294 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); 295 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); 296 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); 297} 298 299class VOP3Pe <bits<10> op, VOPProfile P> : Enc64 { 300 bits<8> vdst; 301 // neg, neg_hi, op_sel put in srcN_modifiers 302 bits<4> src0_modifiers; 303 bits<9> src0; 304 bits<4> src1_modifiers; 305 bits<9> src1; 306 bits<4> src2_modifiers; 307 bits<9> src2; 308 bits<1> clamp; 309 310 let Inst{7-0} = vdst; 311 let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0 312 let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1 313 let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2 314 315 let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0) 316 let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1) 317 let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2) 318 319 let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, 0); // op_sel_hi(2) 320 321 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 322 323 let Inst{25-16} = op; 324 let Inst{31-26} = 0x34; //encoding 325 let Inst{40-32} = !if(P.HasSrc0, src0, 0); 326 let Inst{49-41} = !if(P.HasSrc1, src1, 0); 327 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 328 let Inst{59} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, 0); // op_sel_hi(0) 329 let Inst{60} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, 0); // op_sel_hi(1) 330 let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo) 331 let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo) 332 let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo) 333} 334 335class VOP3Pe_MAI <bits<10> op, VOPProfile P> : Enc64 { 336 bits<8> vdst; 337 bits<10> src0; 338 bits<10> src1; 339 bits<9> src2; 340 bits<3> blgp; 341 bits<3> cbsz; 342 bits<4> abid; 343 bits<1> clamp; 344 345 let Inst{7-0} = vdst; 346 347 let Inst{10-8} = !if(P.HasSrc1, cbsz, 0); 348 let Inst{14-11} = !if(P.HasSrc1, abid, 0); 349 350 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 351 352 let Inst{25-16} = op; 353 let Inst{31-26} = 0x34; //encoding 354 let Inst{40-32} = !if(P.HasSrc0, src0{8-0}, 0); 355 let Inst{49-41} = !if(P.HasSrc1, src1{8-0}, 0); 356 let Inst{58-50} = !if(P.HasSrc2, src2, 0); 357 358 let Inst{59} = !if(P.HasSrc0, src0{9}, 0); // acc(0) 359 let Inst{60} = !if(P.HasSrc1, src1{9}, 0); // acc(1) 360 361 let Inst{63-61} = !if(P.HasSrc1, blgp, 0); 362} 363 364 365class VOP3Pe_gfx10 <bits<10> op, VOPProfile P> : VOP3Pe<op, P> { 366 let Inst{31-26} = 0x33; //encoding 367} 368 369class VOP3be_gfx6_gfx7<bits<9> op, VOPProfile p> : VOP3be<p> { 370 let Inst{25-17} = op; 371} 372 373class VOP3be_gfx10<bits<10> op, VOPProfile p> : VOP3be<p> { 374 bits<1> clamp; 375 let Inst{15} = !if(p.HasClamp, clamp{0}, 0); 376 let Inst{25-16} = op; 377 let Inst{31-26} = 0x35; 378} 379 380class VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> { 381 bits<1> clamp; 382 let Inst{25-16} = op; 383 let Inst{15} = !if(P.HasClamp, clamp{0}, 0); 384} 385 386def SDWA { 387 // sdwa_sel 388 int BYTE_0 = 0; 389 int BYTE_1 = 1; 390 int BYTE_2 = 2; 391 int BYTE_3 = 3; 392 int WORD_0 = 4; 393 int WORD_1 = 5; 394 int DWORD = 6; 395 396 // dst_unused 397 int UNUSED_PAD = 0; 398 int UNUSED_SEXT = 1; 399 int UNUSED_PRESERVE = 2; 400} 401 402class VOP_SDWAe<VOPProfile P> : Enc64 { 403 bits<8> src0; 404 bits<3> src0_sel; 405 bits<2> src0_modifiers; // float: {abs,neg}, int {sext} 406 bits<3> src1_sel; 407 bits<2> src1_modifiers; 408 bits<3> dst_sel; 409 bits<2> dst_unused; 410 bits<1> clamp; 411 412 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 413 let Inst{42-40} = !if(P.EmitDst, dst_sel{2-0}, 0); 414 let Inst{44-43} = !if(P.EmitDst, dst_unused{1-0}, 0); 415 let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0); 416 let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0); 417 let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0); 418 let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0); 419 let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0); 420 let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0); 421 let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0); 422} 423 424// GFX9 adds two features to SDWA: 425// 1. Add 3 fields to the SDWA microcode word: S0, S1 and OMOD. 426// a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather 427// than VGPRs (at most 1 can be an SGPR); 428// b. OMOD is the standard output modifier (result *2, *4, /2) 429// 2. Add a new version of the SDWA microcode word for VOPC: SDWAB. This 430// replaces OMOD and the dest fields with SD and SDST (SGPR destination) 431// field. 432// a. When SD=1, the SDST is used as the destination for the compare result; 433// b. When SD=0, VCC is used. 434// 435// In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA 436 437// gfx9 SDWA basic encoding 438class VOP_SDWA9e<VOPProfile P> : Enc64 { 439 bits<9> src0; // {src0_sgpr{0}, src0{7-0}} 440 bits<3> src0_sel; 441 bits<2> src0_modifiers; // float: {abs,neg}, int {sext} 442 bits<3> src1_sel; 443 bits<2> src1_modifiers; 444 bits<1> src1_sgpr; 445 446 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 447 let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0); 448 let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0); 449 let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0); 450 let Inst{55} = !if(P.HasSrc0, src0{8}, 0); 451 let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0); 452 let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0); 453 let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0); 454 let Inst{63} = 0; // src1_sgpr - should be specified in subclass 455} 456 457// gfx9 SDWA-A 458class VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> { 459 bits<3> dst_sel; 460 bits<2> dst_unused; 461 bits<1> clamp; 462 bits<2> omod; 463 464 let Inst{42-40} = !if(P.EmitDst, dst_sel{2-0}, 0); 465 let Inst{44-43} = !if(P.EmitDst, dst_unused{1-0}, 0); 466 let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0); 467 let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0); 468} 469 470// gfx9 SDWA-B 471class VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> { 472 bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}} 473 474 let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, ?); 475 let Inst{47} = !if(P.EmitDst, sdst{7}, 0); 476} 477 478class VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> : 479 InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>, 480 VOP <opName>, 481 SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE> { 482 483 let isPseudo = 1; 484 let isCodeGenOnly = 1; 485 let UseNamedOperandTable = 1; 486 487 string Mnemonic = opName; 488 string AsmOperands = P.AsmSDWA; 489 string AsmOperands9 = P.AsmSDWA9; 490 491 let Size = 8; 492 let mayLoad = 0; 493 let mayStore = 0; 494 let hasSideEffects = 0; 495 496 let VALU = 1; 497 let SDWA = 1; 498 499 let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret); 500 501 let mayRaiseFPException = ReadsModeReg; 502 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 503 504 let SubtargetPredicate = HasSDWA; 505 let AssemblerPredicate = HasSDWA; 506 let AsmVariantName = !if(P.HasExtSDWA, AMDGPUAsmVariants.SDWA, 507 AMDGPUAsmVariants.Disable); 508 let DecoderNamespace = "SDWA"; 509 510 VOPProfile Pfl = P; 511} 512 513class VOP_SDWA_Real <VOP_SDWA_Pseudo ps> : 514 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 515 SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> { 516 517 let isPseudo = 0; 518 let isCodeGenOnly = 0; 519 520 let Defs = ps.Defs; 521 let Uses = ps.Uses; 522 let SchedRW = ps.SchedRW; 523 let hasSideEffects = ps.hasSideEffects; 524 525 let Constraints = ps.Constraints; 526 let DisableEncoding = ps.DisableEncoding; 527 528 // Copy relevant pseudo op flags 529 let SubtargetPredicate = ps.SubtargetPredicate; 530 let AssemblerPredicate = ps.AssemblerPredicate; 531 let AsmMatchConverter = ps.AsmMatchConverter; 532 let AsmVariantName = ps.AsmVariantName; 533 let UseNamedOperandTable = ps.UseNamedOperandTable; 534 let DecoderNamespace = ps.DecoderNamespace; 535 let Constraints = ps.Constraints; 536 let DisableEncoding = ps.DisableEncoding; 537 let TSFlags = ps.TSFlags; 538} 539 540class Base_VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> : 541 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []> { 542 543 let isPseudo = 0; 544 let isCodeGenOnly = 0; 545 546 let Defs = ps.Defs; 547 let Uses = ps.Uses; 548 let SchedRW = ps.SchedRW; 549 let hasSideEffects = ps.hasSideEffects; 550 551 let Constraints = ps.Constraints; 552 let DisableEncoding = ps.DisableEncoding; 553 554 let SubtargetPredicate = HasSDWA9; 555 let AssemblerPredicate = HasSDWA9; 556 let AsmVariantName = !if(ps.Pfl.HasExtSDWA9, AMDGPUAsmVariants.SDWA9, 557 AMDGPUAsmVariants.Disable); 558 let DecoderNamespace = "SDWA9"; 559 560 // Copy relevant pseudo op flags 561 let AsmMatchConverter = ps.AsmMatchConverter; 562 let UseNamedOperandTable = ps.UseNamedOperandTable; 563 let Constraints = ps.Constraints; 564 let DisableEncoding = ps.DisableEncoding; 565 let TSFlags = ps.TSFlags; 566} 567 568class VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> : 569 Base_VOP_SDWA9_Real <ps >, 570 SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9>; 571 572class Base_VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : Base_VOP_SDWA9_Real<ps> { 573 let SubtargetPredicate = HasSDWA10; 574 let AssemblerPredicate = HasSDWA10; 575 let DecoderNamespace = "SDWA10"; 576} 577 578class VOP_SDWA10_Real<VOP_SDWA_Pseudo ps> : 579 Base_VOP_SDWA10_Real<ps>, SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SDWA10>; 580 581class VOP_DPPe<VOPProfile P, bit IsDPP16=0> : Enc64 { 582 bits<2> src0_modifiers; 583 bits<8> src0; 584 bits<2> src1_modifiers; 585 bits<9> dpp_ctrl; 586 bits<1> bound_ctrl; 587 bits<4> bank_mask; 588 bits<4> row_mask; 589 bit fi; 590 591 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 592 let Inst{48-40} = dpp_ctrl; 593 let Inst{50} = !if(IsDPP16, fi, ?); 594 let Inst{51} = bound_ctrl; 595 let Inst{52} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg 596 let Inst{53} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs 597 let Inst{54} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg 598 let Inst{55} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs 599 let Inst{59-56} = bank_mask; 600 let Inst{63-60} = row_mask; 601} 602 603class VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> : 604 InstSI <P.OutsDPP, P.InsDPP, OpName#P.AsmDPP, pattern>, 605 VOP <OpName>, 606 SIMCInstr <OpName#"_dpp", SIEncodingFamily.NONE> { 607 608 let isPseudo = 1; 609 let isCodeGenOnly = 1; 610 611 let mayLoad = 0; 612 let mayStore = 0; 613 let hasSideEffects = 0; 614 let UseNamedOperandTable = 1; 615 616 let VALU = 1; 617 let DPP = 1; 618 let Size = 8; 619 620 let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret); 621 622 let mayRaiseFPException = ReadsModeReg; 623 let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]); 624 let isConvergent = 1; 625 626 string Mnemonic = OpName; 627 string AsmOperands = P.AsmDPP; 628 629 let AsmMatchConverter = !if(!eq(P.HasModifiers,1), "cvtDPP", ""); 630 let SubtargetPredicate = HasDPP; 631 let AssemblerPredicate = HasDPP; 632 let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP, 633 AMDGPUAsmVariants.Disable); 634 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", ""); 635 let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, ""); 636 let DecoderNamespace = "DPP"; 637 638 VOPProfile Pfl = P; 639} 640 641class VOP_DPP_Real <VOP_DPP_Pseudo ps, int EncodingFamily> : 642 InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, 643 SIMCInstr <ps.PseudoInstr, EncodingFamily> { 644 645 let isPseudo = 0; 646 let isCodeGenOnly = 0; 647 648 let Defs = ps.Defs; 649 let Uses = ps.Uses; 650 let SchedRW = ps.SchedRW; 651 let hasSideEffects = ps.hasSideEffects; 652 653 let Constraints = ps.Constraints; 654 let DisableEncoding = ps.DisableEncoding; 655 656 // Copy relevant pseudo op flags 657 let isConvergent = ps.isConvergent; 658 let SubtargetPredicate = ps.SubtargetPredicate; 659 let AssemblerPredicate = ps.AssemblerPredicate; 660 let AsmMatchConverter = ps.AsmMatchConverter; 661 let AsmVariantName = ps.AsmVariantName; 662 let UseNamedOperandTable = ps.UseNamedOperandTable; 663 let DecoderNamespace = ps.DecoderNamespace; 664 let Constraints = ps.Constraints; 665 let DisableEncoding = ps.DisableEncoding; 666 let TSFlags = ps.TSFlags; 667} 668 669class VOP_DPP <string OpName, VOPProfile P, bit IsDPP16, 670 dag InsDPP = !if(IsDPP16, P.InsDPP16, P.InsDPP), 671 string AsmDPP = !if(IsDPP16, P.AsmDPP16, P.AsmDPP)> : 672 InstSI <P.OutsDPP, InsDPP, OpName#AsmDPP, []>, 673 VOP_DPPe<P, IsDPP16> { 674 675 let mayLoad = 0; 676 let mayStore = 0; 677 let hasSideEffects = 0; 678 let UseNamedOperandTable = 1; 679 680 let VALU = 1; 681 let DPP = 1; 682 let Size = 8; 683 684 let AsmMatchConverter = !if(!eq(P.HasModifiers,1), "cvtDPP", ""); 685 let SubtargetPredicate = HasDPP; 686 let AssemblerPredicate = HasDPP; 687 let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP, 688 AMDGPUAsmVariants.Disable); 689 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", ""); 690 let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, ""); 691 let DecoderNamespace = "DPP"; 692} 693 694class VOP_DPP8e<VOPProfile P> : Enc64 { 695 bits<8> src0; 696 bits<24> dpp8; 697 bits<9> fi; 698 699 let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); 700 let Inst{63-40} = dpp8{23-0}; 701} 702 703class VOP_DPP8<string OpName, VOPProfile P> : 704 InstSI<P.OutsDPP8, P.InsDPP8, OpName#P.AsmDPP8, []>, 705 VOP_DPP8e<P> { 706 707 let mayLoad = 0; 708 let mayStore = 0; 709 let hasSideEffects = 0; 710 let UseNamedOperandTable = 1; 711 712 let VALU = 1; 713 let DPP = 1; 714 let Size = 8; 715 716 let AsmMatchConverter = "cvtDPP8"; 717 let SubtargetPredicate = HasDPP8; 718 let AssemblerPredicate = HasDPP8; 719 let AsmVariantName = !if(P.HasExt, AMDGPUAsmVariants.DPP, 720 AMDGPUAsmVariants.Disable); 721 let Constraints = !if(P.NumSrcArgs, P.TieRegDPP # " = $vdst", ""); 722 let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, ""); 723} 724 725def DPP8Mode { 726 int FI_0 = 0xE9; 727 int FI_1 = 0xEA; 728} 729 730class getNumNodeArgs<SDPatternOperator Op> { 731 SDNode N = !cast<SDNode>(Op); 732 SDTypeProfile TP = N.TypeProfile; 733 int ret = TP.NumOperands; 734} 735 736 737class getDivergentFrag<SDPatternOperator Op> { 738 739 int NumSrcArgs = getNumNodeArgs<Op>.ret; 740 PatFrag ret = PatFrag < 741 !if(!eq(NumSrcArgs, 1), 742 (ops node:$src0), 743 !if(!eq(NumSrcArgs, 2), 744 (ops node:$src0, node:$src1), 745 (ops node:$src0, node:$src1, node:$src2))), 746 !if(!eq(NumSrcArgs, 1), 747 (Op $src0), 748 !if(!eq(NumSrcArgs, 2), 749 (Op $src0, $src1), 750 (Op $src0, $src1, $src2))), 751 [{ return N->isDivergent(); }] 752 >; 753} 754 755class VOPPatGen<SDPatternOperator Op, VOPProfile P> { 756 757 PatFrag Operator = getDivergentFrag < Op >.ret; 758 759 dag Ins = !foreach(tmp, P.Ins32, !subst(ins, Operator, 760 !subst(P.Src0RC32, P.Src0VT, 761 !subst(P.Src1RC32, P.Src1VT, tmp)))); 762 763 764 dag Outs = !foreach(tmp, P.Outs32, !subst(outs, set, 765 !subst(P.DstRC, P.DstVT, tmp))); 766 767 list<dag> ret = [!con(Outs, (set Ins))]; 768} 769 770class VOPPatOrNull<SDPatternOperator Op, VOPProfile P> { 771 list<dag> ret = !if(!ne(P.NeedPatGen,PatGenMode.NoPattern), VOPPatGen<Op, P>.ret, []); 772} 773 774class DivergentFragOrOp<SDPatternOperator Op, VOPProfile P> { 775 SDPatternOperator ret = !if(!eq(P.NeedPatGen,PatGenMode.Pattern), 776 !if(!isa<SDNode>(Op), getDivergentFrag<Op>.ret, Op), Op); 777} 778 779include "VOPCInstructions.td" 780include "VOP1Instructions.td" 781include "VOP2Instructions.td" 782include "VOP3Instructions.td" 783include "VOP3PInstructions.td" 784