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 "HexagonAsmPrinter.h"
     16 #include "Hexagon.h"
     17 #include "HexagonInstPrinter.h"
     18 #include "MCTargetDesc/HexagonMCInst.h"
     19 #include "llvm/MC/MCInst.h"
     20 #include "llvm/ADT/StringExtras.h"
     21 #include "llvm/MC/MCAsmInfo.h"
     22 #include "llvm/MC/MCExpr.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 #include <cstdio>
     25 
     26 using namespace llvm;
     27 
     28 #define GET_INSTRUCTION_NAME
     29 #include "HexagonGenAsmWriter.inc"
     30 
     31 const char HexagonInstPrinter::PacketPadding = '\t';
     32 
     33 StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
     34   return MII.getName(Opcode);
     35 }
     36 
     37 StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
     38   return getRegisterName(RegNo);
     39 }
     40 
     41 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     42                                    StringRef Annot) {
     43   printInst((const HexagonMCInst*)(MI), O, Annot);
     44 }
     45 
     46 void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
     47                                    StringRef Annot) {
     48   const char startPacket = '{',
     49              endPacket = '}';
     50   // TODO: add outer HW loop when it's supported too.
     51   if (MI->getOpcode() == Hexagon::ENDLOOP0) {
     52     // Ending a harware loop is different from ending an regular packet.
     53     assert(MI->isPacketEnd() && "Loop-end must also end the packet");
     54 
     55     if (MI->isPacketStart()) {
     56       // There must be a packet to end a loop.
     57       // FIXME: when shuffling is always run, this shouldn't be needed.
     58       HexagonMCInst Nop;
     59       StringRef NoAnnot;
     60 
     61       Nop.setOpcode (Hexagon::NOP);
     62       Nop.setPacketStart (MI->isPacketStart());
     63       printInst (&Nop, O, NoAnnot);
     64     }
     65 
     66     // Close the packet.
     67     if (MI->isPacketEnd())
     68       O << PacketPadding << endPacket;
     69 
     70     printInstruction(MI, O);
     71   }
     72   else {
     73     // Prefix the insn opening the packet.
     74     if (MI->isPacketStart())
     75       O << PacketPadding << startPacket << '\n';
     76 
     77     printInstruction(MI, O);
     78 
     79     // Suffix the insn closing the packet.
     80     if (MI->isPacketEnd())
     81       // Suffix the packet in a new line always, since the GNU assembler has
     82       // issues with a closing brace on the same line as CONST{32,64}.
     83       O << '\n' << PacketPadding << endPacket;
     84   }
     85 
     86   printAnnotation(O, Annot);
     87 }
     88 
     89 void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     90                                       raw_ostream &O) const {
     91   const MCOperand& MO = MI->getOperand(OpNo);
     92 
     93   if (MO.isReg()) {
     94     O << getRegisterName(MO.getReg());
     95   } else if(MO.isExpr()) {
     96     O << *MO.getExpr();
     97   } else if(MO.isImm()) {
     98     printImmOperand(MI, OpNo, O);
     99   } else {
    100     llvm_unreachable("Unknown operand");
    101   }
    102 }
    103 
    104 void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
    105                                          raw_ostream &O) const {
    106   const MCOperand& MO = MI->getOperand(OpNo);
    107 
    108   if(MO.isExpr()) {
    109     O << *MO.getExpr();
    110   } else if(MO.isImm()) {
    111     O << MI->getOperand(OpNo).getImm();
    112   } else {
    113     llvm_unreachable("Unknown operand");
    114   }
    115 }
    116 
    117 void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
    118                                          raw_ostream &O) const {
    119   const HexagonMCInst *HMCI = static_cast<const HexagonMCInst*>(MI);
    120   if (HMCI->isConstExtended())
    121     O << "#";
    122   printOperand(MI, OpNo, O);
    123 }
    124 
    125 void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
    126                                     unsigned OpNo, raw_ostream &O) const {
    127   O << MI->getOperand(OpNo).getImm();
    128 }
    129 
    130 void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
    131                                             raw_ostream &O) const {
    132   O << -MI->getOperand(OpNo).getImm();
    133 }
    134 
    135 void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
    136                                              raw_ostream &O) const {
    137   O << -1;
    138 }
    139 
    140 void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
    141                                            raw_ostream &O) const {
    142   const MCOperand& MO0 = MI->getOperand(OpNo);
    143   const MCOperand& MO1 = MI->getOperand(OpNo + 1);
    144 
    145   O << getRegisterName(MO0.getReg());
    146   O << " + #" << MO1.getImm();
    147 }
    148 
    149 void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
    150                                                 raw_ostream &O) const {
    151   const MCOperand& MO0 = MI->getOperand(OpNo);
    152   const MCOperand& MO1 = MI->getOperand(OpNo + 1);
    153 
    154   O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm();
    155 }
    156 
    157 void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
    158                                             raw_ostream &O) const {
    159   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
    160 
    161   printOperand(MI, OpNo, O);
    162 }
    163 
    164 void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
    165                                         raw_ostream &O) const {
    166   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
    167 
    168   printOperand(MI, OpNo, O);
    169 }
    170 
    171 void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
    172                                            raw_ostream &O) const {
    173   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
    174 
    175   printOperand(MI, OpNo, O);
    176 }
    177 
    178 void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
    179                                             raw_ostream &O) const {
    180   // Branches can take an immediate operand.  This is used by the branch
    181   // selection pass to print $+8, an eight byte displacement from the PC.
    182   assert("Unknown branch operand.");
    183 }
    184 
    185 void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
    186                                           raw_ostream &O) const {
    187 }
    188 
    189 void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
    190                                              raw_ostream &O) const {
    191 }
    192 
    193 void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
    194                                                raw_ostream &O) const {
    195 }
    196 
    197 void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
    198                                      raw_ostream &O, bool hi) const {
    199   const MCOperand& MO = MI->getOperand(OpNo);
    200 
    201   O << '#' << (hi? "HI": "LO") << '(';
    202   if (MO.isImm()) {
    203     O << '#';
    204     printOperand(MI, OpNo, O);
    205   } else {
    206     assert("Unknown symbol operand");
    207     printOperand(MI, OpNo, O);
    208   }
    209   O << ')';
    210 }
    211