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