xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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