LLVM 19.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"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCInstrDesc.h"
18#include "llvm/MC/MCInstrInfo.h"
23
24using namespace llvm;
25using namespace llvm::AMDGPU;
26
28 // FIXME: The current implementation of
29 // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
30 // as an integer or we provide a name which represents a physical register.
31 // For CFI instructions we really want to emit a name for the DWARF register
32 // instead, because there may be multiple DWARF registers corresponding to a
33 // single physical register. One case where this problem manifests is with
34 // wave32/wave64 where using the physical register name is ambiguous: if we
35 // write e.g. `.cfi_undefined v0` we lose information about the wavefront
36 // size which we need to encode the register in the final DWARF. Ideally we
37 // would extend MC to support parsing DWARF register names so we could do
38 // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
39 // non-pretty DWARF register names in assembly text.
40 OS << Reg.id();
41}
42
44 StringRef Annot, const MCSubtargetInfo &STI,
45 raw_ostream &OS) {
46 OS.flush();
48 printAnnotation(OS, Annot);
49}
50
51void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
52 const MCSubtargetInfo &STI,
53 raw_ostream &O) {
54 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
55}
56
57void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
58 const MCSubtargetInfo &STI,
59 raw_ostream &O) {
60 // It's possible to end up with a 32-bit literal used with a 16-bit operand
61 // with ignored high bits. Print as 32-bit anyway in that case.
62 int64_t Imm = MI->getOperand(OpNo).getImm();
63 if (isInt<16>(Imm) || isUInt<16>(Imm))
64 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
65 else
66 printU32ImmOperand(MI, OpNo, STI, O);
67}
68
69void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
70 raw_ostream &O) {
71 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
72}
73
74void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
75 raw_ostream &O) {
76 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
77}
78
79void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
80 raw_ostream &O) {
81 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
82}
83
84void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
85 const MCSubtargetInfo &STI,
86 raw_ostream &O) {
87 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
88}
89
90void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
91 raw_ostream &O, StringRef BitName) {
92 if (MI->getOperand(OpNo).getImm()) {
93 O << ' ' << BitName;
94 }
95}
96
97void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
98 const MCSubtargetInfo &STI,
99 raw_ostream &O) {
100 uint32_t Imm = MI->getOperand(OpNo).getImm();
101 if (Imm != 0) {
102 O << " offset:";
103
104 // GFX12 uses a 24-bit signed offset for VBUFFER.
105 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
106 bool IsVBuffer = Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF);
107 if (AMDGPU::isGFX12(STI) && IsVBuffer)
108 O << formatDec(SignExtend32<24>(Imm));
109 else
110 printU16ImmDecOperand(MI, OpNo, O);
111 }
112}
113
114void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
115 const MCSubtargetInfo &STI,
116 raw_ostream &O) {
117 uint32_t Imm = MI->getOperand(OpNo).getImm();
118 if (Imm != 0) {
119 O << " offset:";
120
121 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
122 bool AllowNegative = (Desc.TSFlags & (SIInstrFlags::FlatGlobal |
124 AMDGPU::isGFX12(STI);
125
126 if (AllowNegative) // Signed offset
128 else // Unsigned offset
129 printU16ImmDecOperand(MI, OpNo, O);
130 }
131}
132
133void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
134 const MCSubtargetInfo &STI,
135 raw_ostream &O) {
136 if (MI->getOperand(OpNo).getImm()) {
137 O << " offset0:";
138 printU8ImmDecOperand(MI, OpNo, O);
139 }
140}
141
142void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
143 const MCSubtargetInfo &STI,
144 raw_ostream &O) {
145 if (MI->getOperand(OpNo).getImm()) {
146 O << " offset1:";
147 printU8ImmDecOperand(MI, OpNo, O);
148 }
149}
150
151void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
152 const MCSubtargetInfo &STI,
153 raw_ostream &O) {
154 printU32ImmOperand(MI, OpNo, STI, O);
155}
156
157void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
158 const MCSubtargetInfo &STI,
159 raw_ostream &O) {
160 O << formatHex(MI->getOperand(OpNo).getImm());
161}
162
163void AMDGPUInstPrinter::printSMEMOffsetMod(const MCInst *MI, unsigned OpNo,
164 const MCSubtargetInfo &STI,
165 raw_ostream &O) {
166 O << " offset:";
167 printSMEMOffset(MI, OpNo, STI, O);
168}
169
170void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
171 const MCSubtargetInfo &STI,
172 raw_ostream &O) {
173 printU32ImmOperand(MI, OpNo, STI, O);
174}
175
176void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
177 const MCSubtargetInfo &STI, raw_ostream &O) {
178 auto Imm = MI->getOperand(OpNo).getImm();
179
180 if (AMDGPU::isGFX12Plus(STI)) {
181 const int64_t TH = Imm & CPol::TH;
182 const int64_t Scope = Imm & CPol::SCOPE;
183
184 printTH(MI, TH, Scope, O);
185 printScope(Scope, O);
186
187 return;
188 }
189
190 if (Imm & CPol::GLC)
191 O << ((AMDGPU::isGFX940(STI) &&
192 !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"
193 : " glc");
194 if (Imm & CPol::SLC)
195 O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
196 if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
197 O << " dlc";
198 if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
199 O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
200 if (Imm & ~CPol::ALL)
201 O << " /* unexpected cache policy bit */";
202}
203
204void AMDGPUInstPrinter::printTH(const MCInst *MI, int64_t TH, int64_t Scope,
205 raw_ostream &O) {
206 // For th = 0 do not print this field
207 if (TH == 0)
208 return;
209
210 const unsigned Opcode = MI->getOpcode();
211 const MCInstrDesc &TID = MII.get(Opcode);
212 bool IsStore = TID.mayStore();
213 bool IsAtomic =
215
216 O << " th:";
217
218 if (IsAtomic) {
219 O << "TH_ATOMIC_";
221 if (Scope >= AMDGPU::CPol::SCOPE_DEV)
222 O << "CASCADE" << (TH & AMDGPU::CPol::TH_ATOMIC_NT ? "_NT" : "_RT");
223 else
224 O << formatHex(TH);
225 } else if (TH & AMDGPU::CPol::TH_ATOMIC_NT)
226 O << "NT" << (TH & AMDGPU::CPol::TH_ATOMIC_RETURN ? "_RETURN" : "");
227 else if (TH & AMDGPU::CPol::TH_ATOMIC_RETURN)
228 O << "RETURN";
229 else
230 O << formatHex(TH);
231 } else {
232 if (!IsStore && TH == AMDGPU::CPol::TH_RESERVED)
233 O << formatHex(TH);
234 else {
235 // This will default to printing load variants when neither MayStore nor
236 // MayLoad flag is present which is the case with instructions like
237 // image_get_resinfo.
238 O << (IsStore ? "TH_STORE_" : "TH_LOAD_");
239 switch (TH) {
241 O << "NT";
242 break;
244 O << "HT";
245 break;
246 case AMDGPU::CPol::TH_BYPASS: // or LU or RT_WB
247 O << (Scope == AMDGPU::CPol::SCOPE_SYS ? "BYPASS"
248 : (IsStore ? "RT_WB" : "LU"));
249 break;
251 O << "NT_RT";
252 break;
254 O << "RT_NT";
255 break;
257 O << "NT_HT";
258 break;
260 O << "NT_WB";
261 break;
262 default:
263 llvm_unreachable("unexpected th value");
264 }
265 }
266 }
267}
268
269void AMDGPUInstPrinter::printScope(int64_t Scope, raw_ostream &O) {
270 if (Scope == CPol::SCOPE_CU)
271 return;
272
273 O << " scope:";
274
275 if (Scope == CPol::SCOPE_SE)
276 O << "SCOPE_SE";
277 else if (Scope == CPol::SCOPE_DEV)
278 O << "SCOPE_DEV";
279 else if (Scope == CPol::SCOPE_SYS)
280 O << "SCOPE_SYS";
281 else
282 llvm_unreachable("unexpected scope policy value");
283
284 return;
285}
286
287void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
288 const MCSubtargetInfo &STI, raw_ostream &O) {
289 if (MI->getOperand(OpNo).getImm()) {
290 O << " dmask:";
291 printU16ImmOperand(MI, OpNo, STI, O);
292 }
293}
294
295void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
296 const MCSubtargetInfo &STI, raw_ostream &O) {
297 unsigned Dim = MI->getOperand(OpNo).getImm();
298 O << " dim:SQ_RSRC_IMG_";
299
301 if (DimInfo)
302 O << DimInfo->AsmSuffix;
303 else
304 O << Dim;
305}
306
307void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
308 const MCSubtargetInfo &STI, raw_ostream &O) {
309 if (STI.hasFeature(AMDGPU::FeatureR128A16))
310 printNamedBit(MI, OpNo, O, "a16");
311 else
312 printNamedBit(MI, OpNo, O, "r128");
313}
314
315void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
316 const MCSubtargetInfo &STI,
317 raw_ostream &O) {
318}
319
320void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
321 const MCSubtargetInfo &STI,
322 raw_ostream &O) {
323 using namespace llvm::AMDGPU::MTBUFFormat;
324
325 int OpNo =
326 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
327 assert(OpNo != -1);
328
329 unsigned Val = MI->getOperand(OpNo).getImm();
330 if (AMDGPU::isGFX10Plus(STI)) {
331 if (Val == UFMT_DEFAULT)
332 return;
333 if (isValidUnifiedFormat(Val, STI)) {
334 O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
335 } else {
336 O << " format:" << Val;
337 }
338 } else {
339 if (Val == DFMT_NFMT_DEFAULT)
340 return;
341 if (isValidDfmtNfmt(Val, STI)) {
342 unsigned Dfmt;
343 unsigned Nfmt;
344 decodeDfmtNfmt(Val, Dfmt, Nfmt);
345 O << " format:[";
346 if (Dfmt != DFMT_DEFAULT) {
347 O << getDfmtName(Dfmt);
348 if (Nfmt != NFMT_DEFAULT) {
349 O << ',';
350 }
351 }
352 if (Nfmt != NFMT_DEFAULT) {
353 O << getNfmtName(Nfmt, STI);
354 }
355 O << ']';
356 } else {
357 O << " format:" << Val;
358 }
359 }
360}
361
363 const MCRegisterInfo &MRI) {
364#if !defined(NDEBUG)
365 switch (RegNo) {
366 case AMDGPU::FP_REG:
367 case AMDGPU::SP_REG:
368 case AMDGPU::PRIVATE_RSRC_REG:
369 llvm_unreachable("pseudo-register should not ever be emitted");
370 case AMDGPU::SCC:
371 llvm_unreachable("pseudo scc should not ever be emitted");
372 default:
373 break;
374 }
375#endif
376
377 O << getRegisterName(RegNo);
378}
379
380void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
381 const MCSubtargetInfo &STI, raw_ostream &O) {
382 auto Opcode = MI->getOpcode();
383 auto Flags = MII.get(Opcode).TSFlags;
384 if (OpNo == 0) {
385 if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)
386 O << "_e64_dpp";
387 else if (Flags & SIInstrFlags::VOP3) {
388 if (!getVOP3IsSingle(Opcode))
389 O << "_e64";
390 } else if (Flags & SIInstrFlags::DPP)
391 O << "_dpp";
392 else if (Flags & SIInstrFlags::SDWA)
393 O << "_sdwa";
394 else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
395 ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))
396 O << "_e32";
397 O << " ";
398 }
399
400 printRegularOperand(MI, OpNo, STI, O);
401
402 // Print default vcc/vcc_lo operand.
403 switch (Opcode) {
404 default: break;
405
406 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
407 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
408 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
409 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
410 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
411 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
412 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
413 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
414 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
415 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
416 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
417 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
418 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
419 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
420 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
421 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
422 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
423 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
424 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
425 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
426 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
427 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
428 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
429 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
430 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
431 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
432 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
433 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
434 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
435 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
436 printDefaultVccOperand(false, STI, O);
437 break;
438 }
439}
440
441void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
442 const MCSubtargetInfo &STI, raw_ostream &O) {
443 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
444 O << " ";
445 else
446 O << "_e32 ";
447
448 printRegularOperand(MI, OpNo, STI, O);
449}
450
451void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
452 const MCSubtargetInfo &STI,
453 raw_ostream &O) {
454 int32_t SImm = static_cast<int32_t>(Imm);
455 if (isInlinableIntLiteral(SImm)) {
456 O << SImm;
457 return;
458 }
459
460 if (printImmediateFloat32(Imm, STI, O))
461 return;
462
463 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
464}
465
466static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI,
467 raw_ostream &O) {
468 if (Imm == 0x3C00)
469 O << "1.0";
470 else if (Imm == 0xBC00)
471 O << "-1.0";
472 else if (Imm == 0x3800)
473 O << "0.5";
474 else if (Imm == 0xB800)
475 O << "-0.5";
476 else if (Imm == 0x4000)
477 O << "2.0";
478 else if (Imm == 0xC000)
479 O << "-2.0";
480 else if (Imm == 0x4400)
481 O << "4.0";
482 else if (Imm == 0xC400)
483 O << "-4.0";
484 else if (Imm == 0x3118 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
485 O << "0.15915494";
486 else
487 return false;
488
489 return true;
490}
491
493 raw_ostream &O) {
494 if (Imm == 0x3F80)
495 O << "1.0";
496 else if (Imm == 0xBF80)
497 O << "-1.0";
498 else if (Imm == 0x3F00)
499 O << "0.5";
500 else if (Imm == 0xBF00)
501 O << "-0.5";
502 else if (Imm == 0x4000)
503 O << "2.0";
504 else if (Imm == 0xC000)
505 O << "-2.0";
506 else if (Imm == 0x4080)
507 O << "4.0";
508 else if (Imm == 0xC080)
509 O << "-4.0";
510 else if (Imm == 0x3E22 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
511 O << "0.15915494";
512 else
513 return false;
514
515 return true;
516}
517
518void AMDGPUInstPrinter::printImmediateBF16(uint32_t Imm,
519 const MCSubtargetInfo &STI,
520 raw_ostream &O) {
521 int16_t SImm = static_cast<int16_t>(Imm);
522 if (isInlinableIntLiteral(SImm)) {
523 O << SImm;
524 return;
525 }
526
527 if (printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
528 return;
529
530 O << formatHex(static_cast<uint64_t>(Imm));
531}
532
533void AMDGPUInstPrinter::printImmediateF16(uint32_t Imm,
534 const MCSubtargetInfo &STI,
535 raw_ostream &O) {
536 int16_t SImm = static_cast<int16_t>(Imm);
537 if (isInlinableIntLiteral(SImm)) {
538 O << SImm;
539 return;
540 }
541
542 uint16_t HImm = static_cast<uint16_t>(Imm);
543 if (printImmediateFP16(HImm, STI, O))
544 return;
545
546 uint64_t Imm16 = static_cast<uint16_t>(Imm);
547 O << formatHex(Imm16);
548}
549
550void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, uint8_t OpType,
551 const MCSubtargetInfo &STI,
552 raw_ostream &O) {
553 int32_t SImm = static_cast<int32_t>(Imm);
554 if (isInlinableIntLiteral(SImm)) {
555 O << SImm;
556 return;
557 }
558
559 switch (OpType) {
563 if (printImmediateFloat32(Imm, STI, O))
564 return;
565 break;
569 if (isUInt<16>(Imm) &&
570 printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
571 return;
572 break;
576 if (isUInt<16>(Imm) &&
577 printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
578 return;
579 break;
580 default:
581 llvm_unreachable("bad operand type");
582 }
583
584 O << formatHex(static_cast<uint64_t>(Imm));
585}
586
587bool AMDGPUInstPrinter::printImmediateFloat32(uint32_t Imm,
588 const MCSubtargetInfo &STI,
589 raw_ostream &O) {
590 if (Imm == llvm::bit_cast<uint32_t>(0.0f))
591 O << "0.0";
592 else if (Imm == llvm::bit_cast<uint32_t>(1.0f))
593 O << "1.0";
594 else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))
595 O << "-1.0";
596 else if (Imm == llvm::bit_cast<uint32_t>(0.5f))
597 O << "0.5";
598 else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))
599 O << "-0.5";
600 else if (Imm == llvm::bit_cast<uint32_t>(2.0f))
601 O << "2.0";
602 else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))
603 O << "-2.0";
604 else if (Imm == llvm::bit_cast<uint32_t>(4.0f))
605 O << "4.0";
606 else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))
607 O << "-4.0";
608 else if (Imm == 0x3e22f983 &&
609 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
610 O << "0.15915494";
611 else
612 return false;
613
614 return true;
615}
616
617void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
618 const MCSubtargetInfo &STI,
619 raw_ostream &O) {
620 int32_t SImm = static_cast<int32_t>(Imm);
621 if (isInlinableIntLiteral(SImm)) {
622 O << SImm;
623 return;
624 }
625
626 if (printImmediateFloat32(Imm, STI, O))
627 return;
628
629 O << formatHex(static_cast<uint64_t>(Imm));
630}
631
632void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
633 const MCSubtargetInfo &STI,
634 raw_ostream &O, bool IsFP) {
635 int64_t SImm = static_cast<int64_t>(Imm);
636 if (SImm >= -16 && SImm <= 64) {
637 O << SImm;
638 return;
639 }
640
641 if (Imm == llvm::bit_cast<uint64_t>(0.0))
642 O << "0.0";
643 else if (Imm == llvm::bit_cast<uint64_t>(1.0))
644 O << "1.0";
645 else if (Imm == llvm::bit_cast<uint64_t>(-1.0))
646 O << "-1.0";
647 else if (Imm == llvm::bit_cast<uint64_t>(0.5))
648 O << "0.5";
649 else if (Imm == llvm::bit_cast<uint64_t>(-0.5))
650 O << "-0.5";
651 else if (Imm == llvm::bit_cast<uint64_t>(2.0))
652 O << "2.0";
653 else if (Imm == llvm::bit_cast<uint64_t>(-2.0))
654 O << "-2.0";
655 else if (Imm == llvm::bit_cast<uint64_t>(4.0))
656 O << "4.0";
657 else if (Imm == llvm::bit_cast<uint64_t>(-4.0))
658 O << "-4.0";
659 else if (Imm == 0x3fc45f306dc9c882 &&
660 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
661 O << "0.15915494309189532";
662 else if (IsFP) {
664 O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
665 } else {
666 assert(isUInt<32>(Imm) || isInt<32>(Imm));
667
668 // In rare situations, we will have a 32-bit literal in a 64-bit
669 // operand. This is technically allowed for the encoding of s_mov_b64.
670 O << formatHex(static_cast<uint64_t>(Imm));
671 }
672}
673
674void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
675 const MCSubtargetInfo &STI,
676 raw_ostream &O) {
677 unsigned Imm = MI->getOperand(OpNo).getImm();
678 if (!Imm)
679 return;
680
681 if (AMDGPU::isGFX940(STI)) {
682 switch (MI->getOpcode()) {
683 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
684 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
685 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
686 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
687 O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
688 << ((Imm >> 2) & 1) << ']';
689 return;
690 }
691 }
692
693 O << " blgp:" << Imm;
694}
695
696void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
697 const MCSubtargetInfo &STI,
698 raw_ostream &O) {
699 unsigned Imm = MI->getOperand(OpNo).getImm();
700 if (!Imm)
701 return;
702
703 O << " cbsz:" << Imm;
704}
705
706void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
707 const MCSubtargetInfo &STI,
708 raw_ostream &O) {
709 unsigned Imm = MI->getOperand(OpNo).getImm();
710 if (!Imm)
711 return;
712
713 O << " abid:" << Imm;
714}
715
716void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
717 const MCSubtargetInfo &STI,
718 raw_ostream &O) {
719 if (!FirstOperand)
720 O << ", ";
721 printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize64)
722 ? AMDGPU::VCC
723 : AMDGPU::VCC_LO,
724 O, MRI);
725 if (FirstOperand)
726 O << ", ";
727}
728
729void AMDGPUInstPrinter::printWaitVDST(const MCInst *MI, unsigned OpNo,
730 const MCSubtargetInfo &STI,
731 raw_ostream &O) {
732 O << " wait_vdst:";
733 printU4ImmDecOperand(MI, OpNo, O);
734}
735
736void AMDGPUInstPrinter::printWaitVAVDst(const MCInst *MI, unsigned OpNo,
737 const MCSubtargetInfo &STI,
738 raw_ostream &O) {
739 O << " wait_va_vdst:";
740 printU4ImmDecOperand(MI, OpNo, O);
741}
742
743void AMDGPUInstPrinter::printWaitVMVSrc(const MCInst *MI, unsigned OpNo,
744 const MCSubtargetInfo &STI,
745 raw_ostream &O) {
746 O << " wait_vm_vsrc:";
747 printU4ImmDecOperand(MI, OpNo, O);
748}
749
750void AMDGPUInstPrinter::printWaitEXP(const MCInst *MI, unsigned OpNo,
751 const MCSubtargetInfo &STI,
752 raw_ostream &O) {
753 O << " wait_exp:";
754 printU4ImmDecOperand(MI, OpNo, O);
755}
756
757bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
758 unsigned OpNo) const {
759 return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&
760 (Desc.TSFlags & SIInstrFlags::VOPC) &&
761 !isVOPCAsmOnly(Desc.getOpcode()) &&
762 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
763 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
764}
765
766// Print default vcc/vcc_lo operand of VOPC.
767void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
768 const MCSubtargetInfo &STI,
769 raw_ostream &O) {
770 unsigned Opc = MI->getOpcode();
771 const MCInstrDesc &Desc = MII.get(Opc);
772 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
773 // 0, 1 and 2 are the first printed operands in different cases
774 // If there are printed modifiers, printOperandAndFPInputMods or
775 // printOperandAndIntInputMods will be called instead
776 if ((OpNo == 0 ||
777 (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&
778 (Desc.TSFlags & SIInstrFlags::VOPC) && !isVOPCAsmOnly(Desc.getOpcode()) &&
779 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
780 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
781 printDefaultVccOperand(true, STI, O);
782
783 printRegularOperand(MI, OpNo, STI, O);
784}
785
786// Print operands after vcc or modifier handling.
787void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
788 const MCSubtargetInfo &STI,
789 raw_ostream &O) {
790 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
791
792 if (OpNo >= MI->getNumOperands()) {
793 O << "/*Missing OP" << OpNo << "*/";
794 return;
795 }
796
797 const MCOperand &Op = MI->getOperand(OpNo);
798 if (Op.isReg()) {
799 printRegOperand(Op.getReg(), O, MRI);
800
801 // Check if operand register class contains register used.
802 // Intention: print disassembler message when invalid code is decoded,
803 // for example sgpr register used in VReg or VISrc(VReg or imm) operand.
804 int RCID = Desc.operands()[OpNo].RegClass;
805 if (RCID != -1) {
806 const MCRegisterClass RC = MRI.getRegClass(RCID);
807 auto Reg = mc2PseudoReg(Op.getReg());
808 if (!RC.contains(Reg) && !isInlineValue(Reg)) {
809 O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
810 << "\' register class*/";
811 }
812 }
813 } else if (Op.isImm()) {
814 const uint8_t OpTy = Desc.operands()[OpNo].OperandType;
815 switch (OpTy) {
829 printImmediate32(Op.getImm(), STI, O);
830 break;
833 printImmediate64(Op.getImm(), STI, O, false);
834 break;
838 printImmediate64(Op.getImm(), STI, O, true);
839 break;
843 printImmediateInt16(Op.getImm(), STI, O);
844 break;
849 printImmediateF16(Op.getImm(), STI, O);
850 break;
855 printImmediateBF16(Op.getImm(), STI, O);
856 break;
866 printImmediateV216(Op.getImm(), OpTy, STI, O);
867 break;
870 O << formatDec(Op.getImm());
871 break;
873 // Disassembler does not fail when operand should not allow immediate
874 // operands but decodes them into 32bit immediate operand.
875 printImmediate32(Op.getImm(), STI, O);
876 O << "/*Invalid immediate*/";
877 break;
878 default:
879 // We hit this for the immediate instruction bits that don't yet have a
880 // custom printer.
881 llvm_unreachable("unexpected immediate operand type");
882 }
883 } else if (Op.isDFPImm()) {
884 double Value = bit_cast<double>(Op.getDFPImm());
885 // We special case 0.0 because otherwise it will be printed as an integer.
886 if (Value == 0.0)
887 O << "0.0";
888 else {
889 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
890 int RCID = Desc.operands()[OpNo].RegClass;
891 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
892 if (RCBits == 32)
893 printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
894 else if (RCBits == 64)
895 printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O, true);
896 else
897 llvm_unreachable("Invalid register class size");
898 }
899 } else if (Op.isExpr()) {
900 const MCExpr *Exp = Op.getExpr();
901 Exp->print(O, &MAI);
902 } else {
903 O << "/*INV_OP*/";
904 }
905
906 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
907 switch (MI->getOpcode()) {
908 default: break;
909
910 case AMDGPU::V_CNDMASK_B32_e32_gfx10:
911 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
912 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
913 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
914 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
915 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
916 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
917 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
918 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
919 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
920 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
921 case AMDGPU::V_CNDMASK_B32_e32_gfx11:
922 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
923 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
924 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
925 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
926 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
927 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
928 case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
929 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
930 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
931 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
932 case AMDGPU::V_CNDMASK_B32_e32_gfx12:
933 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
934 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
935 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
936 case AMDGPU::V_CNDMASK_B32_dpp_gfx12:
937 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
938 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
939 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
940 case AMDGPU::V_CNDMASK_B32_dpp8_gfx12:
941 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
942 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
943 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
944
945 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
946 case AMDGPU::V_CNDMASK_B32_e32_vi:
947 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
948 AMDGPU::OpName::src1))
949 printDefaultVccOperand(OpNo == 0, STI, O);
950 break;
951 }
952
953 if (Desc.TSFlags & SIInstrFlags::MTBUF) {
954 int SOffsetIdx =
955 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
956 assert(SOffsetIdx != -1);
957 if ((int)OpNo == SOffsetIdx)
958 printSymbolicFormat(MI, STI, O);
959 }
960}
961
962void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
963 unsigned OpNo,
964 const MCSubtargetInfo &STI,
965 raw_ostream &O) {
966 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
967 if (needsImpliedVcc(Desc, OpNo))
968 printDefaultVccOperand(true, STI, O);
969
970 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
971
972 // Use 'neg(...)' instead of '-' to avoid ambiguity.
973 // This is important for integer literals because
974 // -1 is not the same value as neg(1).
975 bool NegMnemo = false;
976
977 if (InputModifiers & SISrcMods::NEG) {
978 if (OpNo + 1 < MI->getNumOperands() &&
979 (InputModifiers & SISrcMods::ABS) == 0) {
980 const MCOperand &Op = MI->getOperand(OpNo + 1);
981 NegMnemo = Op.isImm() || Op.isDFPImm();
982 }
983 if (NegMnemo) {
984 O << "neg(";
985 } else {
986 O << '-';
987 }
988 }
989
990 if (InputModifiers & SISrcMods::ABS)
991 O << '|';
992 printRegularOperand(MI, OpNo + 1, STI, O);
993 if (InputModifiers & SISrcMods::ABS)
994 O << '|';
995
996 if (NegMnemo) {
997 O << ')';
998 }
999
1000 // Print default vcc/vcc_lo operand of VOP2b.
1001 switch (MI->getOpcode()) {
1002 default:
1003 break;
1004
1005 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
1006 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
1007 case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
1008 if ((int)OpNo + 1 ==
1009 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))
1010 printDefaultVccOperand(OpNo == 0, STI, O);
1011 break;
1012 }
1013}
1014
1015void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
1016 unsigned OpNo,
1017 const MCSubtargetInfo &STI,
1018 raw_ostream &O) {
1019 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1020 if (needsImpliedVcc(Desc, OpNo))
1021 printDefaultVccOperand(true, STI, O);
1022
1023 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
1024 if (InputModifiers & SISrcMods::SEXT)
1025 O << "sext(";
1026 printRegularOperand(MI, OpNo + 1, STI, O);
1027 if (InputModifiers & SISrcMods::SEXT)
1028 O << ')';
1029
1030 // Print default vcc/vcc_lo operand of VOP2b.
1031 switch (MI->getOpcode()) {
1032 default: break;
1033
1034 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
1035 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
1036 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
1037 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
1038 AMDGPU::OpName::src1))
1039 printDefaultVccOperand(OpNo == 0, STI, O);
1040 break;
1041 }
1042}
1043
1044void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
1045 const MCSubtargetInfo &STI,
1046 raw_ostream &O) {
1047 if (!AMDGPU::isGFX10Plus(STI))
1048 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
1049
1050 unsigned Imm = MI->getOperand(OpNo).getImm();
1051 O << "dpp8:[" << formatDec(Imm & 0x7);
1052 for (size_t i = 1; i < 8; ++i) {
1053 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
1054 }
1055 O << ']';
1056}
1057
1058void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
1059 const MCSubtargetInfo &STI,
1060 raw_ostream &O) {
1061 using namespace AMDGPU::DPP;
1062
1063 unsigned Imm = MI->getOperand(OpNo).getImm();
1064 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1065
1067 O << " /* DP ALU dpp only supports row_newbcast */";
1068 return;
1069 } else if (Imm <= DppCtrl::QUAD_PERM_LAST) {
1070 O << "quad_perm:[";
1071 O << formatDec(Imm & 0x3) << ',';
1072 O << formatDec((Imm & 0xc) >> 2) << ',';
1073 O << formatDec((Imm & 0x30) >> 4) << ',';
1074 O << formatDec((Imm & 0xc0) >> 6) << ']';
1075 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
1076 (Imm <= DppCtrl::ROW_SHL_LAST)) {
1077 O << "row_shl:";
1078 printU4ImmDecOperand(MI, OpNo, O);
1079 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
1080 (Imm <= DppCtrl::ROW_SHR_LAST)) {
1081 O << "row_shr:";
1082 printU4ImmDecOperand(MI, OpNo, O);
1083 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
1084 (Imm <= DppCtrl::ROW_ROR_LAST)) {
1085 O << "row_ror:";
1086 printU4ImmDecOperand(MI, OpNo, O);
1087 } else if (Imm == DppCtrl::WAVE_SHL1) {
1088 if (AMDGPU::isGFX10Plus(STI)) {
1089 O << "/* wave_shl is not supported starting from GFX10 */";
1090 return;
1091 }
1092 O << "wave_shl:1";
1093 } else if (Imm == DppCtrl::WAVE_ROL1) {
1094 if (AMDGPU::isGFX10Plus(STI)) {
1095 O << "/* wave_rol is not supported starting from GFX10 */";
1096 return;
1097 }
1098 O << "wave_rol:1";
1099 } else if (Imm == DppCtrl::WAVE_SHR1) {
1100 if (AMDGPU::isGFX10Plus(STI)) {
1101 O << "/* wave_shr is not supported starting from GFX10 */";
1102 return;
1103 }
1104 O << "wave_shr:1";
1105 } else if (Imm == DppCtrl::WAVE_ROR1) {
1106 if (AMDGPU::isGFX10Plus(STI)) {
1107 O << "/* wave_ror is not supported starting from GFX10 */";
1108 return;
1109 }
1110 O << "wave_ror:1";
1111 } else if (Imm == DppCtrl::ROW_MIRROR) {
1112 O << "row_mirror";
1113 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
1114 O << "row_half_mirror";
1115 } else if (Imm == DppCtrl::BCAST15) {
1116 if (AMDGPU::isGFX10Plus(STI)) {
1117 O << "/* row_bcast is not supported starting from GFX10 */";
1118 return;
1119 }
1120 O << "row_bcast:15";
1121 } else if (Imm == DppCtrl::BCAST31) {
1122 if (AMDGPU::isGFX10Plus(STI)) {
1123 O << "/* row_bcast is not supported starting from GFX10 */";
1124 return;
1125 }
1126 O << "row_bcast:31";
1127 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
1128 (Imm <= DppCtrl::ROW_SHARE_LAST)) {
1129 if (AMDGPU::isGFX90A(STI)) {
1130 O << "row_newbcast:";
1131 } else if (AMDGPU::isGFX10Plus(STI)) {
1132 O << "row_share:";
1133 } else {
1134 O << " /* row_newbcast/row_share is not supported on ASICs earlier "
1135 "than GFX90A/GFX10 */";
1136 return;
1137 }
1138 printU4ImmDecOperand(MI, OpNo, O);
1139 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
1140 (Imm <= DppCtrl::ROW_XMASK_LAST)) {
1141 if (!AMDGPU::isGFX10Plus(STI)) {
1142 O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
1143 return;
1144 }
1145 O << "row_xmask:";
1146 printU4ImmDecOperand(MI, OpNo, O);
1147 } else {
1148 O << "/* Invalid dpp_ctrl value */";
1149 }
1150}
1151
1152void AMDGPUInstPrinter::printDppRowMask(const MCInst *MI, unsigned OpNo,
1153 const MCSubtargetInfo &STI,
1154 raw_ostream &O) {
1155 O << " row_mask:";
1156 printU4ImmOperand(MI, OpNo, STI, O);
1157}
1158
1159void AMDGPUInstPrinter::printDppBankMask(const MCInst *MI, unsigned OpNo,
1160 const MCSubtargetInfo &STI,
1161 raw_ostream &O) {
1162 O << " bank_mask:";
1163 printU4ImmOperand(MI, OpNo, STI, O);
1164}
1165
1166void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,
1167 const MCSubtargetInfo &STI,
1168 raw_ostream &O) {
1169 unsigned Imm = MI->getOperand(OpNo).getImm();
1170 if (Imm) {
1171 O << " bound_ctrl:1";
1172 }
1173}
1174
1175void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,
1176 const MCSubtargetInfo &STI, raw_ostream &O) {
1177 using namespace llvm::AMDGPU::DPP;
1178 unsigned Imm = MI->getOperand(OpNo).getImm();
1179 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
1180 O << " fi:1";
1181 }
1182}
1183
1184void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
1185 raw_ostream &O) {
1186 using namespace llvm::AMDGPU::SDWA;
1187
1188 unsigned Imm = MI->getOperand(OpNo).getImm();
1189 switch (Imm) {
1190 case SdwaSel::BYTE_0: O << "BYTE_0"; break;
1191 case SdwaSel::BYTE_1: O << "BYTE_1"; break;
1192 case SdwaSel::BYTE_2: O << "BYTE_2"; break;
1193 case SdwaSel::BYTE_3: O << "BYTE_3"; break;
1194 case SdwaSel::WORD_0: O << "WORD_0"; break;
1195 case SdwaSel::WORD_1: O << "WORD_1"; break;
1196 case SdwaSel::DWORD: O << "DWORD"; break;
1197 default: llvm_unreachable("Invalid SDWA data select operand");
1198 }
1199}
1200
1201void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
1202 const MCSubtargetInfo &STI,
1203 raw_ostream &O) {
1204 O << "dst_sel:";
1205 printSDWASel(MI, OpNo, O);
1206}
1207
1208void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
1209 const MCSubtargetInfo &STI,
1210 raw_ostream &O) {
1211 O << "src0_sel:";
1212 printSDWASel(MI, OpNo, O);
1213}
1214
1215void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
1216 const MCSubtargetInfo &STI,
1217 raw_ostream &O) {
1218 O << "src1_sel:";
1219 printSDWASel(MI, OpNo, O);
1220}
1221
1222void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
1223 const MCSubtargetInfo &STI,
1224 raw_ostream &O) {
1225 using namespace llvm::AMDGPU::SDWA;
1226
1227 O << "dst_unused:";
1228 unsigned Imm = MI->getOperand(OpNo).getImm();
1229 switch (Imm) {
1230 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
1231 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
1232 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
1233 default: llvm_unreachable("Invalid SDWA dest_unused operand");
1234 }
1235}
1236
1237void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
1238 const MCSubtargetInfo &STI, raw_ostream &O,
1239 unsigned N) {
1240 unsigned Opc = MI->getOpcode();
1241 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
1242 unsigned En = MI->getOperand(EnIdx).getImm();
1243
1244 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
1245
1246 // If compr is set, print as src0, src0, src1, src1
1247 if (MI->getOperand(ComprIdx).getImm())
1248 OpNo = OpNo - N + N / 2;
1249
1250 if (En & (1 << N))
1251 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
1252 else
1253 O << "off";
1254}
1255
1256void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
1257 const MCSubtargetInfo &STI,
1258 raw_ostream &O) {
1259 printExpSrcN(MI, OpNo, STI, O, 0);
1260}
1261
1262void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
1263 const MCSubtargetInfo &STI,
1264 raw_ostream &O) {
1265 printExpSrcN(MI, OpNo, STI, O, 1);
1266}
1267
1268void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
1269 const MCSubtargetInfo &STI,
1270 raw_ostream &O) {
1271 printExpSrcN(MI, OpNo, STI, O, 2);
1272}
1273
1274void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
1275 const MCSubtargetInfo &STI,
1276 raw_ostream &O) {
1277 printExpSrcN(MI, OpNo, STI, O, 3);
1278}
1279
1280void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
1281 const MCSubtargetInfo &STI,
1282 raw_ostream &O) {
1283 using namespace llvm::AMDGPU::Exp;
1284
1285 // This is really a 6 bit field.
1286 unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1287
1288 int Index;
1289 StringRef TgtName;
1290 if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1291 O << ' ' << TgtName;
1292 if (Index >= 0)
1293 O << Index;
1294 } else {
1295 O << " invalid_target_" << Id;
1296 }
1297}
1298
1299static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
1300 bool IsPacked, bool HasDstSel) {
1301 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
1302
1303 for (int I = 0; I < NumOps; ++I) {
1304 if (!!(Ops[I] & Mod) != DefaultValue)
1305 return false;
1306 }
1307
1308 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
1309 return false;
1310
1311 return true;
1312}
1313
1314void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
1316 unsigned Mod,
1317 raw_ostream &O) {
1318 unsigned Opc = MI->getOpcode();
1319 int NumOps = 0;
1320 int Ops[3];
1321
1322 std::pair<int, int> MOps[] = {
1323 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src0},
1324 {AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src1},
1325 {AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::src2}};
1326 int DefaultValue = (Mod == SISrcMods::OP_SEL_1);
1327
1328 for (auto [SrcMod, Src] : MOps) {
1329 if (!AMDGPU::hasNamedOperand(Opc, Src))
1330 break;
1331
1332 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, SrcMod);
1333 Ops[NumOps++] =
1334 (ModIdx != -1) ? MI->getOperand(ModIdx).getImm() : DefaultValue;
1335 }
1336
1337 // Print three values of neg/opsel for wmma instructions (prints 0 when there
1338 // is no src_modifier operand instead of not printing anything).
1339 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsSWMMAC ||
1340 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsWMMA) {
1341 NumOps = 0;
1342 int DefaultValue = Mod == SISrcMods::OP_SEL_1;
1343 for (int OpName :
1344 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,
1345 AMDGPU::OpName::src2_modifiers}) {
1347 if (Idx != -1)
1348 Ops[NumOps++] = MI->getOperand(Idx).getImm();
1349 else
1350 Ops[NumOps++] = DefaultValue;
1351 }
1352 }
1353
1354 const bool HasDstSel =
1355 NumOps > 0 &&
1357 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
1358
1359 const bool IsPacked =
1360 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
1361
1362 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1363 return;
1364
1365 O << Name;
1366 for (int I = 0; I < NumOps; ++I) {
1367 if (I != 0)
1368 O << ',';
1369
1370 O << !!(Ops[I] & Mod);
1371 }
1372
1373 if (HasDstSel) {
1374 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1375 }
1376
1377 O << ']';
1378}
1379
1380void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1381 const MCSubtargetInfo &STI,
1382 raw_ostream &O) {
1383 unsigned Opc = MI->getOpcode();
1384 if (isCvt_F32_Fp8_Bf8_e64(Opc)) {
1385 auto SrcMod =
1386 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1387 unsigned Mod = MI->getOperand(SrcMod).getImm();
1388 unsigned Index0 = !!(Mod & SISrcMods::OP_SEL_0);
1389 unsigned Index1 = !!(Mod & SISrcMods::OP_SEL_1);
1390 if (Index0 || Index1)
1391 O << " op_sel:[" << Index0 << ',' << Index1 << ']';
1392 return;
1393 }
1394 if (isPermlane16(Opc)) {
1395 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1396 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1397 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1398 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1399 if (FI || BC)
1400 O << " op_sel:[" << FI << ',' << BC << ']';
1401 return;
1402 }
1403
1404 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1405}
1406
1407void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1408 const MCSubtargetInfo &STI,
1409 raw_ostream &O) {
1410 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1411}
1412
1413void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1414 const MCSubtargetInfo &STI,
1415 raw_ostream &O) {
1416 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1417}
1418
1419void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1420 const MCSubtargetInfo &STI,
1421 raw_ostream &O) {
1422 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1423}
1424
1425void AMDGPUInstPrinter::printIndexKey8bit(const MCInst *MI, unsigned OpNo,
1426 const MCSubtargetInfo &STI,
1427 raw_ostream &O) {
1428 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1429 if (Imm == 0)
1430 return;
1431
1432 O << " index_key:" << Imm;
1433}
1434
1435void AMDGPUInstPrinter::printIndexKey16bit(const MCInst *MI, unsigned OpNo,
1436 const MCSubtargetInfo &STI,
1437 raw_ostream &O) {
1438 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1439 if (Imm == 0)
1440 return;
1441
1442 O << " index_key:" << Imm;
1443}
1444
1445void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1446 const MCSubtargetInfo &STI,
1447 raw_ostream &O) {
1448 unsigned Imm = MI->getOperand(OpNum).getImm();
1449 switch (Imm) {
1450 case 0:
1451 O << "p10";
1452 break;
1453 case 1:
1454 O << "p20";
1455 break;
1456 case 2:
1457 O << "p0";
1458 break;
1459 default:
1460 O << "invalid_param_" << Imm;
1461 }
1462}
1463
1464void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1465 const MCSubtargetInfo &STI,
1466 raw_ostream &O) {
1467 unsigned Attr = MI->getOperand(OpNum).getImm();
1468 O << "attr" << Attr;
1469}
1470
1471void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1472 const MCSubtargetInfo &STI,
1473 raw_ostream &O) {
1474 unsigned Chan = MI->getOperand(OpNum).getImm();
1475 O << '.' << "xyzw"[Chan & 0x3];
1476}
1477
1478void AMDGPUInstPrinter::printGPRIdxMode(const MCInst *MI, unsigned OpNo,
1479 const MCSubtargetInfo &STI,
1480 raw_ostream &O) {
1481 using namespace llvm::AMDGPU::VGPRIndexMode;
1482 unsigned Val = MI->getOperand(OpNo).getImm();
1483
1484 if ((Val & ~ENABLE_MASK) != 0) {
1485 O << formatHex(static_cast<uint64_t>(Val));
1486 } else {
1487 O << "gpr_idx(";
1488 bool NeedComma = false;
1489 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1490 if (Val & (1 << ModeId)) {
1491 if (NeedComma)
1492 O << ',';
1493 O << IdSymbolic[ModeId];
1494 NeedComma = true;
1495 }
1496 }
1497 O << ')';
1498 }
1499}
1500
1501void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1502 const MCSubtargetInfo &STI,
1503 raw_ostream &O) {
1504 printRegularOperand(MI, OpNo, STI, O);
1505 O << ", ";
1506 printRegularOperand(MI, OpNo + 1, STI, O);
1507}
1508
1509void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1510 raw_ostream &O, StringRef Asm,
1512 const MCOperand &Op = MI->getOperand(OpNo);
1513 assert(Op.isImm());
1514 if (Op.getImm() == 1) {
1515 O << Asm;
1516 } else {
1517 O << Default;
1518 }
1519}
1520
1521void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1522 raw_ostream &O, char Asm) {
1523 const MCOperand &Op = MI->getOperand(OpNo);
1524 assert(Op.isImm());
1525 if (Op.getImm() == 1)
1526 O << Asm;
1527}
1528
1529void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1530 const MCSubtargetInfo &STI,
1531 raw_ostream &O) {
1532 int Imm = MI->getOperand(OpNo).getImm();
1533 if (Imm == SIOutMods::MUL2)
1534 O << " mul:2";
1535 else if (Imm == SIOutMods::MUL4)
1536 O << " mul:4";
1537 else if (Imm == SIOutMods::DIV2)
1538 O << " div:2";
1539}
1540
1541void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1542 const MCSubtargetInfo &STI,
1543 raw_ostream &O) {
1544 using namespace llvm::AMDGPU::SendMsg;
1545
1546 const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1547
1548 uint16_t MsgId;
1549 uint16_t OpId;
1551 decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
1552
1553 StringRef MsgName = getMsgName(MsgId, STI);
1554
1555 if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
1556 isValidMsgStream(MsgId, OpId, StreamId, STI)) {
1557 O << "sendmsg(" << MsgName;
1558 if (msgRequiresOp(MsgId, STI)) {
1559 O << ", " << getMsgOpName(MsgId, OpId, STI);
1560 if (msgSupportsStream(MsgId, OpId, STI)) {
1561 O << ", " << StreamId;
1562 }
1563 }
1564 O << ')';
1565 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1566 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1567 } else {
1568 O << Imm16; // Unknown imm16 code.
1569 }
1570}
1571
1572static void printSwizzleBitmask(const uint16_t AndMask,
1573 const uint16_t OrMask,
1574 const uint16_t XorMask,
1575 raw_ostream &O) {
1576 using namespace llvm::AMDGPU::Swizzle;
1577
1578 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1579 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1580
1581 O << "\"";
1582
1583 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1584 uint16_t p0 = Probe0 & Mask;
1585 uint16_t p1 = Probe1 & Mask;
1586
1587 if (p0 == p1) {
1588 if (p0 == 0) {
1589 O << "0";
1590 } else {
1591 O << "1";
1592 }
1593 } else {
1594 if (p0 == 0) {
1595 O << "p";
1596 } else {
1597 O << "i";
1598 }
1599 }
1600 }
1601
1602 O << "\"";
1603}
1604
1605void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1606 const MCSubtargetInfo &STI,
1607 raw_ostream &O) {
1608 using namespace llvm::AMDGPU::Swizzle;
1609
1610 uint16_t Imm = MI->getOperand(OpNo).getImm();
1611 if (Imm == 0) {
1612 return;
1613 }
1614
1615 O << " offset:";
1616
1617 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1618
1619 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1620 for (unsigned I = 0; I < LANE_NUM; ++I) {
1621 O << ",";
1622 O << formatDec(Imm & LANE_MASK);
1623 Imm >>= LANE_SHIFT;
1624 }
1625 O << ")";
1626
1627 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1628
1629 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1630 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1631 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1632
1633 if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {
1634
1635 O << "swizzle(" << IdSymbolic[ID_SWAP];
1636 O << ",";
1637 O << formatDec(XorMask);
1638 O << ")";
1639
1640 } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&
1641 isPowerOf2_64(XorMask + 1)) {
1642
1643 O << "swizzle(" << IdSymbolic[ID_REVERSE];
1644 O << ",";
1645 O << formatDec(XorMask + 1);
1646 O << ")";
1647
1648 } else {
1649
1650 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1651 if (GroupSize > 1 &&
1652 isPowerOf2_64(GroupSize) &&
1653 OrMask < GroupSize &&
1654 XorMask == 0) {
1655
1656 O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1657 O << ",";
1658 O << formatDec(GroupSize);
1659 O << ",";
1660 O << formatDec(OrMask);
1661 O << ")";
1662
1663 } else {
1664 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1665 O << ",";
1666 printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1667 O << ")";
1668 }
1669 }
1670 } else {
1671 printU16ImmDecOperand(MI, OpNo, O);
1672 }
1673}
1674
1675void AMDGPUInstPrinter::printSWaitCnt(const MCInst *MI, unsigned OpNo,
1676 const MCSubtargetInfo &STI,
1677 raw_ostream &O) {
1679
1680 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1681 unsigned Vmcnt, Expcnt, Lgkmcnt;
1682 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1683
1684 bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
1685 bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
1686 bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
1687 bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
1688
1689 bool NeedSpace = false;
1690
1691 if (!IsDefaultVmcnt || PrintAll) {
1692 O << "vmcnt(" << Vmcnt << ')';
1693 NeedSpace = true;
1694 }
1695
1696 if (!IsDefaultExpcnt || PrintAll) {
1697 if (NeedSpace)
1698 O << ' ';
1699 O << "expcnt(" << Expcnt << ')';
1700 NeedSpace = true;
1701 }
1702
1703 if (!IsDefaultLgkmcnt || PrintAll) {
1704 if (NeedSpace)
1705 O << ' ';
1706 O << "lgkmcnt(" << Lgkmcnt << ')';
1707 }
1708}
1709
1710void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
1711 const MCSubtargetInfo &STI,
1712 raw_ostream &O) {
1713 using namespace llvm::AMDGPU::DepCtr;
1714
1715 uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
1716
1717 bool HasNonDefaultVal = false;
1718 if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
1719 int Id = 0;
1721 unsigned Val;
1722 bool IsDefault;
1723 bool NeedSpace = false;
1724 while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
1725 if (!IsDefault || !HasNonDefaultVal) {
1726 if (NeedSpace)
1727 O << ' ';
1728 O << Name << '(' << Val << ')';
1729 NeedSpace = true;
1730 }
1731 }
1732 } else {
1733 O << formatHex(Imm16);
1734 }
1735}
1736
1738 const MCSubtargetInfo &STI,
1739 raw_ostream &O) {
1740 const char *BadInstId = "/* invalid instid value */";
1741 static const std::array<const char *, 12> InstIds = {
1742 "NO_DEP", "VALU_DEP_1", "VALU_DEP_2",
1743 "VALU_DEP_3", "VALU_DEP_4", "TRANS32_DEP_1",
1744 "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
1745 "SALU_CYCLE_1", "SALU_CYCLE_2", "SALU_CYCLE_3"};
1746
1747 const char *BadInstSkip = "/* invalid instskip value */";
1748 static const std::array<const char *, 6> InstSkips = {
1749 "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
1750
1751 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1752 const char *Prefix = "";
1753
1754 unsigned Value = SImm16 & 0xF;
1755 if (Value) {
1756 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1757 O << Prefix << "instid0(" << Name << ')';
1758 Prefix = " | ";
1759 }
1760
1761 Value = (SImm16 >> 4) & 7;
1762 if (Value) {
1763 const char *Name =
1764 Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
1765 O << Prefix << "instskip(" << Name << ')';
1766 Prefix = " | ";
1767 }
1768
1769 Value = (SImm16 >> 7) & 0xF;
1770 if (Value) {
1771 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1772 O << Prefix << "instid1(" << Name << ')';
1773 Prefix = " | ";
1774 }
1775
1776 if (!*Prefix)
1777 O << "0";
1778}
1779
1780void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1781 const MCSubtargetInfo &STI, raw_ostream &O) {
1782 using namespace llvm::AMDGPU::Hwreg;
1783 unsigned Val = MI->getOperand(OpNo).getImm();
1784 auto [Id, Offset, Width] = HwregEncoding::decode(Val);
1785 StringRef HwRegName = getHwreg(Id, STI);
1786
1787 O << "hwreg(";
1788 if (!HwRegName.empty()) {
1789 O << HwRegName;
1790 } else {
1791 O << Id;
1792 }
1793 if (Width != HwregSize::Default || Offset != HwregOffset::Default)
1794 O << ", " << Offset << ", " << Width;
1795 O << ')';
1796}
1797
1798void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1799 const MCSubtargetInfo &STI,
1800 raw_ostream &O) {
1801 uint16_t Imm = MI->getOperand(OpNo).getImm();
1802 if (Imm == 0) {
1803 return;
1804 }
1805
1806 O << ' ' << formatDec(Imm);
1807}
1808
1809#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 printImmediateBFloat16(uint32_t Imm, const MCSubtargetInfo &STI, raw_ostream &O)
static bool allOpsDefaultValue(const int *Ops, int NumOps, int Mod, bool IsPacked, bool HasDstSel)
static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI, raw_ostream &O)
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 I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
void printSwizzle(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 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 printSWaitCnt(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printOModSI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printSDelayALU(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
This class represents an Operation in the Expression.
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:52
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:53
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:51
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
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:444
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:33
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...
bool isVOPCAsmOnly(unsigned Opc)
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions 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 isGFX12Plus(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
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)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned getVmcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
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:201
@ OPERAND_REG_IMM_V2FP16
Definition: SIDefines.h:211
@ OPERAND_REG_INLINE_C_V2INT32
Definition: SIDefines.h:227
@ OPERAND_REG_INLINE_C_FP64
Definition: SIDefines.h:223
@ OPERAND_REG_INLINE_C_BF16
Definition: SIDefines.h:220
@ OPERAND_REG_INLINE_C_V2BF16
Definition: SIDefines.h:225
@ OPERAND_REG_IMM_V2INT16
Definition: SIDefines.h:212
@ OPERAND_REG_IMM_BF16
Definition: SIDefines.h:205
@ OPERAND_REG_INLINE_AC_V2FP16
Definition: SIDefines.h:246
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
Definition: SIDefines.h:200
@ OPERAND_REG_IMM_V2BF16
Definition: SIDefines.h:210
@ OPERAND_REG_IMM_BF16_DEFERRED
Definition: SIDefines.h:207
@ OPERAND_REG_IMM_FP16
Definition: SIDefines.h:206
@ OPERAND_REG_INLINE_C_INT64
Definition: SIDefines.h:219
@ OPERAND_REG_INLINE_AC_BF16
Definition: SIDefines.h:240
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition: SIDefines.h:217
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
Definition: SIDefines.h:238
@ OPERAND_REG_IMM_FP64
Definition: SIDefines.h:204
@ OPERAND_REG_INLINE_C_V2FP16
Definition: SIDefines.h:226
@ OPERAND_REG_INLINE_AC_V2INT16
Definition: SIDefines.h:244
@ OPERAND_REG_INLINE_AC_FP16
Definition: SIDefines.h:241
@ OPERAND_REG_INLINE_AC_INT32
Definition: SIDefines.h:239
@ OPERAND_REG_INLINE_AC_FP32
Definition: SIDefines.h:242
@ OPERAND_REG_INLINE_AC_V2BF16
Definition: SIDefines.h:245
@ OPERAND_REG_IMM_V2INT32
Definition: SIDefines.h:213
@ OPERAND_REG_IMM_FP32
Definition: SIDefines.h:203
@ OPERAND_REG_INLINE_C_FP32
Definition: SIDefines.h:222
@ OPERAND_REG_INLINE_C_INT32
Definition: SIDefines.h:218
@ OPERAND_REG_INLINE_C_V2INT16
Definition: SIDefines.h:224
@ OPERAND_REG_IMM_V2FP32
Definition: SIDefines.h:214
@ OPERAND_REG_INLINE_AC_FP64
Definition: SIDefines.h:243
@ OPERAND_REG_INLINE_C_FP16
Definition: SIDefines.h:221
@ OPERAND_REG_IMM_INT16
Definition: SIDefines.h:202
@ OPERAND_REG_INLINE_C_V2FP32
Definition: SIDefines.h:228
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
Definition: SIDefines.h:231
@ OPERAND_REG_IMM_FP32_DEFERRED
Definition: SIDefines.h:209
@ OPERAND_REG_IMM_FP16_DEFERRED
Definition: SIDefines.h:208
bool isCvt_F32_Fp8_Bf8_e64(unsigned Opc)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
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.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition: bit.h:385
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:269
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:136
@ 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:436
@ Default
The result values are uniform if and only if all operands are uniform.
#define N
Instruction set architecture version.
Definition: TargetParser.h:125
Description of the encoding of one expression Op.