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