Home | History | Annotate | Download | only in InstPrinter
      1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 // \file
      9 //===----------------------------------------------------------------------===//
     10 
     11 #include "AMDGPUInstPrinter.h"
     12 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
     13 #include "SIDefines.h"
     14 #include "llvm/MC/MCExpr.h"
     15 #include "llvm/MC/MCInst.h"
     16 #include "llvm/MC/MCInstrInfo.h"
     17 #include "llvm/MC/MCRegisterInfo.h"
     18 #include "llvm/Support/MathExtras.h"
     19 
     20 using namespace llvm;
     21 
     22 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
     23                                   StringRef Annot, const MCSubtargetInfo &STI) {
     24   OS.flush();
     25   printInstruction(MI, OS);
     26 
     27   printAnnotation(OS, Annot);
     28 }
     29 
     30 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
     31                                            raw_ostream &O) {
     32   O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
     33 }
     34 
     35 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
     36                                            raw_ostream &O) {
     37   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffff);
     38 }
     39 
     40 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
     41                                            raw_ostream &O) {
     42   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
     43 }
     44 
     45 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
     46                                              raw_ostream &O) {
     47   O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
     48 }
     49 
     50 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
     51                                               raw_ostream &O) {
     52   O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
     53 }
     54 
     55 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
     56                                    raw_ostream &O) {
     57   if (MI->getOperand(OpNo).getImm())
     58     O << " offen";
     59 }
     60 
     61 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
     62                                    raw_ostream &O) {
     63   if (MI->getOperand(OpNo).getImm())
     64     O << " idxen";
     65 }
     66 
     67 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
     68                                     raw_ostream &O) {
     69   if (MI->getOperand(OpNo).getImm())
     70     O << " addr64";
     71 }
     72 
     73 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
     74                                         raw_ostream &O) {
     75   if (MI->getOperand(OpNo).getImm()) {
     76     O << " offset:";
     77     printU16ImmDecOperand(MI, OpNo, O);
     78   }
     79 }
     80 
     81 void AMDGPUInstPrinter::printDSOffset(const MCInst *MI, unsigned OpNo,
     82                                       raw_ostream &O) {
     83   uint16_t Imm = MI->getOperand(OpNo).getImm();
     84   if (Imm != 0) {
     85     O << " offset:";
     86     printU16ImmDecOperand(MI, OpNo, O);
     87   }
     88 }
     89 
     90 void AMDGPUInstPrinter::printDSOffset0(const MCInst *MI, unsigned OpNo,
     91                                         raw_ostream &O) {
     92   if (MI->getOperand(OpNo).getImm()) {
     93     O << " offset0:";
     94     printU8ImmDecOperand(MI, OpNo, O);
     95   }
     96 }
     97 
     98 void AMDGPUInstPrinter::printDSOffset1(const MCInst *MI, unsigned OpNo,
     99                                         raw_ostream &O) {
    100   if (MI->getOperand(OpNo).getImm()) {
    101     O << " offset1:";
    102     printU8ImmDecOperand(MI, OpNo, O);
    103   }
    104 }
    105 
    106 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
    107                                  raw_ostream &O) {
    108   if (MI->getOperand(OpNo).getImm())
    109     O << " gds";
    110 }
    111 
    112 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
    113                                  raw_ostream &O) {
    114   if (MI->getOperand(OpNo).getImm())
    115     O << " glc";
    116 }
    117 
    118 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
    119                                  raw_ostream &O) {
    120   if (MI->getOperand(OpNo).getImm())
    121     O << " slc";
    122 }
    123 
    124 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
    125                                  raw_ostream &O) {
    126   if (MI->getOperand(OpNo).getImm())
    127     O << " tfe";
    128 }
    129 
    130 void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O,
    131                                         const MCRegisterInfo &MRI) {
    132   switch (reg) {
    133   case AMDGPU::VCC:
    134     O << "vcc";
    135     return;
    136   case AMDGPU::SCC:
    137     O << "scc";
    138     return;
    139   case AMDGPU::EXEC:
    140     O << "exec";
    141     return;
    142   case AMDGPU::M0:
    143     O << "m0";
    144     return;
    145   case AMDGPU::FLAT_SCR:
    146     O << "flat_scratch";
    147     return;
    148   case AMDGPU::VCC_LO:
    149     O << "vcc_lo";
    150     return;
    151   case AMDGPU::VCC_HI:
    152     O << "vcc_hi";
    153     return;
    154   case AMDGPU::EXEC_LO:
    155     O << "exec_lo";
    156     return;
    157   case AMDGPU::EXEC_HI:
    158     O << "exec_hi";
    159     return;
    160   case AMDGPU::FLAT_SCR_LO:
    161     O << "flat_scratch_lo";
    162     return;
    163   case AMDGPU::FLAT_SCR_HI:
    164     O << "flat_scratch_hi";
    165     return;
    166   default:
    167     break;
    168   }
    169 
    170   char Type;
    171   unsigned NumRegs;
    172 
    173   if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) {
    174     Type = 'v';
    175     NumRegs = 1;
    176   } else  if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) {
    177     Type = 's';
    178     NumRegs = 1;
    179   } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) {
    180     Type = 'v';
    181     NumRegs = 2;
    182   } else  if (MRI.getRegClass(AMDGPU::SReg_64RegClassID).contains(reg)) {
    183     Type = 's';
    184     NumRegs = 2;
    185   } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) {
    186     Type = 'v';
    187     NumRegs = 4;
    188   } else  if (MRI.getRegClass(AMDGPU::SReg_128RegClassID).contains(reg)) {
    189     Type = 's';
    190     NumRegs = 4;
    191   } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) {
    192     Type = 'v';
    193     NumRegs = 3;
    194   } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) {
    195     Type = 'v';
    196     NumRegs = 8;
    197   } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) {
    198     Type = 's';
    199     NumRegs = 8;
    200   } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) {
    201     Type = 'v';
    202     NumRegs = 16;
    203   } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) {
    204     Type = 's';
    205     NumRegs = 16;
    206   } else {
    207     O << getRegisterName(reg);
    208     return;
    209   }
    210 
    211   // The low 8 bits of the encoding value is the register index, for both VGPRs
    212   // and SGPRs.
    213   unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1);
    214   if (NumRegs == 1) {
    215     O << Type << RegIdx;
    216     return;
    217   }
    218 
    219   O << Type << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
    220 }
    221 
    222 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
    223                                     raw_ostream &O) {
    224   if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
    225     O << "_e64 ";
    226   else
    227     O << "_e32 ";
    228 
    229   printOperand(MI, OpNo, O);
    230 }
    231 
    232 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, raw_ostream &O) {
    233   int32_t SImm = static_cast<int32_t>(Imm);
    234   if (SImm >= -16 && SImm <= 64) {
    235     O << SImm;
    236     return;
    237   }
    238 
    239   if (Imm == FloatToBits(0.0f))
    240     O << "0.0";
    241   else if (Imm == FloatToBits(1.0f))
    242     O << "1.0";
    243   else if (Imm == FloatToBits(-1.0f))
    244     O << "-1.0";
    245   else if (Imm == FloatToBits(0.5f))
    246     O << "0.5";
    247   else if (Imm == FloatToBits(-0.5f))
    248     O << "-0.5";
    249   else if (Imm == FloatToBits(2.0f))
    250     O << "2.0";
    251   else if (Imm == FloatToBits(-2.0f))
    252     O << "-2.0";
    253   else if (Imm == FloatToBits(4.0f))
    254     O << "4.0";
    255   else if (Imm == FloatToBits(-4.0f))
    256     O << "-4.0";
    257   else
    258     O << formatHex(static_cast<uint64_t>(Imm));
    259 }
    260 
    261 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, raw_ostream &O) {
    262   int64_t SImm = static_cast<int64_t>(Imm);
    263   if (SImm >= -16 && SImm <= 64) {
    264     O << SImm;
    265     return;
    266   }
    267 
    268   if (Imm == DoubleToBits(0.0))
    269     O << "0.0";
    270   else if (Imm == DoubleToBits(1.0))
    271     O << "1.0";
    272   else if (Imm == DoubleToBits(-1.0))
    273     O << "-1.0";
    274   else if (Imm == DoubleToBits(0.5))
    275     O << "0.5";
    276   else if (Imm == DoubleToBits(-0.5))
    277     O << "-0.5";
    278   else if (Imm == DoubleToBits(2.0))
    279     O << "2.0";
    280   else if (Imm == DoubleToBits(-2.0))
    281     O << "-2.0";
    282   else if (Imm == DoubleToBits(4.0))
    283     O << "4.0";
    284   else if (Imm == DoubleToBits(-4.0))
    285     O << "-4.0";
    286   else {
    287     assert(isUInt<32>(Imm));
    288 
    289     // In rare situations, we will have a 32-bit literal in a 64-bit
    290     // operand. This is technically allowed for the encoding of s_mov_b64.
    291     O << formatHex(static_cast<uint64_t>(Imm));
    292   }
    293 }
    294 
    295 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
    296                                      raw_ostream &O) {
    297 
    298   const MCOperand &Op = MI->getOperand(OpNo);
    299   if (Op.isReg()) {
    300     switch (Op.getReg()) {
    301     // This is the default predicate state, so we don't need to print it.
    302     case AMDGPU::PRED_SEL_OFF:
    303       break;
    304 
    305     default:
    306       printRegOperand(Op.getReg(), O, MRI);
    307       break;
    308     }
    309   } else if (Op.isImm()) {
    310     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
    311     int RCID = Desc.OpInfo[OpNo].RegClass;
    312     if (RCID != -1) {
    313       const MCRegisterClass &ImmRC = MRI.getRegClass(RCID);
    314       if (ImmRC.getSize() == 4)
    315         printImmediate32(Op.getImm(), O);
    316       else if (ImmRC.getSize() == 8)
    317         printImmediate64(Op.getImm(), O);
    318       else
    319         llvm_unreachable("Invalid register class size");
    320     } else if (Desc.OpInfo[OpNo].OperandType == MCOI::OPERAND_IMMEDIATE) {
    321       printImmediate32(Op.getImm(), O);
    322     } else {
    323       // We hit this for the immediate instruction bits that don't yet have a
    324       // custom printer.
    325       // TODO: Eventually this should be unnecessary.
    326       O << formatDec(Op.getImm());
    327     }
    328   } else if (Op.isFPImm()) {
    329     // We special case 0.0 because otherwise it will be printed as an integer.
    330     if (Op.getFPImm() == 0.0)
    331       O << "0.0";
    332     else {
    333       const MCInstrDesc &Desc = MII.get(MI->getOpcode());
    334       const MCRegisterClass &ImmRC = MRI.getRegClass(Desc.OpInfo[OpNo].RegClass);
    335 
    336       if (ImmRC.getSize() == 4)
    337         printImmediate32(FloatToBits(Op.getFPImm()), O);
    338       else if (ImmRC.getSize() == 8)
    339         printImmediate64(DoubleToBits(Op.getFPImm()), O);
    340       else
    341         llvm_unreachable("Invalid register class size");
    342     }
    343   } else if (Op.isExpr()) {
    344     const MCExpr *Exp = Op.getExpr();
    345     Exp->print(O, &MAI);
    346   } else {
    347     llvm_unreachable("unknown operand type in printOperand");
    348   }
    349 }
    350 
    351 void AMDGPUInstPrinter::printOperandAndMods(const MCInst *MI, unsigned OpNo,
    352                                             raw_ostream &O) {
    353   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
    354   if (InputModifiers & SISrcMods::NEG)
    355     O << '-';
    356   if (InputModifiers & SISrcMods::ABS)
    357     O << '|';
    358   printOperand(MI, OpNo + 1, O);
    359   if (InputModifiers & SISrcMods::ABS)
    360     O << '|';
    361 }
    362 
    363 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
    364                                         raw_ostream &O) {
    365   unsigned Imm = MI->getOperand(OpNum).getImm();
    366 
    367   if (Imm == 2) {
    368     O << "P0";
    369   } else if (Imm == 1) {
    370     O << "P20";
    371   } else if (Imm == 0) {
    372     O << "P10";
    373   } else {
    374     llvm_unreachable("Invalid interpolation parameter slot");
    375   }
    376 }
    377 
    378 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
    379                                         raw_ostream &O) {
    380   printOperand(MI, OpNo, O);
    381   O  << ", ";
    382   printOperand(MI, OpNo + 1, O);
    383 }
    384 
    385 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
    386                                    raw_ostream &O, StringRef Asm,
    387                                    StringRef Default) {
    388   const MCOperand &Op = MI->getOperand(OpNo);
    389   assert(Op.isImm());
    390   if (Op.getImm() == 1) {
    391     O << Asm;
    392   } else {
    393     O << Default;
    394   }
    395 }
    396 
    397 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
    398                                  raw_ostream &O) {
    399   printIfSet(MI, OpNo, O, "|");
    400 }
    401 
    402 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
    403                                    raw_ostream &O) {
    404   printIfSet(MI, OpNo, O, "_SAT");
    405 }
    406 
    407 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
    408                                      raw_ostream &O) {
    409   if (MI->getOperand(OpNo).getImm())
    410     O << " clamp";
    411 }
    412 
    413 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
    414                                      raw_ostream &O) {
    415   int Imm = MI->getOperand(OpNo).getImm();
    416   if (Imm == SIOutMods::MUL2)
    417     O << " mul:2";
    418   else if (Imm == SIOutMods::MUL4)
    419     O << " mul:4";
    420   else if (Imm == SIOutMods::DIV2)
    421     O << " div:2";
    422 }
    423 
    424 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
    425                                      raw_ostream &O) {
    426   int32_t Imm = MI->getOperand(OpNo).getImm();
    427   O << Imm << '(' << BitsToFloat(Imm) << ')';
    428 }
    429 
    430 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
    431                                   raw_ostream &O) {
    432   printIfSet(MI, OpNo, O, "*", " ");
    433 }
    434 
    435 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
    436                                  raw_ostream &O) {
    437   printIfSet(MI, OpNo, O, "-");
    438 }
    439 
    440 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
    441                                   raw_ostream &O) {
    442   switch (MI->getOperand(OpNo).getImm()) {
    443   default: break;
    444   case 1:
    445     O << " * 2.0";
    446     break;
    447   case 2:
    448     O << " * 4.0";
    449     break;
    450   case 3:
    451     O << " / 2.0";
    452     break;
    453   }
    454 }
    455 
    456 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
    457                                  raw_ostream &O) {
    458   printIfSet(MI, OpNo, O, "+");
    459 }
    460 
    461 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
    462                                             raw_ostream &O) {
    463   printIfSet(MI, OpNo, O, "ExecMask,");
    464 }
    465 
    466 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
    467                                         raw_ostream &O) {
    468   printIfSet(MI, OpNo, O, "Pred,");
    469 }
    470 
    471 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
    472                                        raw_ostream &O) {
    473   const MCOperand &Op = MI->getOperand(OpNo);
    474   if (Op.getImm() == 0) {
    475     O << " (MASKED)";
    476   }
    477 }
    478 
    479 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
    480                                   raw_ostream &O) {
    481   const char * chans = "XYZW";
    482   int sel = MI->getOperand(OpNo).getImm();
    483 
    484   int chan = sel & 3;
    485   sel >>= 2;
    486 
    487   if (sel >= 512) {
    488     sel -= 512;
    489     int cb = sel >> 12;
    490     sel &= 4095;
    491     O << cb << '[' << sel << ']';
    492   } else if (sel >= 448) {
    493     sel -= 448;
    494     O << sel;
    495   } else if (sel >= 0){
    496     O << sel;
    497   }
    498 
    499   if (sel >= 0)
    500     O << '.' << chans[chan];
    501 }
    502 
    503 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
    504                                          raw_ostream &O) {
    505   int BankSwizzle = MI->getOperand(OpNo).getImm();
    506   switch (BankSwizzle) {
    507   case 1:
    508     O << "BS:VEC_021/SCL_122";
    509     break;
    510   case 2:
    511     O << "BS:VEC_120/SCL_212";
    512     break;
    513   case 3:
    514     O << "BS:VEC_102/SCL_221";
    515     break;
    516   case 4:
    517     O << "BS:VEC_201";
    518     break;
    519   case 5:
    520     O << "BS:VEC_210";
    521     break;
    522   default:
    523     break;
    524   }
    525   return;
    526 }
    527 
    528 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
    529                                   raw_ostream &O) {
    530   unsigned Sel = MI->getOperand(OpNo).getImm();
    531   switch (Sel) {
    532   case 0:
    533     O << 'X';
    534     break;
    535   case 1:
    536     O << 'Y';
    537     break;
    538   case 2:
    539     O << 'Z';
    540     break;
    541   case 3:
    542     O << 'W';
    543     break;
    544   case 4:
    545     O << '0';
    546     break;
    547   case 5:
    548     O << '1';
    549     break;
    550   case 7:
    551     O << '_';
    552     break;
    553   default:
    554     break;
    555   }
    556 }
    557 
    558 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
    559                                   raw_ostream &O) {
    560   unsigned CT = MI->getOperand(OpNo).getImm();
    561   switch (CT) {
    562   case 0:
    563     O << 'U';
    564     break;
    565   case 1:
    566     O << 'N';
    567     break;
    568   default:
    569     break;
    570   }
    571 }
    572 
    573 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
    574                                     raw_ostream &O) {
    575   int KCacheMode = MI->getOperand(OpNo).getImm();
    576   if (KCacheMode > 0) {
    577     int KCacheBank = MI->getOperand(OpNo - 2).getImm();
    578     O << "CB" << KCacheBank << ':';
    579     int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
    580     int LineSize = (KCacheMode == 1) ? 16 : 32;
    581     O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
    582   }
    583 }
    584 
    585 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
    586                                      raw_ostream &O) {
    587   unsigned SImm16 = MI->getOperand(OpNo).getImm();
    588   unsigned Msg = SImm16 & 0xF;
    589   if (Msg == 2 || Msg == 3) {
    590     unsigned Op = (SImm16 >> 4) & 0xF;
    591     if (Msg == 3)
    592       O << "Gs_done(";
    593     else
    594       O << "Gs(";
    595     if (Op == 0) {
    596       O << "nop";
    597     } else {
    598       unsigned Stream = (SImm16 >> 8) & 0x3;
    599       if (Op == 1)
    600         O << "cut";
    601       else if (Op == 2)
    602         O << "emit";
    603       else if (Op == 3)
    604         O << "emit-cut";
    605       O << " stream " << Stream;
    606     }
    607     O << "), [m0] ";
    608   } else if (Msg == 1)
    609     O << "interrupt ";
    610   else if (Msg == 15)
    611     O << "system ";
    612   else
    613     O << "unknown(" << Msg << ") ";
    614 }
    615 
    616 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
    617                                       raw_ostream &O) {
    618   // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs
    619   // SIInsertWaits.cpp bits usage does not match ISA docs description but it
    620   // works so it might be a misprint in docs.
    621   unsigned SImm16 = MI->getOperand(OpNo).getImm();
    622   unsigned Vmcnt = SImm16 & 0xF;
    623   unsigned Expcnt = (SImm16 >> 4) & 0xF;
    624   unsigned Lgkmcnt = (SImm16 >> 8) & 0xF;
    625 
    626   bool NeedSpace = false;
    627 
    628   if (Vmcnt != 0xF) {
    629     O << "vmcnt(" << Vmcnt << ')';
    630     NeedSpace = true;
    631   }
    632 
    633   if (Expcnt != 0x7) {
    634     if (NeedSpace)
    635       O << ' ';
    636     O << "expcnt(" << Expcnt << ')';
    637     NeedSpace = true;
    638   }
    639 
    640   if (Lgkmcnt != 0x7) {
    641     if (NeedSpace)
    642       O << ' ';
    643     O << "lgkmcnt(" << Lgkmcnt << ')';
    644   }
    645 }
    646 
    647 #include "AMDGPUGenAsmWriter.inc"
    648