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