LLVM  8.0.1
RISCVAsmPrinter.cpp
Go to the documentation of this file.
1 //===-- RISCVAsmPrinter.cpp - RISCV LLVM assembly writer ------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to the RISCV assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "RISCV.h"
18 #include "RISCVTargetMachine.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCInst.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSymbol.h"
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "asm-printer"
33 
34 namespace {
35 class RISCVAsmPrinter : public AsmPrinter {
36 public:
37  explicit RISCVAsmPrinter(TargetMachine &TM,
38  std::unique_ptr<MCStreamer> Streamer)
39  : AsmPrinter(TM, std::move(Streamer)) {}
40 
41  StringRef getPassName() const override { return "RISCV Assembly Printer"; }
42 
43  void EmitInstruction(const MachineInstr *MI) override;
44 
45  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
46  unsigned AsmVariant, const char *ExtraCode,
47  raw_ostream &OS) override;
48  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
49  unsigned AsmVariant, const char *ExtraCode,
50  raw_ostream &OS) override;
51 
52  void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
53  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
54  const MachineInstr *MI);
55 
56  // Wrapper needed for tblgenned pseudo lowering.
57  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
58  return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this);
59  }
60 };
61 }
62 
63 #define GEN_COMPRESS_INSTR
64 #include "RISCVGenCompressInstEmitter.inc"
65 void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
66  MCInst CInst;
67  bool Res = compressInst(CInst, Inst, *TM.getMCSubtargetInfo(),
68  OutStreamer->getContext());
69  AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
70 }
71 
72 // Simple pseudo-instructions have their lowering (with expansion to real
73 // instructions) auto-generated.
74 #include "RISCVGenMCPseudoLowering.inc"
75 
76 void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {
77  // Do any auto-generated pseudo lowerings.
78  if (emitPseudoExpansionLowering(*OutStreamer, MI))
79  return;
80 
81  MCInst TmpInst;
82  LowerRISCVMachineInstrToMCInst(MI, TmpInst, *this);
83  EmitToStreamer(*OutStreamer, TmpInst);
84 }
85 
86 bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
87  unsigned AsmVariant,
88  const char *ExtraCode, raw_ostream &OS) {
89  if (AsmVariant != 0)
90  report_fatal_error("There are no defined alternate asm variants");
91 
92  // First try the generic code, which knows about modifiers like 'c' and 'n'.
93  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS))
94  return false;
95 
96  if (!ExtraCode) {
97  const MachineOperand &MO = MI->getOperand(OpNo);
98  switch (MO.getType()) {
100  OS << MO.getImm();
101  return false;
104  return false;
105  default:
106  break;
107  }
108  }
109 
110  return true;
111 }
112 
113 bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
114  unsigned OpNo, unsigned AsmVariant,
115  const char *ExtraCode,
116  raw_ostream &OS) {
117  if (AsmVariant != 0)
118  report_fatal_error("There are no defined alternate asm variants");
119 
120  if (!ExtraCode) {
121  const MachineOperand &MO = MI->getOperand(OpNo);
122  // For now, we only support register memory operands in registers and
123  // assume there is no addend
124  if (!MO.isReg())
125  return true;
126 
127  OS << "0(" << RISCVInstPrinter::getRegisterName(MO.getReg()) << ")";
128  return false;
129  }
130 
131  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
132 }
133 
134 // Force static initialization.
135 extern "C" void LLVMInitializeRISCVAsmPrinter() {
138 }
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
unsigned getReg() const
getReg - Returns the register number.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Target & getTheRISCV32Target()
void LLVMInitializeRISCVAsmPrinter()
void LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, const AsmPrinter &AP)
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
Streaming machine code generation interface.
Definition: MCStreamer.h:189
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
Target & getTheRISCV64Target()
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:79
static const char * getRegisterName(unsigned RegNo, unsigned AltIdx=RISCV::ABIRegAltName)
MachineOperand class - Representation of each machine instruction operand.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:231
int64_t getImm() const
Representation of each machine instruction.
Definition: MachineInstr.h:64
bool LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &MCOp, const AsmPrinter &AP)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.