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 Separator = " "; 83 MCInst ME; 84 ME.setOpcode(Hexagon::ENDLOOP1); 85 printInstruction(&ME, OS); 86 } 87} 88 89void 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 108void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo, 109 raw_ostream &O) const { 110 printOperand(MI, OpNo, O); 111} 112 113void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI, 114 unsigned OpNo, 115 raw_ostream &O) const { 116 O << MI->getOperand(OpNo).getImm(); 117} 118 119void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo, 120 raw_ostream &O) const { 121 O << -MI->getOperand(OpNo).getImm(); 122} 123 124void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo, 125 raw_ostream &O) const { 126 O << -1; 127} 128 129void 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 139void 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 149void 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 159void 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 169void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo, 170 raw_ostream &O) const { 171 printOperand(MI, OpNo, O); 172} 173 174void 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 181void 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 188void 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 195void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo, 196 raw_ostream &O) const {} 197 198void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo, 199 raw_ostream &O) const {} 200 201void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo, 202 raw_ostream &O) const {} 203 204void 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 219void 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