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(*MI)) {
41     MCInst const &MCI = *I.getInst();
42     if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
43       printInstruction(MCI.getOperand(1).getInst(), Address, OS);
44       OS << '\v';
45       HasExtender = false;
46       printInstruction(MCI.getOperand(0).getInst(), Address, OS);
47     } else
48       printInstruction(&MCI, Address, OS);
49     HasExtender = HexagonMCInstrInfo::isImmext(MCI);
50     OS << "\n";
51   }
52 
53   bool IsLoop0 = HexagonMCInstrInfo::isInnerLoop(*MI);
54   bool IsLoop1 = HexagonMCInstrInfo::isOuterLoop(*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(MII, *MI) == OpNo &&
65       (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
66     O << "#";
67   MCOperand const &MO = MI->getOperand(OpNo);
68   if (MO.isReg()) {
69     O << getRegisterName(MO.getReg());
70   } else if (MO.isExpr()) {
71     int64_t Value;
72     if (MO.getExpr()->evaluateAsAbsolute(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(OpNo);
84   assert (MO.isExpr());
85   MCExpr const &Expr = *MO.getExpr();
86   int64_t Value;
87   if (Expr.evaluateAsAbsolute(Value))
88     O << format("0x%" PRIx64, Value);
89   else {
90     if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
91       if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
92         O << "##";
93     O << Expr;
94   }
95 }
96