LLVM  9.0.0svn
RISCVMCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- RISCVMCCodeEmitter.cpp - Convert RISCV code to machine code -------===//
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 implements the RISCVMCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12 
16 #include "Utils/RISCVBaseInfo.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/Support/Casting.h"
30 
31 using namespace llvm;
32 
33 #define DEBUG_TYPE "mccodeemitter"
34 
35 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
36 STATISTIC(MCNumFixups, "Number of MC fixups created");
37 
38 namespace {
39 class RISCVMCCodeEmitter : public MCCodeEmitter {
40  RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete;
41  void operator=(const RISCVMCCodeEmitter &) = delete;
42  MCContext &Ctx;
43  MCInstrInfo const &MCII;
44 
45 public:
46  RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
47  : Ctx(ctx), MCII(MCII) {}
48 
49  ~RISCVMCCodeEmitter() override {}
50 
51  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
53  const MCSubtargetInfo &STI) const override;
54 
55  void expandFunctionCall(const MCInst &MI, raw_ostream &OS,
57  const MCSubtargetInfo &STI) const;
58 
59  /// TableGen'erated function for getting the binary encoding for an
60  /// instruction.
61  uint64_t getBinaryCodeForInstr(const MCInst &MI,
63  const MCSubtargetInfo &STI) const;
64 
65  /// Return binary encoding of operand. If the machine operand requires
66  /// relocation, record the relocation and return zero.
67  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
69  const MCSubtargetInfo &STI) const;
70 
71  unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
73  const MCSubtargetInfo &STI) const;
74 
75  unsigned getImmOpValue(const MCInst &MI, unsigned OpNo,
77  const MCSubtargetInfo &STI) const;
78 };
79 } // end anonymous namespace
80 
82  const MCRegisterInfo &MRI,
83  MCContext &Ctx) {
84  return new RISCVMCCodeEmitter(Ctx, MCII);
85 }
86 
87 // Expand PseudoCALL and PseudoTAIL to AUIPC and JALR with relocation types.
88 // We expand PseudoCALL and PseudoTAIL while encoding, meaning AUIPC and JALR
89 // won't go through RISCV MC to MC compressed instruction transformation. This
90 // is acceptable because AUIPC has no 16-bit form and C_JALR have no immediate
91 // operand field. We let linker relaxation deal with it. When linker
92 // relaxation enabled, AUIPC and JALR have chance relax to JAL. If C extension
93 // is enabled, JAL has chance relax to C_JAL.
94 void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS,
96  const MCSubtargetInfo &STI) const {
97  MCInst TmpInst;
98  MCOperand Func = MI.getOperand(0);
99  unsigned Ra = (MI.getOpcode() == RISCV::PseudoTAIL) ? RISCV::X6 : RISCV::X1;
100  uint32_t Binary;
101 
102  assert(Func.isExpr() && "Expected expression");
103 
104  const MCExpr *Expr = Func.getExpr();
105 
106  // Create function call expression CallExpr for AUIPC.
107  const MCExpr *CallExpr =
109 
110  // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
111  TmpInst = MCInstBuilder(RISCV::AUIPC)
112  .addReg(Ra)
113  .addOperand(MCOperand::createExpr(CallExpr));
114  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
116 
117  if (MI.getOpcode() == RISCV::PseudoTAIL)
118  // Emit JALR X0, X6, 0
119  TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
120  else
121  // Emit JALR X1, X1, 0
122  TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
123  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
125 }
126 
127 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
128  SmallVectorImpl<MCFixup> &Fixups,
129  const MCSubtargetInfo &STI) const {
130  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
131  // Get byte count of instruction.
132  unsigned Size = Desc.getSize();
133 
134  if (MI.getOpcode() == RISCV::PseudoCALL ||
135  MI.getOpcode() == RISCV::PseudoTAIL) {
136  expandFunctionCall(MI, OS, Fixups, STI);
137  MCNumEmitted += 2;
138  return;
139  }
140 
141  switch (Size) {
142  default:
143  llvm_unreachable("Unhandled encodeInstruction length!");
144  case 2: {
145  uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
146  support::endian::write<uint16_t>(OS, Bits, support::little);
147  break;
148  }
149  case 4: {
150  uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
152  break;
153  }
154  }
155 
156  ++MCNumEmitted; // Keep track of the # of mi's emitted.
157 }
158 
159 unsigned
160 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
161  SmallVectorImpl<MCFixup> &Fixups,
162  const MCSubtargetInfo &STI) const {
163 
164  if (MO.isReg())
165  return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
166 
167  if (MO.isImm())
168  return static_cast<unsigned>(MO.getImm());
169 
170  llvm_unreachable("Unhandled expression!");
171  return 0;
172 }
173 
174 unsigned
175 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
176  SmallVectorImpl<MCFixup> &Fixups,
177  const MCSubtargetInfo &STI) const {
178  const MCOperand &MO = MI.getOperand(OpNo);
179 
180  if (MO.isImm()) {
181  unsigned Res = MO.getImm();
182  assert((Res & 1) == 0 && "LSB is non-zero");
183  return Res >> 1;
184  }
185 
186  return getImmOpValue(MI, OpNo, Fixups, STI);
187 }
188 
189 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
190  SmallVectorImpl<MCFixup> &Fixups,
191  const MCSubtargetInfo &STI) const {
192  bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax];
193  const MCOperand &MO = MI.getOperand(OpNo);
194 
195  MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
196  unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask;
197 
198  // If the destination is an immediate, there is nothing to do.
199  if (MO.isImm())
200  return MO.getImm();
201 
202  assert(MO.isExpr() &&
203  "getImmOpValue expects only expressions or immediates");
204  const MCExpr *Expr = MO.getExpr();
205  MCExpr::ExprKind Kind = Expr->getKind();
207  bool RelaxCandidate = false;
208  if (Kind == MCExpr::Target) {
209  const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
210 
211  switch (RVExpr->getKind()) {
214  llvm_unreachable("Unhandled fixup kind!");
216  if (MIFrm == RISCVII::InstFormatI)
217  FixupKind = RISCV::fixup_riscv_lo12_i;
218  else if (MIFrm == RISCVII::InstFormatS)
219  FixupKind = RISCV::fixup_riscv_lo12_s;
220  else
221  llvm_unreachable("VK_RISCV_LO used with unexpected instruction format");
222  RelaxCandidate = true;
223  break;
225  FixupKind = RISCV::fixup_riscv_hi20;
226  RelaxCandidate = true;
227  break;
229  if (MIFrm == RISCVII::InstFormatI)
231  else if (MIFrm == RISCVII::InstFormatS)
233  else
235  "VK_RISCV_PCREL_LO used with unexpected instruction format");
236  RelaxCandidate = true;
237  break;
239  FixupKind = RISCV::fixup_riscv_pcrel_hi20;
240  RelaxCandidate = true;
241  break;
243  FixupKind = RISCV::fixup_riscv_got_hi20;
244  break;
246  FixupKind = RISCV::fixup_riscv_call;
247  RelaxCandidate = true;
248  break;
249  }
250  } else if (Kind == MCExpr::SymbolRef &&
251  cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) {
252  if (Desc.getOpcode() == RISCV::JAL) {
253  FixupKind = RISCV::fixup_riscv_jal;
254  } else if (MIFrm == RISCVII::InstFormatB) {
255  FixupKind = RISCV::fixup_riscv_branch;
256  } else if (MIFrm == RISCVII::InstFormatCJ) {
257  FixupKind = RISCV::fixup_riscv_rvc_jump;
258  } else if (MIFrm == RISCVII::InstFormatCB) {
259  FixupKind = RISCV::fixup_riscv_rvc_branch;
260  }
261  }
262 
263  assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
264 
265  Fixups.push_back(
266  MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
267  ++MCNumFixups;
268 
269  // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is
270  // enabled and the current fixup will result in a relocation that may be
271  // relaxed.
272  if (EnableRelax && RelaxCandidate) {
274  Fixups.push_back(
276  MI.getLoc()));
277  ++MCNumFixups;
278  }
279 
280  return 0;
281 }
282 
283 #include "RISCVGenMCCodeEmitter.inc"
bool isImm() const
Definition: MCInst.h:58
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:136
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
bool isReg() const
Definition: MCInst.h:57
VariantKind getKind() const
Definition: RISCVMCExpr.h:52
STATISTIC(NumFunctions, "Total number of functions")
static Lanai::Fixups FixupKind(const MCExpr *Expr)
const FeatureBitset & getFeatureBits() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
MCCodeEmitter * createRISCVMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
Context object for machine code objects.
Definition: MCContext.h:62
const MCExpr * getExpr() const
Definition: MCInst.h:95
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
Definition: MCInstBuilder.h:61
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:99
int64_t getImm() const
Definition: MCInst.h:75
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:31
unsigned const MachineRegisterInfo * MRI
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
bool isExpr() const
Definition: MCInst.h:60
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:89
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
SMLoc getLoc() const
Definition: MCInst.h:177
Generic base class for all target subtargets.
References to labels and assigned expressions.
Definition: MCExpr.h:40
uint32_t Size
Definition: Profile.cpp:46
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:203
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
Target specific expression.
Definition: MCExpr.h:42
unsigned getOpcode() const
Definition: MCInst.h:171
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:163
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Definition: RISCVMCExpr.cpp:28
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:580