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 Separator = " "; 83 MCInst ME; 84 ME.setOpcode(Hexagon::ENDLOOP1); 85 printInstruction(&ME, OS); 86 } 87 } 88 89 void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo, 90 raw_ostream &O) const { 91 if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo && 92 (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))) 93 O << "#"; 94 MCOperand const &MO = MI->getOperand(OpNo); 95 if (MO.isReg()) { 96 O << getRegisterName(MO.getReg()); 97 } else if (MO.isExpr()) { 98 int64_t Value; 99 if (MO.getExpr()->evaluateAsAbsolute(Value)) 100 O << formatImm(Value); 101 else 102 O << *MO.getExpr(); 103 } else { 104 llvm_unreachable("Unknown operand"); 105 } 106 } 107 108 void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo, 109 raw_ostream &O) const { 110 printOperand(MI, OpNo, O); 111 } 112 113 void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI, 114 unsigned OpNo, 115 raw_ostream &O) const { 116 O << MI->getOperand(OpNo).getImm(); 117 } 118 119 void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo, 120 raw_ostream &O) const { 121 O << -MI->getOperand(OpNo).getImm(); 122 } 123 124 void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo, 125 raw_ostream &O) const { 126 O << -1; 127 } 128 129 void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned OpNo, 130 raw_ostream &O) const { 131 int64_t Imm; 132 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 133 Imm = SignExtend64<9>(Imm); 134 assert(Success); (void)Success; 135 assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO."); 136 O << formatImm(Imm/64); 137 } 138 139 void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned OpNo, 140 raw_ostream &O) const { 141 int64_t Imm; 142 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 143 Imm = SignExtend64<10>(Imm); 144 assert(Success); (void)Success; 145 assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO."); 146 O << formatImm(Imm/128); 147 } 148 149 void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned OpNo, 150 raw_ostream &O) const { 151 int64_t Imm; 152 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 153 Imm = SignExtend64<10>(Imm); 154 assert(Success); (void)Success; 155 assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO."); 156 O << formatImm(Imm/64); 157 } 158 159 void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned OpNo, 160 raw_ostream &O) const { 161 int64_t Imm; 162 bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm); 163 Imm = SignExtend64<11>(Imm); 164 assert(Success); (void)Success; 165 assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO."); 166 O << formatImm(Imm/128); 167 } 168 169 void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo, 170 raw_ostream &O) const { 171 printOperand(MI, OpNo, O); 172 } 173 174 void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo, 175 raw_ostream &O) const { 176 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 177 178 printOperand(MI, OpNo, O); 179 } 180 181 void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo, 182 raw_ostream &O) const { 183 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 184 185 printOperand(MI, OpNo, O); 186 } 187 188 void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo, 189 raw_ostream &O) const { 190 // Branches can take an immediate operand. This is used by the branch 191 // selection pass to print $+8, an eight byte displacement from the PC. 192 llvm_unreachable("Unknown branch operand."); 193 } 194 195 void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo, 196 raw_ostream &O) const {} 197 198 void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo, 199 raw_ostream &O) const {} 200 201 void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo, 202 raw_ostream &O) const {} 203 204 void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo, 205 raw_ostream &O, bool hi) const { 206 MCOperand const &MO = MI->getOperand(OpNo); 207 208 O << '#' << (hi ? "HI" : "LO") << '('; 209 if (MO.isImm()) { 210 O << '#'; 211 printOperand(MI, OpNo, O); 212 } else { 213 printOperand(MI, OpNo, O); 214 assert("Unknown symbol operand"); 215 } 216 O << ')'; 217 } 218 219 void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo, 220 raw_ostream &O) const { 221 MCOperand const &MO = MI->getOperand(OpNo); 222 assert (MO.isExpr()); 223 MCExpr const &Expr = *MO.getExpr(); 224 int64_t Value; 225 if (Expr.evaluateAsAbsolute(Value)) 226 O << format("0x%" PRIx64, Value); 227 else { 228 if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)) 229 if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo) 230 O << "##"; 231 O << Expr; 232 } 233 } 234