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 24using namespace llvm; 25 26#define DEBUG_TYPE "asm-printer" 27 28#define GET_INSTRUCTION_NAME 29#include "HexagonGenAsmWriter.inc" 30 31HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI, 32 MCInstrInfo const &MII, 33 MCRegisterInfo const &MRI) 34 : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) { 35} 36 37StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { 38 return MII.getName(Opcode); 39} 40 41void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 42 O << getRegName(RegNo); 43} 44 45StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { 46 return getRegisterName(RegNo); 47} 48 49void HexagonInstPrinter::setExtender(MCInst const &MCI) { 50 HasExtender = HexagonMCInstrInfo::isImmext(MCI); 51} 52 53void 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 88void 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 107void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo, 108 raw_ostream &O) const { 109 printOperand(MI, OpNo, O); 110} 111 112void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI, 113 unsigned OpNo, 114 raw_ostream &O) const { 115 O << MI->getOperand(OpNo).getImm(); 116} 117 118void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo, 119 raw_ostream &O) const { 120 O << -MI->getOperand(OpNo).getImm(); 121} 122 123void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo, 124 raw_ostream &O) const { 125 O << -1; 126} 127 128void 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 138void 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 148void 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 158void 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 168void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo, 169 raw_ostream &O) const { 170 printOperand(MI, OpNo, O); 171} 172 173void 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 180void 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 187void 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 194void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo, 195 raw_ostream &O) const {} 196 197void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo, 198 raw_ostream &O) const {} 199 200void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo, 201 raw_ostream &O) const {} 202 203void 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 213void 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