Home | History | Annotate | Download | only in InstPrinter
      1 //===-- PTXInstPrinter.cpp - Convert PTX MCInst to assembly syntax --------===//
      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 //===----------------------------------------------------------------------===//
      9 //
     10 // This class prints a PTX MCInst to a .ptx file.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #define DEBUG_TYPE "asm-printer"
     15 #include "PTXInstPrinter.h"
     16 #include "MCTargetDesc/PTXBaseInfo.h"
     17 #include "llvm/MC/MCAsmInfo.h"
     18 #include "llvm/MC/MCExpr.h"
     19 #include "llvm/MC/MCInst.h"
     20 #include "llvm/MC/MCSymbol.h"
     21 #include "llvm/ADT/StringExtras.h"
     22 #include "llvm/Support/ErrorHandling.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 using namespace llvm;
     25 
     26 #define GET_INSTRUCTION_NAME
     27 #include "PTXGenAsmWriter.inc"
     28 
     29 PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI,
     30                                const MCSubtargetInfo &STI) :
     31   MCInstPrinter(MAI) {
     32   // Initialize the set of available features.
     33   setAvailableFeatures(STI.getFeatureBits());
     34 }
     35 
     36 StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const {
     37   return getInstructionName(Opcode);
     38 }
     39 
     40 void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
     41   OS << getRegisterName(RegNo);
     42 }
     43 
     44 void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     45                                StringRef Annot) {
     46   printPredicate(MI, O);
     47   switch (MI->getOpcode()) {
     48   default:
     49     printInstruction(MI, O);
     50     break;
     51   case PTX::CALL:
     52     printCall(MI, O);
     53   }
     54   O << ";";
     55   printAnnotation(O, Annot);
     56 }
     57 
     58 void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) {
     59   // The last two operands are the predicate operands
     60   int RegIndex;
     61   int OpIndex;
     62 
     63   if (MI->getOpcode() == PTX::CALL) {
     64     RegIndex = 0;
     65     OpIndex  = 1;
     66   } else {
     67     RegIndex = MI->getNumOperands()-2;
     68     OpIndex = MI->getNumOperands()-1;
     69   }
     70 
     71   int PredOp = MI->getOperand(OpIndex).getImm();
     72   if (PredOp == PTXPredicate::None)
     73     return;
     74 
     75   if (PredOp == PTXPredicate::Negate)
     76     O << '!';
     77   else
     78     O << '@';
     79 
     80   printOperand(MI, RegIndex, O);
     81 }
     82 
     83 void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) {
     84   O << "\tcall.uni\t";
     85   // The first two operands are the predicate slot
     86   unsigned Index = 2;
     87   unsigned NumRets = MI->getOperand(Index++).getImm();
     88 
     89   if (NumRets > 0) {
     90     O << "(";
     91     printOperand(MI, Index++, O);
     92     for (unsigned i = 1; i < NumRets; ++i) {
     93       O << ", ";
     94       printOperand(MI, Index++, O);
     95     }
     96     O << "), ";
     97   }
     98 
     99   O << *(MI->getOperand(Index++).getExpr()) << ", (";
    100 
    101   unsigned NumArgs = MI->getOperand(Index++).getImm();
    102   if (NumArgs > 0) {
    103     printOperand(MI, Index++, O);
    104     for (unsigned i = 1; i < NumArgs; ++i) {
    105       O << ", ";
    106       printOperand(MI, Index++, O);
    107     }
    108   }
    109   O << ")";
    110 }
    111 
    112 void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
    113                                   raw_ostream &O) {
    114   const MCOperand &Op = MI->getOperand(OpNo);
    115   if (Op.isImm()) {
    116     O << Op.getImm();
    117   } else if (Op.isFPImm()) {
    118     double Imm = Op.getFPImm();
    119     APFloat FPImm(Imm);
    120     APInt FPIntImm = FPImm.bitcastToAPInt();
    121     O << "0D";
    122     // PTX requires us to output the full 64 bits, even if the number is zero
    123     if (FPIntImm.getZExtValue() > 0) {
    124       O << FPIntImm.toString(16, false);
    125     } else {
    126       O << "0000000000000000";
    127     }
    128   } else {
    129     assert(Op.isExpr() && "unknown operand kind in printOperand");
    130     const MCExpr *Expr = Op.getExpr();
    131     if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
    132       const MCSymbol &Sym = SymRefExpr->getSymbol();
    133       O << Sym.getName();
    134     } else {
    135       O << *Op.getExpr();
    136     }
    137   }
    138 }
    139 
    140 void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
    141                                      raw_ostream &O) {
    142   // By definition, operand OpNo+1 is an i32imm
    143   const MCOperand &Op2 = MI->getOperand(OpNo+1);
    144   printOperand(MI, OpNo, O);
    145   if (Op2.getImm() == 0)
    146     return; // don't print "+0"
    147   O << "+" << Op2.getImm();
    148 }
    149 
    150 void PTXInstPrinter::printRoundingMode(const MCInst *MI, unsigned OpNo,
    151                                        raw_ostream &O) {
    152   const MCOperand &Op = MI->getOperand(OpNo);
    153   assert (Op.isImm() && "Rounding modes must be immediate values");
    154   switch (Op.getImm()) {
    155   default:
    156     llvm_unreachable("Unknown rounding mode!");
    157   case PTXRoundingMode::RndDefault:
    158     llvm_unreachable("FP rounding-mode pass did not handle instruction!");
    159     break;
    160   case PTXRoundingMode::RndNone:
    161     // Do not print anything.
    162     break;
    163   case PTXRoundingMode::RndNearestEven:
    164     O << ".rn";
    165     break;
    166   case PTXRoundingMode::RndTowardsZero:
    167     O << ".rz";
    168     break;
    169   case PTXRoundingMode::RndNegInf:
    170     O << ".rm";
    171     break;
    172   case PTXRoundingMode::RndPosInf:
    173     O << ".rp";
    174     break;
    175   case PTXRoundingMode::RndApprox:
    176     O << ".approx";
    177     break;
    178   case PTXRoundingMode::RndNearestEvenInt:
    179     O << ".rni";
    180     break;
    181   case PTXRoundingMode::RndTowardsZeroInt:
    182     O << ".rzi";
    183     break;
    184   case PTXRoundingMode::RndNegInfInt:
    185     O << ".rmi";
    186     break;
    187   case PTXRoundingMode::RndPosInfInt:
    188     O << ".rpi";
    189     break;
    190   }
    191 }
    192 
    193