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