LLVM 20.0.0git
RISCVMCCodeEmitter.cpp
Go to the documentation of this file.
1//===-- RISCVMCCodeEmitter.cpp - Convert RISC-V 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
17#include "llvm/ADT/Statistic.h"
18#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
24#include "llvm/MC/MCInstrInfo.h"
27#include "llvm/MC/MCSymbol.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE "mccodeemitter"
34
35STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
36STATISTIC(MCNumFixups, "Number of MC fixups created");
37
38namespace {
39class RISCVMCCodeEmitter : public MCCodeEmitter {
40 RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete;
41 void operator=(const RISCVMCCodeEmitter &) = delete;
42 MCContext &Ctx;
43 MCInstrInfo const &MCII;
44
45public:
46 RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
47 : Ctx(ctx), MCII(MCII) {}
48
49 ~RISCVMCCodeEmitter() override = default;
50
53 const MCSubtargetInfo &STI) const override;
54
55 void expandFunctionCall(const MCInst &MI, SmallVectorImpl<char> &CB,
57 const MCSubtargetInfo &STI) const;
58
59 void expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB,
61 const MCSubtargetInfo &STI) const;
62
63 void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB,
65 const MCSubtargetInfo &STI) const;
66
67 void expandLongCondBr(const MCInst &MI, SmallVectorImpl<char> &CB,
69 const MCSubtargetInfo &STI) const;
70
71 /// TableGen'erated function for getting the binary encoding for an
72 /// instruction.
73 uint64_t getBinaryCodeForInstr(const MCInst &MI,
75 const MCSubtargetInfo &STI) const;
76
77 /// Return binary encoding of operand. If the machine operand requires
78 /// relocation, record the relocation and return zero.
79 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
81 const MCSubtargetInfo &STI) const;
82
83 unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
85 const MCSubtargetInfo &STI) const;
86
87 unsigned getImmOpValue(const MCInst &MI, unsigned OpNo,
89 const MCSubtargetInfo &STI) const;
90
91 unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
93 const MCSubtargetInfo &STI) const;
94
95 unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo,
97 const MCSubtargetInfo &STI) const;
98
99 unsigned getRegReg(const MCInst &MI, unsigned OpNo,
101 const MCSubtargetInfo &STI) const;
102};
103} // end anonymous namespace
104
106 MCContext &Ctx) {
107 return new RISCVMCCodeEmitter(Ctx, MCII);
108}
109
110// Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with
111// relocation types. We expand those pseudo-instructions while encoding them,
112// meaning AUIPC and JALR won't go through RISC-V MC to MC compressed
113// instruction transformation. This is acceptable because AUIPC has no 16-bit
114// form and C_JALR has no immediate operand field. We let linker relaxation
115// deal with it. When linker relaxation is enabled, AUIPC and JALR have a
116// chance to relax to JAL.
117// If the C extension is enabled, JAL has a chance relax to C_JAL.
118void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI,
121 const MCSubtargetInfo &STI) const {
122 MCInst TmpInst;
123 MCOperand Func;
124 MCRegister Ra;
125 if (MI.getOpcode() == RISCV::PseudoTAIL) {
126 Func = MI.getOperand(0);
128 } else if (MI.getOpcode() == RISCV::PseudoCALLReg) {
129 Func = MI.getOperand(1);
130 Ra = MI.getOperand(0).getReg();
131 } else if (MI.getOpcode() == RISCV::PseudoCALL) {
132 Func = MI.getOperand(0);
133 Ra = RISCV::X1;
134 } else if (MI.getOpcode() == RISCV::PseudoJump) {
135 Func = MI.getOperand(1);
136 Ra = MI.getOperand(0).getReg();
137 }
139
140 assert(Func.isExpr() && "Expected expression");
141
142 const MCExpr *CallExpr = Func.getExpr();
143
144 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
145 TmpInst = MCInstBuilder(RISCV::AUIPC).addReg(Ra).addExpr(CallExpr);
146 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
148
149 if (MI.getOpcode() == RISCV::PseudoTAIL ||
150 MI.getOpcode() == RISCV::PseudoJump)
151 // Emit JALR X0, Ra, 0
152 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
153 else
154 // Emit JALR Ra, Ra, 0
155 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
156 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
158}
159
160void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI,
163 const MCSubtargetInfo &STI) const {
164 MCOperand SrcSymbol = MI.getOperand(3);
165 assert(SrcSymbol.isExpr() &&
166 "Expected expression as first input to TLSDESCCALL");
167 const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
168 MCRegister Link = MI.getOperand(0).getReg();
169 MCRegister Dest = MI.getOperand(1).getReg();
170 int64_t Imm = MI.getOperand(2).getImm();
171 Fixups.push_back(MCFixup::create(
172 0, Expr, MCFixupKind(RISCV::fixup_riscv_tlsdesc_call), MI.getLoc()));
173 MCInst Call =
174 MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm);
175
176 uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI);
178}
179
180// Expand PseudoAddTPRel to a simple ADD with the correct relocation.
181void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI,
184 const MCSubtargetInfo &STI) const {
185 MCOperand DestReg = MI.getOperand(0);
186 MCOperand SrcReg = MI.getOperand(1);
187 MCOperand TPReg = MI.getOperand(2);
188 assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 &&
189 "Expected thread pointer as second input to TP-relative add");
190
191 MCOperand SrcSymbol = MI.getOperand(3);
192 assert(SrcSymbol.isExpr() &&
193 "Expected expression as third input to TP-relative add");
194
195 const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
197 "Expected tprel_add relocation on TP-relative symbol");
198
199 // Emit the correct tprel_add relocation for the symbol.
200 Fixups.push_back(MCFixup::create(
201 0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc()));
202
203 // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled.
204 if (STI.hasFeature(RISCV::FeatureRelax)) {
206 Fixups.push_back(MCFixup::create(
207 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc()));
208 }
209
210 // Emit a normal ADD instruction with the given operands.
211 MCInst TmpInst = MCInstBuilder(RISCV::ADD)
212 .addOperand(DestReg)
213 .addOperand(SrcReg)
214 .addOperand(TPReg);
215 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
217}
218
219static unsigned getInvertedBranchOp(unsigned BrOp) {
220 switch (BrOp) {
221 default:
222 llvm_unreachable("Unexpected branch opcode!");
223 case RISCV::PseudoLongBEQ:
224 return RISCV::BNE;
225 case RISCV::PseudoLongBNE:
226 return RISCV::BEQ;
227 case RISCV::PseudoLongBLT:
228 return RISCV::BGE;
229 case RISCV::PseudoLongBGE:
230 return RISCV::BLT;
231 case RISCV::PseudoLongBLTU:
232 return RISCV::BGEU;
233 case RISCV::PseudoLongBGEU:
234 return RISCV::BLTU;
235 }
236}
237
238// Expand PseudoLongBxx to an inverted conditional branch and an unconditional
239// jump.
240void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
243 const MCSubtargetInfo &STI) const {
244 MCRegister SrcReg1 = MI.getOperand(0).getReg();
245 MCRegister SrcReg2 = MI.getOperand(1).getReg();
246 MCOperand SrcSymbol = MI.getOperand(2);
247 unsigned Opcode = MI.getOpcode();
248 bool IsEqTest =
249 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
250
251 bool UseCompressedBr = false;
252 if (IsEqTest && (STI.hasFeature(RISCV::FeatureStdExtC) ||
253 STI.hasFeature(RISCV::FeatureStdExtZca))) {
254 if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 &&
255 SrcReg2.id() == RISCV::X0) {
256 UseCompressedBr = true;
257 } else if (RISCV::X8 <= SrcReg2.id() && SrcReg2.id() <= RISCV::X15 &&
258 SrcReg1.id() == RISCV::X0) {
259 std::swap(SrcReg1, SrcReg2);
260 UseCompressedBr = true;
261 }
262 }
263
265 if (UseCompressedBr) {
266 unsigned InvOpc =
267 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
268 MCInst TmpInst = MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(6);
269 uint16_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
270 support::endian::write<uint16_t>(CB, Binary, llvm::endianness::little);
271 Offset = 2;
272 } else {
273 unsigned InvOpc = getInvertedBranchOp(Opcode);
274 MCInst TmpInst =
275 MCInstBuilder(InvOpc).addReg(SrcReg1).addReg(SrcReg2).addImm(8);
276 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
278 Offset = 4;
279 }
280
281 // Save the number fixups.
282 size_t FixupStartIndex = Fixups.size();
283
284 // Emit an unconditional jump to the destination.
285 MCInst TmpInst =
286 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
287 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
289
290 // Drop any fixup added so we can add the correct one.
291 Fixups.resize(FixupStartIndex);
292
293 if (SrcSymbol.isExpr()) {
294 Fixups.push_back(MCFixup::create(Offset, SrcSymbol.getExpr(),
296 MI.getLoc()));
297 }
298}
299
300void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
303 const MCSubtargetInfo &STI) const {
304 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
305 // Get byte count of instruction.
306 unsigned Size = Desc.getSize();
307
308 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
309 // expanded instructions for each pseudo is correct in the Size field of the
310 // tablegen definition for the pseudo.
311 switch (MI.getOpcode()) {
312 default:
313 break;
314 case RISCV::PseudoCALLReg:
315 case RISCV::PseudoCALL:
316 case RISCV::PseudoTAIL:
317 case RISCV::PseudoJump:
318 expandFunctionCall(MI, CB, Fixups, STI);
319 MCNumEmitted += 2;
320 return;
321 case RISCV::PseudoAddTPRel:
322 expandAddTPRel(MI, CB, Fixups, STI);
323 MCNumEmitted += 1;
324 return;
325 case RISCV::PseudoLongBEQ:
326 case RISCV::PseudoLongBNE:
327 case RISCV::PseudoLongBLT:
328 case RISCV::PseudoLongBGE:
329 case RISCV::PseudoLongBLTU:
330 case RISCV::PseudoLongBGEU:
331 expandLongCondBr(MI, CB, Fixups, STI);
332 MCNumEmitted += 2;
333 return;
334 case RISCV::PseudoTLSDESCCall:
335 expandTLSDESCCall(MI, CB, Fixups, STI);
336 MCNumEmitted += 1;
337 return;
338 }
339
340 switch (Size) {
341 default:
342 llvm_unreachable("Unhandled encodeInstruction length!");
343 case 2: {
344 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
345 support::endian::write<uint16_t>(CB, Bits, llvm::endianness::little);
346 break;
347 }
348 case 4: {
349 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
351 break;
352 }
353 case 6: {
354 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI) & 0xffff'ffff'ffffu;
355 SmallVector<char, 8> Encoding;
357 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
358 "Unexpected encoding for 48-bit instruction");
359 Encoding.truncate(6);
360 CB.append(Encoding);
361 break;
362 }
363 case 8: {
364 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
366 break;
367 }
368 }
369
370 ++MCNumEmitted; // Keep track of the # of mi's emitted.
371}
372
374RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
376 const MCSubtargetInfo &STI) const {
377
378 if (MO.isReg())
379 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
380
381 if (MO.isImm())
382 return MO.getImm();
383
384 llvm_unreachable("Unhandled expression!");
385 return 0;
386}
387
388unsigned
389RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
391 const MCSubtargetInfo &STI) const {
392 const MCOperand &MO = MI.getOperand(OpNo);
393
394 if (MO.isImm()) {
395 unsigned Res = MO.getImm();
396 assert((Res & 1) == 0 && "LSB is non-zero");
397 return Res >> 1;
398 }
399
400 return getImmOpValue(MI, OpNo, Fixups, STI);
401}
402
403unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
405 const MCSubtargetInfo &STI) const {
406 bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax);
407 const MCOperand &MO = MI.getOperand(OpNo);
408
409 MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
410 unsigned MIFrm = RISCVII::getFormat(Desc.TSFlags);
411
412 // If the destination is an immediate, there is nothing to do.
413 if (MO.isImm())
414 return MO.getImm();
415
416 assert(MO.isExpr() &&
417 "getImmOpValue expects only expressions or immediates");
418 const MCExpr *Expr = MO.getExpr();
419 MCExpr::ExprKind Kind = Expr->getKind();
421 bool RelaxCandidate = false;
422 if (Kind == MCExpr::Target) {
423 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
424
425 switch (RVExpr->getKind()) {
429 llvm_unreachable("Unhandled fixup kind!");
431 // tprel_add is only used to indicate that a relocation should be emitted
432 // for an add instruction used in TP-relative addressing. It should not be
433 // expanded as if representing an actual instruction operand and so to
434 // encounter it here is an error.
436 "VK_RISCV_TPREL_ADD should not represent an instruction operand");
438 if (MIFrm == RISCVII::InstFormatI)
440 else if (MIFrm == RISCVII::InstFormatS)
442 else
443 llvm_unreachable("VK_RISCV_LO used with unexpected instruction format");
444 RelaxCandidate = true;
445 break;
448 RelaxCandidate = true;
449 break;
451 if (MIFrm == RISCVII::InstFormatI)
453 else if (MIFrm == RISCVII::InstFormatS)
455 else
457 "VK_RISCV_PCREL_LO used with unexpected instruction format");
458 RelaxCandidate = true;
459 break;
462 RelaxCandidate = true;
463 break;
466 break;
468 if (MIFrm == RISCVII::InstFormatI)
470 else if (MIFrm == RISCVII::InstFormatS)
472 else
474 "VK_RISCV_TPREL_LO used with unexpected instruction format");
475 RelaxCandidate = true;
476 break;
479 RelaxCandidate = true;
480 break;
483 break;
486 break;
489 RelaxCandidate = true;
490 break;
493 RelaxCandidate = true;
494 break;
497 break;
500 break;
503 break;
506 break;
507 }
508 } else if ((Kind == MCExpr::SymbolRef &&
509 cast<MCSymbolRefExpr>(Expr)->getKind() ==
511 Kind == MCExpr::Binary) {
512 // FIXME: Sub kind binary exprs have chance of underflow.
513 if (MIFrm == RISCVII::InstFormatJ) {
515 } else if (MIFrm == RISCVII::InstFormatB) {
517 } else if (MIFrm == RISCVII::InstFormatCJ) {
519 } else if (MIFrm == RISCVII::InstFormatCB) {
521 } else if (MIFrm == RISCVII::InstFormatI) {
523 }
524 }
525
526 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
527
528 Fixups.push_back(
529 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
530 ++MCNumFixups;
531
532 // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is
533 // enabled and the current fixup will result in a relocation that may be
534 // relaxed.
535 if (EnableRelax && RelaxCandidate) {
537 Fixups.push_back(
539 MI.getLoc()));
540 ++MCNumFixups;
541 }
542
543 return 0;
544}
545
546unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
548 const MCSubtargetInfo &STI) const {
549 MCOperand MO = MI.getOperand(OpNo);
550 assert(MO.isReg() && "Expected a register.");
551
552 switch (MO.getReg()) {
553 default:
554 llvm_unreachable("Invalid mask register.");
555 case RISCV::V0:
556 return 0;
557 case RISCV::NoRegister:
558 return 1;
559 }
560}
561
562unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
564 const MCSubtargetInfo &STI) const {
565 const MCOperand &MO = MI.getOperand(OpNo);
566 assert(MO.isImm() && "Rlist operand must be immediate");
567 auto Imm = MO.getImm();
568 assert(Imm >= 4 && "EABI is currently not implemented");
569 return Imm;
570}
571
572unsigned RISCVMCCodeEmitter::getRegReg(const MCInst &MI, unsigned OpNo,
574 const MCSubtargetInfo &STI) const {
575 const MCOperand &MO = MI.getOperand(OpNo);
576 const MCOperand &MO1 = MI.getOperand(OpNo + 1);
577 assert(MO.isReg() && MO1.isReg() && "Expected registers.");
578
579 unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
580 unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
581
582 return Op | Op1 << 5;
583}
584
585#include "RISCVGenMCCodeEmitter.inc"
uint64_t Size
IRTranslator LLVM IR MI
static unsigned getInvertedBranchOp(unsigned BrOp)
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)
Definition: Statistic.h:166
This class represents an Operation in the Expression.
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
Context object for machine code objects.
Definition: MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:39
@ Target
Target specific expression.
Definition: MCExpr.h:41
@ Binary
Binary expressions.
Definition: MCExpr.h:37
ExprKind getKind() const
Definition: MCExpr.h:78
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
Definition: MCInstBuilder.h:73
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:61
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
int64_t getImm() const
Definition: MCInst.h:81
bool isImm() const
Definition: MCInst.h:63
bool isReg() const
Definition: MCInst.h:62
MCRegister getReg() const
Returns the register number.
Definition: MCInst.h:70
const MCExpr * getExpr() const
Definition: MCInst.h:115
bool isExpr() const
Definition: MCInst.h:66
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
constexpr unsigned id() const
Definition: MCRegister.h:79
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
VariantKind getKind() const
Definition: RISCVMCExpr.h:60
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
void truncate(size_type N)
Like resize, but requires that N is less than size().
Definition: SmallVector.h:644
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getFormat(uint64_t TSFlags)
static unsigned getTailExpandUseRegNo(const FeatureBitset &FeatureBits)
@ fixup_riscv_tprel_lo12_s
@ fixup_riscv_tls_got_hi20
@ fixup_riscv_pcrel_lo12_i
@ fixup_riscv_tlsdesc_call
@ fixup_riscv_pcrel_lo12_s
@ fixup_riscv_tprel_lo12_i
@ fixup_riscv_tlsdesc_load_lo12
@ fixup_riscv_tlsdesc_hi20
@ fixup_riscv_tlsdesc_add_lo12
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:92
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MCCodeEmitter * createRISCVMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
Description of the encoding of one expression Op.