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 "llvm/MC/MCExpr.h"
     14 #include "llvm/MC/MCInst.h"
     15 
     16 using namespace llvm;
     17 
     18 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
     19                              StringRef Annot) {
     20   OS.flush();
     21   printInstruction(MI, OS);
     22 
     23   printAnnotation(OS, Annot);
     24 }
     25 
     26 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     27                                      raw_ostream &O) {
     28 
     29   const MCOperand &Op = MI->getOperand(OpNo);
     30   if (Op.isReg()) {
     31     switch (Op.getReg()) {
     32     // This is the default predicate state, so we don't need to print it.
     33     case AMDGPU::PRED_SEL_OFF: break;
     34     default: O << getRegisterName(Op.getReg()); break;
     35     }
     36   } else if (Op.isImm()) {
     37     O << Op.getImm();
     38   } else if (Op.isFPImm()) {
     39     O << Op.getFPImm();
     40   } else if (Op.isExpr()) {
     41     const MCExpr *Exp = Op.getExpr();
     42     Exp->print(O);
     43   } else {
     44     assert(!"unknown operand type in printOperand");
     45   }
     46 }
     47 
     48 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
     49                                         raw_ostream &O) {
     50   unsigned Imm = MI->getOperand(OpNum).getImm();
     51 
     52   if (Imm == 2) {
     53     O << "P0";
     54   } else if (Imm == 1) {
     55     O << "P20";
     56   } else if (Imm == 0) {
     57     O << "P10";
     58   } else {
     59     assert(!"Invalid interpolation parameter slot");
     60   }
     61 }
     62 
     63 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
     64                                         raw_ostream &O) {
     65   printOperand(MI, OpNo, O);
     66   O  << ", ";
     67   printOperand(MI, OpNo + 1, O);
     68 }
     69 
     70 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
     71                                    raw_ostream &O, StringRef Asm,
     72                                    StringRef Default) {
     73   const MCOperand &Op = MI->getOperand(OpNo);
     74   assert(Op.isImm());
     75   if (Op.getImm() == 1) {
     76     O << Asm;
     77   } else {
     78     O << Default;
     79   }
     80 }
     81 
     82 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
     83                                  raw_ostream &O) {
     84   printIfSet(MI, OpNo, O, "|");
     85 }
     86 
     87 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
     88                                    raw_ostream &O) {
     89   printIfSet(MI, OpNo, O, "_SAT");
     90 }
     91 
     92 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
     93                                      raw_ostream &O) {
     94   union Literal {
     95     float f;
     96     int32_t i;
     97   } L;
     98 
     99   L.i = MI->getOperand(OpNo).getImm();
    100   O << L.i << "(" << L.f << ")";
    101 }
    102 
    103 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
    104                                   raw_ostream &O) {
    105   printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " ");
    106 }
    107 
    108 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
    109                                  raw_ostream &O) {
    110   printIfSet(MI, OpNo, O, "-");
    111 }
    112 
    113 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
    114                                   raw_ostream &O) {
    115   switch (MI->getOperand(OpNo).getImm()) {
    116   default: break;
    117   case 1:
    118     O << " * 2.0";
    119     break;
    120   case 2:
    121     O << " * 4.0";
    122     break;
    123   case 3:
    124     O << " / 2.0";
    125     break;
    126   }
    127 }
    128 
    129 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
    130                                  raw_ostream &O) {
    131   printIfSet(MI, OpNo, O, "+");
    132 }
    133 
    134 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
    135                                             raw_ostream &O) {
    136   printIfSet(MI, OpNo, O, "ExecMask,");
    137 }
    138 
    139 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
    140                                         raw_ostream &O) {
    141   printIfSet(MI, OpNo, O, "Pred,");
    142 }
    143 
    144 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
    145                                        raw_ostream &O) {
    146   const MCOperand &Op = MI->getOperand(OpNo);
    147   if (Op.getImm() == 0) {
    148     O << " (MASKED)";
    149   }
    150 }
    151 
    152 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
    153                                   raw_ostream &O) {
    154   const char * chans = "XYZW";
    155   int sel = MI->getOperand(OpNo).getImm();
    156 
    157   int chan = sel & 3;
    158   sel >>= 2;
    159 
    160   if (sel >= 512) {
    161     sel -= 512;
    162     int cb = sel >> 12;
    163     sel &= 4095;
    164     O << cb << "[" << sel << "]";
    165   } else if (sel >= 448) {
    166     sel -= 448;
    167     O << sel;
    168   } else if (sel >= 0){
    169     O << sel;
    170   }
    171 
    172   if (sel >= 0)
    173     O << "." << chans[chan];
    174 }
    175 
    176 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
    177                                          raw_ostream &O) {
    178   int BankSwizzle = MI->getOperand(OpNo).getImm();
    179   switch (BankSwizzle) {
    180   case 1:
    181     O << "BS:VEC_021/SCL_122";
    182     break;
    183   case 2:
    184     O << "BS:VEC_120/SCL_212";
    185     break;
    186   case 3:
    187     O << "BS:VEC_102/SCL_221";
    188     break;
    189   case 4:
    190     O << "BS:VEC_201";
    191     break;
    192   case 5:
    193     O << "BS:VEC_210";
    194     break;
    195   default:
    196     break;
    197   }
    198   return;
    199 }
    200 
    201 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
    202                                   raw_ostream &O) {
    203   unsigned Sel = MI->getOperand(OpNo).getImm();
    204   switch (Sel) {
    205   case 0:
    206     O << "X";
    207     break;
    208   case 1:
    209     O << "Y";
    210     break;
    211   case 2:
    212     O << "Z";
    213     break;
    214   case 3:
    215     O << "W";
    216     break;
    217   case 4:
    218     O << "0";
    219     break;
    220   case 5:
    221     O << "1";
    222     break;
    223   case 7:
    224     O << "_";
    225     break;
    226   default:
    227     break;
    228   }
    229 }
    230 
    231 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
    232                                   raw_ostream &O) {
    233   unsigned CT = MI->getOperand(OpNo).getImm();
    234   switch (CT) {
    235   case 0:
    236     O << "U";
    237     break;
    238   case 1:
    239     O << "N";
    240     break;
    241   default:
    242     break;
    243   }
    244 }
    245 
    246 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
    247                                     raw_ostream &O) {
    248   int KCacheMode = MI->getOperand(OpNo).getImm();
    249   if (KCacheMode > 0) {
    250     int KCacheBank = MI->getOperand(OpNo - 2).getImm();
    251     O << "CB" << KCacheBank <<":";
    252     int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
    253     int LineSize = (KCacheMode == 1)?16:32;
    254     O << KCacheAddr * 16 << "-" << KCacheAddr * 16 + LineSize;
    255   }
    256 }
    257 
    258 #include "AMDGPUGenAsmWriter.inc"
    259