Home | History | Annotate | Download | only in InstPrinter
      1 //===-- SystemZInstPrinter.cpp - Convert SystemZ 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 #include "SystemZInstPrinter.h"
     11 #include "llvm/MC/MCExpr.h"
     12 #include "llvm/MC/MCInst.h"
     13 #include "llvm/MC/MCInstrInfo.h"
     14 #include "llvm/MC/MCSymbol.h"
     15 #include "llvm/Support/ErrorHandling.h"
     16 #include "llvm/Support/raw_ostream.h"
     17 
     18 using namespace llvm;
     19 
     20 #define DEBUG_TYPE "asm-printer"
     21 
     22 #include "SystemZGenAsmWriter.inc"
     23 
     24 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
     25                                       unsigned Index, raw_ostream &O) {
     26   O << Disp;
     27   if (Base || Index) {
     28     O << '(';
     29     if (Index) {
     30       O << '%' << getRegisterName(Index);
     31       if (Base)
     32         O << ',';
     33     }
     34     if (Base)
     35       O << '%' << getRegisterName(Base);
     36     O << ')';
     37   }
     38 }
     39 
     40 void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
     41                                       raw_ostream &O) {
     42   if (MO.isReg())
     43     O << '%' << getRegisterName(MO.getReg());
     44   else if (MO.isImm())
     45     O << MO.getImm();
     46   else if (MO.isExpr())
     47     MO.getExpr()->print(O, MAI);
     48   else
     49     llvm_unreachable("Invalid operand");
     50 }
     51 
     52 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     53                                    StringRef Annot,
     54                                    const MCSubtargetInfo &STI) {
     55   printInstruction(MI, O);
     56   printAnnotation(O, Annot);
     57 }
     58 
     59 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
     60   O << '%' << getRegisterName(RegNo);
     61 }
     62 
     63 template <unsigned N>
     64 static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
     65   int64_t Value = MI->getOperand(OpNum).getImm();
     66   assert(isUInt<N>(Value) && "Invalid uimm argument");
     67   O << Value;
     68 }
     69 
     70 template <unsigned N>
     71 static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
     72   int64_t Value = MI->getOperand(OpNum).getImm();
     73   assert(isInt<N>(Value) && "Invalid simm argument");
     74   O << Value;
     75 }
     76 
     77 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
     78                                            raw_ostream &O) {
     79   printUImmOperand<1>(MI, OpNum, O);
     80 }
     81 
     82 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
     83                                            raw_ostream &O) {
     84   printUImmOperand<2>(MI, OpNum, O);
     85 }
     86 
     87 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
     88                                            raw_ostream &O) {
     89   printUImmOperand<3>(MI, OpNum, O);
     90 }
     91 
     92 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
     93                                            raw_ostream &O) {
     94   printUImmOperand<4>(MI, OpNum, O);
     95 }
     96 
     97 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
     98                                            raw_ostream &O) {
     99   printUImmOperand<6>(MI, OpNum, O);
    100 }
    101 
    102 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
    103                                            raw_ostream &O) {
    104   printSImmOperand<8>(MI, OpNum, O);
    105 }
    106 
    107 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
    108                                            raw_ostream &O) {
    109   printUImmOperand<8>(MI, OpNum, O);
    110 }
    111 
    112 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
    113                                             raw_ostream &O) {
    114   printUImmOperand<12>(MI, OpNum, O);
    115 }
    116 
    117 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
    118                                             raw_ostream &O) {
    119   printSImmOperand<16>(MI, OpNum, O);
    120 }
    121 
    122 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
    123                                             raw_ostream &O) {
    124   printUImmOperand<16>(MI, OpNum, O);
    125 }
    126 
    127 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
    128                                             raw_ostream &O) {
    129   printSImmOperand<32>(MI, OpNum, O);
    130 }
    131 
    132 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
    133                                             raw_ostream &O) {
    134   printUImmOperand<32>(MI, OpNum, O);
    135 }
    136 
    137 void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum,
    138                                                raw_ostream &O) {
    139   uint64_t Value = MI->getOperand(OpNum).getImm();
    140   assert(Value < 16 && "Invalid access register number");
    141   O << "%a" << (unsigned int)Value;
    142 }
    143 
    144 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
    145                                            raw_ostream &O) {
    146   const MCOperand &MO = MI->getOperand(OpNum);
    147   if (MO.isImm()) {
    148     O << "0x";
    149     O.write_hex(MO.getImm());
    150   } else
    151     MO.getExpr()->print(O, &MAI);
    152 }
    153 
    154 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
    155                                               raw_ostream &O) {
    156   // Output the PC-relative operand.
    157   printPCRelOperand(MI, OpNum, O);
    158 
    159   // Output the TLS marker if present.
    160   if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
    161     const MCOperand &MO = MI->getOperand(OpNum + 1);
    162     const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
    163     switch (refExp.getKind()) {
    164       case MCSymbolRefExpr::VK_TLSGD:
    165         O << ":tls_gdcall:";
    166         break;
    167       case MCSymbolRefExpr::VK_TLSLDM:
    168         O << ":tls_ldcall:";
    169         break;
    170       default:
    171         llvm_unreachable("Unexpected symbol kind");
    172     }
    173     O << refExp.getSymbol().getName();
    174   }
    175 }
    176 
    177 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
    178                                       raw_ostream &O) {
    179   printOperand(MI->getOperand(OpNum), &MAI, O);
    180 }
    181 
    182 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
    183                                             raw_ostream &O) {
    184   printAddress(MI->getOperand(OpNum).getReg(),
    185                MI->getOperand(OpNum + 1).getImm(), 0, O);
    186 }
    187 
    188 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
    189                                              raw_ostream &O) {
    190   printAddress(MI->getOperand(OpNum).getReg(),
    191                MI->getOperand(OpNum + 1).getImm(),
    192                MI->getOperand(OpNum + 2).getReg(), O);
    193 }
    194 
    195 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
    196                                              raw_ostream &O) {
    197   unsigned Base = MI->getOperand(OpNum).getReg();
    198   uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
    199   uint64_t Length = MI->getOperand(OpNum + 2).getImm();
    200   O << Disp << '(' << Length;
    201   if (Base)
    202     O << ",%" << getRegisterName(Base);
    203   O << ')';
    204 }
    205 
    206 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
    207                                              raw_ostream &O) {
    208   printAddress(MI->getOperand(OpNum).getReg(),
    209                MI->getOperand(OpNum + 1).getImm(),
    210                MI->getOperand(OpNum + 2).getReg(), O);
    211 }
    212 
    213 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
    214                                            raw_ostream &O) {
    215   static const char *const CondNames[] = {
    216     "o", "h", "nle", "l", "nhe", "lh", "ne",
    217     "e", "nlh", "he", "nl", "le", "nh", "no"
    218   };
    219   uint64_t Imm = MI->getOperand(OpNum).getImm();
    220   assert(Imm > 0 && Imm < 15 && "Invalid condition");
    221   O << CondNames[Imm - 1];
    222 }
    223