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/MC/MCInstrInfo.h"
     22 #include "llvm/ADT/APFloat.h"
     23 #include "llvm/ADT/StringExtras.h"
     24 #include "llvm/Support/ErrorHandling.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 using namespace llvm;
     27 
     28 #include "PTXGenAsmWriter.inc"
     29 
     30 PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI,
     31                                const MCInstrInfo &MII,
     32                                const MCRegisterInfo &MRI,
     33                                const MCSubtargetInfo &STI) :
     34   MCInstPrinter(MAI, MII, MRI) {
     35   // Initialize the set of available features.
     36   setAvailableFeatures(STI.getFeatureBits());
     37 }
     38 
     39 void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
     40   // Decode the register number into type and offset
     41   unsigned RegSpace  = RegNo & 0x7;
     42   unsigned RegType   = (RegNo >> 3) & 0x7;
     43   unsigned RegOffset = RegNo >> 6;
     44 
     45   // Print the register
     46   OS << "%";
     47 
     48   switch (RegSpace) {
     49   default:
     50     llvm_unreachable("Unknown register space!");
     51   case PTXRegisterSpace::Reg:
     52     switch (RegType) {
     53     default:
     54       llvm_unreachable("Unknown register type!");
     55     case PTXRegisterType::Pred:
     56       OS << "p";
     57       break;
     58     case PTXRegisterType::B16:
     59       OS << "rh";
     60       break;
     61     case PTXRegisterType::B32:
     62       OS << "r";
     63       break;
     64     case PTXRegisterType::B64:
     65       OS << "rd";
     66       break;
     67     case PTXRegisterType::F32:
     68       OS << "f";
     69       break;
     70     case PTXRegisterType::F64:
     71       OS << "fd";
     72       break;
     73     }
     74     break;
     75   case PTXRegisterSpace::Return:
     76     OS << "ret";
     77     break;
     78   case PTXRegisterSpace::Argument:
     79     OS << "arg";
     80     break;
     81   }
     82 
     83   OS << RegOffset;
     84 }
     85 
     86 void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     87                                StringRef Annot) {
     88   printPredicate(MI, O);
     89   switch (MI->getOpcode()) {
     90   default:
     91     printInstruction(MI, O);
     92     break;
     93   case PTX::CALL:
     94     printCall(MI, O);
     95   }
     96   O << ";";
     97   printAnnotation(O, Annot);
     98 }
     99 
    100 void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) {
    101   // The last two operands are the predicate operands
    102   int RegIndex;
    103   int OpIndex;
    104 
    105   if (MI->getOpcode() == PTX::CALL) {
    106     RegIndex = 0;
    107     OpIndex  = 1;
    108   } else {
    109     RegIndex = MI->getNumOperands()-2;
    110     OpIndex = MI->getNumOperands()-1;
    111   }
    112 
    113   int PredOp = MI->getOperand(OpIndex).getImm();
    114   if (PredOp == PTXPredicate::None)
    115     return;
    116 
    117   if (PredOp == PTXPredicate::Negate)
    118     O << '!';
    119   else
    120     O << '@';
    121 
    122   printOperand(MI, RegIndex, O);
    123 }
    124 
    125 void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) {
    126   O << "\tcall.uni\t";
    127   // The first two operands are the predicate slot
    128   unsigned Index = 2;
    129   unsigned NumRets = MI->getOperand(Index++).getImm();
    130 
    131   if (NumRets > 0) {
    132     O << "(";
    133     printOperand(MI, Index++, O);
    134     for (unsigned i = 1; i < NumRets; ++i) {
    135       O << ", ";
    136       printOperand(MI, Index++, O);
    137     }
    138     O << "), ";
    139   }
    140 
    141   const MCExpr* Expr = MI->getOperand(Index++).getExpr();
    142   unsigned NumArgs = MI->getOperand(Index++).getImm();
    143 
    144   // if the function call is to printf or puts, change to vprintf
    145   if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
    146     const MCSymbol &Sym = SymRefExpr->getSymbol();
    147     if (Sym.getName() == "printf" || Sym.getName() == "puts") {
    148       O << "vprintf";
    149     } else {
    150       O << Sym.getName();
    151     }
    152   } else {
    153     O << *Expr;
    154   }
    155 
    156   O << ", (";
    157 
    158   if (NumArgs > 0) {
    159     printOperand(MI, Index++, O);
    160     for (unsigned i = 1; i < NumArgs; ++i) {
    161       O << ", ";
    162       printOperand(MI, Index++, O);
    163     }
    164   }
    165   O << ")";
    166 }
    167 
    168 void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
    169                                   raw_ostream &O) {
    170   const MCOperand &Op = MI->getOperand(OpNo);
    171   if (Op.isImm()) {
    172     O << Op.getImm();
    173   } else if (Op.isFPImm()) {
    174     double Imm = Op.getFPImm();
    175     APFloat FPImm(Imm);
    176     APInt FPIntImm = FPImm.bitcastToAPInt();
    177     O << "0D";
    178     // PTX requires us to output the full 64 bits, even if the number is zero
    179     if (FPIntImm.getZExtValue() > 0) {
    180       O << FPIntImm.toString(16, false);
    181     } else {
    182       O << "0000000000000000";
    183     }
    184   } else if (Op.isReg()) {
    185     printRegName(O, Op.getReg());
    186   } else {
    187     assert(Op.isExpr() && "unknown operand kind in printOperand");
    188     const MCExpr *Expr = Op.getExpr();
    189     if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
    190       const MCSymbol &Sym = SymRefExpr->getSymbol();
    191       O << Sym.getName();
    192     } else {
    193       O << *Op.getExpr();
    194     }
    195   }
    196 }
    197 
    198 void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
    199                                      raw_ostream &O) {
    200   // By definition, operand OpNo+1 is an i32imm
    201   const MCOperand &Op2 = MI->getOperand(OpNo+1);
    202   printOperand(MI, OpNo, O);
    203   if (Op2.getImm() == 0)
    204     return; // don't print "+0"
    205   O << "+" << Op2.getImm();
    206 }
    207 
    208 void PTXInstPrinter::printRoundingMode(const MCInst *MI, unsigned OpNo,
    209                                        raw_ostream &O) {
    210   const MCOperand &Op = MI->getOperand(OpNo);
    211   assert (Op.isImm() && "Rounding modes must be immediate values");
    212   switch (Op.getImm()) {
    213   default:
    214     llvm_unreachable("Unknown rounding mode!");
    215   case PTXRoundingMode::RndDefault:
    216     llvm_unreachable("FP rounding-mode pass did not handle instruction!");
    217   case PTXRoundingMode::RndNone:
    218     // Do not print anything.
    219     break;
    220   case PTXRoundingMode::RndNearestEven:
    221     O << ".rn";
    222     break;
    223   case PTXRoundingMode::RndTowardsZero:
    224     O << ".rz";
    225     break;
    226   case PTXRoundingMode::RndNegInf:
    227     O << ".rm";
    228     break;
    229   case PTXRoundingMode::RndPosInf:
    230     O << ".rp";
    231     break;
    232   case PTXRoundingMode::RndApprox:
    233     O << ".approx";
    234     break;
    235   case PTXRoundingMode::RndNearestEvenInt:
    236     O << ".rni";
    237     break;
    238   case PTXRoundingMode::RndTowardsZeroInt:
    239     O << ".rzi";
    240     break;
    241   case PTXRoundingMode::RndNegInfInt:
    242     O << ".rmi";
    243     break;
    244   case PTXRoundingMode::RndPosInfInt:
    245     O << ".rpi";
    246     break;
    247   }
    248 }
    249 
    250