1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 // \file
8 //===----------------------------------------------------------------------===//
9
10 #include "AMDGPUInstPrinter.h"
11 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
12 #include "SIDefines.h"
13 #include "Utils/AMDGPUAsmUtils.h"
14 #include "Utils/AMDGPUBaseInfo.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCInstrDesc.h"
18 #include "llvm/MC/MCInstrInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <cassert>
25
26 using namespace llvm;
27 using namespace llvm::AMDGPU;
28
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)29 void AMDGPUInstPrinter::printInst(const MCInst *MI, uint64_t Address,
30 StringRef Annot, const MCSubtargetInfo &STI,
31 raw_ostream &OS) {
32 OS.flush();
33 printInstruction(MI, Address, STI, OS);
34 printAnnotation(OS, Annot);
35 }
36
printU4ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)37 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
38 const MCSubtargetInfo &STI,
39 raw_ostream &O) {
40 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
41 }
42
printU8ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)43 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
44 raw_ostream &O) {
45 O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
46 }
47
printU16ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)48 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
49 const MCSubtargetInfo &STI,
50 raw_ostream &O) {
51 // It's possible to end up with a 32-bit literal used with a 16-bit operand
52 // with ignored high bits. Print as 32-bit anyway in that case.
53 int64_t Imm = MI->getOperand(OpNo).getImm();
54 if (isInt<16>(Imm) || isUInt<16>(Imm))
55 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
56 else
57 printU32ImmOperand(MI, OpNo, STI, O);
58 }
59
printU4ImmDecOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)60 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
61 raw_ostream &O) {
62 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
63 }
64
printU8ImmDecOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)65 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
66 raw_ostream &O) {
67 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
68 }
69
printU16ImmDecOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)70 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
71 raw_ostream &O) {
72 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
73 }
74
printU32ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)75 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
76 const MCSubtargetInfo &STI,
77 raw_ostream &O) {
78 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
79 }
80
printNamedBit(const MCInst * MI,unsigned OpNo,raw_ostream & O,StringRef BitName)81 void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
82 raw_ostream &O, StringRef BitName) {
83 if (MI->getOperand(OpNo).getImm()) {
84 O << ' ' << BitName;
85 }
86 }
87
printOffen(const MCInst * MI,unsigned OpNo,raw_ostream & O)88 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
89 raw_ostream &O) {
90 printNamedBit(MI, OpNo, O, "offen");
91 }
92
printIdxen(const MCInst * MI,unsigned OpNo,raw_ostream & O)93 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
94 raw_ostream &O) {
95 printNamedBit(MI, OpNo, O, "idxen");
96 }
97
printAddr64(const MCInst * MI,unsigned OpNo,raw_ostream & O)98 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
99 raw_ostream &O) {
100 printNamedBit(MI, OpNo, O, "addr64");
101 }
102
printMBUFOffset(const MCInst * MI,unsigned OpNo,raw_ostream & O)103 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
104 raw_ostream &O) {
105 if (MI->getOperand(OpNo).getImm()) {
106 O << " offset:";
107 printU16ImmDecOperand(MI, OpNo, O);
108 }
109 }
110
printOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)111 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
112 const MCSubtargetInfo &STI,
113 raw_ostream &O) {
114 uint16_t Imm = MI->getOperand(OpNo).getImm();
115 if (Imm != 0) {
116 O << ((OpNo == 0)? "offset:" : " offset:");
117 printU16ImmDecOperand(MI, OpNo, O);
118 }
119 }
120
printFlatOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)121 void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
122 const MCSubtargetInfo &STI,
123 raw_ostream &O) {
124 uint16_t Imm = MI->getOperand(OpNo).getImm();
125 if (Imm != 0) {
126 O << ((OpNo == 0)? "offset:" : " offset:");
127
128 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
129 bool IsFlatSeg = !(Desc.TSFlags & SIInstrFlags::IsNonFlatSeg);
130
131 if (IsFlatSeg) { // Unsigned offset
132 printU16ImmDecOperand(MI, OpNo, O);
133 } else { // Signed offset
134 if (AMDGPU::isGFX10(STI)) {
135 O << formatDec(SignExtend32<12>(MI->getOperand(OpNo).getImm()));
136 } else {
137 O << formatDec(SignExtend32<13>(MI->getOperand(OpNo).getImm()));
138 }
139 }
140 }
141 }
142
printOffset0(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)143 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
144 const MCSubtargetInfo &STI,
145 raw_ostream &O) {
146 if (MI->getOperand(OpNo).getImm()) {
147 O << " offset0:";
148 printU8ImmDecOperand(MI, OpNo, O);
149 }
150 }
151
printOffset1(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)152 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
153 const MCSubtargetInfo &STI,
154 raw_ostream &O) {
155 if (MI->getOperand(OpNo).getImm()) {
156 O << " offset1:";
157 printU8ImmDecOperand(MI, OpNo, O);
158 }
159 }
160
printSMRDOffset8(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)161 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
162 const MCSubtargetInfo &STI,
163 raw_ostream &O) {
164 printU32ImmOperand(MI, OpNo, STI, O);
165 }
166
printSMRDOffset20(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)167 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
168 const MCSubtargetInfo &STI,
169 raw_ostream &O) {
170 printU32ImmOperand(MI, OpNo, STI, O);
171 }
172
printSMRDLiteralOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)173 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
174 const MCSubtargetInfo &STI,
175 raw_ostream &O) {
176 printU32ImmOperand(MI, OpNo, STI, O);
177 }
178
printGDS(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)179 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
180 const MCSubtargetInfo &STI, raw_ostream &O) {
181 printNamedBit(MI, OpNo, O, "gds");
182 }
183
printDLC(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)184 void AMDGPUInstPrinter::printDLC(const MCInst *MI, unsigned OpNo,
185 const MCSubtargetInfo &STI, raw_ostream &O) {
186 if (AMDGPU::isGFX10(STI))
187 printNamedBit(MI, OpNo, O, "dlc");
188 }
189
printGLC(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)190 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
191 const MCSubtargetInfo &STI, raw_ostream &O) {
192 printNamedBit(MI, OpNo, O, "glc");
193 }
194
printSLC(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)195 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
196 const MCSubtargetInfo &STI, raw_ostream &O) {
197 printNamedBit(MI, OpNo, O, "slc");
198 }
199
printSWZ(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)200 void AMDGPUInstPrinter::printSWZ(const MCInst *MI, unsigned OpNo,
201 const MCSubtargetInfo &STI, raw_ostream &O) {
202 }
203
printTFE(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)204 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
205 const MCSubtargetInfo &STI, raw_ostream &O) {
206 printNamedBit(MI, OpNo, O, "tfe");
207 }
208
printDMask(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)209 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
210 const MCSubtargetInfo &STI, raw_ostream &O) {
211 if (MI->getOperand(OpNo).getImm()) {
212 O << " dmask:";
213 printU16ImmOperand(MI, OpNo, STI, O);
214 }
215 }
216
printDim(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)217 void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
218 const MCSubtargetInfo &STI, raw_ostream &O) {
219 unsigned Dim = MI->getOperand(OpNo).getImm();
220 O << " dim:SQ_RSRC_IMG_";
221
222 const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
223 if (DimInfo)
224 O << DimInfo->AsmSuffix;
225 else
226 O << Dim;
227 }
228
printUNorm(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)229 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
230 const MCSubtargetInfo &STI, raw_ostream &O) {
231 printNamedBit(MI, OpNo, O, "unorm");
232 }
233
printDA(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)234 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
235 const MCSubtargetInfo &STI, raw_ostream &O) {
236 printNamedBit(MI, OpNo, O, "da");
237 }
238
printR128A16(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)239 void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
240 const MCSubtargetInfo &STI, raw_ostream &O) {
241 if (STI.hasFeature(AMDGPU::FeatureR128A16))
242 printNamedBit(MI, OpNo, O, "a16");
243 else
244 printNamedBit(MI, OpNo, O, "r128");
245 }
246
printLWE(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)247 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
248 const MCSubtargetInfo &STI, raw_ostream &O) {
249 printNamedBit(MI, OpNo, O, "lwe");
250 }
251
printD16(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)252 void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
253 const MCSubtargetInfo &STI, raw_ostream &O) {
254 printNamedBit(MI, OpNo, O, "d16");
255 }
256
printExpCompr(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)257 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
258 const MCSubtargetInfo &STI,
259 raw_ostream &O) {
260 if (MI->getOperand(OpNo).getImm())
261 O << " compr";
262 }
263
printExpVM(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)264 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
265 const MCSubtargetInfo &STI,
266 raw_ostream &O) {
267 if (MI->getOperand(OpNo).getImm())
268 O << " vm";
269 }
270
printFORMAT(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)271 void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
272 const MCSubtargetInfo &STI,
273 raw_ostream &O) {
274 if (unsigned Val = MI->getOperand(OpNo).getImm()) {
275 if (AMDGPU::isGFX10(STI))
276 O << " format:" << Val;
277 else {
278 O << " dfmt:" << (Val & 15);
279 O << ", nfmt:" << (Val >> 4);
280 }
281 }
282 }
283
printRegOperand(unsigned RegNo,raw_ostream & O,const MCRegisterInfo & MRI)284 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
285 const MCRegisterInfo &MRI) {
286 #if !defined(NDEBUG)
287 switch (RegNo) {
288 case AMDGPU::FP_REG:
289 case AMDGPU::SP_REG:
290 case AMDGPU::SCRATCH_WAVE_OFFSET_REG:
291 case AMDGPU::PRIVATE_RSRC_REG:
292 llvm_unreachable("pseudo-register should not ever be emitted");
293 case AMDGPU::SCC:
294 llvm_unreachable("pseudo scc should not ever be emitted");
295 default:
296 break;
297 }
298 #endif
299
300 O << getRegisterName(RegNo);
301 }
302
printVOPDst(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)303 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
304 const MCSubtargetInfo &STI, raw_ostream &O) {
305 if (OpNo == 0) {
306 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
307 O << "_e64 ";
308 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
309 O << "_dpp ";
310 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
311 O << "_sdwa ";
312 else
313 O << "_e32 ";
314 }
315
316 printOperand(MI, OpNo, STI, O);
317
318 // Print default vcc/vcc_lo operand.
319 switch (MI->getOpcode()) {
320 default: break;
321
322 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
323 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
324 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
325 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
326 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
327 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
328 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
329 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
330 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
331 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
332 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
333 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
334 printDefaultVccOperand(1, STI, O);
335 break;
336 }
337 }
338
printVINTRPDst(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)339 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
340 const MCSubtargetInfo &STI, raw_ostream &O) {
341 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
342 O << " ";
343 else
344 O << "_e32 ";
345
346 printOperand(MI, OpNo, STI, O);
347 }
348
printImmediate16(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)349 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
350 const MCSubtargetInfo &STI,
351 raw_ostream &O) {
352 int16_t SImm = static_cast<int16_t>(Imm);
353 if (SImm >= -16 && SImm <= 64) {
354 O << SImm;
355 return;
356 }
357
358 if (Imm == 0x3C00)
359 O<< "1.0";
360 else if (Imm == 0xBC00)
361 O<< "-1.0";
362 else if (Imm == 0x3800)
363 O<< "0.5";
364 else if (Imm == 0xB800)
365 O<< "-0.5";
366 else if (Imm == 0x4000)
367 O<< "2.0";
368 else if (Imm == 0xC000)
369 O<< "-2.0";
370 else if (Imm == 0x4400)
371 O<< "4.0";
372 else if (Imm == 0xC400)
373 O<< "-4.0";
374 else if (Imm == 0x3118) {
375 assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]);
376 O << "0.15915494";
377 } else
378 O << formatHex(static_cast<uint64_t>(Imm));
379 }
380
printImmediateV216(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)381 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
382 const MCSubtargetInfo &STI,
383 raw_ostream &O) {
384 uint16_t Lo16 = static_cast<uint16_t>(Imm);
385 printImmediate16(Lo16, STI, O);
386 }
387
printImmediate32(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)388 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
389 const MCSubtargetInfo &STI,
390 raw_ostream &O) {
391 int32_t SImm = static_cast<int32_t>(Imm);
392 if (SImm >= -16 && SImm <= 64) {
393 O << SImm;
394 return;
395 }
396
397 if (Imm == FloatToBits(0.0f))
398 O << "0.0";
399 else if (Imm == FloatToBits(1.0f))
400 O << "1.0";
401 else if (Imm == FloatToBits(-1.0f))
402 O << "-1.0";
403 else if (Imm == FloatToBits(0.5f))
404 O << "0.5";
405 else if (Imm == FloatToBits(-0.5f))
406 O << "-0.5";
407 else if (Imm == FloatToBits(2.0f))
408 O << "2.0";
409 else if (Imm == FloatToBits(-2.0f))
410 O << "-2.0";
411 else if (Imm == FloatToBits(4.0f))
412 O << "4.0";
413 else if (Imm == FloatToBits(-4.0f))
414 O << "-4.0";
415 else if (Imm == 0x3e22f983 &&
416 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
417 O << "0.15915494";
418 else
419 O << formatHex(static_cast<uint64_t>(Imm));
420 }
421
printImmediate64(uint64_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)422 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
423 const MCSubtargetInfo &STI,
424 raw_ostream &O) {
425 int64_t SImm = static_cast<int64_t>(Imm);
426 if (SImm >= -16 && SImm <= 64) {
427 O << SImm;
428 return;
429 }
430
431 if (Imm == DoubleToBits(0.0))
432 O << "0.0";
433 else if (Imm == DoubleToBits(1.0))
434 O << "1.0";
435 else if (Imm == DoubleToBits(-1.0))
436 O << "-1.0";
437 else if (Imm == DoubleToBits(0.5))
438 O << "0.5";
439 else if (Imm == DoubleToBits(-0.5))
440 O << "-0.5";
441 else if (Imm == DoubleToBits(2.0))
442 O << "2.0";
443 else if (Imm == DoubleToBits(-2.0))
444 O << "-2.0";
445 else if (Imm == DoubleToBits(4.0))
446 O << "4.0";
447 else if (Imm == DoubleToBits(-4.0))
448 O << "-4.0";
449 else if (Imm == 0x3fc45f306dc9c882 &&
450 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
451 O << "0.15915494309189532";
452 else {
453 assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882);
454
455 // In rare situations, we will have a 32-bit literal in a 64-bit
456 // operand. This is technically allowed for the encoding of s_mov_b64.
457 O << formatHex(static_cast<uint64_t>(Imm));
458 }
459 }
460
printBLGP(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)461 void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
462 const MCSubtargetInfo &STI,
463 raw_ostream &O) {
464 unsigned Imm = MI->getOperand(OpNo).getImm();
465 if (!Imm)
466 return;
467
468 O << " blgp:" << Imm;
469 }
470
printCBSZ(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)471 void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
472 const MCSubtargetInfo &STI,
473 raw_ostream &O) {
474 unsigned Imm = MI->getOperand(OpNo).getImm();
475 if (!Imm)
476 return;
477
478 O << " cbsz:" << Imm;
479 }
480
printABID(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)481 void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
482 const MCSubtargetInfo &STI,
483 raw_ostream &O) {
484 unsigned Imm = MI->getOperand(OpNo).getImm();
485 if (!Imm)
486 return;
487
488 O << " abid:" << Imm;
489 }
490
printDefaultVccOperand(unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)491 void AMDGPUInstPrinter::printDefaultVccOperand(unsigned OpNo,
492 const MCSubtargetInfo &STI,
493 raw_ostream &O) {
494 if (OpNo > 0)
495 O << ", ";
496 printRegOperand(STI.getFeatureBits()[AMDGPU::FeatureWavefrontSize64] ?
497 AMDGPU::VCC : AMDGPU::VCC_LO, O, MRI);
498 if (OpNo == 0)
499 O << ", ";
500 }
501
printOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)502 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
503 const MCSubtargetInfo &STI,
504 raw_ostream &O) {
505 // Print default vcc/vcc_lo operand of VOPC.
506 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
507 if (OpNo == 0 && (Desc.TSFlags & SIInstrFlags::VOPC) &&
508 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
509 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
510 printDefaultVccOperand(OpNo, STI, O);
511
512 if (OpNo >= MI->getNumOperands()) {
513 O << "/*Missing OP" << OpNo << "*/";
514 return;
515 }
516
517 const MCOperand &Op = MI->getOperand(OpNo);
518 if (Op.isReg()) {
519 printRegOperand(Op.getReg(), O, MRI);
520 } else if (Op.isImm()) {
521 switch (Desc.OpInfo[OpNo].OperandType) {
522 case AMDGPU::OPERAND_REG_IMM_INT32:
523 case AMDGPU::OPERAND_REG_IMM_FP32:
524 case AMDGPU::OPERAND_REG_INLINE_C_INT32:
525 case AMDGPU::OPERAND_REG_INLINE_C_FP32:
526 case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
527 case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
528 case MCOI::OPERAND_IMMEDIATE:
529 printImmediate32(Op.getImm(), STI, O);
530 break;
531 case AMDGPU::OPERAND_REG_IMM_INT64:
532 case AMDGPU::OPERAND_REG_IMM_FP64:
533 case AMDGPU::OPERAND_REG_INLINE_C_INT64:
534 case AMDGPU::OPERAND_REG_INLINE_C_FP64:
535 printImmediate64(Op.getImm(), STI, O);
536 break;
537 case AMDGPU::OPERAND_REG_INLINE_C_INT16:
538 case AMDGPU::OPERAND_REG_INLINE_C_FP16:
539 case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
540 case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
541 case AMDGPU::OPERAND_REG_IMM_INT16:
542 case AMDGPU::OPERAND_REG_IMM_FP16:
543 printImmediate16(Op.getImm(), STI, O);
544 break;
545 case AMDGPU::OPERAND_REG_IMM_V2INT16:
546 case AMDGPU::OPERAND_REG_IMM_V2FP16:
547 if (!isUInt<16>(Op.getImm()) &&
548 STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
549 printImmediate32(Op.getImm(), STI, O);
550 break;
551 }
552 LLVM_FALLTHROUGH;
553 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
554 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
555 case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
556 case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
557 printImmediateV216(Op.getImm(), STI, O);
558 break;
559 case MCOI::OPERAND_UNKNOWN:
560 case MCOI::OPERAND_PCREL:
561 O << formatDec(Op.getImm());
562 break;
563 case MCOI::OPERAND_REGISTER:
564 // FIXME: This should be removed and handled somewhere else. Seems to come
565 // from a disassembler bug.
566 O << "/*invalid immediate*/";
567 break;
568 default:
569 // We hit this for the immediate instruction bits that don't yet have a
570 // custom printer.
571 llvm_unreachable("unexpected immediate operand type");
572 }
573 } else if (Op.isFPImm()) {
574 // We special case 0.0 because otherwise it will be printed as an integer.
575 if (Op.getFPImm() == 0.0)
576 O << "0.0";
577 else {
578 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
579 int RCID = Desc.OpInfo[OpNo].RegClass;
580 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
581 if (RCBits == 32)
582 printImmediate32(FloatToBits(Op.getFPImm()), STI, O);
583 else if (RCBits == 64)
584 printImmediate64(DoubleToBits(Op.getFPImm()), STI, O);
585 else
586 llvm_unreachable("Invalid register class size");
587 }
588 } else if (Op.isExpr()) {
589 const MCExpr *Exp = Op.getExpr();
590 Exp->print(O, &MAI);
591 } else {
592 O << "/*INV_OP*/";
593 }
594
595 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
596 switch (MI->getOpcode()) {
597 default: break;
598
599 case AMDGPU::V_CNDMASK_B32_e32_gfx10:
600 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
601 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
602 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
603 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
604 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
605 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
606 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
607 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
608 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
609 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
610 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
611
612 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
613 case AMDGPU::V_CNDMASK_B32_e32_vi:
614 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
615 AMDGPU::OpName::src1))
616 printDefaultVccOperand(OpNo, STI, O);
617 break;
618 }
619 }
620
printOperandAndFPInputMods(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)621 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
622 unsigned OpNo,
623 const MCSubtargetInfo &STI,
624 raw_ostream &O) {
625 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
626
627 // Use 'neg(...)' instead of '-' to avoid ambiguity.
628 // This is important for integer literals because
629 // -1 is not the same value as neg(1).
630 bool NegMnemo = false;
631
632 if (InputModifiers & SISrcMods::NEG) {
633 if (OpNo + 1 < MI->getNumOperands() &&
634 (InputModifiers & SISrcMods::ABS) == 0) {
635 const MCOperand &Op = MI->getOperand(OpNo + 1);
636 NegMnemo = Op.isImm() || Op.isFPImm();
637 }
638 if (NegMnemo) {
639 O << "neg(";
640 } else {
641 O << '-';
642 }
643 }
644
645 if (InputModifiers & SISrcMods::ABS)
646 O << '|';
647 printOperand(MI, OpNo + 1, STI, O);
648 if (InputModifiers & SISrcMods::ABS)
649 O << '|';
650
651 if (NegMnemo) {
652 O << ')';
653 }
654 }
655
printOperandAndIntInputMods(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)656 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
657 unsigned OpNo,
658 const MCSubtargetInfo &STI,
659 raw_ostream &O) {
660 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
661 if (InputModifiers & SISrcMods::SEXT)
662 O << "sext(";
663 printOperand(MI, OpNo + 1, STI, O);
664 if (InputModifiers & SISrcMods::SEXT)
665 O << ')';
666
667 // Print default vcc/vcc_lo operand of VOP2b.
668 switch (MI->getOpcode()) {
669 default: break;
670
671 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
672 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
673 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
674 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
675 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
676 AMDGPU::OpName::src1))
677 printDefaultVccOperand(OpNo, STI, O);
678 break;
679 }
680 }
681
printDPP8(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)682 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
683 const MCSubtargetInfo &STI,
684 raw_ostream &O) {
685 if (!AMDGPU::isGFX10(STI))
686 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
687
688 unsigned Imm = MI->getOperand(OpNo).getImm();
689 O << " dpp8:[" << formatDec(Imm & 0x7);
690 for (size_t i = 1; i < 8; ++i) {
691 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
692 }
693 O << ']';
694 }
695
printDPPCtrl(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)696 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
697 const MCSubtargetInfo &STI,
698 raw_ostream &O) {
699 using namespace AMDGPU::DPP;
700
701 unsigned Imm = MI->getOperand(OpNo).getImm();
702 if (Imm <= DppCtrl::QUAD_PERM_LAST) {
703 O << " quad_perm:[";
704 O << formatDec(Imm & 0x3) << ',';
705 O << formatDec((Imm & 0xc) >> 2) << ',';
706 O << formatDec((Imm & 0x30) >> 4) << ',';
707 O << formatDec((Imm & 0xc0) >> 6) << ']';
708 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
709 (Imm <= DppCtrl::ROW_SHL_LAST)) {
710 O << " row_shl:";
711 printU4ImmDecOperand(MI, OpNo, O);
712 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
713 (Imm <= DppCtrl::ROW_SHR_LAST)) {
714 O << " row_shr:";
715 printU4ImmDecOperand(MI, OpNo, O);
716 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
717 (Imm <= DppCtrl::ROW_ROR_LAST)) {
718 O << " row_ror:";
719 printU4ImmDecOperand(MI, OpNo, O);
720 } else if (Imm == DppCtrl::WAVE_SHL1) {
721 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
722 O << " /* wave_shl is not supported starting from GFX10 */";
723 return;
724 }
725 O << " wave_shl:1";
726 } else if (Imm == DppCtrl::WAVE_ROL1) {
727 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
728 O << " /* wave_rol is not supported starting from GFX10 */";
729 return;
730 }
731 O << " wave_rol:1";
732 } else if (Imm == DppCtrl::WAVE_SHR1) {
733 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
734 O << " /* wave_shr is not supported starting from GFX10 */";
735 return;
736 }
737 O << " wave_shr:1";
738 } else if (Imm == DppCtrl::WAVE_ROR1) {
739 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
740 O << " /* wave_ror is not supported starting from GFX10 */";
741 return;
742 }
743 O << " wave_ror:1";
744 } else if (Imm == DppCtrl::ROW_MIRROR) {
745 O << " row_mirror";
746 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
747 O << " row_half_mirror";
748 } else if (Imm == DppCtrl::BCAST15) {
749 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
750 O << " /* row_bcast is not supported starting from GFX10 */";
751 return;
752 }
753 O << " row_bcast:15";
754 } else if (Imm == DppCtrl::BCAST31) {
755 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
756 O << " /* row_bcast is not supported starting from GFX10 */";
757 return;
758 }
759 O << " row_bcast:31";
760 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
761 (Imm <= DppCtrl::ROW_SHARE_LAST)) {
762 if (!AMDGPU::isGFX10(STI)) {
763 O << " /* row_share is not supported on ASICs earlier than GFX10 */";
764 return;
765 }
766 O << " row_share:";
767 printU4ImmDecOperand(MI, OpNo, O);
768 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
769 (Imm <= DppCtrl::ROW_XMASK_LAST)) {
770 if (!AMDGPU::isGFX10(STI)) {
771 O << " /* row_xmask is not supported on ASICs earlier than GFX10 */";
772 return;
773 }
774 O << "row_xmask:";
775 printU4ImmDecOperand(MI, OpNo, O);
776 } else {
777 O << " /* Invalid dpp_ctrl value */";
778 }
779 }
780
printRowMask(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)781 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
782 const MCSubtargetInfo &STI,
783 raw_ostream &O) {
784 O << " row_mask:";
785 printU4ImmOperand(MI, OpNo, STI, O);
786 }
787
printBankMask(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)788 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
789 const MCSubtargetInfo &STI,
790 raw_ostream &O) {
791 O << " bank_mask:";
792 printU4ImmOperand(MI, OpNo, STI, O);
793 }
794
printBoundCtrl(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)795 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
796 const MCSubtargetInfo &STI,
797 raw_ostream &O) {
798 unsigned Imm = MI->getOperand(OpNo).getImm();
799 if (Imm) {
800 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
801 }
802 }
803
printFI(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)804 void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo,
805 const MCSubtargetInfo &STI,
806 raw_ostream &O) {
807 using namespace llvm::AMDGPU::DPP;
808 unsigned Imm = MI->getOperand(OpNo).getImm();
809 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
810 O << " fi:1";
811 }
812 }
813
printSDWASel(const MCInst * MI,unsigned OpNo,raw_ostream & O)814 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
815 raw_ostream &O) {
816 using namespace llvm::AMDGPU::SDWA;
817
818 unsigned Imm = MI->getOperand(OpNo).getImm();
819 switch (Imm) {
820 case SdwaSel::BYTE_0: O << "BYTE_0"; break;
821 case SdwaSel::BYTE_1: O << "BYTE_1"; break;
822 case SdwaSel::BYTE_2: O << "BYTE_2"; break;
823 case SdwaSel::BYTE_3: O << "BYTE_3"; break;
824 case SdwaSel::WORD_0: O << "WORD_0"; break;
825 case SdwaSel::WORD_1: O << "WORD_1"; break;
826 case SdwaSel::DWORD: O << "DWORD"; break;
827 default: llvm_unreachable("Invalid SDWA data select operand");
828 }
829 }
830
printSDWADstSel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)831 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
832 const MCSubtargetInfo &STI,
833 raw_ostream &O) {
834 O << "dst_sel:";
835 printSDWASel(MI, OpNo, O);
836 }
837
printSDWASrc0Sel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)838 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
839 const MCSubtargetInfo &STI,
840 raw_ostream &O) {
841 O << "src0_sel:";
842 printSDWASel(MI, OpNo, O);
843 }
844
printSDWASrc1Sel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)845 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
846 const MCSubtargetInfo &STI,
847 raw_ostream &O) {
848 O << "src1_sel:";
849 printSDWASel(MI, OpNo, O);
850 }
851
printSDWADstUnused(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)852 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
853 const MCSubtargetInfo &STI,
854 raw_ostream &O) {
855 using namespace llvm::AMDGPU::SDWA;
856
857 O << "dst_unused:";
858 unsigned Imm = MI->getOperand(OpNo).getImm();
859 switch (Imm) {
860 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
861 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
862 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
863 default: llvm_unreachable("Invalid SDWA dest_unused operand");
864 }
865 }
866
867 template <unsigned N>
printExpSrcN(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)868 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
869 const MCSubtargetInfo &STI,
870 raw_ostream &O) {
871 unsigned Opc = MI->getOpcode();
872 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
873 unsigned En = MI->getOperand(EnIdx).getImm();
874
875 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
876
877 // If compr is set, print as src0, src0, src1, src1
878 if (MI->getOperand(ComprIdx).getImm()) {
879 if (N == 1 || N == 2)
880 --OpNo;
881 else if (N == 3)
882 OpNo -= 2;
883 }
884
885 if (En & (1 << N))
886 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
887 else
888 O << "off";
889 }
890
printExpSrc0(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)891 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
892 const MCSubtargetInfo &STI,
893 raw_ostream &O) {
894 printExpSrcN<0>(MI, OpNo, STI, O);
895 }
896
printExpSrc1(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)897 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
898 const MCSubtargetInfo &STI,
899 raw_ostream &O) {
900 printExpSrcN<1>(MI, OpNo, STI, O);
901 }
902
printExpSrc2(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)903 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
904 const MCSubtargetInfo &STI,
905 raw_ostream &O) {
906 printExpSrcN<2>(MI, OpNo, STI, O);
907 }
908
printExpSrc3(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)909 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
910 const MCSubtargetInfo &STI,
911 raw_ostream &O) {
912 printExpSrcN<3>(MI, OpNo, STI, O);
913 }
914
printExpTgt(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)915 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
916 const MCSubtargetInfo &STI,
917 raw_ostream &O) {
918 // This is really a 6 bit field.
919 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
920
921 if (Tgt <= 7)
922 O << " mrt" << Tgt;
923 else if (Tgt == 8)
924 O << " mrtz";
925 else if (Tgt == 9)
926 O << " null";
927 else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI)))
928 O << " pos" << Tgt - 12;
929 else if (AMDGPU::isGFX10(STI) && Tgt == 20)
930 O << " prim";
931 else if (Tgt >= 32 && Tgt <= 63)
932 O << " param" << Tgt - 32;
933 else {
934 // Reserved values 10, 11
935 O << " invalid_target_" << Tgt;
936 }
937 }
938
allOpsDefaultValue(const int * Ops,int NumOps,int Mod,bool IsPacked,bool HasDstSel)939 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
940 bool IsPacked, bool HasDstSel) {
941 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
942
943 for (int I = 0; I < NumOps; ++I) {
944 if (!!(Ops[I] & Mod) != DefaultValue)
945 return false;
946 }
947
948 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
949 return false;
950
951 return true;
952 }
953
printPackedModifier(const MCInst * MI,StringRef Name,unsigned Mod,raw_ostream & O)954 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
955 StringRef Name,
956 unsigned Mod,
957 raw_ostream &O) {
958 unsigned Opc = MI->getOpcode();
959 int NumOps = 0;
960 int Ops[3];
961
962 for (int OpName : { AMDGPU::OpName::src0_modifiers,
963 AMDGPU::OpName::src1_modifiers,
964 AMDGPU::OpName::src2_modifiers }) {
965 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
966 if (Idx == -1)
967 break;
968
969 Ops[NumOps++] = MI->getOperand(Idx).getImm();
970 }
971
972 const bool HasDstSel =
973 NumOps > 0 &&
974 Mod == SISrcMods::OP_SEL_0 &&
975 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
976
977 const bool IsPacked =
978 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
979
980 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
981 return;
982
983 O << Name;
984 for (int I = 0; I < NumOps; ++I) {
985 if (I != 0)
986 O << ',';
987
988 O << !!(Ops[I] & Mod);
989 }
990
991 if (HasDstSel) {
992 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
993 }
994
995 O << ']';
996 }
997
printOpSel(const MCInst * MI,unsigned,const MCSubtargetInfo & STI,raw_ostream & O)998 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
999 const MCSubtargetInfo &STI,
1000 raw_ostream &O) {
1001 unsigned Opc = MI->getOpcode();
1002 if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 ||
1003 Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) {
1004 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1005 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1006 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1007 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1008 if (FI || BC)
1009 O << " op_sel:[" << FI << ',' << BC << ']';
1010 return;
1011 }
1012
1013 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1014 }
1015
printOpSelHi(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1016 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1017 const MCSubtargetInfo &STI,
1018 raw_ostream &O) {
1019 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1020 }
1021
printNegLo(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1022 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1023 const MCSubtargetInfo &STI,
1024 raw_ostream &O) {
1025 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1026 }
1027
printNegHi(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1028 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1029 const MCSubtargetInfo &STI,
1030 raw_ostream &O) {
1031 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1032 }
1033
printInterpSlot(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1034 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1035 const MCSubtargetInfo &STI,
1036 raw_ostream &O) {
1037 unsigned Imm = MI->getOperand(OpNum).getImm();
1038 switch (Imm) {
1039 case 0:
1040 O << "p10";
1041 break;
1042 case 1:
1043 O << "p20";
1044 break;
1045 case 2:
1046 O << "p0";
1047 break;
1048 default:
1049 O << "invalid_param_" << Imm;
1050 }
1051 }
1052
printInterpAttr(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1053 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1054 const MCSubtargetInfo &STI,
1055 raw_ostream &O) {
1056 unsigned Attr = MI->getOperand(OpNum).getImm();
1057 O << "attr" << Attr;
1058 }
1059
printInterpAttrChan(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1060 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1061 const MCSubtargetInfo &STI,
1062 raw_ostream &O) {
1063 unsigned Chan = MI->getOperand(OpNum).getImm();
1064 O << '.' << "xyzw"[Chan & 0x3];
1065 }
1066
printVGPRIndexMode(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1067 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
1068 const MCSubtargetInfo &STI,
1069 raw_ostream &O) {
1070 using namespace llvm::AMDGPU::VGPRIndexMode;
1071 unsigned Val = MI->getOperand(OpNo).getImm();
1072
1073 if ((Val & ~ENABLE_MASK) != 0) {
1074 O << " " << formatHex(static_cast<uint64_t>(Val));
1075 } else {
1076 O << " gpr_idx(";
1077 bool NeedComma = false;
1078 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1079 if (Val & (1 << ModeId)) {
1080 if (NeedComma)
1081 O << ',';
1082 O << IdSymbolic[ModeId];
1083 NeedComma = true;
1084 }
1085 }
1086 O << ')';
1087 }
1088 }
1089
printMemOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1090 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1091 const MCSubtargetInfo &STI,
1092 raw_ostream &O) {
1093 printOperand(MI, OpNo, STI, O);
1094 O << ", ";
1095 printOperand(MI, OpNo + 1, STI, O);
1096 }
1097
printIfSet(const MCInst * MI,unsigned OpNo,raw_ostream & O,StringRef Asm,StringRef Default)1098 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1099 raw_ostream &O, StringRef Asm,
1100 StringRef Default) {
1101 const MCOperand &Op = MI->getOperand(OpNo);
1102 assert(Op.isImm());
1103 if (Op.getImm() == 1) {
1104 O << Asm;
1105 } else {
1106 O << Default;
1107 }
1108 }
1109
printIfSet(const MCInst * MI,unsigned OpNo,raw_ostream & O,char Asm)1110 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1111 raw_ostream &O, char Asm) {
1112 const MCOperand &Op = MI->getOperand(OpNo);
1113 assert(Op.isImm());
1114 if (Op.getImm() == 1)
1115 O << Asm;
1116 }
1117
printHigh(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1118 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
1119 const MCSubtargetInfo &STI,
1120 raw_ostream &O) {
1121 if (MI->getOperand(OpNo).getImm())
1122 O << " high";
1123 }
1124
printClampSI(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1125 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
1126 const MCSubtargetInfo &STI,
1127 raw_ostream &O) {
1128 if (MI->getOperand(OpNo).getImm())
1129 O << " clamp";
1130 }
1131
printOModSI(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1132 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1133 const MCSubtargetInfo &STI,
1134 raw_ostream &O) {
1135 int Imm = MI->getOperand(OpNo).getImm();
1136 if (Imm == SIOutMods::MUL2)
1137 O << " mul:2";
1138 else if (Imm == SIOutMods::MUL4)
1139 O << " mul:4";
1140 else if (Imm == SIOutMods::DIV2)
1141 O << " div:2";
1142 }
1143
printSendMsg(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1144 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1145 const MCSubtargetInfo &STI,
1146 raw_ostream &O) {
1147 using namespace llvm::AMDGPU::SendMsg;
1148
1149 const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1150
1151 uint16_t MsgId;
1152 uint16_t OpId;
1153 uint16_t StreamId;
1154 decodeMsg(Imm16, MsgId, OpId, StreamId);
1155
1156 if (isValidMsgId(MsgId, STI) &&
1157 isValidMsgOp(MsgId, OpId) &&
1158 isValidMsgStream(MsgId, OpId, StreamId)) {
1159 O << "sendmsg(" << getMsgName(MsgId);
1160 if (msgRequiresOp(MsgId)) {
1161 O << ", " << getMsgOpName(MsgId, OpId);
1162 if (msgSupportsStream(MsgId, OpId)) {
1163 O << ", " << StreamId;
1164 }
1165 }
1166 O << ')';
1167 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1168 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1169 } else {
1170 O << Imm16; // Unknown imm16 code.
1171 }
1172 }
1173
printSwizzleBitmask(const uint16_t AndMask,const uint16_t OrMask,const uint16_t XorMask,raw_ostream & O)1174 static void printSwizzleBitmask(const uint16_t AndMask,
1175 const uint16_t OrMask,
1176 const uint16_t XorMask,
1177 raw_ostream &O) {
1178 using namespace llvm::AMDGPU::Swizzle;
1179
1180 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1181 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1182
1183 O << "\"";
1184
1185 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1186 uint16_t p0 = Probe0 & Mask;
1187 uint16_t p1 = Probe1 & Mask;
1188
1189 if (p0 == p1) {
1190 if (p0 == 0) {
1191 O << "0";
1192 } else {
1193 O << "1";
1194 }
1195 } else {
1196 if (p0 == 0) {
1197 O << "p";
1198 } else {
1199 O << "i";
1200 }
1201 }
1202 }
1203
1204 O << "\"";
1205 }
1206
printSwizzle(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1207 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1208 const MCSubtargetInfo &STI,
1209 raw_ostream &O) {
1210 using namespace llvm::AMDGPU::Swizzle;
1211
1212 uint16_t Imm = MI->getOperand(OpNo).getImm();
1213 if (Imm == 0) {
1214 return;
1215 }
1216
1217 O << " offset:";
1218
1219 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1220
1221 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1222 for (unsigned I = 0; I < LANE_NUM; ++I) {
1223 O << ",";
1224 O << formatDec(Imm & LANE_MASK);
1225 Imm >>= LANE_SHIFT;
1226 }
1227 O << ")";
1228
1229 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1230
1231 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1232 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1233 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1234
1235 if (AndMask == BITMASK_MAX &&
1236 OrMask == 0 &&
1237 countPopulation(XorMask) == 1) {
1238
1239 O << "swizzle(" << IdSymbolic[ID_SWAP];
1240 O << ",";
1241 O << formatDec(XorMask);
1242 O << ")";
1243
1244 } else if (AndMask == BITMASK_MAX &&
1245 OrMask == 0 && XorMask > 0 &&
1246 isPowerOf2_64(XorMask + 1)) {
1247
1248 O << "swizzle(" << IdSymbolic[ID_REVERSE];
1249 O << ",";
1250 O << formatDec(XorMask + 1);
1251 O << ")";
1252
1253 } else {
1254
1255 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1256 if (GroupSize > 1 &&
1257 isPowerOf2_64(GroupSize) &&
1258 OrMask < GroupSize &&
1259 XorMask == 0) {
1260
1261 O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1262 O << ",";
1263 O << formatDec(GroupSize);
1264 O << ",";
1265 O << formatDec(OrMask);
1266 O << ")";
1267
1268 } else {
1269 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1270 O << ",";
1271 printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1272 O << ")";
1273 }
1274 }
1275 } else {
1276 printU16ImmDecOperand(MI, OpNo, O);
1277 }
1278 }
1279
printWaitFlag(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1280 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1281 const MCSubtargetInfo &STI,
1282 raw_ostream &O) {
1283 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
1284
1285 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1286 unsigned Vmcnt, Expcnt, Lgkmcnt;
1287 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1288
1289 bool NeedSpace = false;
1290
1291 if (Vmcnt != getVmcntBitMask(ISA)) {
1292 O << "vmcnt(" << Vmcnt << ')';
1293 NeedSpace = true;
1294 }
1295
1296 if (Expcnt != getExpcntBitMask(ISA)) {
1297 if (NeedSpace)
1298 O << ' ';
1299 O << "expcnt(" << Expcnt << ')';
1300 NeedSpace = true;
1301 }
1302
1303 if (Lgkmcnt != getLgkmcntBitMask(ISA)) {
1304 if (NeedSpace)
1305 O << ' ';
1306 O << "lgkmcnt(" << Lgkmcnt << ')';
1307 }
1308 }
1309
printHwreg(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1310 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1311 const MCSubtargetInfo &STI, raw_ostream &O) {
1312 unsigned Id;
1313 unsigned Offset;
1314 unsigned Width;
1315
1316 using namespace llvm::AMDGPU::Hwreg;
1317 unsigned Val = MI->getOperand(OpNo).getImm();
1318 decodeHwreg(Val, Id, Offset, Width);
1319 StringRef HwRegName = getHwreg(Id, STI);
1320
1321 O << "hwreg(";
1322 if (!HwRegName.empty()) {
1323 O << HwRegName;
1324 } else {
1325 O << Id;
1326 }
1327 if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) {
1328 O << ", " << Offset << ", " << Width;
1329 }
1330 O << ')';
1331 }
1332
printEndpgm(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1333 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1334 const MCSubtargetInfo &STI,
1335 raw_ostream &O) {
1336 uint16_t Imm = MI->getOperand(OpNo).getImm();
1337 if (Imm == 0) {
1338 return;
1339 }
1340
1341 O << ' ' << formatDec(Imm);
1342 }
1343
1344 #include "AMDGPUGenAsmWriter.inc"
1345
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & O)1346 void R600InstPrinter::printInst(const MCInst *MI, uint64_t Address,
1347 StringRef Annot, const MCSubtargetInfo &STI,
1348 raw_ostream &O) {
1349 O.flush();
1350 printInstruction(MI, Address, O);
1351 printAnnotation(O, Annot);
1352 }
1353
printAbs(const MCInst * MI,unsigned OpNo,raw_ostream & O)1354 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1355 raw_ostream &O) {
1356 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1357 }
1358
printBankSwizzle(const MCInst * MI,unsigned OpNo,raw_ostream & O)1359 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1360 raw_ostream &O) {
1361 int BankSwizzle = MI->getOperand(OpNo).getImm();
1362 switch (BankSwizzle) {
1363 case 1:
1364 O << "BS:VEC_021/SCL_122";
1365 break;
1366 case 2:
1367 O << "BS:VEC_120/SCL_212";
1368 break;
1369 case 3:
1370 O << "BS:VEC_102/SCL_221";
1371 break;
1372 case 4:
1373 O << "BS:VEC_201";
1374 break;
1375 case 5:
1376 O << "BS:VEC_210";
1377 break;
1378 default:
1379 break;
1380 }
1381 }
1382
printClamp(const MCInst * MI,unsigned OpNo,raw_ostream & O)1383 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1384 raw_ostream &O) {
1385 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1386 }
1387
printCT(const MCInst * MI,unsigned OpNo,raw_ostream & O)1388 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1389 raw_ostream &O) {
1390 unsigned CT = MI->getOperand(OpNo).getImm();
1391 switch (CT) {
1392 case 0:
1393 O << 'U';
1394 break;
1395 case 1:
1396 O << 'N';
1397 break;
1398 default:
1399 break;
1400 }
1401 }
1402
printKCache(const MCInst * MI,unsigned OpNo,raw_ostream & O)1403 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1404 raw_ostream &O) {
1405 int KCacheMode = MI->getOperand(OpNo).getImm();
1406 if (KCacheMode > 0) {
1407 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1408 O << "CB" << KCacheBank << ':';
1409 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1410 int LineSize = (KCacheMode == 1) ? 16 : 32;
1411 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1412 }
1413 }
1414
printLast(const MCInst * MI,unsigned OpNo,raw_ostream & O)1415 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1416 raw_ostream &O) {
1417 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1418 }
1419
printLiteral(const MCInst * MI,unsigned OpNo,raw_ostream & O)1420 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1421 raw_ostream &O) {
1422 const MCOperand &Op = MI->getOperand(OpNo);
1423 assert(Op.isImm() || Op.isExpr());
1424 if (Op.isImm()) {
1425 int64_t Imm = Op.getImm();
1426 O << Imm << '(' << BitsToFloat(Imm) << ')';
1427 }
1428 if (Op.isExpr()) {
1429 Op.getExpr()->print(O << '@', &MAI);
1430 }
1431 }
1432
printNeg(const MCInst * MI,unsigned OpNo,raw_ostream & O)1433 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1434 raw_ostream &O) {
1435 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1436 }
1437
printOMOD(const MCInst * MI,unsigned OpNo,raw_ostream & O)1438 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1439 raw_ostream &O) {
1440 switch (MI->getOperand(OpNo).getImm()) {
1441 default: break;
1442 case 1:
1443 O << " * 2.0";
1444 break;
1445 case 2:
1446 O << " * 4.0";
1447 break;
1448 case 3:
1449 O << " / 2.0";
1450 break;
1451 }
1452 }
1453
printMemOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)1454 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1455 raw_ostream &O) {
1456 printOperand(MI, OpNo, O);
1457 O << ", ";
1458 printOperand(MI, OpNo + 1, O);
1459 }
1460
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)1461 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1462 raw_ostream &O) {
1463 if (OpNo >= MI->getNumOperands()) {
1464 O << "/*Missing OP" << OpNo << "*/";
1465 return;
1466 }
1467
1468 const MCOperand &Op = MI->getOperand(OpNo);
1469 if (Op.isReg()) {
1470 switch (Op.getReg()) {
1471 // This is the default predicate state, so we don't need to print it.
1472 case R600::PRED_SEL_OFF:
1473 break;
1474
1475 default:
1476 O << getRegisterName(Op.getReg());
1477 break;
1478 }
1479 } else if (Op.isImm()) {
1480 O << Op.getImm();
1481 } else if (Op.isFPImm()) {
1482 // We special case 0.0 because otherwise it will be printed as an integer.
1483 if (Op.getFPImm() == 0.0)
1484 O << "0.0";
1485 else {
1486 O << Op.getFPImm();
1487 }
1488 } else if (Op.isExpr()) {
1489 const MCExpr *Exp = Op.getExpr();
1490 Exp->print(O, &MAI);
1491 } else {
1492 O << "/*INV_OP*/";
1493 }
1494 }
1495
printRel(const MCInst * MI,unsigned OpNo,raw_ostream & O)1496 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1497 raw_ostream &O) {
1498 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1499 }
1500
printRSel(const MCInst * MI,unsigned OpNo,raw_ostream & O)1501 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1502 raw_ostream &O) {
1503 unsigned Sel = MI->getOperand(OpNo).getImm();
1504 switch (Sel) {
1505 case 0:
1506 O << 'X';
1507 break;
1508 case 1:
1509 O << 'Y';
1510 break;
1511 case 2:
1512 O << 'Z';
1513 break;
1514 case 3:
1515 O << 'W';
1516 break;
1517 case 4:
1518 O << '0';
1519 break;
1520 case 5:
1521 O << '1';
1522 break;
1523 case 7:
1524 O << '_';
1525 break;
1526 default:
1527 break;
1528 }
1529 }
1530
printUpdateExecMask(const MCInst * MI,unsigned OpNo,raw_ostream & O)1531 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1532 raw_ostream &O) {
1533 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1534 }
1535
printUpdatePred(const MCInst * MI,unsigned OpNo,raw_ostream & O)1536 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1537 raw_ostream &O) {
1538 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1539 }
1540
printWrite(const MCInst * MI,unsigned OpNo,raw_ostream & O)1541 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1542 raw_ostream &O) {
1543 const MCOperand &Op = MI->getOperand(OpNo);
1544 if (Op.getImm() == 0) {
1545 O << " (MASKED)";
1546 }
1547 }
1548
1549 #include "R600GenAsmWriter.inc"
1550