xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCInst.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- lib/MC/MCInst.cpp - MCInst implementation --------------------------===//
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 #include "llvm/MC/MCInst.h"
100b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
110b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCInstPrinter.h"
13fe6060f1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
140b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
150b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
160b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
170b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric 
print(raw_ostream & OS,const MCRegisterInfo * RegInfo) const21fe6060f1SDimitry Andric void MCOperand::print(raw_ostream &OS, const MCRegisterInfo *RegInfo) const {
220b57cec5SDimitry Andric   OS << "<MCOperand ";
230b57cec5SDimitry Andric   if (!isValid())
240b57cec5SDimitry Andric     OS << "INVALID";
25fe6060f1SDimitry Andric   else if (isReg()) {
26fe6060f1SDimitry Andric     OS << "Reg:";
27fe6060f1SDimitry Andric     if (RegInfo)
28fe6060f1SDimitry Andric       OS << RegInfo->getName(getReg());
29fe6060f1SDimitry Andric     else
30fe6060f1SDimitry Andric       OS << getReg();
31fe6060f1SDimitry Andric   } else if (isImm())
320b57cec5SDimitry Andric     OS << "Imm:" << getImm();
33fe6060f1SDimitry Andric   else if (isSFPImm())
34fe6060f1SDimitry Andric     OS << "SFPImm:" << bit_cast<float>(getSFPImm());
35fe6060f1SDimitry Andric   else if (isDFPImm())
36fe6060f1SDimitry Andric     OS << "DFPImm:" << bit_cast<double>(getDFPImm());
370b57cec5SDimitry Andric   else if (isExpr()) {
380b57cec5SDimitry Andric     OS << "Expr:(" << *getExpr() << ")";
390b57cec5SDimitry Andric   } else if (isInst()) {
40fe6060f1SDimitry Andric     OS << "Inst:(";
41*0fca6ea1SDimitry Andric     if (const auto *Inst = getInst())
42*0fca6ea1SDimitry Andric       Inst->print(OS, RegInfo);
43*0fca6ea1SDimitry Andric     else
44*0fca6ea1SDimitry Andric       OS << "NULL";
45fe6060f1SDimitry Andric     OS << ")";
460b57cec5SDimitry Andric   } else
470b57cec5SDimitry Andric     OS << "UNDEFINED";
480b57cec5SDimitry Andric   OS << ">";
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric 
evaluateAsConstantImm(int64_t & Imm) const510b57cec5SDimitry Andric bool MCOperand::evaluateAsConstantImm(int64_t &Imm) const {
520b57cec5SDimitry Andric   if (isImm()) {
530b57cec5SDimitry Andric     Imm = getImm();
540b57cec5SDimitry Andric     return true;
550b57cec5SDimitry Andric   }
560b57cec5SDimitry Andric   return false;
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
isBareSymbolRef() const590b57cec5SDimitry Andric bool MCOperand::isBareSymbolRef() const {
600b57cec5SDimitry Andric   assert(isExpr() &&
610b57cec5SDimitry Andric          "isBareSymbolRef expects only expressions");
620b57cec5SDimitry Andric   const MCExpr *Expr = getExpr();
630b57cec5SDimitry Andric   MCExpr::ExprKind Kind = getExpr()->getKind();
640b57cec5SDimitry Andric   return Kind == MCExpr::SymbolRef &&
650b57cec5SDimitry Andric     cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const690b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCOperand::dump() const {
700b57cec5SDimitry Andric   print(dbgs());
710b57cec5SDimitry Andric   dbgs() << "\n";
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric #endif
740b57cec5SDimitry Andric 
print(raw_ostream & OS,const MCRegisterInfo * RegInfo) const75fe6060f1SDimitry Andric void MCInst::print(raw_ostream &OS, const MCRegisterInfo *RegInfo) const {
760b57cec5SDimitry Andric   OS << "<MCInst " << getOpcode();
770b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
780b57cec5SDimitry Andric     OS << " ";
79fe6060f1SDimitry Andric     getOperand(i).print(OS, RegInfo);
800b57cec5SDimitry Andric   }
810b57cec5SDimitry Andric   OS << ">";
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
dump_pretty(raw_ostream & OS,const MCInstPrinter * Printer,StringRef Separator,const MCRegisterInfo * RegInfo) const840b57cec5SDimitry Andric void MCInst::dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer,
85fe6060f1SDimitry Andric                          StringRef Separator,
86fe6060f1SDimitry Andric                          const MCRegisterInfo *RegInfo) const {
870b57cec5SDimitry Andric   StringRef InstName = Printer ? Printer->getOpcodeName(getOpcode()) : "";
88fe6060f1SDimitry Andric   dump_pretty(OS, InstName, Separator, RegInfo);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
dump_pretty(raw_ostream & OS,StringRef Name,StringRef Separator,const MCRegisterInfo * RegInfo) const91fe6060f1SDimitry Andric void MCInst::dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator,
92fe6060f1SDimitry Andric                          const MCRegisterInfo *RegInfo) const {
930b57cec5SDimitry Andric   OS << "<MCInst #" << getOpcode();
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   // Show the instruction opcode name if we have it.
960b57cec5SDimitry Andric   if (!Name.empty())
970b57cec5SDimitry Andric     OS << ' ' << Name;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
1000b57cec5SDimitry Andric     OS << Separator;
101fe6060f1SDimitry Andric     getOperand(i).print(OS, RegInfo);
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric   OS << ">";
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1070b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCInst::dump() const {
1080b57cec5SDimitry Andric   print(dbgs());
1090b57cec5SDimitry Andric   dbgs() << "\n";
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric #endif
112