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 "HexagonInstPrinter.h"
15 #include "HexagonAsmPrinter.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
printRegName(raw_ostream & O,unsigned RegNo) const31 void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
32 O << getRegisterName(RegNo);
33 }
34
printInst(const MCInst * MI,raw_ostream & OS,StringRef Annot,const MCSubtargetInfo & STI)35 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
36 StringRef Annot, const MCSubtargetInfo &STI) {
37 assert(HexagonMCInstrInfo::isBundle(*MI));
38 assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
39 assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
40 HasExtender = false;
41 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
42 MCInst const &MCI = *I.getInst();
43 if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
44 printInstruction(MCI.getOperand(1).getInst(), OS);
45 OS << '\v';
46 HasExtender = false;
47 printInstruction(MCI.getOperand(0).getInst(), OS);
48 } else
49 printInstruction(&MCI, OS);
50 HasExtender = HexagonMCInstrInfo::isImmext(MCI);
51 OS << "\n";
52 }
53
54 bool IsLoop0 = HexagonMCInstrInfo::isInnerLoop(*MI);
55 bool IsLoop1 = HexagonMCInstrInfo::isOuterLoop(*MI);
56 if (IsLoop0) {
57 OS << (IsLoop1 ? " :endloop01" : " :endloop0");
58 } else if (IsLoop1) {
59 OS << " :endloop1";
60 }
61 }
62
printOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const63 void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
64 raw_ostream &O) const {
65 if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
66 (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
67 O << "#";
68 MCOperand const &MO = MI->getOperand(OpNo);
69 if (MO.isReg()) {
70 O << getRegisterName(MO.getReg());
71 } else if (MO.isExpr()) {
72 int64_t Value;
73 if (MO.getExpr()->evaluateAsAbsolute(Value))
74 O << formatImm(Value);
75 else
76 O << *MO.getExpr();
77 } else {
78 llvm_unreachable("Unknown operand");
79 }
80 }
81
printBrtarget(MCInst const * MI,unsigned OpNo,raw_ostream & O) const82 void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
83 raw_ostream &O) const {
84 MCOperand const &MO = MI->getOperand(OpNo);
85 assert (MO.isExpr());
86 MCExpr const &Expr = *MO.getExpr();
87 int64_t Value;
88 if (Expr.evaluateAsAbsolute(Value))
89 O << format("0x%" PRIx64, Value);
90 else {
91 if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
92 if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
93 O << "##";
94 O << Expr;
95 }
96 }
97