[InstCombine] Signed saturation patterns
[llvm-core.git] / lib / Target / AMDGPU / MCTargetDesc / AMDGPUInstPrinter.cpp
bloba9888e6ed92460313c15a66290041f5b57b0b9f9
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::printSWZ(const MCInst *MI, unsigned OpNo,
200 const MCSubtargetInfo &STI, raw_ostream &O) {
203 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
204 const MCSubtargetInfo &STI, raw_ostream &O) {
205 printNamedBit(MI, OpNo, O, "tfe");
208 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
209 const MCSubtargetInfo &STI, raw_ostream &O) {
210 if (MI->getOperand(OpNo).getImm()) {
211 O << " dmask:";
212 printU16ImmOperand(MI, OpNo, STI, O);
216 void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
217 const MCSubtargetInfo &STI, raw_ostream &O) {
218 unsigned Dim = MI->getOperand(OpNo).getImm();
219 O << " dim:SQ_RSRC_IMG_";
221 const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
222 if (DimInfo)
223 O << DimInfo->AsmSuffix;
224 else
225 O << Dim;
228 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
229 const MCSubtargetInfo &STI, raw_ostream &O) {
230 printNamedBit(MI, OpNo, O, "unorm");
233 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
234 const MCSubtargetInfo &STI, raw_ostream &O) {
235 printNamedBit(MI, OpNo, O, "da");
238 void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
239 const MCSubtargetInfo &STI, raw_ostream &O) {
240 if (STI.hasFeature(AMDGPU::FeatureR128A16))
241 printNamedBit(MI, OpNo, O, "a16");
242 else
243 printNamedBit(MI, OpNo, O, "r128");
246 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
247 const MCSubtargetInfo &STI, raw_ostream &O) {
248 printNamedBit(MI, OpNo, O, "lwe");
251 void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
252 const MCSubtargetInfo &STI, raw_ostream &O) {
253 printNamedBit(MI, OpNo, O, "d16");
256 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
257 const MCSubtargetInfo &STI,
258 raw_ostream &O) {
259 if (MI->getOperand(OpNo).getImm())
260 O << " compr";
263 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
264 const MCSubtargetInfo &STI,
265 raw_ostream &O) {
266 if (MI->getOperand(OpNo).getImm())
267 O << " vm";
270 void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
271 const MCSubtargetInfo &STI,
272 raw_ostream &O) {
273 if (unsigned Val = MI->getOperand(OpNo).getImm()) {
274 if (AMDGPU::isGFX10(STI))
275 O << " format:" << Val;
276 else {
277 O << " dfmt:" << (Val & 15);
278 O << ", nfmt:" << (Val >> 4);
283 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
284 const MCRegisterInfo &MRI) {
285 #if !defined(NDEBUG)
286 switch (RegNo) {
287 case AMDGPU::FP_REG:
288 case AMDGPU::SP_REG:
289 case AMDGPU::SCRATCH_WAVE_OFFSET_REG:
290 case AMDGPU::PRIVATE_RSRC_REG:
291 llvm_unreachable("pseudo-register should not ever be emitted");
292 case AMDGPU::SCC:
293 llvm_unreachable("pseudo scc should not ever be emitted");
294 default:
295 break;
297 #endif
299 O << getRegisterName(RegNo);
302 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
303 const MCSubtargetInfo &STI, raw_ostream &O) {
304 if (OpNo == 0) {
305 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
306 O << "_e64 ";
307 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
308 O << "_dpp ";
309 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
310 O << "_sdwa ";
311 else
312 O << "_e32 ";
315 printOperand(MI, OpNo, STI, O);
317 // Print default vcc/vcc_lo operand.
318 switch (MI->getOpcode()) {
319 default: break;
321 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
322 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
323 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
324 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
325 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
326 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
327 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
328 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
329 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
330 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
331 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
332 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
333 printDefaultVccOperand(1, STI, O);
334 break;
338 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
339 const MCSubtargetInfo &STI, raw_ostream &O) {
340 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
341 O << " ";
342 else
343 O << "_e32 ";
345 printOperand(MI, OpNo, STI, O);
348 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
349 const MCSubtargetInfo &STI,
350 raw_ostream &O) {
351 int16_t SImm = static_cast<int16_t>(Imm);
352 if (SImm >= -16 && SImm <= 64) {
353 O << SImm;
354 return;
357 if (Imm == 0x3C00)
358 O<< "1.0";
359 else if (Imm == 0xBC00)
360 O<< "-1.0";
361 else if (Imm == 0x3800)
362 O<< "0.5";
363 else if (Imm == 0xB800)
364 O<< "-0.5";
365 else if (Imm == 0x4000)
366 O<< "2.0";
367 else if (Imm == 0xC000)
368 O<< "-2.0";
369 else if (Imm == 0x4400)
370 O<< "4.0";
371 else if (Imm == 0xC400)
372 O<< "-4.0";
373 else if (Imm == 0x3118) {
374 assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]);
375 O << "0.15915494";
376 } else
377 O << formatHex(static_cast<uint64_t>(Imm));
380 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
381 const MCSubtargetInfo &STI,
382 raw_ostream &O) {
383 uint16_t Lo16 = static_cast<uint16_t>(Imm);
384 printImmediate16(Lo16, STI, O);
387 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
388 const MCSubtargetInfo &STI,
389 raw_ostream &O) {
390 int32_t SImm = static_cast<int32_t>(Imm);
391 if (SImm >= -16 && SImm <= 64) {
392 O << SImm;
393 return;
396 if (Imm == FloatToBits(0.0f))
397 O << "0.0";
398 else if (Imm == FloatToBits(1.0f))
399 O << "1.0";
400 else if (Imm == FloatToBits(-1.0f))
401 O << "-1.0";
402 else if (Imm == FloatToBits(0.5f))
403 O << "0.5";
404 else if (Imm == FloatToBits(-0.5f))
405 O << "-0.5";
406 else if (Imm == FloatToBits(2.0f))
407 O << "2.0";
408 else if (Imm == FloatToBits(-2.0f))
409 O << "-2.0";
410 else if (Imm == FloatToBits(4.0f))
411 O << "4.0";
412 else if (Imm == FloatToBits(-4.0f))
413 O << "-4.0";
414 else if (Imm == 0x3e22f983 &&
415 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
416 O << "0.15915494";
417 else
418 O << formatHex(static_cast<uint64_t>(Imm));
421 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
422 const MCSubtargetInfo &STI,
423 raw_ostream &O) {
424 int64_t SImm = static_cast<int64_t>(Imm);
425 if (SImm >= -16 && SImm <= 64) {
426 O << SImm;
427 return;
430 if (Imm == DoubleToBits(0.0))
431 O << "0.0";
432 else if (Imm == DoubleToBits(1.0))
433 O << "1.0";
434 else if (Imm == DoubleToBits(-1.0))
435 O << "-1.0";
436 else if (Imm == DoubleToBits(0.5))
437 O << "0.5";
438 else if (Imm == DoubleToBits(-0.5))
439 O << "-0.5";
440 else if (Imm == DoubleToBits(2.0))
441 O << "2.0";
442 else if (Imm == DoubleToBits(-2.0))
443 O << "-2.0";
444 else if (Imm == DoubleToBits(4.0))
445 O << "4.0";
446 else if (Imm == DoubleToBits(-4.0))
447 O << "-4.0";
448 else if (Imm == 0x3fc45f306dc9c882 &&
449 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
450 O << "0.15915494309189532";
451 else {
452 assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882);
454 // In rare situations, we will have a 32-bit literal in a 64-bit
455 // operand. This is technically allowed for the encoding of s_mov_b64.
456 O << formatHex(static_cast<uint64_t>(Imm));
460 void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
461 const MCSubtargetInfo &STI,
462 raw_ostream &O) {
463 unsigned Imm = MI->getOperand(OpNo).getImm();
464 if (!Imm)
465 return;
467 O << " blgp:" << Imm;
470 void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
471 const MCSubtargetInfo &STI,
472 raw_ostream &O) {
473 unsigned Imm = MI->getOperand(OpNo).getImm();
474 if (!Imm)
475 return;
477 O << " cbsz:" << Imm;
480 void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
481 const MCSubtargetInfo &STI,
482 raw_ostream &O) {
483 unsigned Imm = MI->getOperand(OpNo).getImm();
484 if (!Imm)
485 return;
487 O << " abid:" << Imm;
490 void AMDGPUInstPrinter::printDefaultVccOperand(unsigned OpNo,
491 const MCSubtargetInfo &STI,
492 raw_ostream &O) {
493 if (OpNo > 0)
494 O << ", ";
495 printRegOperand(STI.getFeatureBits()[AMDGPU::FeatureWavefrontSize64] ?
496 AMDGPU::VCC : AMDGPU::VCC_LO, O, MRI);
497 if (OpNo == 0)
498 O << ", ";
501 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
502 const MCSubtargetInfo &STI,
503 raw_ostream &O) {
504 // Print default vcc/vcc_lo operand of VOPC.
505 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
506 if (OpNo == 0 && (Desc.TSFlags & SIInstrFlags::VOPC) &&
507 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
508 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
509 printDefaultVccOperand(OpNo, STI, O);
511 if (OpNo >= MI->getNumOperands()) {
512 O << "/*Missing OP" << OpNo << "*/";
513 return;
516 const MCOperand &Op = MI->getOperand(OpNo);
517 if (Op.isReg()) {
518 printRegOperand(Op.getReg(), O, MRI);
519 } else if (Op.isImm()) {
520 switch (Desc.OpInfo[OpNo].OperandType) {
521 case AMDGPU::OPERAND_REG_IMM_INT32:
522 case AMDGPU::OPERAND_REG_IMM_FP32:
523 case AMDGPU::OPERAND_REG_INLINE_C_INT32:
524 case AMDGPU::OPERAND_REG_INLINE_C_FP32:
525 case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
526 case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
527 case MCOI::OPERAND_IMMEDIATE:
528 printImmediate32(Op.getImm(), STI, O);
529 break;
530 case AMDGPU::OPERAND_REG_IMM_INT64:
531 case AMDGPU::OPERAND_REG_IMM_FP64:
532 case AMDGPU::OPERAND_REG_INLINE_C_INT64:
533 case AMDGPU::OPERAND_REG_INLINE_C_FP64:
534 printImmediate64(Op.getImm(), STI, O);
535 break;
536 case AMDGPU::OPERAND_REG_INLINE_C_INT16:
537 case AMDGPU::OPERAND_REG_INLINE_C_FP16:
538 case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
539 case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
540 case AMDGPU::OPERAND_REG_IMM_INT16:
541 case AMDGPU::OPERAND_REG_IMM_FP16:
542 printImmediate16(Op.getImm(), STI, O);
543 break;
544 case AMDGPU::OPERAND_REG_IMM_V2INT16:
545 case AMDGPU::OPERAND_REG_IMM_V2FP16:
546 if (!isUInt<16>(Op.getImm()) &&
547 STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
548 printImmediate32(Op.getImm(), STI, O);
549 break;
551 LLVM_FALLTHROUGH;
552 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
553 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
554 case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
555 case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
556 printImmediateV216(Op.getImm(), STI, O);
557 break;
558 case MCOI::OPERAND_UNKNOWN:
559 case MCOI::OPERAND_PCREL:
560 O << formatDec(Op.getImm());
561 break;
562 case MCOI::OPERAND_REGISTER:
563 // FIXME: This should be removed and handled somewhere else. Seems to come
564 // from a disassembler bug.
565 O << "/*invalid immediate*/";
566 break;
567 default:
568 // We hit this for the immediate instruction bits that don't yet have a
569 // custom printer.
570 llvm_unreachable("unexpected immediate operand type");
572 } else if (Op.isFPImm()) {
573 // We special case 0.0 because otherwise it will be printed as an integer.
574 if (Op.getFPImm() == 0.0)
575 O << "0.0";
576 else {
577 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
578 int RCID = Desc.OpInfo[OpNo].RegClass;
579 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
580 if (RCBits == 32)
581 printImmediate32(FloatToBits(Op.getFPImm()), STI, O);
582 else if (RCBits == 64)
583 printImmediate64(DoubleToBits(Op.getFPImm()), STI, O);
584 else
585 llvm_unreachable("Invalid register class size");
587 } else if (Op.isExpr()) {
588 const MCExpr *Exp = Op.getExpr();
589 Exp->print(O, &MAI);
590 } else {
591 O << "/*INV_OP*/";
594 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
595 switch (MI->getOpcode()) {
596 default: break;
598 case AMDGPU::V_CNDMASK_B32_e32_gfx10:
599 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
600 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
601 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
602 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
603 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
604 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
605 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
606 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
607 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
608 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
609 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
611 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
612 case AMDGPU::V_CNDMASK_B32_e32_vi:
613 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
614 AMDGPU::OpName::src1))
615 printDefaultVccOperand(OpNo, STI, O);
616 break;
620 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
621 unsigned OpNo,
622 const MCSubtargetInfo &STI,
623 raw_ostream &O) {
624 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
626 // Use 'neg(...)' instead of '-' to avoid ambiguity.
627 // This is important for integer literals because
628 // -1 is not the same value as neg(1).
629 bool NegMnemo = false;
631 if (InputModifiers & SISrcMods::NEG) {
632 if (OpNo + 1 < MI->getNumOperands() &&
633 (InputModifiers & SISrcMods::ABS) == 0) {
634 const MCOperand &Op = MI->getOperand(OpNo + 1);
635 NegMnemo = Op.isImm() || Op.isFPImm();
637 if (NegMnemo) {
638 O << "neg(";
639 } else {
640 O << '-';
644 if (InputModifiers & SISrcMods::ABS)
645 O << '|';
646 printOperand(MI, OpNo + 1, STI, O);
647 if (InputModifiers & SISrcMods::ABS)
648 O << '|';
650 if (NegMnemo) {
651 O << ')';
655 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
656 unsigned OpNo,
657 const MCSubtargetInfo &STI,
658 raw_ostream &O) {
659 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
660 if (InputModifiers & SISrcMods::SEXT)
661 O << "sext(";
662 printOperand(MI, OpNo + 1, STI, O);
663 if (InputModifiers & SISrcMods::SEXT)
664 O << ')';
666 // Print default vcc/vcc_lo operand of VOP2b.
667 switch (MI->getOpcode()) {
668 default: break;
670 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
671 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
672 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
673 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
674 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
675 AMDGPU::OpName::src1))
676 printDefaultVccOperand(OpNo, STI, O);
677 break;
681 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
682 const MCSubtargetInfo &STI,
683 raw_ostream &O) {
684 if (!AMDGPU::isGFX10(STI))
685 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
687 unsigned Imm = MI->getOperand(OpNo).getImm();
688 O << " dpp8:[" << formatDec(Imm & 0x7);
689 for (size_t i = 1; i < 8; ++i) {
690 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
692 O << ']';
695 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
696 const MCSubtargetInfo &STI,
697 raw_ostream &O) {
698 using namespace AMDGPU::DPP;
700 unsigned Imm = MI->getOperand(OpNo).getImm();
701 if (Imm <= DppCtrl::QUAD_PERM_LAST) {
702 O << " quad_perm:[";
703 O << formatDec(Imm & 0x3) << ',';
704 O << formatDec((Imm & 0xc) >> 2) << ',';
705 O << formatDec((Imm & 0x30) >> 4) << ',';
706 O << formatDec((Imm & 0xc0) >> 6) << ']';
707 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
708 (Imm <= DppCtrl::ROW_SHL_LAST)) {
709 O << " row_shl:";
710 printU4ImmDecOperand(MI, OpNo, O);
711 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
712 (Imm <= DppCtrl::ROW_SHR_LAST)) {
713 O << " row_shr:";
714 printU4ImmDecOperand(MI, OpNo, O);
715 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
716 (Imm <= DppCtrl::ROW_ROR_LAST)) {
717 O << " row_ror:";
718 printU4ImmDecOperand(MI, OpNo, O);
719 } else if (Imm == DppCtrl::WAVE_SHL1) {
720 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
721 O << " /* wave_shl is not supported starting from GFX10 */";
722 return;
724 O << " wave_shl:1";
725 } else if (Imm == DppCtrl::WAVE_ROL1) {
726 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
727 O << " /* wave_rol is not supported starting from GFX10 */";
728 return;
730 O << " wave_rol:1";
731 } else if (Imm == DppCtrl::WAVE_SHR1) {
732 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
733 O << " /* wave_shr is not supported starting from GFX10 */";
734 return;
736 O << " wave_shr:1";
737 } else if (Imm == DppCtrl::WAVE_ROR1) {
738 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
739 O << " /* wave_ror is not supported starting from GFX10 */";
740 return;
742 O << " wave_ror:1";
743 } else if (Imm == DppCtrl::ROW_MIRROR) {
744 O << " row_mirror";
745 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
746 O << " row_half_mirror";
747 } else if (Imm == DppCtrl::BCAST15) {
748 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
749 O << " /* row_bcast is not supported starting from GFX10 */";
750 return;
752 O << " row_bcast:15";
753 } else if (Imm == DppCtrl::BCAST31) {
754 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
755 O << " /* row_bcast is not supported starting from GFX10 */";
756 return;
758 O << " row_bcast:31";
759 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
760 (Imm <= DppCtrl::ROW_SHARE_LAST)) {
761 if (!AMDGPU::isGFX10(STI)) {
762 O << " /* row_share is not supported on ASICs earlier than GFX10 */";
763 return;
765 O << " row_share:";
766 printU4ImmDecOperand(MI, OpNo, O);
767 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
768 (Imm <= DppCtrl::ROW_XMASK_LAST)) {
769 if (!AMDGPU::isGFX10(STI)) {
770 O << " /* row_xmask is not supported on ASICs earlier than GFX10 */";
771 return;
773 O << "row_xmask:";
774 printU4ImmDecOperand(MI, OpNo, O);
775 } else {
776 O << " /* Invalid dpp_ctrl value */";
780 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
781 const MCSubtargetInfo &STI,
782 raw_ostream &O) {
783 O << " row_mask:";
784 printU4ImmOperand(MI, OpNo, STI, O);
787 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
788 const MCSubtargetInfo &STI,
789 raw_ostream &O) {
790 O << " bank_mask:";
791 printU4ImmOperand(MI, OpNo, STI, O);
794 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
795 const MCSubtargetInfo &STI,
796 raw_ostream &O) {
797 unsigned Imm = MI->getOperand(OpNo).getImm();
798 if (Imm) {
799 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
803 void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo,
804 const MCSubtargetInfo &STI,
805 raw_ostream &O) {
806 using namespace llvm::AMDGPU::DPP;
807 unsigned Imm = MI->getOperand(OpNo).getImm();
808 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
809 O << " fi:1";
813 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
814 raw_ostream &O) {
815 using namespace llvm::AMDGPU::SDWA;
817 unsigned Imm = MI->getOperand(OpNo).getImm();
818 switch (Imm) {
819 case SdwaSel::BYTE_0: O << "BYTE_0"; break;
820 case SdwaSel::BYTE_1: O << "BYTE_1"; break;
821 case SdwaSel::BYTE_2: O << "BYTE_2"; break;
822 case SdwaSel::BYTE_3: O << "BYTE_3"; break;
823 case SdwaSel::WORD_0: O << "WORD_0"; break;
824 case SdwaSel::WORD_1: O << "WORD_1"; break;
825 case SdwaSel::DWORD: O << "DWORD"; break;
826 default: llvm_unreachable("Invalid SDWA data select operand");
830 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
831 const MCSubtargetInfo &STI,
832 raw_ostream &O) {
833 O << "dst_sel:";
834 printSDWASel(MI, OpNo, O);
837 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
838 const MCSubtargetInfo &STI,
839 raw_ostream &O) {
840 O << "src0_sel:";
841 printSDWASel(MI, OpNo, O);
844 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
845 const MCSubtargetInfo &STI,
846 raw_ostream &O) {
847 O << "src1_sel:";
848 printSDWASel(MI, OpNo, O);
851 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
852 const MCSubtargetInfo &STI,
853 raw_ostream &O) {
854 using namespace llvm::AMDGPU::SDWA;
856 O << "dst_unused:";
857 unsigned Imm = MI->getOperand(OpNo).getImm();
858 switch (Imm) {
859 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
860 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
861 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
862 default: llvm_unreachable("Invalid SDWA dest_unused operand");
866 template <unsigned N>
867 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
868 const MCSubtargetInfo &STI,
869 raw_ostream &O) {
870 unsigned Opc = MI->getOpcode();
871 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
872 unsigned En = MI->getOperand(EnIdx).getImm();
874 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
876 // If compr is set, print as src0, src0, src1, src1
877 if (MI->getOperand(ComprIdx).getImm()) {
878 if (N == 1 || N == 2)
879 --OpNo;
880 else if (N == 3)
881 OpNo -= 2;
884 if (En & (1 << N))
885 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
886 else
887 O << "off";
890 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
891 const MCSubtargetInfo &STI,
892 raw_ostream &O) {
893 printExpSrcN<0>(MI, OpNo, STI, O);
896 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
897 const MCSubtargetInfo &STI,
898 raw_ostream &O) {
899 printExpSrcN<1>(MI, OpNo, STI, O);
902 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
903 const MCSubtargetInfo &STI,
904 raw_ostream &O) {
905 printExpSrcN<2>(MI, OpNo, STI, O);
908 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
909 const MCSubtargetInfo &STI,
910 raw_ostream &O) {
911 printExpSrcN<3>(MI, OpNo, STI, O);
914 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
915 const MCSubtargetInfo &STI,
916 raw_ostream &O) {
917 // This is really a 6 bit field.
918 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
920 if (Tgt <= 7)
921 O << " mrt" << Tgt;
922 else if (Tgt == 8)
923 O << " mrtz";
924 else if (Tgt == 9)
925 O << " null";
926 else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI)))
927 O << " pos" << Tgt - 12;
928 else if (AMDGPU::isGFX10(STI) && Tgt == 20)
929 O << " prim";
930 else if (Tgt >= 32 && Tgt <= 63)
931 O << " param" << Tgt - 32;
932 else {
933 // Reserved values 10, 11
934 O << " invalid_target_" << Tgt;
938 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
939 bool IsPacked, bool HasDstSel) {
940 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
942 for (int I = 0; I < NumOps; ++I) {
943 if (!!(Ops[I] & Mod) != DefaultValue)
944 return false;
947 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
948 return false;
950 return true;
953 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
954 StringRef Name,
955 unsigned Mod,
956 raw_ostream &O) {
957 unsigned Opc = MI->getOpcode();
958 int NumOps = 0;
959 int Ops[3];
961 for (int OpName : { AMDGPU::OpName::src0_modifiers,
962 AMDGPU::OpName::src1_modifiers,
963 AMDGPU::OpName::src2_modifiers }) {
964 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
965 if (Idx == -1)
966 break;
968 Ops[NumOps++] = MI->getOperand(Idx).getImm();
971 const bool HasDstSel =
972 NumOps > 0 &&
973 Mod == SISrcMods::OP_SEL_0 &&
974 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
976 const bool IsPacked =
977 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
979 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
980 return;
982 O << Name;
983 for (int I = 0; I < NumOps; ++I) {
984 if (I != 0)
985 O << ',';
987 O << !!(Ops[I] & Mod);
990 if (HasDstSel) {
991 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
994 O << ']';
997 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
998 const MCSubtargetInfo &STI,
999 raw_ostream &O) {
1000 unsigned Opc = MI->getOpcode();
1001 if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 ||
1002 Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) {
1003 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1004 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1005 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1006 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1007 if (FI || BC)
1008 O << " op_sel:[" << FI << ',' << BC << ']';
1009 return;
1012 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1015 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1016 const MCSubtargetInfo &STI,
1017 raw_ostream &O) {
1018 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1021 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1022 const MCSubtargetInfo &STI,
1023 raw_ostream &O) {
1024 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1027 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1028 const MCSubtargetInfo &STI,
1029 raw_ostream &O) {
1030 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1033 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1034 const MCSubtargetInfo &STI,
1035 raw_ostream &O) {
1036 unsigned Imm = MI->getOperand(OpNum).getImm();
1037 switch (Imm) {
1038 case 0:
1039 O << "p10";
1040 break;
1041 case 1:
1042 O << "p20";
1043 break;
1044 case 2:
1045 O << "p0";
1046 break;
1047 default:
1048 O << "invalid_param_" << Imm;
1052 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1053 const MCSubtargetInfo &STI,
1054 raw_ostream &O) {
1055 unsigned Attr = MI->getOperand(OpNum).getImm();
1056 O << "attr" << Attr;
1059 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1060 const MCSubtargetInfo &STI,
1061 raw_ostream &O) {
1062 unsigned Chan = MI->getOperand(OpNum).getImm();
1063 O << '.' << "xyzw"[Chan & 0x3];
1066 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
1067 const MCSubtargetInfo &STI,
1068 raw_ostream &O) {
1069 using namespace llvm::AMDGPU::VGPRIndexMode;
1070 unsigned Val = MI->getOperand(OpNo).getImm();
1072 if ((Val & ~ENABLE_MASK) != 0) {
1073 O << " " << formatHex(static_cast<uint64_t>(Val));
1074 } else {
1075 O << " gpr_idx(";
1076 bool NeedComma = false;
1077 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1078 if (Val & (1 << ModeId)) {
1079 if (NeedComma)
1080 O << ',';
1081 O << IdSymbolic[ModeId];
1082 NeedComma = true;
1085 O << ')';
1089 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1090 const MCSubtargetInfo &STI,
1091 raw_ostream &O) {
1092 printOperand(MI, OpNo, STI, O);
1093 O << ", ";
1094 printOperand(MI, OpNo + 1, STI, O);
1097 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1098 raw_ostream &O, StringRef Asm,
1099 StringRef Default) {
1100 const MCOperand &Op = MI->getOperand(OpNo);
1101 assert(Op.isImm());
1102 if (Op.getImm() == 1) {
1103 O << Asm;
1104 } else {
1105 O << Default;
1109 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1110 raw_ostream &O, char Asm) {
1111 const MCOperand &Op = MI->getOperand(OpNo);
1112 assert(Op.isImm());
1113 if (Op.getImm() == 1)
1114 O << Asm;
1117 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
1118 const MCSubtargetInfo &STI,
1119 raw_ostream &O) {
1120 if (MI->getOperand(OpNo).getImm())
1121 O << " high";
1124 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
1125 const MCSubtargetInfo &STI,
1126 raw_ostream &O) {
1127 if (MI->getOperand(OpNo).getImm())
1128 O << " clamp";
1131 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1132 const MCSubtargetInfo &STI,
1133 raw_ostream &O) {
1134 int Imm = MI->getOperand(OpNo).getImm();
1135 if (Imm == SIOutMods::MUL2)
1136 O << " mul:2";
1137 else if (Imm == SIOutMods::MUL4)
1138 O << " mul:4";
1139 else if (Imm == SIOutMods::DIV2)
1140 O << " div:2";
1143 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1144 const MCSubtargetInfo &STI,
1145 raw_ostream &O) {
1146 using namespace llvm::AMDGPU::SendMsg;
1148 const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1150 uint16_t MsgId;
1151 uint16_t OpId;
1152 uint16_t StreamId;
1153 decodeMsg(Imm16, MsgId, OpId, StreamId);
1155 if (isValidMsgId(MsgId, STI) &&
1156 isValidMsgOp(MsgId, OpId) &&
1157 isValidMsgStream(MsgId, OpId, StreamId)) {
1158 O << "sendmsg(" << getMsgName(MsgId);
1159 if (msgRequiresOp(MsgId)) {
1160 O << ", " << getMsgOpName(MsgId, OpId);
1161 if (msgSupportsStream(MsgId, OpId)) {
1162 O << ", " << StreamId;
1165 O << ')';
1166 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1167 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1168 } else {
1169 O << Imm16; // Unknown imm16 code.
1173 static void printSwizzleBitmask(const uint16_t AndMask,
1174 const uint16_t OrMask,
1175 const uint16_t XorMask,
1176 raw_ostream &O) {
1177 using namespace llvm::AMDGPU::Swizzle;
1179 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1180 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1182 O << "\"";
1184 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1185 uint16_t p0 = Probe0 & Mask;
1186 uint16_t p1 = Probe1 & Mask;
1188 if (p0 == p1) {
1189 if (p0 == 0) {
1190 O << "0";
1191 } else {
1192 O << "1";
1194 } else {
1195 if (p0 == 0) {
1196 O << "p";
1197 } else {
1198 O << "i";
1203 O << "\"";
1206 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1207 const MCSubtargetInfo &STI,
1208 raw_ostream &O) {
1209 using namespace llvm::AMDGPU::Swizzle;
1211 uint16_t Imm = MI->getOperand(OpNo).getImm();
1212 if (Imm == 0) {
1213 return;
1216 O << " offset:";
1218 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1220 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1221 for (unsigned I = 0; I < LANE_NUM; ++I) {
1222 O << ",";
1223 O << formatDec(Imm & LANE_MASK);
1224 Imm >>= LANE_SHIFT;
1226 O << ")";
1228 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1230 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1231 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1232 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1234 if (AndMask == BITMASK_MAX &&
1235 OrMask == 0 &&
1236 countPopulation(XorMask) == 1) {
1238 O << "swizzle(" << IdSymbolic[ID_SWAP];
1239 O << ",";
1240 O << formatDec(XorMask);
1241 O << ")";
1243 } else if (AndMask == BITMASK_MAX &&
1244 OrMask == 0 && XorMask > 0 &&
1245 isPowerOf2_64(XorMask + 1)) {
1247 O << "swizzle(" << IdSymbolic[ID_REVERSE];
1248 O << ",";
1249 O << formatDec(XorMask + 1);
1250 O << ")";
1252 } else {
1254 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1255 if (GroupSize > 1 &&
1256 isPowerOf2_64(GroupSize) &&
1257 OrMask < GroupSize &&
1258 XorMask == 0) {
1260 O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1261 O << ",";
1262 O << formatDec(GroupSize);
1263 O << ",";
1264 O << formatDec(OrMask);
1265 O << ")";
1267 } else {
1268 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1269 O << ",";
1270 printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1271 O << ")";
1274 } else {
1275 printU16ImmDecOperand(MI, OpNo, O);
1279 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1280 const MCSubtargetInfo &STI,
1281 raw_ostream &O) {
1282 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
1284 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1285 unsigned Vmcnt, Expcnt, Lgkmcnt;
1286 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1288 bool NeedSpace = false;
1290 if (Vmcnt != getVmcntBitMask(ISA)) {
1291 O << "vmcnt(" << Vmcnt << ')';
1292 NeedSpace = true;
1295 if (Expcnt != getExpcntBitMask(ISA)) {
1296 if (NeedSpace)
1297 O << ' ';
1298 O << "expcnt(" << Expcnt << ')';
1299 NeedSpace = true;
1302 if (Lgkmcnt != getLgkmcntBitMask(ISA)) {
1303 if (NeedSpace)
1304 O << ' ';
1305 O << "lgkmcnt(" << Lgkmcnt << ')';
1309 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1310 const MCSubtargetInfo &STI, raw_ostream &O) {
1311 unsigned Id;
1312 unsigned Offset;
1313 unsigned Width;
1315 using namespace llvm::AMDGPU::Hwreg;
1316 unsigned Val = MI->getOperand(OpNo).getImm();
1317 decodeHwreg(Val, Id, Offset, Width);
1318 StringRef HwRegName = getHwreg(Id, STI);
1320 O << "hwreg(";
1321 if (!HwRegName.empty()) {
1322 O << HwRegName;
1323 } else {
1324 O << Id;
1326 if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) {
1327 O << ", " << Offset << ", " << Width;
1329 O << ')';
1332 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1333 const MCSubtargetInfo &STI,
1334 raw_ostream &O) {
1335 uint16_t Imm = MI->getOperand(OpNo).getImm();
1336 if (Imm == 0) {
1337 return;
1340 O << ' ' << formatDec(Imm);
1343 #include "AMDGPUGenAsmWriter.inc"
1345 void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
1346 StringRef Annot, const MCSubtargetInfo &STI) {
1347 O.flush();
1348 printInstruction(MI, O);
1349 printAnnotation(O, Annot);
1352 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1353 raw_ostream &O) {
1354 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1357 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1358 raw_ostream &O) {
1359 int BankSwizzle = MI->getOperand(OpNo).getImm();
1360 switch (BankSwizzle) {
1361 case 1:
1362 O << "BS:VEC_021/SCL_122";
1363 break;
1364 case 2:
1365 O << "BS:VEC_120/SCL_212";
1366 break;
1367 case 3:
1368 O << "BS:VEC_102/SCL_221";
1369 break;
1370 case 4:
1371 O << "BS:VEC_201";
1372 break;
1373 case 5:
1374 O << "BS:VEC_210";
1375 break;
1376 default:
1377 break;
1381 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1382 raw_ostream &O) {
1383 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1386 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1387 raw_ostream &O) {
1388 unsigned CT = MI->getOperand(OpNo).getImm();
1389 switch (CT) {
1390 case 0:
1391 O << 'U';
1392 break;
1393 case 1:
1394 O << 'N';
1395 break;
1396 default:
1397 break;
1401 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1402 raw_ostream &O) {
1403 int KCacheMode = MI->getOperand(OpNo).getImm();
1404 if (KCacheMode > 0) {
1405 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1406 O << "CB" << KCacheBank << ':';
1407 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1408 int LineSize = (KCacheMode == 1) ? 16 : 32;
1409 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1413 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1414 raw_ostream &O) {
1415 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1418 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1419 raw_ostream &O) {
1420 const MCOperand &Op = MI->getOperand(OpNo);
1421 assert(Op.isImm() || Op.isExpr());
1422 if (Op.isImm()) {
1423 int64_t Imm = Op.getImm();
1424 O << Imm << '(' << BitsToFloat(Imm) << ')';
1426 if (Op.isExpr()) {
1427 Op.getExpr()->print(O << '@', &MAI);
1431 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1432 raw_ostream &O) {
1433 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1436 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1437 raw_ostream &O) {
1438 switch (MI->getOperand(OpNo).getImm()) {
1439 default: break;
1440 case 1:
1441 O << " * 2.0";
1442 break;
1443 case 2:
1444 O << " * 4.0";
1445 break;
1446 case 3:
1447 O << " / 2.0";
1448 break;
1452 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1453 raw_ostream &O) {
1454 printOperand(MI, OpNo, O);
1455 O << ", ";
1456 printOperand(MI, OpNo + 1, O);
1459 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1460 raw_ostream &O) {
1461 if (OpNo >= MI->getNumOperands()) {
1462 O << "/*Missing OP" << OpNo << "*/";
1463 return;
1466 const MCOperand &Op = MI->getOperand(OpNo);
1467 if (Op.isReg()) {
1468 switch (Op.getReg()) {
1469 // This is the default predicate state, so we don't need to print it.
1470 case R600::PRED_SEL_OFF:
1471 break;
1473 default:
1474 O << getRegisterName(Op.getReg());
1475 break;
1477 } else if (Op.isImm()) {
1478 O << Op.getImm();
1479 } else if (Op.isFPImm()) {
1480 // We special case 0.0 because otherwise it will be printed as an integer.
1481 if (Op.getFPImm() == 0.0)
1482 O << "0.0";
1483 else {
1484 O << Op.getFPImm();
1486 } else if (Op.isExpr()) {
1487 const MCExpr *Exp = Op.getExpr();
1488 Exp->print(O, &MAI);
1489 } else {
1490 O << "/*INV_OP*/";
1494 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1495 raw_ostream &O) {
1496 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1499 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1500 raw_ostream &O) {
1501 unsigned Sel = MI->getOperand(OpNo).getImm();
1502 switch (Sel) {
1503 case 0:
1504 O << 'X';
1505 break;
1506 case 1:
1507 O << 'Y';
1508 break;
1509 case 2:
1510 O << 'Z';
1511 break;
1512 case 3:
1513 O << 'W';
1514 break;
1515 case 4:
1516 O << '0';
1517 break;
1518 case 5:
1519 O << '1';
1520 break;
1521 case 7:
1522 O << '_';
1523 break;
1524 default:
1525 break;
1529 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1530 raw_ostream &O) {
1531 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1534 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1535 raw_ostream &O) {
1536 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1539 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1540 raw_ostream &O) {
1541 const MCOperand &Op = MI->getOperand(OpNo);
1542 if (Op.getImm() == 0) {
1543 O << " (MASKED)";
1547 #include "R600GenAsmWriter.inc"