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