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