LLVM 17.0.0git
AMDGPUInstPrinter.cpp
Go to the documentation of this file.
1//===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
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// \file
8//===----------------------------------------------------------------------===//
9
10#include "AMDGPUInstPrinter.h"
12#include "SIDefines.h"
13#include "SIRegisterInfo.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCInst.h"
18#include "llvm/MC/MCInstrDesc.h"
19#include "llvm/MC/MCInstrInfo.h"
23
24using namespace llvm;
25using namespace llvm::AMDGPU;
26
28 "amdgpu-keep-16-bit-reg-suffixes",
29 cl::desc("Keep .l and .h suffixes in asm for debugging purposes"),
30 cl::init(false),
32
34 // FIXME: The current implementation of
35 // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
36 // as an integer or we provide a name which represents a physical register.
37 // For CFI instructions we really want to emit a name for the DWARF register
38 // instead, because there may be multiple DWARF registers corresponding to a
39 // single physical register. One case where this problem manifests is with
40 // wave32/wave64 where using the physical register name is ambiguous: if we
41 // write e.g. `.cfi_undefined v0` we lose information about the wavefront
42 // size which we need to encode the register in the final DWARF. Ideally we
43 // would extend MC to support parsing DWARF register names so we could do
44 // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
45 // non-pretty DWARF register names in assembly text.
46 OS << Reg.id();
47}
48
50 StringRef Annot, const MCSubtargetInfo &STI,
51 raw_ostream &OS) {
52 OS.flush();
54 printAnnotation(OS, Annot);
55}
56
57void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
58 const MCSubtargetInfo &STI,
59 raw_ostream &O) {
60 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
61}
62
63void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
64 const MCSubtargetInfo &STI,
65 raw_ostream &O) {
66 // It's possible to end up with a 32-bit literal used with a 16-bit operand
67 // with ignored high bits. Print as 32-bit anyway in that case.
68 int64_t Imm = MI->getOperand(OpNo).getImm();
69 if (isInt<16>(Imm) || isUInt<16>(Imm))
70 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
71 else
72 printU32ImmOperand(MI, OpNo, STI, O);
73}
74
75void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
76 raw_ostream &O) {
77 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
78}
79
80void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
81 raw_ostream &O) {
82 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
83}
84
85void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
86 raw_ostream &O) {
87 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
88}
89
90void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
91 const MCSubtargetInfo &STI,
92 raw_ostream &O) {
93 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
94}
95
96void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
97 raw_ostream &O, StringRef BitName) {
98 if (MI->getOperand(OpNo).getImm()) {
99 O << ' ' << BitName;
100 }
101}
102
103void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
104 raw_ostream &O) {
105 printNamedBit(MI, OpNo, O, "offen");
106}
107
108void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
109 raw_ostream &O) {
110 printNamedBit(MI, OpNo, O, "idxen");
111}
112
113void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
114 raw_ostream &O) {
115 printNamedBit(MI, OpNo, O, "addr64");
116}
117
118void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
119 const MCSubtargetInfo &STI,
120 raw_ostream &O) {
121 uint16_t Imm = MI->getOperand(OpNo).getImm();
122 if (Imm != 0) {
123 O << " offset:";
124 printU16ImmDecOperand(MI, OpNo, O);
125 }
126}
127
128void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
129 const MCSubtargetInfo &STI,
130 raw_ostream &O) {
131 uint16_t Imm = MI->getOperand(OpNo).getImm();
132 if (Imm != 0) {
133 O << " offset:";
134
135 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
136 bool IsFlatSeg = !(Desc.TSFlags &
138
139 if (IsFlatSeg) // Unsigned offset
140 printU16ImmDecOperand(MI, OpNo, O);
141 else // Signed offset
143 }
144}
145
146void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
147 const MCSubtargetInfo &STI,
148 raw_ostream &O) {
149 if (MI->getOperand(OpNo).getImm()) {
150 O << " offset0:";
151 printU8ImmDecOperand(MI, OpNo, O);
152 }
153}
154
155void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
156 const MCSubtargetInfo &STI,
157 raw_ostream &O) {
158 if (MI->getOperand(OpNo).getImm()) {
159 O << " offset1:";
160 printU8ImmDecOperand(MI, OpNo, O);
161 }
162}
163
164void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
165 const MCSubtargetInfo &STI,
166 raw_ostream &O) {
167 printU32ImmOperand(MI, OpNo, STI, O);
168}
169
170void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
171 const MCSubtargetInfo &STI,
172 raw_ostream &O) {
173 O << formatHex(MI->getOperand(OpNo).getImm());
174}
175
176void AMDGPUInstPrinter::printSMEMOffsetMod(const MCInst *MI, unsigned OpNo,
177 const MCSubtargetInfo &STI,
178 raw_ostream &O) {
179 O << " offset:";
180 printSMEMOffset(MI, OpNo, STI, O);
181}
182
183void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
184 const MCSubtargetInfo &STI,
185 raw_ostream &O) {
186 printU32ImmOperand(MI, OpNo, STI, O);
187}
188
189void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
190 const MCSubtargetInfo &STI, raw_ostream &O) {
191 printNamedBit(MI, OpNo, O, "gds");
192}
193
194void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
195 const MCSubtargetInfo &STI, raw_ostream &O) {
196 auto Imm = MI->getOperand(OpNo).getImm();
197 if (Imm & CPol::GLC)
198 O << ((AMDGPU::isGFX940(STI) &&
199 !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"
200 : " glc");
201 if (Imm & CPol::SLC)
202 O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
203 if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
204 O << " dlc";
205 if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
206 O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
207 if (Imm & ~CPol::ALL)
208 O << " /* unexpected cache policy bit */";
209}
210
211void AMDGPUInstPrinter::printSWZ(const MCInst *MI, unsigned OpNo,
212 const MCSubtargetInfo &STI, raw_ostream &O) {
213}
214
215void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
216 const MCSubtargetInfo &STI, raw_ostream &O) {
217 printNamedBit(MI, OpNo, O, "tfe");
218}
219
220void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
221 const MCSubtargetInfo &STI, raw_ostream &O) {
222 if (MI->getOperand(OpNo).getImm()) {
223 O << " dmask:";
224 printU16ImmOperand(MI, OpNo, STI, O);
225 }
226}
227
228void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
229 const MCSubtargetInfo &STI, raw_ostream &O) {
230 unsigned Dim = MI->getOperand(OpNo).getImm();
231 O << " dim:SQ_RSRC_IMG_";
232
234 if (DimInfo)
235 O << DimInfo->AsmSuffix;
236 else
237 O << Dim;
238}
239
240void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
241 const MCSubtargetInfo &STI, raw_ostream &O) {
242 printNamedBit(MI, OpNo, O, "unorm");
243}
244
245void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
246 const MCSubtargetInfo &STI, raw_ostream &O) {
247 printNamedBit(MI, OpNo, O, "da");
248}
249
250void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
251 const MCSubtargetInfo &STI, raw_ostream &O) {
252 if (STI.hasFeature(AMDGPU::FeatureR128A16))
253 printNamedBit(MI, OpNo, O, "a16");
254 else
255 printNamedBit(MI, OpNo, O, "r128");
256}
257
258void AMDGPUInstPrinter::printA16(const MCInst *MI, unsigned OpNo,
259 const MCSubtargetInfo &STI, raw_ostream &O) {
260 printNamedBit(MI, OpNo, O, "a16");
261}
262
263void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
264 const MCSubtargetInfo &STI, raw_ostream &O) {
265 printNamedBit(MI, OpNo, O, "lwe");
266}
267
268void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
269 const MCSubtargetInfo &STI, raw_ostream &O) {
270 printNamedBit(MI, OpNo, O, "d16");
271}
272
273void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
274 const MCSubtargetInfo &STI,
275 raw_ostream &O) {
276 printNamedBit(MI, OpNo, O, "compr");
277}
278
279void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
280 const MCSubtargetInfo &STI,
281 raw_ostream &O) {
282 printNamedBit(MI, OpNo, O, "vm");
283}
284
285void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
286 const MCSubtargetInfo &STI,
287 raw_ostream &O) {
288}
289
290void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
291 const MCSubtargetInfo &STI,
292 raw_ostream &O) {
293 using namespace llvm::AMDGPU::MTBUFFormat;
294
295 int OpNo =
296 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
297 assert(OpNo != -1);
298
299 unsigned Val = MI->getOperand(OpNo).getImm();
300 if (AMDGPU::isGFX10Plus(STI)) {
301 if (Val == UFMT_DEFAULT)
302 return;
303 if (isValidUnifiedFormat(Val, STI)) {
304 O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
305 } else {
306 O << " format:" << Val;
307 }
308 } else {
309 if (Val == DFMT_NFMT_DEFAULT)
310 return;
311 if (isValidDfmtNfmt(Val, STI)) {
312 unsigned Dfmt;
313 unsigned Nfmt;
314 decodeDfmtNfmt(Val, Dfmt, Nfmt);
315 O << " format:[";
316 if (Dfmt != DFMT_DEFAULT) {
317 O << getDfmtName(Dfmt);
318 if (Nfmt != NFMT_DEFAULT) {
319 O << ',';
320 }
321 }
322 if (Nfmt != NFMT_DEFAULT) {
323 O << getNfmtName(Nfmt, STI);
324 }
325 O << ']';
326 } else {
327 O << " format:" << Val;
328 }
329 }
330}
331
333 const MCRegisterInfo &MRI) {
334#if !defined(NDEBUG)
335 switch (RegNo) {
336 case AMDGPU::FP_REG:
337 case AMDGPU::SP_REG:
338 case AMDGPU::PRIVATE_RSRC_REG:
339 llvm_unreachable("pseudo-register should not ever be emitted");
340 case AMDGPU::SCC:
341 llvm_unreachable("pseudo scc should not ever be emitted");
342 default:
343 break;
344 }
345#endif
346
349 if (!RegName.consume_back(".l"))
350 RegName.consume_back(".h");
351
352 O << RegName;
353}
354
355void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
356 const MCSubtargetInfo &STI, raw_ostream &O) {
357 auto Opcode = MI->getOpcode();
358 auto Flags = MII.get(Opcode).TSFlags;
359 if (OpNo == 0) {
360 if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)
361 O << "_e64_dpp";
362 else if (Flags & SIInstrFlags::VOP3) {
363 if (!getVOP3IsSingle(Opcode))
364 O << "_e64";
365 } else if (Flags & SIInstrFlags::DPP)
366 O << "_dpp";
367 else if (Flags & SIInstrFlags::SDWA)
368 O << "_sdwa";
369 else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
370 ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))
371 O << "_e32";
372 O << " ";
373 }
374
375 printRegularOperand(MI, OpNo, STI, O);
376
377 // Print default vcc/vcc_lo operand.
378 switch (Opcode) {
379 default: break;
380
381 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
382 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
383 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
384 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
385 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
386 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
387 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
388 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
389 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
390 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
391 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
392 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
393 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
394 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
395 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
396 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
397 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
398 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
399 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
400 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
401 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
402 printDefaultVccOperand(false, STI, O);
403 break;
404 }
405}
406
407void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
408 const MCSubtargetInfo &STI, raw_ostream &O) {
409 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
410 O << " ";
411 else
412 O << "_e32 ";
413
414 printRegularOperand(MI, OpNo, STI, O);
415}
416
417void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
418 const MCSubtargetInfo &STI,
419 raw_ostream &O) {
420 int16_t SImm = static_cast<int16_t>(Imm);
421 if (isInlinableIntLiteral(SImm)) {
422 O << SImm;
423 } else {
424 uint64_t Imm16 = static_cast<uint16_t>(Imm);
425 O << formatHex(Imm16);
426 }
427}
428
429void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
430 const MCSubtargetInfo &STI,
431 raw_ostream &O) {
432 int16_t SImm = static_cast<int16_t>(Imm);
433 if (isInlinableIntLiteral(SImm)) {
434 O << SImm;
435 return;
436 }
437
438 if (Imm == 0x3C00)
439 O<< "1.0";
440 else if (Imm == 0xBC00)
441 O<< "-1.0";
442 else if (Imm == 0x3800)
443 O<< "0.5";
444 else if (Imm == 0xB800)
445 O<< "-0.5";
446 else if (Imm == 0x4000)
447 O<< "2.0";
448 else if (Imm == 0xC000)
449 O<< "-2.0";
450 else if (Imm == 0x4400)
451 O<< "4.0";
452 else if (Imm == 0xC400)
453 O<< "-4.0";
454 else if (Imm == 0x3118 &&
455 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm)) {
456 O << "0.15915494";
457 } else {
458 uint64_t Imm16 = static_cast<uint16_t>(Imm);
459 O << formatHex(Imm16);
460 }
461}
462
463void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
464 const MCSubtargetInfo &STI,
465 raw_ostream &O) {
466 uint16_t Lo16 = static_cast<uint16_t>(Imm);
467 printImmediate16(Lo16, STI, O);
468}
469
470void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
471 const MCSubtargetInfo &STI,
472 raw_ostream &O) {
473 int32_t SImm = static_cast<int32_t>(Imm);
474 if (SImm >= -16 && SImm <= 64) {
475 O << SImm;
476 return;
477 }
478
479 if (Imm == llvm::bit_cast<uint32_t>(0.0f))
480 O << "0.0";
481 else if (Imm == llvm::bit_cast<uint32_t>(1.0f))
482 O << "1.0";
483 else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))
484 O << "-1.0";
485 else if (Imm == llvm::bit_cast<uint32_t>(0.5f))
486 O << "0.5";
487 else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))
488 O << "-0.5";
489 else if (Imm == llvm::bit_cast<uint32_t>(2.0f))
490 O << "2.0";
491 else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))
492 O << "-2.0";
493 else if (Imm == llvm::bit_cast<uint32_t>(4.0f))
494 O << "4.0";
495 else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))
496 O << "-4.0";
497 else if (Imm == 0x3e22f983 &&
498 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
499 O << "0.15915494";
500 else
501 O << formatHex(static_cast<uint64_t>(Imm));
502}
503
504void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
505 const MCSubtargetInfo &STI,
506 raw_ostream &O) {
507 int64_t SImm = static_cast<int64_t>(Imm);
508 if (SImm >= -16 && SImm <= 64) {
509 O << SImm;
510 return;
511 }
512
513 if (Imm == llvm::bit_cast<uint64_t>(0.0))
514 O << "0.0";
515 else if (Imm == llvm::bit_cast<uint64_t>(1.0))
516 O << "1.0";
517 else if (Imm == llvm::bit_cast<uint64_t>(-1.0))
518 O << "-1.0";
519 else if (Imm == llvm::bit_cast<uint64_t>(0.5))
520 O << "0.5";
521 else if (Imm == llvm::bit_cast<uint64_t>(-0.5))
522 O << "-0.5";
523 else if (Imm == llvm::bit_cast<uint64_t>(2.0))
524 O << "2.0";
525 else if (Imm == llvm::bit_cast<uint64_t>(-2.0))
526 O << "-2.0";
527 else if (Imm == llvm::bit_cast<uint64_t>(4.0))
528 O << "4.0";
529 else if (Imm == llvm::bit_cast<uint64_t>(-4.0))
530 O << "-4.0";
531 else if (Imm == 0x3fc45f306dc9c882 &&
532 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
533 O << "0.15915494309189532";
534 else {
535 assert(isUInt<32>(Imm) || isInt<32>(Imm));
536
537 // In rare situations, we will have a 32-bit literal in a 64-bit
538 // operand. This is technically allowed for the encoding of s_mov_b64.
539 O << formatHex(static_cast<uint64_t>(Imm));
540 }
541}
542
543void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
544 const MCSubtargetInfo &STI,
545 raw_ostream &O) {
546 unsigned Imm = MI->getOperand(OpNo).getImm();
547 if (!Imm)
548 return;
549
550 if (AMDGPU::isGFX940(STI)) {
551 switch (MI->getOpcode()) {
552 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
553 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
554 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
555 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
556 O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
557 << ((Imm >> 2) & 1) << ']';
558 return;
559 }
560 }
561
562 O << " blgp:" << Imm;
563}
564
565void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
566 const MCSubtargetInfo &STI,
567 raw_ostream &O) {
568 unsigned Imm = MI->getOperand(OpNo).getImm();
569 if (!Imm)
570 return;
571
572 O << " cbsz:" << Imm;
573}
574
575void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
576 const MCSubtargetInfo &STI,
577 raw_ostream &O) {
578 unsigned Imm = MI->getOperand(OpNo).getImm();
579 if (!Imm)
580 return;
581
582 O << " abid:" << Imm;
583}
584
585void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
586 const MCSubtargetInfo &STI,
587 raw_ostream &O) {
588 if (!FirstOperand)
589 O << ", ";
590 printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize64)
591 ? AMDGPU::VCC
592 : AMDGPU::VCC_LO,
593 O, MRI);
594 if (FirstOperand)
595 O << ", ";
596}
597
598void AMDGPUInstPrinter::printWaitVDST(const MCInst *MI, unsigned OpNo,
599 const MCSubtargetInfo &STI,
600 raw_ostream &O) {
601 uint8_t Imm = MI->getOperand(OpNo).getImm();
602 if (Imm != 0) {
603 O << " wait_vdst:";
604 printU4ImmDecOperand(MI, OpNo, O);
605 }
606}
607
608void AMDGPUInstPrinter::printWaitEXP(const MCInst *MI, unsigned OpNo,
609 const MCSubtargetInfo &STI,
610 raw_ostream &O) {
611 uint8_t Imm = MI->getOperand(OpNo).getImm();
612 if (Imm != 0) {
613 O << " wait_exp:";
614 printU4ImmDecOperand(MI, OpNo, O);
615 }
616}
617
618bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
619 unsigned OpNo) const {
620 return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&
621 (Desc.TSFlags & SIInstrFlags::VOPC) &&
622 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
623 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
624}
625
626// Print default vcc/vcc_lo operand of VOPC.
627void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
628 const MCSubtargetInfo &STI,
629 raw_ostream &O) {
630 unsigned Opc = MI->getOpcode();
631 const MCInstrDesc &Desc = MII.get(Opc);
632 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
633 // 0, 1 and 2 are the first printed operands in different cases
634 // If there are printed modifiers, printOperandAndFPInputMods or
635 // printOperandAndIntInputMods will be called instead
636 if ((OpNo == 0 ||
637 (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&
638 (Desc.TSFlags & SIInstrFlags::VOPC) &&
639 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
640 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
641 printDefaultVccOperand(true, STI, O);
642
643 printRegularOperand(MI, OpNo, STI, O);
644}
645
646// Print operands after vcc or modifier handling.
647void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
648 const MCSubtargetInfo &STI,
649 raw_ostream &O) {
650 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
651
652 if (OpNo >= MI->getNumOperands()) {
653 O << "/*Missing OP" << OpNo << "*/";
654 return;
655 }
656
657 const MCOperand &Op = MI->getOperand(OpNo);
658 if (Op.isReg()) {
659 printRegOperand(Op.getReg(), O, MRI);
660
661 // Check if operand register class contains register used.
662 // Intention: print disassembler message when invalid code is decoded,
663 // for example sgpr register used in VReg or VISrc(VReg or imm) operand.
664 int RCID = Desc.operands()[OpNo].RegClass;
665 if (RCID != -1) {
666 const MCRegisterClass RC = MRI.getRegClass(RCID);
667 auto Reg = mc2PseudoReg(Op.getReg());
668 if (!RC.contains(Reg) && !isInlineValue(Reg)) {
669 O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
670 << "\' register class*/";
671 }
672 }
673 } else if (Op.isImm()) {
674 const uint8_t OpTy = Desc.operands()[OpNo].OperandType;
675 switch (OpTy) {
688 printImmediate32(Op.getImm(), STI, O);
689 break;
695 printImmediate64(Op.getImm(), STI, O);
696 break;
700 printImmediateInt16(Op.getImm(), STI, O);
701 break;
706 printImmediate16(Op.getImm(), STI, O);
707 break;
710 if (!isUInt<16>(Op.getImm()) &&
711 STI.hasFeature(AMDGPU::FeatureVOP3Literal)) {
712 printImmediate32(Op.getImm(), STI, O);
713 break;
714 }
715
716 // Deal with 16-bit FP inline immediates not working.
717 if (OpTy == AMDGPU::OPERAND_REG_IMM_V2FP16) {
718 printImmediate16(static_cast<uint16_t>(Op.getImm()), STI, O);
719 break;
720 }
721 [[fallthrough]];
724 printImmediateInt16(static_cast<uint16_t>(Op.getImm()), STI, O);
725 break;
728 printImmediateV216(Op.getImm(), STI, O);
729 break;
732 O << formatDec(Op.getImm());
733 break;
735 // Disassembler does not fail when operand should not allow immediate
736 // operands but decodes them into 32bit immediate operand.
737 printImmediate32(Op.getImm(), STI, O);
738 O << "/*Invalid immediate*/";
739 break;
740 default:
741 // We hit this for the immediate instruction bits that don't yet have a
742 // custom printer.
743 llvm_unreachable("unexpected immediate operand type");
744 }
745 } else if (Op.isDFPImm()) {
746 double Value = bit_cast<double>(Op.getDFPImm());
747 // We special case 0.0 because otherwise it will be printed as an integer.
748 if (Value == 0.0)
749 O << "0.0";
750 else {
751 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
752 int RCID = Desc.operands()[OpNo].RegClass;
753 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
754 if (RCBits == 32)
755 printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
756 else if (RCBits == 64)
757 printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O);
758 else
759 llvm_unreachable("Invalid register class size");
760 }
761 } else if (Op.isExpr()) {
762 const MCExpr *Exp = Op.getExpr();
763 Exp->print(O, &MAI);
764 } else {
765 O << "/*INV_OP*/";
766 }
767
768 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
769 switch (MI->getOpcode()) {
770 default: break;
771
772 case AMDGPU::V_CNDMASK_B32_e32_gfx10:
773 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
774 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
775 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
776 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
777 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
778 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
779 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
780 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
781 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
782 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
783 case AMDGPU::V_CNDMASK_B32_e32_gfx11:
784 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
785 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
786 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
787 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
788 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
789 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
790 case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
791 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
792 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
793 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
794
795 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
796 case AMDGPU::V_CNDMASK_B32_e32_vi:
797 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
798 AMDGPU::OpName::src1))
799 printDefaultVccOperand(OpNo == 0, STI, O);
800 break;
801 }
802
803 if (Desc.TSFlags & SIInstrFlags::MTBUF) {
804 int SOffsetIdx =
805 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
806 assert(SOffsetIdx != -1);
807 if ((int)OpNo == SOffsetIdx)
808 printSymbolicFormat(MI, STI, O);
809 }
810}
811
812void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
813 unsigned OpNo,
814 const MCSubtargetInfo &STI,
815 raw_ostream &O) {
816 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
817 if (needsImpliedVcc(Desc, OpNo))
818 printDefaultVccOperand(true, STI, O);
819
820 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
821
822 // Use 'neg(...)' instead of '-' to avoid ambiguity.
823 // This is important for integer literals because
824 // -1 is not the same value as neg(1).
825 bool NegMnemo = false;
826
827 if (InputModifiers & SISrcMods::NEG) {
828 if (OpNo + 1 < MI->getNumOperands() &&
829 (InputModifiers & SISrcMods::ABS) == 0) {
830 const MCOperand &Op = MI->getOperand(OpNo + 1);
831 NegMnemo = Op.isImm() || Op.isDFPImm();
832 }
833 if (NegMnemo) {
834 O << "neg(";
835 } else {
836 O << '-';
837 }
838 }
839
840 if (InputModifiers & SISrcMods::ABS)
841 O << '|';
842 printRegularOperand(MI, OpNo + 1, STI, O);
843 if (InputModifiers & SISrcMods::ABS)
844 O << '|';
845
846 if (NegMnemo) {
847 O << ')';
848 }
849
850 // Print default vcc/vcc_lo operand of VOP2b.
851 switch (MI->getOpcode()) {
852 default:
853 break;
854
855 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
856 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
857 case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
858 if ((int)OpNo + 1 ==
859 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))
860 printDefaultVccOperand(OpNo == 0, STI, O);
861 break;
862 }
863}
864
865void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
866 unsigned OpNo,
867 const MCSubtargetInfo &STI,
868 raw_ostream &O) {
869 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
870 if (needsImpliedVcc(Desc, OpNo))
871 printDefaultVccOperand(true, STI, O);
872
873 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
874 if (InputModifiers & SISrcMods::SEXT)
875 O << "sext(";
876 printRegularOperand(MI, OpNo + 1, STI, O);
877 if (InputModifiers & SISrcMods::SEXT)
878 O << ')';
879
880 // Print default vcc/vcc_lo operand of VOP2b.
881 switch (MI->getOpcode()) {
882 default: break;
883
884 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
885 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
886 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
887 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
888 AMDGPU::OpName::src1))
889 printDefaultVccOperand(OpNo == 0, STI, O);
890 break;
891 }
892}
893
894void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
895 const MCSubtargetInfo &STI,
896 raw_ostream &O) {
897 if (!AMDGPU::isGFX10Plus(STI))
898 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
899
900 unsigned Imm = MI->getOperand(OpNo).getImm();
901 O << "dpp8:[" << formatDec(Imm & 0x7);
902 for (size_t i = 1; i < 8; ++i) {
903 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
904 }
905 O << ']';
906}
907
908void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
909 const MCSubtargetInfo &STI,
910 raw_ostream &O) {
911 using namespace AMDGPU::DPP;
912
913 unsigned Imm = MI->getOperand(OpNo).getImm();
914 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
915 int Src0Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(),
916 AMDGPU::OpName::src0);
917
918 if (Src0Idx >= 0 &&
919 Desc.operands()[Src0Idx].RegClass == AMDGPU::VReg_64RegClassID &&
921 O << " /* 64 bit dpp only supports row_newbcast */";
922 return;
923 } else if (Imm <= DppCtrl::QUAD_PERM_LAST) {
924 O << "quad_perm:[";
925 O << formatDec(Imm & 0x3) << ',';
926 O << formatDec((Imm & 0xc) >> 2) << ',';
927 O << formatDec((Imm & 0x30) >> 4) << ',';
928 O << formatDec((Imm & 0xc0) >> 6) << ']';
929 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
930 (Imm <= DppCtrl::ROW_SHL_LAST)) {
931 O << "row_shl:";
932 printU4ImmDecOperand(MI, OpNo, O);
933 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
934 (Imm <= DppCtrl::ROW_SHR_LAST)) {
935 O << "row_shr:";
936 printU4ImmDecOperand(MI, OpNo, O);
937 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
938 (Imm <= DppCtrl::ROW_ROR_LAST)) {
939 O << "row_ror:";
940 printU4ImmDecOperand(MI, OpNo, O);
941 } else if (Imm == DppCtrl::WAVE_SHL1) {
942 if (AMDGPU::isGFX10Plus(STI)) {
943 O << "/* wave_shl is not supported starting from GFX10 */";
944 return;
945 }
946 O << "wave_shl:1";
947 } else if (Imm == DppCtrl::WAVE_ROL1) {
948 if (AMDGPU::isGFX10Plus(STI)) {
949 O << "/* wave_rol is not supported starting from GFX10 */";
950 return;
951 }
952 O << "wave_rol:1";
953 } else if (Imm == DppCtrl::WAVE_SHR1) {
954 if (AMDGPU::isGFX10Plus(STI)) {
955 O << "/* wave_shr is not supported starting from GFX10 */";
956 return;
957 }
958 O << "wave_shr:1";
959 } else if (Imm == DppCtrl::WAVE_ROR1) {
960 if (AMDGPU::isGFX10Plus(STI)) {
961 O << "/* wave_ror is not supported starting from GFX10 */";
962 return;
963 }
964 O << "wave_ror:1";
965 } else if (Imm == DppCtrl::ROW_MIRROR) {
966 O << "row_mirror";
967 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
968 O << "row_half_mirror";
969 } else if (Imm == DppCtrl::BCAST15) {
970 if (AMDGPU::isGFX10Plus(STI)) {
971 O << "/* row_bcast is not supported starting from GFX10 */";
972 return;
973 }
974 O << "row_bcast:15";
975 } else if (Imm == DppCtrl::BCAST31) {
976 if (AMDGPU::isGFX10Plus(STI)) {
977 O << "/* row_bcast is not supported starting from GFX10 */";
978 return;
979 }
980 O << "row_bcast:31";
981 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
982 (Imm <= DppCtrl::ROW_SHARE_LAST)) {
983 if (AMDGPU::isGFX90A(STI)) {
984 O << "row_newbcast:";
985 } else if (AMDGPU::isGFX10Plus(STI)) {
986 O << "row_share:";
987 } else {
988 O << " /* row_newbcast/row_share is not supported on ASICs earlier "
989 "than GFX90A/GFX10 */";
990 return;
991 }
992 printU4ImmDecOperand(MI, OpNo, O);
993 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
994 (Imm <= DppCtrl::ROW_XMASK_LAST)) {
995 if (!AMDGPU::isGFX10Plus(STI)) {
996 O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
997 return;
998 }
999 O << "row_xmask:";
1000 printU4ImmDecOperand(MI, OpNo, O);
1001 } else {
1002 O << "/* Invalid dpp_ctrl value */";
1003 }
1004}
1005
1006void AMDGPUInstPrinter::printDppRowMask(const MCInst *MI, unsigned OpNo,
1007 const MCSubtargetInfo &STI,
1008 raw_ostream &O) {
1009 O << " row_mask:";
1010 printU4ImmOperand(MI, OpNo, STI, O);
1011}
1012
1013void AMDGPUInstPrinter::printDppBankMask(const MCInst *MI, unsigned OpNo,
1014 const MCSubtargetInfo &STI,
1015 raw_ostream &O) {
1016 O << " bank_mask:";
1017 printU4ImmOperand(MI, OpNo, STI, O);
1018}
1019
1020void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,
1021 const MCSubtargetInfo &STI,
1022 raw_ostream &O) {
1023 unsigned Imm = MI->getOperand(OpNo).getImm();
1024 if (Imm) {
1025 O << " bound_ctrl:1";
1026 }
1027}
1028
1029void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,
1030 const MCSubtargetInfo &STI, raw_ostream &O) {
1031 using namespace llvm::AMDGPU::DPP;
1032 unsigned Imm = MI->getOperand(OpNo).getImm();
1033 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
1034 O << " fi:1";
1035 }
1036}
1037
1038void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
1039 raw_ostream &O) {
1040 using namespace llvm::AMDGPU::SDWA;
1041
1042 unsigned Imm = MI->getOperand(OpNo).getImm();
1043 switch (Imm) {
1044 case SdwaSel::BYTE_0: O << "BYTE_0"; break;
1045 case SdwaSel::BYTE_1: O << "BYTE_1"; break;
1046 case SdwaSel::BYTE_2: O << "BYTE_2"; break;
1047 case SdwaSel::BYTE_3: O << "BYTE_3"; break;
1048 case SdwaSel::WORD_0: O << "WORD_0"; break;
1049 case SdwaSel::WORD_1: O << "WORD_1"; break;
1050 case SdwaSel::DWORD: O << "DWORD"; break;
1051 default: llvm_unreachable("Invalid SDWA data select operand");
1052 }
1053}
1054
1055void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
1056 const MCSubtargetInfo &STI,
1057 raw_ostream &O) {
1058 O << "dst_sel:";
1059 printSDWASel(MI, OpNo, O);
1060}
1061
1062void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
1063 const MCSubtargetInfo &STI,
1064 raw_ostream &O) {
1065 O << "src0_sel:";
1066 printSDWASel(MI, OpNo, O);
1067}
1068
1069void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
1070 const MCSubtargetInfo &STI,
1071 raw_ostream &O) {
1072 O << "src1_sel:";
1073 printSDWASel(MI, OpNo, O);
1074}
1075
1076void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
1077 const MCSubtargetInfo &STI,
1078 raw_ostream &O) {
1079 using namespace llvm::AMDGPU::SDWA;
1080
1081 O << "dst_unused:";
1082 unsigned Imm = MI->getOperand(OpNo).getImm();
1083 switch (Imm) {
1084 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
1085 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
1086 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
1087 default: llvm_unreachable("Invalid SDWA dest_unused operand");
1088 }
1089}
1090
1091void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
1092 const MCSubtargetInfo &STI, raw_ostream &O,
1093 unsigned N) {
1094 unsigned Opc = MI->getOpcode();
1095 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
1096 unsigned En = MI->getOperand(EnIdx).getImm();
1097
1098 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
1099
1100 // If compr is set, print as src0, src0, src1, src1
1101 if (MI->getOperand(ComprIdx).getImm())
1102 OpNo = OpNo - N + N / 2;
1103
1104 if (En & (1 << N))
1105 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
1106 else
1107 O << "off";
1108}
1109
1110void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
1111 const MCSubtargetInfo &STI,
1112 raw_ostream &O) {
1113 printExpSrcN(MI, OpNo, STI, O, 0);
1114}
1115
1116void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
1117 const MCSubtargetInfo &STI,
1118 raw_ostream &O) {
1119 printExpSrcN(MI, OpNo, STI, O, 1);
1120}
1121
1122void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
1123 const MCSubtargetInfo &STI,
1124 raw_ostream &O) {
1125 printExpSrcN(MI, OpNo, STI, O, 2);
1126}
1127
1128void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
1129 const MCSubtargetInfo &STI,
1130 raw_ostream &O) {
1131 printExpSrcN(MI, OpNo, STI, O, 3);
1132}
1133
1134void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
1135 const MCSubtargetInfo &STI,
1136 raw_ostream &O) {
1137 using namespace llvm::AMDGPU::Exp;
1138
1139 // This is really a 6 bit field.
1140 unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1141
1142 int Index;
1143 StringRef TgtName;
1144 if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1145 O << ' ' << TgtName;
1146 if (Index >= 0)
1147 O << Index;
1148 } else {
1149 O << " invalid_target_" << Id;
1150 }
1151}
1152
1153static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
1154 bool IsPacked, bool HasDstSel) {
1155 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
1156
1157 for (int I = 0; I < NumOps; ++I) {
1158 if (!!(Ops[I] & Mod) != DefaultValue)
1159 return false;
1160 }
1161
1162 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
1163 return false;
1164
1165 return true;
1166}
1167
1168void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
1170 unsigned Mod,
1171 raw_ostream &O) {
1172 unsigned Opc = MI->getOpcode();
1173 int NumOps = 0;
1174 int Ops[3];
1175
1176 for (int OpName : { AMDGPU::OpName::src0_modifiers,
1177 AMDGPU::OpName::src1_modifiers,
1178 AMDGPU::OpName::src2_modifiers }) {
1180 if (Idx == -1)
1181 break;
1182
1183 Ops[NumOps++] = MI->getOperand(Idx).getImm();
1184 }
1185
1186 const bool HasDstSel =
1187 NumOps > 0 &&
1189 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
1190
1191 const bool IsPacked =
1192 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
1193
1194 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1195 return;
1196
1197 O << Name;
1198 for (int I = 0; I < NumOps; ++I) {
1199 if (I != 0)
1200 O << ',';
1201
1202 O << !!(Ops[I] & Mod);
1203 }
1204
1205 if (HasDstSel) {
1206 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1207 }
1208
1209 O << ']';
1210}
1211
1212void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1213 const MCSubtargetInfo &STI,
1214 raw_ostream &O) {
1215 unsigned Opc = MI->getOpcode();
1216 if (isPermlane16(Opc)) {
1217 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1218 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1219 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1220 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1221 if (FI || BC)
1222 O << " op_sel:[" << FI << ',' << BC << ']';
1223 return;
1224 }
1225
1226 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1227}
1228
1229void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1230 const MCSubtargetInfo &STI,
1231 raw_ostream &O) {
1232 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1233}
1234
1235void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1236 const MCSubtargetInfo &STI,
1237 raw_ostream &O) {
1238 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1239}
1240
1241void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1242 const MCSubtargetInfo &STI,
1243 raw_ostream &O) {
1244 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1245}
1246
1247void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1248 const MCSubtargetInfo &STI,
1249 raw_ostream &O) {
1250 unsigned Imm = MI->getOperand(OpNum).getImm();
1251 switch (Imm) {
1252 case 0:
1253 O << "p10";
1254 break;
1255 case 1:
1256 O << "p20";
1257 break;
1258 case 2:
1259 O << "p0";
1260 break;
1261 default:
1262 O << "invalid_param_" << Imm;
1263 }
1264}
1265
1266void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1267 const MCSubtargetInfo &STI,
1268 raw_ostream &O) {
1269 unsigned Attr = MI->getOperand(OpNum).getImm();
1270 O << "attr" << Attr;
1271}
1272
1273void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1274 const MCSubtargetInfo &STI,
1275 raw_ostream &O) {
1276 unsigned Chan = MI->getOperand(OpNum).getImm();
1277 O << '.' << "xyzw"[Chan & 0x3];
1278}
1279
1280void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
1281 const MCSubtargetInfo &STI,
1282 raw_ostream &O) {
1283 using namespace llvm::AMDGPU::VGPRIndexMode;
1284 unsigned Val = MI->getOperand(OpNo).getImm();
1285
1286 if ((Val & ~ENABLE_MASK) != 0) {
1287 O << formatHex(static_cast<uint64_t>(Val));
1288 } else {
1289 O << "gpr_idx(";
1290 bool NeedComma = false;
1291 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1292 if (Val & (1 << ModeId)) {
1293 if (NeedComma)
1294 O << ',';
1295 O << IdSymbolic[ModeId];
1296 NeedComma = true;
1297 }
1298 }
1299 O << ')';
1300 }
1301}
1302
1303void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1304 const MCSubtargetInfo &STI,
1305 raw_ostream &O) {
1306 printRegularOperand(MI, OpNo, STI, O);
1307 O << ", ";
1308 printRegularOperand(MI, OpNo + 1, STI, O);
1309}
1310
1311void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1312 raw_ostream &O, StringRef Asm,
1314 const MCOperand &Op = MI->getOperand(OpNo);
1315 assert(Op.isImm());
1316 if (Op.getImm() == 1) {
1317 O << Asm;
1318 } else {
1319 O << Default;
1320 }
1321}
1322
1323void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1324 raw_ostream &O, char Asm) {
1325 const MCOperand &Op = MI->getOperand(OpNo);
1326 assert(Op.isImm());
1327 if (Op.getImm() == 1)
1328 O << Asm;
1329}
1330
1331void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
1332 const MCSubtargetInfo &STI,
1333 raw_ostream &O) {
1334 printNamedBit(MI, OpNo, O, "high");
1335}
1336
1337void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
1338 const MCSubtargetInfo &STI,
1339 raw_ostream &O) {
1340 printNamedBit(MI, OpNo, O, "clamp");
1341}
1342
1343void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1344 const MCSubtargetInfo &STI,
1345 raw_ostream &O) {
1346 int Imm = MI->getOperand(OpNo).getImm();
1347 if (Imm == SIOutMods::MUL2)
1348 O << " mul:2";
1349 else if (Imm == SIOutMods::MUL4)
1350 O << " mul:4";
1351 else if (Imm == SIOutMods::DIV2)
1352 O << " div:2";
1353}
1354
1355void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1356 const MCSubtargetInfo &STI,
1357 raw_ostream &O) {
1358 using namespace llvm::AMDGPU::SendMsg;
1359
1360 const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1361
1362 uint16_t MsgId;
1363 uint16_t OpId;
1365 decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
1366
1367 StringRef MsgName = getMsgName(MsgId, STI);
1368
1369 if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
1370 isValidMsgStream(MsgId, OpId, StreamId, STI)) {
1371 O << "sendmsg(" << MsgName;
1372 if (msgRequiresOp(MsgId, STI)) {
1373 O << ", " << getMsgOpName(MsgId, OpId, STI);
1374 if (msgSupportsStream(MsgId, OpId, STI)) {
1375 O << ", " << StreamId;
1376 }
1377 }
1378 O << ')';
1379 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1380 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1381 } else {
1382 O << Imm16; // Unknown imm16 code.
1383 }
1384}
1385
1386static void printSwizzleBitmask(const uint16_t AndMask,
1387 const uint16_t OrMask,
1388 const uint16_t XorMask,
1389 raw_ostream &O) {
1390 using namespace llvm::AMDGPU::Swizzle;
1391
1392 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1393 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1394
1395 O << "\"";
1396
1397 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1398 uint16_t p0 = Probe0 & Mask;
1399 uint16_t p1 = Probe1 & Mask;
1400
1401 if (p0 == p1) {
1402 if (p0 == 0) {
1403 O << "0";
1404 } else {
1405 O << "1";
1406 }
1407 } else {
1408 if (p0 == 0) {
1409 O << "p";
1410 } else {
1411 O << "i";
1412 }
1413 }
1414 }
1415
1416 O << "\"";
1417}
1418
1419void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1420 const MCSubtargetInfo &STI,
1421 raw_ostream &O) {
1422 using namespace llvm::AMDGPU::Swizzle;
1423
1424 uint16_t Imm = MI->getOperand(OpNo).getImm();
1425 if (Imm == 0) {
1426 return;
1427 }
1428
1429 O << " offset:";
1430
1431 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1432
1433 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1434 for (unsigned I = 0; I < LANE_NUM; ++I) {
1435 O << ",";
1436 O << formatDec(Imm & LANE_MASK);
1437 Imm >>= LANE_SHIFT;
1438 }
1439 O << ")";
1440
1441 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1442
1443 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1444 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1445 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1446
1447 if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {
1448
1449 O << "swizzle(" << IdSymbolic[ID_SWAP];
1450 O << ",";
1451 O << formatDec(XorMask);
1452 O << ")";
1453
1454 } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&
1455 isPowerOf2_64(XorMask + 1)) {
1456
1457 O << "swizzle(" << IdSymbolic[ID_REVERSE];
1458 O << ",";
1459 O << formatDec(XorMask + 1);
1460 O << ")";
1461
1462 } else {
1463
1464 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1465 if (GroupSize > 1 &&
1466 isPowerOf2_64(GroupSize) &&
1467 OrMask < GroupSize &&
1468 XorMask == 0) {
1469
1470 O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1471 O << ",";
1472 O << formatDec(GroupSize);
1473 O << ",";
1474 O << formatDec(OrMask);
1475 O << ")";
1476
1477 } else {
1478 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1479 O << ",";
1480 printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1481 O << ")";
1482 }
1483 }
1484 } else {
1485 printU16ImmDecOperand(MI, OpNo, O);
1486 }
1487}
1488
1489void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1490 const MCSubtargetInfo &STI,
1491 raw_ostream &O) {
1493
1494 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1495 unsigned Vmcnt, Expcnt, Lgkmcnt;
1496 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1497
1498 bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
1499 bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
1500 bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
1501 bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
1502
1503 bool NeedSpace = false;
1504
1505 if (!IsDefaultVmcnt || PrintAll) {
1506 O << "vmcnt(" << Vmcnt << ')';
1507 NeedSpace = true;
1508 }
1509
1510 if (!IsDefaultExpcnt || PrintAll) {
1511 if (NeedSpace)
1512 O << ' ';
1513 O << "expcnt(" << Expcnt << ')';
1514 NeedSpace = true;
1515 }
1516
1517 if (!IsDefaultLgkmcnt || PrintAll) {
1518 if (NeedSpace)
1519 O << ' ';
1520 O << "lgkmcnt(" << Lgkmcnt << ')';
1521 }
1522}
1523
1524void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
1525 const MCSubtargetInfo &STI,
1526 raw_ostream &O) {
1527 using namespace llvm::AMDGPU::DepCtr;
1528
1529 uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
1530
1531 bool HasNonDefaultVal = false;
1532 if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
1533 int Id = 0;
1535 unsigned Val;
1536 bool IsDefault;
1537 bool NeedSpace = false;
1538 while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
1539 if (!IsDefault || !HasNonDefaultVal) {
1540 if (NeedSpace)
1541 O << ' ';
1542 O << Name << '(' << Val << ')';
1543 NeedSpace = true;
1544 }
1545 }
1546 } else {
1547 O << formatHex(Imm16);
1548 }
1549}
1550
1552 const MCSubtargetInfo &STI,
1553 raw_ostream &O) {
1554 const char *BadInstId = "/* invalid instid value */";
1555 static const std::array<const char *, 12> InstIds = {
1556 "NO_DEP", "VALU_DEP_1", "VALU_DEP_2",
1557 "VALU_DEP_3", "VALU_DEP_4", "TRANS32_DEP_1",
1558 "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
1559 "SALU_CYCLE_1", "SALU_CYCLE_2", "SALU_CYCLE_3"};
1560
1561 const char *BadInstSkip = "/* invalid instskip value */";
1562 static const std::array<const char *, 6> InstSkips = {
1563 "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
1564
1565 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1566 const char *Prefix = "";
1567
1568 unsigned Value = SImm16 & 0xF;
1569 if (Value) {
1570 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1571 O << Prefix << "instid0(" << Name << ')';
1572 Prefix = " | ";
1573 }
1574
1575 Value = (SImm16 >> 4) & 7;
1576 if (Value) {
1577 const char *Name =
1578 Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
1579 O << Prefix << "instskip(" << Name << ')';
1580 Prefix = " | ";
1581 }
1582
1583 Value = (SImm16 >> 7) & 0xF;
1584 if (Value) {
1585 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1586 O << Prefix << "instid1(" << Name << ')';
1587 Prefix = " | ";
1588 }
1589
1590 if (!*Prefix)
1591 O << "0";
1592}
1593
1594void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1595 const MCSubtargetInfo &STI, raw_ostream &O) {
1596 unsigned Id;
1597 unsigned Offset;
1598 unsigned Width;
1599
1600 using namespace llvm::AMDGPU::Hwreg;
1601 unsigned Val = MI->getOperand(OpNo).getImm();
1602 decodeHwreg(Val, Id, Offset, Width);
1603 StringRef HwRegName = getHwreg(Id, STI);
1604
1605 O << "hwreg(";
1606 if (!HwRegName.empty()) {
1607 O << HwRegName;
1608 } else {
1609 O << Id;
1610 }
1611 if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) {
1612 O << ", " << Offset << ", " << Width;
1613 }
1614 O << ')';
1615}
1616
1617void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1618 const MCSubtargetInfo &STI,
1619 raw_ostream &O) {
1620 uint16_t Imm = MI->getOperand(OpNo).getImm();
1621 if (Imm == 0) {
1622 return;
1623 }
1624
1625 O << ' ' << formatDec(Imm);
1626}
1627
1628#include "AMDGPUGenAsmWriter.inc"
unsigned const MachineRegisterInfo * MRI
static void printSwizzleBitmask(const uint16_t AndMask, const uint16_t OrMask, const uint16_t XorMask, raw_ostream &O)
static bool allOpsDefaultValue(const int *Ops, int NumOps, int Mod, bool IsPacked, bool HasDstSel)
static cl::opt< bool > Keep16BitSuffixes("amdgpu-keep-16-bit-reg-suffixes", cl::desc("Keep .l and .h suffixes in asm for debugging purposes"), cl::init(false), cl::ReallyHidden)
Provides AMDGPU specific target descriptions.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
IRTranslator LLVM IR MI
#define RegName(no)
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Interface definition for SIRegisterInfo.
raw_pwrite_stream & OS
@ Flags
Definition: TextStubV5.cpp:93
void printSwizzle(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printClampSI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printDelayFlag(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printEndpgm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
static const char * getRegisterName(MCRegister Reg)
static void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O, StringRef Asm, StringRef Default="")
void printDepCtr(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printHwreg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printSendMsg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &OS, MCRegister Reg) const override
Print the assembler register name.
static void printRegOperand(unsigned RegNo, raw_ostream &O, const MCRegisterInfo &MRI)
void printWaitFlag(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printOModSI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printHigh(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
Definition: MCInstPrinter.h:51
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:52
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:50
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
ArrayRef< MCOperandInfo > operands() const
Definition: MCInstrDesc.h:239
bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
Definition: MCInstrDesc.cpp:32
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
MCRegisterClass - Base class of TargetRegisterClass.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const char * getRegClassName(const MCRegisterClass *Class) const
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
StringRef getCPU() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
bool getTgtName(unsigned Id, StringRef &Name, int &Index)
bool isValidUnifiedFormat(unsigned Id, const MCSubtargetInfo &STI)
StringRef getUnifiedFormatName(unsigned Id, const MCSubtargetInfo &STI)
bool isValidDfmtNfmt(unsigned Id, const MCSubtargetInfo &STI)
StringRef getDfmtName(unsigned Id)
StringRef getNfmtName(unsigned Id, const MCSubtargetInfo &STI)
void decodeDfmtNfmt(unsigned Format, unsigned &Dfmt, unsigned &Nfmt)
const char *const IdSymbolic[]
void decodeWaitcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned &Vmcnt, unsigned &Expcnt, unsigned &Lgkmcnt)
Decodes Vmcnt, Expcnt and Lgkmcnt from given Waitcnt for given isa Version, and writes decoded values...
LLVM_READNONE bool isLegal64BitDPPControl(unsigned DC)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For FLAT segment the offset must be positive; MSB is ignored and forced to zero.
unsigned mc2PseudoReg(unsigned Reg)
Convert hardware register Reg to a pseudo register.
bool isGFX940(const MCSubtargetInfo &STI)
IsaVersion getIsaVersion(StringRef GPU)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
bool isSI(const MCSubtargetInfo &STI)
bool getVOP3IsSingle(unsigned Opc)
bool getVOP1IsSingle(unsigned Opc)
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
unsigned getVmcntBitMask(const IsaVersion &Version)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
unsigned getLgkmcntBitMask(const IsaVersion &Version)
unsigned getExpcntBitMask(const IsaVersion &Version)
bool isInlineValue(unsigned Reg)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ OPERAND_REG_IMM_INT64
Definition: SIDefines.h:168
@ OPERAND_REG_IMM_V2FP16
Definition: SIDefines.h:175
@ OPERAND_REG_INLINE_C_V2INT32
Definition: SIDefines.h:189
@ OPERAND_REG_INLINE_C_FP64
Definition: SIDefines.h:186
@ OPERAND_REG_IMM_V2INT16
Definition: SIDefines.h:176
@ OPERAND_REG_INLINE_AC_V2FP16
Definition: SIDefines.h:203
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
Definition: SIDefines.h:167
@ OPERAND_REG_IMM_FP16
Definition: SIDefines.h:172
@ OPERAND_REG_INLINE_C_INT64
Definition: SIDefines.h:183
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition: SIDefines.h:181
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
Definition: SIDefines.h:197
@ OPERAND_REG_IMM_FP64
Definition: SIDefines.h:171
@ OPERAND_REG_INLINE_C_V2FP16
Definition: SIDefines.h:188
@ OPERAND_REG_INLINE_AC_V2INT16
Definition: SIDefines.h:202
@ OPERAND_REG_INLINE_AC_FP16
Definition: SIDefines.h:199
@ OPERAND_REG_INLINE_AC_INT32
Definition: SIDefines.h:198
@ OPERAND_REG_INLINE_AC_FP32
Definition: SIDefines.h:200
@ OPERAND_REG_IMM_V2INT32
Definition: SIDefines.h:177
@ OPERAND_REG_IMM_FP32
Definition: SIDefines.h:170
@ OPERAND_REG_INLINE_C_FP32
Definition: SIDefines.h:185
@ OPERAND_REG_INLINE_C_INT32
Definition: SIDefines.h:182
@ OPERAND_REG_INLINE_C_V2INT16
Definition: SIDefines.h:187
@ OPERAND_REG_IMM_V2FP32
Definition: SIDefines.h:178
@ OPERAND_REG_INLINE_AC_FP64
Definition: SIDefines.h:201
@ OPERAND_REG_INLINE_C_FP16
Definition: SIDefines.h:184
@ OPERAND_REG_IMM_INT16
Definition: SIDefines.h:169
@ OPERAND_REG_INLINE_C_V2FP32
Definition: SIDefines.h:190
@ OPERAND_REG_IMM_FP32_DEFERRED
Definition: SIDefines.h:174
@ OPERAND_REG_IMM_FP16_DEFERRED
Definition: SIDefines.h:173
bool isCI(const MCSubtargetInfo &STI)
bool getVOP2IsSingle(unsigned Opc)
bool isPermlane16(unsigned Opc)
@ OPERAND_REGISTER
Definition: MCInstrDesc.h:61
@ OPERAND_IMMEDIATE
Definition: MCInstrDesc.h:60
@ OPERAND_UNKNOWN
Definition: MCInstrDesc.h:59
Reg
All possible values of the reg field in the ModR/M byte.
@ ReallyHidden
Definition: CommandLine.h:139
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition: bit.h:349
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:297
@ Mod
The access may modify the value stored in memory.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
Definition: MathExtras.h:502
@ Default
The result values are uniform if and only if all operands are uniform.
#define N
Instruction set architecture version.
Definition: TargetParser.h:112