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