LLVM  10.0.0svn
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 
14 #include "RISCV.h"
17 #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  const char *ExtraCode, raw_ostream &OS) override;
47  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
48  const char *ExtraCode, raw_ostream &OS) override;
49 
50  void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
51  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
52  const MachineInstr *MI);
53 
54  // Wrapper needed for tblgenned pseudo lowering.
55  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
56  return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this);
57  }
58 };
59 }
60 
61 #define GEN_COMPRESS_INSTR
62 #include "RISCVGenCompressInstEmitter.inc"
63 void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
64  MCInst CInst;
65  bool Res = compressInst(CInst, Inst, *TM.getMCSubtargetInfo(),
66  OutStreamer->getContext());
67  AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
68 }
69 
70 // Simple pseudo-instructions have their lowering (with expansion to real
71 // instructions) auto-generated.
72 #include "RISCVGenMCPseudoLowering.inc"
73 
74 void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {
75  // Do any auto-generated pseudo lowerings.
76  if (emitPseudoExpansionLowering(*OutStreamer, MI))
77  return;
78 
79  MCInst TmpInst;
80  LowerRISCVMachineInstrToMCInst(MI, TmpInst, *this);
81  EmitToStreamer(*OutStreamer, TmpInst);
82 }
83 
84 bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
85  const char *ExtraCode, raw_ostream &OS) {
86  // First try the generic code, which knows about modifiers like 'c' and 'n'.
87  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
88  return false;
89 
90  const MachineOperand &MO = MI->getOperand(OpNo);
91  if (ExtraCode && ExtraCode[0]) {
92  if (ExtraCode[1] != 0)
93  return true; // Unknown modifier.
94 
95  switch (ExtraCode[0]) {
96  default:
97  return true; // Unknown modifier.
98  case 'z': // Print zero register if zero, regular printing otherwise.
99  if (MO.isImm() && MO.getImm() == 0) {
100  OS << RISCVInstPrinter::getRegisterName(RISCV::X0);
101  return false;
102  }
103  break;
104  case 'i': // Literal 'i' if operand is not a register.
105  if (!MO.isReg())
106  OS << 'i';
107  return false;
108  }
109  }
110 
111  switch (MO.getType()) {
113  OS << MO.getImm();
114  return false;
117  return false;
118  default:
119  break;
120  }
121 
122  return true;
123 }
124 
125 bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
126  unsigned OpNo,
127  const char *ExtraCode,
128  raw_ostream &OS) {
129  if (!ExtraCode) {
130  const MachineOperand &MO = MI->getOperand(OpNo);
131  // For now, we only support register memory operands in registers and
132  // assume there is no addend
133  if (!MO.isReg())
134  return true;
135 
136  OS << "0(" << RISCVInstPrinter::getRegisterName(MO.getReg()) << ")";
137  return false;
138  }
139 
140  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
141 }
142 
143 // Force static initialization.
144 extern "C" void LLVMInitializeRISCVAsmPrinter() {
147 }
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static const char * getRegisterName(unsigned RegNo)
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)
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:158
Streaming machine code generation interface.
Definition: MCStreamer.h:196
Target & getTheRISCV64Target()
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:78
MachineOperand class - Representation of each machine instruction operand.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:235
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...
int64_t getImm() const
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...
Representation of each machine instruction.
Definition: MachineInstr.h:63
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:45
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.