LLVM API Documentation

HexagonInstPrinter.cpp
Go to the documentation of this file.
00001 //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This class prints an Hexagon MCInst to a .s file.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "HexagonAsmPrinter.h"
00015 #include "Hexagon.h"
00016 #include "HexagonInstPrinter.h"
00017 #include "MCTargetDesc/HexagonMCInst.h"
00018 #include "llvm/ADT/StringExtras.h"
00019 #include "llvm/MC/MCAsmInfo.h"
00020 #include "llvm/MC/MCExpr.h"
00021 #include "llvm/MC/MCInst.h"
00022 #include "llvm/Support/raw_ostream.h"
00023 
00024 using namespace llvm;
00025 
00026 #define DEBUG_TYPE "asm-printer"
00027 
00028 #define GET_INSTRUCTION_NAME
00029 #include "HexagonGenAsmWriter.inc"
00030 
00031 const char HexagonInstPrinter::PacketPadding = '\t';
00032 
00033 StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
00034   return MII.getName(Opcode);
00035 }
00036 
00037 StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
00038   return getRegisterName(RegNo);
00039 }
00040 
00041 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
00042                                    StringRef Annot) {
00043   printInst((const HexagonMCInst*)(MI), O, Annot);
00044 }
00045 
00046 void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
00047                                    StringRef Annot) {
00048   const char startPacket = '{',
00049              endPacket = '}';
00050   // TODO: add outer HW loop when it's supported too.
00051   if (MI->getOpcode() == Hexagon::ENDLOOP0) {
00052     // Ending a harware loop is different from ending an regular packet.
00053     assert(MI->isPacketEnd() && "Loop-end must also end the packet");
00054 
00055     if (MI->isPacketStart()) {
00056       // There must be a packet to end a loop.
00057       // FIXME: when shuffling is always run, this shouldn't be needed.
00058       HexagonMCInst Nop;
00059       StringRef NoAnnot;
00060 
00061       Nop.setOpcode (Hexagon::NOP);
00062       Nop.setPacketStart (MI->isPacketStart());
00063       printInst (&Nop, O, NoAnnot);
00064     }
00065 
00066     // Close the packet.
00067     if (MI->isPacketEnd())
00068       O << PacketPadding << endPacket;
00069 
00070     printInstruction(MI, O);
00071   }
00072   else {
00073     // Prefix the insn opening the packet.
00074     if (MI->isPacketStart())
00075       O << PacketPadding << startPacket << '\n';
00076 
00077     printInstruction(MI, O);
00078 
00079     // Suffix the insn closing the packet.
00080     if (MI->isPacketEnd())
00081       // Suffix the packet in a new line always, since the GNU assembler has
00082       // issues with a closing brace on the same line as CONST{32,64}.
00083       O << '\n' << PacketPadding << endPacket;
00084   }
00085 
00086   printAnnotation(O, Annot);
00087 }
00088 
00089 void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
00090                                       raw_ostream &O) const {
00091   const MCOperand& MO = MI->getOperand(OpNo);
00092 
00093   if (MO.isReg()) {
00094     O << getRegisterName(MO.getReg());
00095   } else if(MO.isExpr()) {
00096     O << *MO.getExpr();
00097   } else if(MO.isImm()) {
00098     printImmOperand(MI, OpNo, O);
00099   } else {
00100     llvm_unreachable("Unknown operand");
00101   }
00102 }
00103 
00104 void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
00105                                          raw_ostream &O) const {
00106   const MCOperand& MO = MI->getOperand(OpNo);
00107 
00108   if(MO.isExpr()) {
00109     O << *MO.getExpr();
00110   } else if(MO.isImm()) {
00111     O << MI->getOperand(OpNo).getImm();
00112   } else {
00113     llvm_unreachable("Unknown operand");
00114   }
00115 }
00116 
00117 void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
00118                                          raw_ostream &O) const {
00119   const HexagonMCInst *HMCI = static_cast<const HexagonMCInst*>(MI);
00120   if (HMCI->isConstExtended())
00121     O << "#";
00122   printOperand(MI, OpNo, O);
00123 }
00124 
00125 void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
00126                                     unsigned OpNo, raw_ostream &O) const {
00127   O << MI->getOperand(OpNo).getImm();
00128 }
00129 
00130 void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
00131                                             raw_ostream &O) const {
00132   O << -MI->getOperand(OpNo).getImm();
00133 }
00134 
00135 void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
00136                                              raw_ostream &O) const {
00137   O << -1;
00138 }
00139 
00140 void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
00141                                            raw_ostream &O) const {
00142   const MCOperand& MO0 = MI->getOperand(OpNo);
00143   const MCOperand& MO1 = MI->getOperand(OpNo + 1);
00144 
00145   O << getRegisterName(MO0.getReg());
00146   O << " + #" << MO1.getImm();
00147 }
00148 
00149 void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
00150                                                 raw_ostream &O) const {
00151   const MCOperand& MO0 = MI->getOperand(OpNo);
00152   const MCOperand& MO1 = MI->getOperand(OpNo + 1);
00153 
00154   O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm();
00155 }
00156 
00157 void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
00158                                             raw_ostream &O) const {
00159   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
00160 
00161   printOperand(MI, OpNo, O);
00162 }
00163 
00164 void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
00165                                         raw_ostream &O) const {
00166   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
00167 
00168   printOperand(MI, OpNo, O);
00169 }
00170 
00171 void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
00172                                            raw_ostream &O) const {
00173   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
00174 
00175   printOperand(MI, OpNo, O);
00176 }
00177 
00178 void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
00179                                             raw_ostream &O) const {
00180   // Branches can take an immediate operand.  This is used by the branch
00181   // selection pass to print $+8, an eight byte displacement from the PC.
00182   llvm_unreachable("Unknown branch operand.");
00183 }
00184 
00185 void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
00186                                           raw_ostream &O) const {
00187 }
00188 
00189 void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
00190                                              raw_ostream &O) const {
00191 }
00192 
00193 void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
00194                                                raw_ostream &O) const {
00195 }
00196 
00197 void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
00198                                      raw_ostream &O, bool hi) const {
00199   assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
00200 
00201   O << '#' << (hi ? "HI" : "LO") << "(#";
00202   printOperand(MI, OpNo, O);
00203   O << ')';
00204 }