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/MCInst.h"
     14 #include "llvm/MC/MCExpr.h"
     15 
     16 using namespace llvm;
     17 
     18 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
     19                              StringRef Annot) {
     20   printInstruction(MI, OS);
     21 
     22   printAnnotation(OS, Annot);
     23 }
     24 
     25 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     26                                      raw_ostream &O) {
     27 
     28   const MCOperand &Op = MI->getOperand(OpNo);
     29   if (Op.isReg()) {
     30     switch (Op.getReg()) {
     31     // This is the default predicate state, so we don't need to print it.
     32     case AMDGPU::PRED_SEL_OFF: break;
     33     default: O << getRegisterName(Op.getReg()); break;
     34     }
     35   } else if (Op.isImm()) {
     36     O << Op.getImm();
     37   } else if (Op.isFPImm()) {
     38     O << Op.getFPImm();
     39   } else if (Op.isExpr()) {
     40     const MCExpr *Exp = Op.getExpr();
     41     Exp->print(O);
     42   } else {
     43     assert(!"unknown operand type in printOperand");
     44   }
     45 }
     46 
     47 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
     48                                         raw_ostream &O) {
     49   unsigned Imm = MI->getOperand(OpNum).getImm();
     50 
     51   if (Imm == 2) {
     52     O << "P0";
     53   } else if (Imm == 1) {
     54     O << "P20";
     55   } else if (Imm == 0) {
     56     O << "P10";
     57   } else {
     58     assert(!"Invalid interpolation parameter slot");
     59   }
     60 }
     61 
     62 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
     63                                         raw_ostream &O) {
     64   printOperand(MI, OpNo, O);
     65   O  << ", ";
     66   printOperand(MI, OpNo + 1, O);
     67 }
     68 
     69 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
     70                                     raw_ostream &O, StringRef Asm) {
     71   const MCOperand &Op = MI->getOperand(OpNo);
     72   assert(Op.isImm());
     73   if (Op.getImm() == 1) {
     74     O << Asm;
     75   }
     76 }
     77 
     78 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
     79                                  raw_ostream &O) {
     80   printIfSet(MI, OpNo, O, "|");
     81 }
     82 
     83 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
     84                                    raw_ostream &O) {
     85   printIfSet(MI, OpNo, O, "_SAT");
     86 }
     87 
     88 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
     89                                      raw_ostream &O) {
     90   union Literal {
     91     float f;
     92     int32_t i;
     93   } L;
     94 
     95   L.i = MI->getOperand(OpNo).getImm();
     96   O << L.i << "(" << L.f << ")";
     97 }
     98 
     99 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
    100                                   raw_ostream &O) {
    101   printIfSet(MI, OpNo, O, " *");
    102 }
    103 
    104 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
    105                                  raw_ostream &O) {
    106   printIfSet(MI, OpNo, O, "-");
    107 }
    108 
    109 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
    110                                   raw_ostream &O) {
    111   switch (MI->getOperand(OpNo).getImm()) {
    112   default: break;
    113   case 1:
    114     O << " * 2.0";
    115     break;
    116   case 2:
    117     O << " * 4.0";
    118     break;
    119   case 3:
    120     O << " / 2.0";
    121     break;
    122   }
    123 }
    124 
    125 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
    126                                  raw_ostream &O) {
    127   printIfSet(MI, OpNo, O, "+");
    128 }
    129 
    130 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
    131                                             raw_ostream &O) {
    132   printIfSet(MI, OpNo, O, "ExecMask,");
    133 }
    134 
    135 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
    136                                         raw_ostream &O) {
    137   printIfSet(MI, OpNo, O, "Pred,");
    138 }
    139 
    140 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
    141                                        raw_ostream &O) {
    142   const MCOperand &Op = MI->getOperand(OpNo);
    143   if (Op.getImm() == 0) {
    144     O << " (MASKED)";
    145   }
    146 }
    147 
    148 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
    149                                   raw_ostream &O) {
    150   const char * chans = "XYZW";
    151   int sel = MI->getOperand(OpNo).getImm();
    152 
    153   int chan = sel & 3;
    154   sel >>= 2;
    155 
    156   if (sel >= 512) {
    157     sel -= 512;
    158     int cb = sel >> 12;
    159     sel &= 4095;
    160     O << cb << "[" << sel << "]";
    161   } else if (sel >= 448) {
    162     sel -= 448;
    163     O << sel;
    164   } else if (sel >= 0){
    165     O << sel;
    166   }
    167 
    168   if (sel >= 0)
    169     O << "." << chans[chan];
    170 }
    171 
    172 #include "AMDGPUGenAsmWriter.inc"
    173