Home | History | Annotate | Download | only in InstPrinter
      1 //===- HexagonInstPrinter.cpp - Convert Hexagon 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 an Hexagon MCInst to a .s file.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #define DEBUG_TYPE "asm-printer"
     15 #include "Hexagon.h"
     16 #include "HexagonAsmPrinter.h"
     17 #include "HexagonInstPrinter.h"
     18 #include "llvm/MC/MCInst.h"
     19 #include "llvm/MC/MCAsmInfo.h"
     20 #include "llvm/MC/MCExpr.h"
     21 #include "llvm/ADT/StringExtras.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 #include <cstdio>
     24 
     25 using namespace llvm;
     26 
     27 #define GET_INSTRUCTION_NAME
     28 #include "HexagonGenAsmWriter.inc"
     29 
     30 StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
     31   return MII.getName(Opcode);
     32 }
     33 
     34 StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
     35   return getRegisterName(RegNo);
     36 }
     37 
     38 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     39                                    StringRef Annot) {
     40   const char packetPadding[] = "      ";
     41   const char startPacket = '{',
     42              endPacket = '}';
     43   // TODO: add outer HW loop when it's supported too.
     44   if (MI->getOpcode() == Hexagon::ENDLOOP0) {
     45     MCInst Nop;
     46 
     47     O << packetPadding << startPacket << '\n';
     48     Nop.setOpcode(Hexagon::NOP);
     49     printInstruction(&Nop, O);
     50     O << packetPadding << endPacket;
     51   }
     52 
     53   printInstruction(MI, O);
     54   printAnnotation(O, Annot);
     55 }
     56 
     57 void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     58                                       raw_ostream &O) const {
     59   const MCOperand& MO = MI->getOperand(OpNo);
     60 
     61   if (MO.isReg()) {
     62     O << getRegisterName(MO.getReg());
     63   } else if(MO.isExpr()) {
     64     O << *MO.getExpr();
     65   } else if(MO.isImm()) {
     66     printImmOperand(MI, OpNo, O);
     67   } else {
     68     assert(false && "Unknown operand");
     69   }
     70 }
     71 
     72 void HexagonInstPrinter::printImmOperand
     73   (const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
     74   O << MI->getOperand(OpNo).getImm();
     75 }
     76 
     77 void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
     78                                                 raw_ostream &O) const {
     79   O << MI->getOperand(OpNo).getImm();
     80 }
     81 
     82 void HexagonInstPrinter::printUnsignedImmOperand
     83   (const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
     84   O << MI->getOperand(OpNo).getImm();
     85 }
     86 
     87 void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
     88                                             raw_ostream &O) const {
     89   O << -MI->getOperand(OpNo).getImm();
     90 }
     91 
     92 void HexagonInstPrinter::printNOneImmOperand
     93   (const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
     94   O << -1;
     95 }
     96 
     97 void HexagonInstPrinter::printMEMriOperand
     98   (const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
     99   const MCOperand& MO0 = MI->getOperand(OpNo);
    100   const MCOperand& MO1 = MI->getOperand(OpNo + 1);
    101 
    102   O << getRegisterName(MO0.getReg());
    103   O << " + #" << MO1.getImm();
    104 }
    105 
    106 void HexagonInstPrinter::printFrameIndexOperand
    107   (const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
    108   const MCOperand& MO0 = MI->getOperand(OpNo);
    109   const MCOperand& MO1 = MI->getOperand(OpNo + 1);
    110 
    111   O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm();
    112 }
    113 
    114 void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
    115                                             raw_ostream &O) const {
    116   const MCOperand& MO = MI->getOperand(OpNo);
    117   assert(MO.isExpr() && "Expecting expression");
    118 
    119   printOperand(MI, OpNo, O);
    120 }
    121 
    122 void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
    123                                         raw_ostream &O) const {
    124   const MCOperand& MO = MI->getOperand(OpNo);
    125   assert(MO.isExpr() && "Expecting expression");
    126 
    127   printOperand(MI, OpNo, O);
    128 }
    129 
    130 void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
    131                                            raw_ostream &O) const {
    132   const MCOperand& MO = MI->getOperand(OpNo);
    133   assert(MO.isExpr() && "Expecting expression");
    134 
    135   printOperand(MI, OpNo, O);
    136 }
    137 
    138 void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
    139                                             raw_ostream &O) const {
    140   // Branches can take an immediate operand.  This is used by the branch
    141   // selection pass to print $+8, an eight byte displacement from the PC.
    142   assert("Unknown branch operand.");
    143 }
    144 
    145 void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
    146                                           raw_ostream &O) const {
    147 }
    148 
    149 void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
    150                                              raw_ostream &O) const {
    151 }
    152 
    153 void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
    154                                                raw_ostream &O) const {
    155 }
    156 
    157 void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
    158                                      raw_ostream &O, bool hi) const {
    159   const MCOperand& MO = MI->getOperand(OpNo);
    160 
    161   O << '#' << (hi? "HI": "LO") << '(';
    162   if (MO.isImm()) {
    163     O << '#';
    164     printOperand(MI, OpNo, O);
    165   } else {
    166     assert("Unknown symbol operand");
    167     printOperand(MI, OpNo, O);
    168   }
    169   O << ')';
    170 }
    171