10b57cec5SDimitry Andric //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This class prints an Hexagon MCInst to a .s file.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "HexagonInstPrinter.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
200b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
210b57cec5SDimitry Andric
220b57cec5SDimitry Andric using namespace llvm;
230b57cec5SDimitry Andric
240b57cec5SDimitry Andric #define DEBUG_TYPE "asm-printer"
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric #define GET_INSTRUCTION_NAME
270b57cec5SDimitry Andric #include "HexagonGenAsmWriter.inc"
280b57cec5SDimitry Andric
printRegName(raw_ostream & O,MCRegister Reg) const29*bdd1243dSDimitry Andric void HexagonInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
30*bdd1243dSDimitry Andric O << getRegisterName(Reg);
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)33480093f4SDimitry Andric void HexagonInstPrinter::printInst(const MCInst *MI, uint64_t Address,
34480093f4SDimitry Andric StringRef Annot, const MCSubtargetInfo &STI,
35480093f4SDimitry Andric raw_ostream &OS) {
360b57cec5SDimitry Andric assert(HexagonMCInstrInfo::isBundle(*MI));
370b57cec5SDimitry Andric assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
380b57cec5SDimitry Andric assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
390b57cec5SDimitry Andric HasExtender = false;
400b57cec5SDimitry Andric for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
410b57cec5SDimitry Andric MCInst const &MCI = *I.getInst();
420b57cec5SDimitry Andric if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
43480093f4SDimitry Andric printInstruction(MCI.getOperand(1).getInst(), Address, OS);
440b57cec5SDimitry Andric OS << '\v';
450b57cec5SDimitry Andric HasExtender = false;
46480093f4SDimitry Andric printInstruction(MCI.getOperand(0).getInst(), Address, OS);
470b57cec5SDimitry Andric } else
48480093f4SDimitry Andric printInstruction(&MCI, Address, OS);
490b57cec5SDimitry Andric HasExtender = HexagonMCInstrInfo::isImmext(MCI);
500b57cec5SDimitry Andric OS << "\n";
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric bool IsLoop0 = HexagonMCInstrInfo::isInnerLoop(*MI);
540b57cec5SDimitry Andric bool IsLoop1 = HexagonMCInstrInfo::isOuterLoop(*MI);
550b57cec5SDimitry Andric if (IsLoop0) {
560b57cec5SDimitry Andric OS << (IsLoop1 ? " :endloop01" : " :endloop0");
570b57cec5SDimitry Andric } else if (IsLoop1) {
580b57cec5SDimitry Andric OS << " :endloop1";
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric
printOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const620b57cec5SDimitry Andric void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
630b57cec5SDimitry Andric raw_ostream &O) const {
640b57cec5SDimitry Andric if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
650b57cec5SDimitry Andric (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
660b57cec5SDimitry Andric O << "#";
670b57cec5SDimitry Andric MCOperand const &MO = MI->getOperand(OpNo);
680b57cec5SDimitry Andric if (MO.isReg()) {
690b57cec5SDimitry Andric O << getRegisterName(MO.getReg());
700b57cec5SDimitry Andric } else if (MO.isExpr()) {
710b57cec5SDimitry Andric int64_t Value;
720b57cec5SDimitry Andric if (MO.getExpr()->evaluateAsAbsolute(Value))
730b57cec5SDimitry Andric O << formatImm(Value);
740b57cec5SDimitry Andric else
750b57cec5SDimitry Andric O << *MO.getExpr();
760b57cec5SDimitry Andric } else {
770b57cec5SDimitry Andric llvm_unreachable("Unknown operand");
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric
printBrtarget(MCInst const * MI,unsigned OpNo,raw_ostream & O) const810b57cec5SDimitry Andric void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
820b57cec5SDimitry Andric raw_ostream &O) const {
830b57cec5SDimitry Andric MCOperand const &MO = MI->getOperand(OpNo);
840b57cec5SDimitry Andric assert (MO.isExpr());
850b57cec5SDimitry Andric MCExpr const &Expr = *MO.getExpr();
860b57cec5SDimitry Andric int64_t Value;
870b57cec5SDimitry Andric if (Expr.evaluateAsAbsolute(Value))
880b57cec5SDimitry Andric O << format("0x%" PRIx64, Value);
890b57cec5SDimitry Andric else {
900b57cec5SDimitry Andric if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
910b57cec5SDimitry Andric if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
920b57cec5SDimitry Andric O << "##";
930b57cec5SDimitry Andric O << Expr;
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric }
96