1 | //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This class prints an Hexagon MCInst to a .s file. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "HexagonInstPrinter.h" |
14 | #include "MCTargetDesc/HexagonBaseInfo.h" |
15 | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
16 | #include "llvm/MC/MCAsmInfo.h" |
17 | #include "llvm/MC/MCExpr.h" |
18 | #include "llvm/MC/MCInst.h" |
19 | #include "llvm/Support/Debug.h" |
20 | #include "llvm/Support/raw_ostream.h" |
21 | |
22 | using namespace llvm; |
23 | |
24 | #define DEBUG_TYPE "asm-printer" |
25 | |
26 | #define GET_INSTRUCTION_NAME |
27 | #include "HexagonGenAsmWriter.inc" |
28 | |
29 | void HexagonInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const { |
30 | O << getRegisterName(Reg); |
31 | } |
32 | |
33 | void HexagonInstPrinter::printInst(const MCInst *MI, uint64_t Address, |
34 | StringRef Annot, const MCSubtargetInfo &STI, |
35 | raw_ostream &OS) { |
36 | assert(HexagonMCInstrInfo::isBundle(*MI)); |
37 | assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE); |
38 | assert(HexagonMCInstrInfo::bundleSize(*MI) > 0); |
39 | HasExtender = false; |
40 | for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI: *MI)) { |
41 | MCInst const &MCI = *I.getInst(); |
42 | if (HexagonMCInstrInfo::isDuplex(MCII: MII, MCI)) { |
43 | printInstruction(MI: MCI.getOperand(i: 1).getInst(), Address, O&: OS); |
44 | OS << '\v'; |
45 | HasExtender = false; |
46 | printInstruction(MI: MCI.getOperand(i: 0).getInst(), Address, O&: OS); |
47 | } else |
48 | printInstruction(MI: &MCI, Address, O&: OS); |
49 | HasExtender = HexagonMCInstrInfo::isImmext(MCI); |
50 | OS << "\n" ; |
51 | } |
52 | |
53 | bool IsLoop0 = HexagonMCInstrInfo::isInnerLoop(MCI: *MI); |
54 | bool IsLoop1 = HexagonMCInstrInfo::isOuterLoop(MCI: *MI); |
55 | if (IsLoop0) { |
56 | OS << (IsLoop1 ? " :endloop01" : " :endloop0" ); |
57 | } else if (IsLoop1) { |
58 | OS << " :endloop1" ; |
59 | } |
60 | } |
61 | |
62 | void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo, |
63 | raw_ostream &O) const { |
64 | if (HexagonMCInstrInfo::getExtendableOp(MCII: MII, MCI: *MI) == OpNo && |
65 | (HasExtender || HexagonMCInstrInfo::isConstExtended(MCII: MII, MCI: *MI))) |
66 | O << "#" ; |
67 | MCOperand const &MO = MI->getOperand(i: OpNo); |
68 | if (MO.isReg()) { |
69 | O << getRegisterName(Reg: MO.getReg()); |
70 | } else if (MO.isExpr()) { |
71 | int64_t Value; |
72 | if (MO.getExpr()->evaluateAsAbsolute(Res&: Value)) |
73 | O << formatImm(Value); |
74 | else |
75 | O << *MO.getExpr(); |
76 | } else { |
77 | llvm_unreachable("Unknown operand" ); |
78 | } |
79 | } |
80 | |
81 | void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo, |
82 | raw_ostream &O) const { |
83 | MCOperand const &MO = MI->getOperand(i: OpNo); |
84 | assert (MO.isExpr()); |
85 | MCExpr const &Expr = *MO.getExpr(); |
86 | int64_t Value; |
87 | if (Expr.evaluateAsAbsolute(Res&: Value)) |
88 | O << format(Fmt: "0x%" PRIx64, Vals: Value); |
89 | else { |
90 | if (HasExtender || HexagonMCInstrInfo::isConstExtended(MCII: MII, MCI: *MI)) |
91 | if (HexagonMCInstrInfo::getExtendableOp(MCII: MII, MCI: *MI) == OpNo) |
92 | O << "##" ; |
93 | O << Expr; |
94 | } |
95 | } |
96 | |