42#define DEBUG_TYPE "asm-printer"
45 "Number of RISC-V Compressed instructions emitted");
53 std::unique_ptr<MCStreamer> Streamer)
68 bool emitPseudoExpansionLowering(
MCStreamer &OutStreamer,
71 typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
72 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
74 void EmitHwasanMemaccessSymbols(
Module &M);
87 void emitAttributes();
95 ++RISCVNumInstrsCompressed;
101#include "RISCVGenMCPseudoLowering.inc"
104 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(),
105 getSubtargetInfo().getFeatureBits());
108 if (emitPseudoExpansionLowering(*OutStreamer,
MI))
112 switch (
MI->getOpcode()) {
113 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
114 LowerHWASAN_CHECK_MEMACCESS(*
MI);
116 case RISCV::PseudoRVVInitUndefM1:
117 case RISCV::PseudoRVVInitUndefM2:
118 case RISCV::PseudoRVVInitUndefM4:
119 case RISCV::PseudoRVVInitUndefM8:
125 EmitToStreamer(*OutStreamer, TmpInst);
128bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
135 if (ExtraCode && ExtraCode[0]) {
136 if (ExtraCode[1] != 0)
139 switch (ExtraCode[0]) {
163 PrintSymbolOperand(MO,
OS);
177bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
179 const char *ExtraCode,
197 SetupMachineFunction(MF);
202void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
205 if (
const MDString *ModuleTargetABI =
206 dyn_cast_or_null<MDString>(
M.getModuleFlag(
"target-abi")))
208 if (
TM.getTargetTriple().isOSBinFormatELF())
212void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
216 if (
TM.getTargetTriple().isOSBinFormatELF())
218 EmitHwasanMemaccessSymbols(M);
221void RISCVAsmPrinter::emitAttributes() {
230void RISCVAsmPrinter::emitFunctionEntryLabel() {
232 if (RMFI->isVectorCall()) {
246void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
248 uint32_t AccessInfo =
MI.getOperand(1).getImm();
250 HwasanMemaccessSymbols[HwasanMemaccessTuple(Reg, AccessInfo)];
253 if (!
TM.getTargetTriple().isOSBinFormatELF())
256 std::string SymName =
"__hwasan_check_x" + utostr(Reg - RISCV::X0) +
"_" +
257 utostr(AccessInfo) +
"_short";
258 Sym = OutContext.getOrCreateSymbol(SymName);
263 EmitToStreamer(*OutStreamer,
MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
266void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
267 if (HwasanMemaccessSymbols.empty())
270 assert(
TM.getTargetTriple().isOSBinFormatELF());
277 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
289 for (
auto &
P : HwasanMemaccessSymbols) {
290 unsigned Reg = std::get<0>(
P.first);
291 uint32_t AccessInfo = std::get<1>(
P.first);
296 OutStreamer->switchSection(OutContext.getELFSection(
302 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Weak);
303 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Hidden);
304 OutStreamer->emitLabel(Sym);
307 OutStreamer->emitInstruction(
321 OutStreamer->emitInstruction(
325 OutStreamer->emitInstruction(
328 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
330 OutStreamer->emitInstruction(
337 MCSymbol *ReturnSym = OutContext.createTempSymbol();
338 OutStreamer->emitLabel(ReturnSym);
344 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
351 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
352 OutStreamer->emitInstruction(
359 OutStreamer->emitInstruction(
369 OutStreamer->emitInstruction(
376 OutStreamer->emitInstruction(
379 OutStreamer->emitInstruction(
382 OutStreamer->emitInstruction(
389 OutStreamer->emitLabel(HandleMismatchSym);
446 OutStreamer->emitInstruction(
451 OutStreamer->emitInstruction(
455 if (Reg != RISCV::X10)
461 OutStreamer->emitInstruction(
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This class is intended to be used as a driving class for all asm writers.
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
virtual void emitEndOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the end of their file...
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
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...
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
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.
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
Instances of this class represent operands of the MCInst class.
Streaming machine code generation interface.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getName() const
getName - Get the symbol name.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_Register
Register operand.
A Module instance is used to store all the information related to an LLVM module.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
static const char * getRegisterName(MCRegister Reg)
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
void emitTargetAttributes(const MCSubtargetInfo &STI)
virtual void emitDirectiveVariantCC(MCSymbol &Symbol)
void setTargetABI(RISCVABI::ABI ABI)
virtual void finishAttributeSection()
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
Primary interface to the complete machine description for the target machine.
This class implements an extremely fast bulk output stream that can only output to a stream.
ABI getTargetABI(StringRef ABIName)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheRISCV32Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool lowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &MCOp, const AsmPrinter &AP)
bool lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
Target & getTheRISCV64Target()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...