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 #include "HexagonAsmPrinter.h" 15 #include "HexagonInstPrinter.h" 16 #include "MCTargetDesc/HexagonBaseInfo.h" 17 #include "MCTargetDesc/HexagonMCInstrInfo.h" 18 #include "llvm/MC/MCAsmInfo.h" 19 #include "llvm/MC/MCExpr.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/raw_ostream.h" 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "asm-printer" 27 28 #define GET_INSTRUCTION_NAME 29 #include "HexagonGenAsmWriter.inc" 30 31 HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI, 32 MCInstrInfo const &MII, 33 MCRegisterInfo const &MRI) 34 : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) { 35 } 36 37 StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { 38 return MII.getName(Opcode); 39 } 40 41 void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 42 O << getRegName(RegNo); 43 } 44 45 StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { 46 return getRegisterName(RegNo); 47 } 48 49 void HexagonInstPrinter::setExtender(MCInst const &MCI) { 50 HasExtender = HexagonMCInstrInfo::isImmext(MCI); 51 } 52 53 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 54 StringRef Annot, const MCSubtargetInfo &STI) { 55 assert(HexagonMCInstrInfo::isBundle(*MI)); 56 assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE); 57 assert(HexagonMCInstrInfo::bundleSize(*MI) > 0); 58 HasExtender = false; 59 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) { 60 MCInst const &MCI = *I.getInst(); 61 if (HexagonMCInstrInfo::isDuplex(MII, MCI)) { 62 printInstruction(MCI.getOperand(1).getInst(), OS); 63 OS << '\v'; 64 HasExtender = false; 65 printInstruction(MCI.getOperand(0).getInst(), OS); 66 } else 67 printInstruction(&MCI, OS); 68 setExtender(MCI); 69 OS << "\n"; 70 } 71 72 auto Separator = ""; 73 if (HexagonMCInstrInfo::isInnerLoop(*MI)) { 74 OS << Separator; 75 Separator = " "; 76 MCInst ME; 77 ME.setOpcode(Hexagon::ENDLOOP0); 78 printInstruction(&ME, OS); 79 } 80 if (HexagonMCInstrInfo::isOuterLoop(*MI)) { 81 OS << Separator; 82 MCInst ME; 83 ME.setOpcode(Hexagon::ENDLOOP1); 84 printInstruction(&ME, OS); 85 } 86 } 87 88 void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo, 89 raw_ostream &O) const { 90 if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo && 91 (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))) 92 O << "#"; 93 MCOperand const &MO = MI->getOperand(OpNo); 94 if (MO.isReg()) { 95 O << getRegisterName(MO.getReg()); 96 } else if (MO.isExpr()) { 97 int64_t Value; 98 if (MO.getExpr()->evaluateAsAbsolute(Value)) 99 O << formatImm(Value); 100 else 101 O << *MO.getExpr(); 102 } else { 103 llvm_unreachable("Unknown operand"); 104 } 105 } 106 107 void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo, 108 raw_ostream &O) const { 109 printOperand(MI, OpNo, O); 110 } 111 112 void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI, 113 unsigned OpNo, 114 raw_ostream &O) const { 115 O << MI->getOperand(OpNo).getImm(); 116 } 117 118 void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo, 119 raw_ostream &O) const { 120 O << -MI->getOperand(OpNo).getImm(); 121 } 122 123 void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo, 124 raw_ostream &O) const { 125 O << -1; 126 } 127 128 void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned OpNo, 129 raw_ostream &O) const { 130 int64_t Imm; 131 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 132 Imm = SignExtend64<9>(Imm); 133 assert(Success); (void)Success; 134 assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO."); 135 O << formatImm(Imm/64); 136 } 137 138 void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned OpNo, 139 raw_ostream &O) const { 140 int64_t Imm; 141 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 142 Imm = SignExtend64<10>(Imm); 143 assert(Success); (void)Success; 144 assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO."); 145 O << formatImm(Imm/128); 146 } 147 148 void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned OpNo, 149 raw_ostream &O) const { 150 int64_t Imm; 151 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 152 Imm = SignExtend64<10>(Imm); 153 assert(Success); (void)Success; 154 assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO."); 155 O << formatImm(Imm/64); 156 } 157 158 void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned OpNo, 159 raw_ostream &O) const { 160 int64_t Imm; 161 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 162 Imm = SignExtend64<11>(Imm); 163 assert(Success); (void)Success; 164 assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO."); 165 O << formatImm(Imm/128); 166 } 167 168 void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo, 169 raw_ostream &O) const { 170 printOperand(MI, OpNo, O); 171 } 172 173 void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo, 174 raw_ostream &O) const { 175 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 176 177 printOperand(MI, OpNo, O); 178 } 179 180 void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo, 181 raw_ostream &O) const { 182 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 183 184 printOperand(MI, OpNo, O); 185 } 186 187 void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo, 188 raw_ostream &O) const { 189 // Branches can take an immediate operand. This is used by the branch 190 // selection pass to print $+8, an eight byte displacement from the PC. 191 llvm_unreachable("Unknown branch operand."); 192 } 193 194 void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo, 195 raw_ostream &O) const {} 196 197 void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo, 198 raw_ostream &O) const {} 199 200 void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo, 201 raw_ostream &O) const {} 202 203 void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo, 204 raw_ostream &O, bool hi) const { 205 assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); 206 207 O << '#' << (hi ? "HI" : "LO") << '('; 208 O << '#'; 209 printOperand(MI, OpNo, O); 210 O << ')'; 211 } 212 213 void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo, 214 raw_ostream &O) const { 215 MCOperand const &MO = MI->getOperand(OpNo); 216 assert (MO.isExpr()); 217 MCExpr const &Expr = *MO.getExpr(); 218 int64_t Value; 219 if (Expr.evaluateAsAbsolute(Value)) 220 O << format("0x%" PRIx64, Value); 221 else { 222 if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)) 223 if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo) 224 O << "##"; 225 O << Expr; 226 } 227 } 228