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