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
22using namespace llvm;
23
24#define DEBUG_TYPE "asm-printer"
25
26#define GET_INSTRUCTION_NAME
27#include "HexagonGenAsmWriter.inc"
28
29void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
30  O << getRegisterName(RegNo);
31}
32
33void 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
62void 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
81void 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