LLVM  14.0.0git
RISCVInstPrinter.cpp
Go to the documentation of this file.
1 //===-- RISCVInstPrinter.cpp - Convert RISCV MCInst to asm 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 RISCV MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVInstPrinter.h"
14 #include "RISCVBaseInfo.h"
15 #include "RISCVMCExpr.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSymbol.h"
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "asm-printer"
28 
29 // Include the auto-generated portion of the assembly writer.
30 #define PRINT_ALIAS_INSTR
31 #include "RISCVGenAsmWriter.inc"
32 
33 // Include the auto-generated portion of the compress emitter.
34 #define GEN_UNCOMPRESS_INSTR
35 #include "RISCVGenCompressInstEmitter.inc"
36 
37 static cl::opt<bool>
38  NoAliases("riscv-no-aliases",
39  cl::desc("Disable the emission of assembler pseudo instructions"),
40  cl::init(false), cl::Hidden);
41 
42 // Print architectural register names rather than the ABI names (such as x2
43 // instead of sp).
44 // TODO: Make RISCVInstPrinter::getRegisterName non-static so that this can a
45 // member.
46 static bool ArchRegNames;
47 
48 // The command-line flags above are used by llvm-mc and llc. They can be used by
49 // `llvm-objdump`, but we override their values here to handle options passed to
50 // `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to
51 // be an easier way to allow these options in all these tools, without doing it
52 // this way.
54  if (Opt == "no-aliases") {
55  PrintAliases = false;
56  return true;
57  }
58  if (Opt == "numeric") {
59  ArchRegNames = true;
60  return true;
61  }
62 
63  return false;
64 }
65 
67  StringRef Annot, const MCSubtargetInfo &STI,
68  raw_ostream &O) {
69  bool Res = false;
70  const MCInst *NewMI = MI;
71  MCInst UncompressedMI;
72  if (PrintAliases && !NoAliases)
73  Res = uncompressInst(UncompressedMI, *MI, MRI, STI);
74  if (Res)
75  NewMI = const_cast<MCInst *>(&UncompressedMI);
76  if (!PrintAliases || NoAliases || !printAliasInstr(NewMI, Address, STI, O))
77  printInstruction(NewMI, Address, STI, O);
78  printAnnotation(O, Annot);
79 }
80 
81 void RISCVInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
82  O << getRegisterName(RegNo);
83 }
84 
85 void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
86  const MCSubtargetInfo &STI, raw_ostream &O,
87  const char *Modifier) {
88  assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
89  const MCOperand &MO = MI->getOperand(OpNo);
90 
91  if (MO.isReg()) {
92  printRegName(O, MO.getReg());
93  return;
94  }
95 
96  if (MO.isImm()) {
97  O << MO.getImm();
98  return;
99  }
100 
101  assert(MO.isExpr() && "Unknown operand kind in printOperand");
102  MO.getExpr()->print(O, &MAI);
103 }
104 
106  unsigned OpNo,
107  const MCSubtargetInfo &STI,
108  raw_ostream &O) {
109  const MCOperand &MO = MI->getOperand(OpNo);
110  if (!MO.isImm())
111  return printOperand(MI, OpNo, STI, O);
112 
114  uint64_t Target = Address + MO.getImm();
115  if (!STI.hasFeature(RISCV::Feature64Bit))
116  Target &= 0xffffffff;
117  O << formatHex(Target);
118  } else {
119  O << MO.getImm();
120  }
121 }
122 
124  const MCSubtargetInfo &STI,
125  raw_ostream &O) {
126  unsigned Imm = MI->getOperand(OpNo).getImm();
127  auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
128  if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits()))
129  O << SysReg->Name;
130  else
131  O << Imm;
132 }
133 
134 void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo,
135  const MCSubtargetInfo &STI,
136  raw_ostream &O) {
137  unsigned FenceArg = MI->getOperand(OpNo).getImm();
138  assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg");
139 
140  if ((FenceArg & RISCVFenceField::I) != 0)
141  O << 'i';
142  if ((FenceArg & RISCVFenceField::O) != 0)
143  O << 'o';
144  if ((FenceArg & RISCVFenceField::R) != 0)
145  O << 'r';
146  if ((FenceArg & RISCVFenceField::W) != 0)
147  O << 'w';
148  if (FenceArg == 0)
149  O << "unknown";
150 }
151 
152 void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo,
153  const MCSubtargetInfo &STI, raw_ostream &O) {
154  auto FRMArg =
155  static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm());
157 }
158 
159 void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo,
160  const MCSubtargetInfo &STI,
161  raw_ostream &O) {
162  const MCOperand &MO = MI->getOperand(OpNo);
163 
164  assert(MO.isReg() && "printAtomicMemOp can only print register operands");
165  O << "(";
166  printRegName(O, MO.getReg());
167  O << ")";
168 }
169 
170 void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo,
171  const MCSubtargetInfo &STI, raw_ostream &O) {
172  unsigned Imm = MI->getOperand(OpNo).getImm();
174 }
175 
176 void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo,
177  const MCSubtargetInfo &STI,
178  raw_ostream &O) {
179  const MCOperand &MO = MI->getOperand(OpNo);
180 
181  assert(MO.isReg() && "printVMaskReg can only print register operands");
182  if (MO.getReg() == RISCV::NoRegister)
183  return;
184  O << ", ";
185  printRegName(O, MO.getReg());
186  O << ".t";
187 }
188 
189 const char *RISCVInstPrinter::getRegisterName(unsigned RegNo) {
190  return getRegisterName(RegNo, ArchRegNames ? RISCV::NoRegAltName
191  : RISCV::ABIRegAltName);
192 }
llvm::RISCVFenceField::I
@ I
Definition: RISCVBaseInfo.h:191
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::RISCVInstPrinter::printOperand
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier=nullptr)
Definition: RISCVInstPrinter.cpp:85
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
llvm::MCInstPrinter::PrintAliases
bool PrintAliases
True if we prefer aliases (e.g. nop) to raw mnemonics.
Definition: MCInstPrinter.h:58
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:194
ErrorHandling.h
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
RISCVMCExpr.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::MCInstPrinter::PrintBranchImmAsAddress
bool PrintBranchImmAsAddress
If true, a branch immediate (e.g.
Definition: MCInstPrinter.h:69
llvm::RISCVInstPrinter::printFenceArg
void printFenceArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:134
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:193
RISCVInstPrinter.h
llvm::RISCVInstPrinter::applyTargetSpecificCLOption
bool applyTargetSpecificCLOption(StringRef Opt) override
Customize the printer according to a command line option.
Definition: RISCVInstPrinter.cpp:53
llvm::MCInstPrinter::MRI
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:51
CommandLine.h
FormattedStream.h
llvm::MCSubtargetInfo::hasFeature
bool hasFeature(unsigned Feature) const
Definition: MCSubtargetInfo.h:118
llvm::RISCVInstPrinter::printFRMArg
void printFRMArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:152
llvm::RISCVInstPrinter::printVMaskReg
void printVMaskReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:176
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCSymbol.h
MCInst.h
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:111
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::RISCVInstPrinter::printRegName
void printRegName(raw_ostream &O, unsigned RegNo) const override
Print the assembler register name.
Definition: RISCVInstPrinter.cpp:81
NoAliases
static cl::opt< bool > NoAliases("riscv-no-aliases", cl::desc("Disable the emission of assembler pseudo instructions"), cl::init(false), cl::Hidden)
llvm::MCInstPrinter::printAnnotation
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Definition: MCInstPrinter.cpp:49
llvm::cl::opt< bool >
llvm::RISCVInstPrinter::printBranchOperand
void printBranchOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:105
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:192
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
uint64_t
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
llvm::MCInstPrinter::formatHex
format_object< int64_t > formatHex(int64_t Value) const
Definition: MCInstPrinter.cpp:197
MCRegisterInfo.h
llvm::HighlightColor::Address
@ Address
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::RISCVInstPrinter::printCSRSystemRegister
void printCSRSystemRegister(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:123
llvm::RISCVInstPrinter::printAtomicMemOp
void printAtomicMemOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:159
MCAsmInfo.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::RISCVInstPrinter::printInst
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
Definition: RISCVInstPrinter.cpp:66
llvm::RISCVFPRndMode::roundingModeToString
static StringRef roundingModeToString(RoundingMode RndMode)
Definition: RISCVBaseInfo.h:210
llvm::RISCVVType::printVType
void printVType(unsigned VType, raw_ostream &OS)
Definition: RISCVBaseInfo.cpp:140
llvm::AArch64SysReg::lookupSysRegByEncoding
const SysReg * lookupSysRegByEncoding(uint16_t)
llvm::RISCVInstPrinter::printAliasInstr
bool printAliasInstr(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
llvm::MCOperand::getExpr
const MCExpr * getExpr() const
Definition: MCInst.h:114
ArchRegNames
static bool ArchRegNames
Definition: RISCVInstPrinter.cpp:46
RISCVBaseInfo.h
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
llvm::MCInstPrinter::MAI
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:49
llvm::RISCVFPRndMode::RoundingMode
RoundingMode
Definition: RISCVBaseInfo.h:200
llvm::MCExpr::print
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:42
llvm::RISCVInstPrinter::printVTypeI
void printVTypeI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: RISCVInstPrinter.cpp:170
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::RISCVInstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo)
Definition: RISCVInstPrinter.cpp:189
llvm::cl::desc
Definition: CommandLine.h:414
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
llvm::RISCVInstPrinter::printInstruction
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)