LLVM  14.0.0git
RISCVAsmPrinter.cpp
Go to the documentation of this file.
1 //===-- RISCVAsmPrinter.cpp - RISCV LLVM assembly writer ------------------===//
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 file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to the RISCV assembly language.
11 //
12 //===----------------------------------------------------------------------===//
13 
17 #include "RISCV.h"
18 #include "RISCVTargetMachine.h"
20 #include "llvm/ADT/Statistic.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSymbol.h"
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "asm-printer"
35 
36 STATISTIC(RISCVNumInstrsCompressed,
37  "Number of RISC-V Compressed instructions emitted");
38 
39 namespace {
40 class RISCVAsmPrinter : public AsmPrinter {
41  const MCSubtargetInfo *STI;
42 
43 public:
44  explicit RISCVAsmPrinter(TargetMachine &TM,
45  std::unique_ptr<MCStreamer> Streamer)
46  : AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {}
47 
48  StringRef getPassName() const override { return "RISCV Assembly Printer"; }
49 
50  bool runOnMachineFunction(MachineFunction &MF) override;
51 
52  void emitInstruction(const MachineInstr *MI) override;
53 
54  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
55  const char *ExtraCode, raw_ostream &OS) override;
56  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
57  const char *ExtraCode, raw_ostream &OS) override;
58 
59  void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
60  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
61  const MachineInstr *MI);
62 
63  // Wrapper needed for tblgenned pseudo lowering.
64  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
65  return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this);
66  }
67 
68  void emitStartOfAsmFile(Module &M) override;
69  void emitEndOfAsmFile(Module &M) override;
70 
71 private:
72  void emitAttributes();
73 };
74 }
75 
76 #define GEN_COMPRESS_INSTR
77 #include "RISCVGenCompressInstEmitter.inc"
78 void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
79  MCInst CInst;
80  bool Res = compressInst(CInst, Inst, *STI, OutStreamer->getContext());
81  if (Res)
82  ++RISCVNumInstrsCompressed;
83  AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
84 }
85 
86 // Simple pseudo-instructions have their lowering (with expansion to real
87 // instructions) auto-generated.
88 #include "RISCVGenMCPseudoLowering.inc"
89 
90 void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
91  // Do any auto-generated pseudo lowerings.
92  if (emitPseudoExpansionLowering(*OutStreamer, MI))
93  return;
94 
95  MCInst TmpInst;
96  if (!lowerRISCVMachineInstrToMCInst(MI, TmpInst, *this))
97  EmitToStreamer(*OutStreamer, TmpInst);
98 }
99 
100 bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
101  const char *ExtraCode, raw_ostream &OS) {
102  // First try the generic code, which knows about modifiers like 'c' and 'n'.
103  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
104  return false;
105 
106  const MachineOperand &MO = MI->getOperand(OpNo);
107  if (ExtraCode && ExtraCode[0]) {
108  if (ExtraCode[1] != 0)
109  return true; // Unknown modifier.
110 
111  switch (ExtraCode[0]) {
112  default:
113  return true; // Unknown modifier.
114  case 'z': // Print zero register if zero, regular printing otherwise.
115  if (MO.isImm() && MO.getImm() == 0) {
116  OS << RISCVInstPrinter::getRegisterName(RISCV::X0);
117  return false;
118  }
119  break;
120  case 'i': // Literal 'i' if operand is not a register.
121  if (!MO.isReg())
122  OS << 'i';
123  return false;
124  }
125  }
126 
127  switch (MO.getType()) {
129  OS << MO.getImm();
130  return false;
133  return false;
135  PrintSymbolOperand(MO, OS);
136  return false;
138  MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
139  Sym->print(OS, MAI);
140  return false;
141  }
142  default:
143  break;
144  }
145 
146  return true;
147 }
148 
149 bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
150  unsigned OpNo,
151  const char *ExtraCode,
152  raw_ostream &OS) {
153  if (!ExtraCode) {
154  const MachineOperand &MO = MI->getOperand(OpNo);
155  // For now, we only support register memory operands in registers and
156  // assume there is no addend
157  if (!MO.isReg())
158  return true;
159 
160  OS << "0(" << RISCVInstPrinter::getRegisterName(MO.getReg()) << ")";
161  return false;
162  }
163 
164  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
165 }
166 
167 bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
168  // Set the current MCSubtargetInfo to a copy which has the correct
169  // feature bits for the current MachineFunction
170  MCSubtargetInfo &NewSTI =
171  OutStreamer->getContext().getSubtargetCopy(*TM.getMCSubtargetInfo());
173  STI = &NewSTI;
174 
175  SetupMachineFunction(MF);
176  emitFunctionBody();
177  return false;
178 }
179 
180 void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
181  if (TM.getTargetTriple().isOSBinFormatELF())
182  emitAttributes();
183 }
184 
185 void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
186  RISCVTargetStreamer &RTS =
187  static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
188 
189  if (TM.getTargetTriple().isOSBinFormatELF())
191 }
192 
193 void RISCVAsmPrinter::emitAttributes() {
194  RISCVTargetStreamer &RTS =
195  static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
196  RTS.emitTargetAttributes(*STI);
197 }
198 
199 // Force static initialization.
203 }
AsmPrinter.h
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:63
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MachineInstr.h
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:53
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::RISCVTargetStreamer::emitTargetAttributes
void emitTargetAttributes(const MCSubtargetInfo &STI)
Definition: RISCVTargetStreamer.cpp:40
llvm::getTheRISCV64Target
Target & getTheRISCV64Target()
Definition: RISCVTargetInfo.cpp:18
Statistic.h
llvm::MachineOperand::getBlockAddress
const BlockAddress * getBlockAddress() const
Definition: MachineOperand.h:568
RISCVMCExpr.h
llvm::MCSubtargetInfo::setFeatureBits
void setFeatureBits(const FeatureBitset &FeatureBits_)
Definition: MCSubtargetInfo.h:112
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:52
llvm::AsmPrinter::EmitToStreamer
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:243
RISCVInstPrinter.h
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:62
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
llvm::AsmPrinter::PrintAsmMemoryOperand
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
Definition: AsmPrinterInlineAsm.cpp:641
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
llvm::lowerRISCVMachineInstrToMCInst
bool lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
Definition: RISCVMCInstLower.cpp:208
MCSymbol.h
MCInst.h
llvm::LowerRISCVMachineOperandToMCOperand
bool LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &MCOp, const AsmPrinter &AP)
Definition: RISCVMCInstLower.cpp:90
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:111
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
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::MCSymbol::print
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:59
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
RISCVTargetStreamer.h
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
MachineConstantPool.h
llvm::MachineOperand::getType
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Definition: MachineOperand.h:219
MachineFunctionPass.h
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:79
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1605
MachineModuleInfo.h
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
RISCV.h
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::RISCVTargetStreamer::finishAttributeSection
virtual void finishAttributeSection()
Definition: RISCVTargetStreamer.cpp:33
LLVMInitializeRISCVAsmPrinter
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter()
Definition: RISCVAsmPrinter.cpp:200
MCAsmInfo.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
std
Definition: BitVector.h:838
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:323
MCStreamer.h
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
RISCVTargetInfo.h
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::RISCVTargetStreamer
Definition: RISCVTargetStreamer.h:19
llvm::RISCVInstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo)
Definition: RISCVInstPrinter.cpp:189
llvm::RegisterAsmPrinter
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Definition: TargetRegistry.h:1338
raw_ostream.h
TargetRegistry.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::getTheRISCV32Target
Target & getTheRISCV32Target()
Definition: RISCVTargetInfo.cpp:13
llvm::AsmPrinter::PrintAsmOperand
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
Definition: AsmPrinterInlineAsm.cpp:599
RISCVTargetMachine.h