LLVM API Documentation
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 }