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