Go to the documentation of this file.
34 #define ELF_RELOC(X, Y) .Case(#X, Y)
35 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
37 .
Case(
"BFD_RELOC_NONE", ELF::R_RISCV_NONE)
54 {
"fixup_riscv_hi20", 12, 20, 0},
55 {
"fixup_riscv_lo12_i", 20, 12, 0},
56 {
"fixup_riscv_lo12_s", 0, 32, 0},
57 {
"fixup_riscv_pcrel_hi20", 12, 20,
59 {
"fixup_riscv_pcrel_lo12_i", 20, 12,
61 {
"fixup_riscv_pcrel_lo12_s", 0, 32,
64 {
"fixup_riscv_tprel_hi20", 12, 20, 0},
65 {
"fixup_riscv_tprel_lo12_i", 20, 12, 0},
66 {
"fixup_riscv_tprel_lo12_s", 0, 32, 0},
67 {
"fixup_riscv_tprel_add", 0, 0, 0},
76 {
"fixup_riscv_relax", 0, 0, 0},
77 {
"fixup_riscv_align", 0, 0, 0},
79 {
"fixup_riscv_set_8", 0, 8, 0},
80 {
"fixup_riscv_add_8", 0, 8, 0},
81 {
"fixup_riscv_sub_8", 0, 8, 0},
83 {
"fixup_riscv_set_16", 0, 16, 0},
84 {
"fixup_riscv_add_16", 0, 16, 0},
85 {
"fixup_riscv_sub_16", 0, 16, 0},
87 {
"fixup_riscv_set_32", 0, 32, 0},
88 {
"fixup_riscv_add_32", 0, 32, 0},
89 {
"fixup_riscv_sub_32", 0, 32, 0},
91 {
"fixup_riscv_add_64", 0, 64, 0},
92 {
"fixup_riscv_sub_64", 0, 64, 0},
94 {
"fixup_riscv_set_6b", 2, 6, 0},
95 {
"fixup_riscv_sub_6b", 2, 6, 0},
98 "Not all fixup kinds added to Infos array");
121 switch (
Fixup.getTargetKind()) {
145 const bool WasForced)
const {
150 if (!Resolved && !WasForced)
153 int64_t Offset = int64_t(
Value);
154 switch (
Fixup.getTargetKind()) {
160 return Offset > 254 || Offset < -256;
164 return Offset > 2046 || Offset < -2048;
207 bool &WasRelaxed)
const {
210 int64_t LineDelta =
DF.getLineDelta();
211 const MCExpr &AddrDelta =
DF.getAddrDelta();
214 size_t OldSize =
Data.size();
218 assert(IsAbsolute &&
"CFA with invalid expression");
227 OS << uint8_t(dwarf::DW_LNS_advance_line);
232 std::pair<unsigned, unsigned>
Fixup;
238 unsigned PtrSize =
C.getAsmInfo()->getCodePointerSize();
240 OS << uint8_t(dwarf::DW_LNS_extended_op);
243 OS << uint8_t(dwarf::DW_LNE_set_address);
251 OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);
257 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
264 OS << uint8_t(dwarf::DW_LNS_extended_op);
266 OS << uint8_t(dwarf::DW_LNE_end_sequence);
268 OS << uint8_t(dwarf::DW_LNS_copy);
271 WasRelaxed = OldSize !=
Data.size();
277 bool &WasRelaxed)
const {
279 const MCExpr &AddrDelta =
DF.getAddrDelta();
282 size_t OldSize =
Data.size();
286 assert(IsAbsolute &&
"CFA with invalid expression");
296 "expected 1-byte alignment");
298 WasRelaxed = OldSize !=
Data.size();
302 auto AddFixups = [&
Fixups, &AddrDelta](
unsigned Offset,
303 std::pair<unsigned, unsigned>
Fixup) {
304 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
312 OS << uint8_t(dwarf::DW_CFA_advance_loc);
315 OS << uint8_t(dwarf::DW_CFA_advance_loc1);
319 OS << uint8_t(dwarf::DW_CFA_advance_loc2);
323 OS << uint8_t(dwarf::DW_CFA_advance_loc4);
330 WasRelaxed = OldSize !=
Data.size();
358 unsigned MinNopLen = HasStdExtC ? 2 : 4;
360 if ((Count % MinNopLen) != 0)
364 for (; Count >= 4; Count -= 4)
365 OS.
write(
"\x13\0\0\0", 4);
368 if (Count && HasStdExtC)
369 OS.
write(
"\x01\0", 2);
376 switch (
Fixup.getTargetKind()) {
405 return Value & 0xfff;
409 return (((
Value >> 5) & 0x7f) << 25) | ((
Value & 0x1f) << 7);
414 return ((
Value + 0x800) >> 12) & 0xfffff;
416 if (!isInt<21>(
Value))
421 unsigned Sbit = (
Value >> 20) & 0x1;
422 unsigned Hi8 = (
Value >> 12) & 0xff;
423 unsigned Mid1 = (
Value >> 11) & 0x1;
424 unsigned Lo10 = (
Value >> 1) & 0x3ff;
429 Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
433 if (!isInt<13>(
Value))
439 unsigned Sbit = (
Value >> 12) & 0x1;
440 unsigned Hi1 = (
Value >> 11) & 0x1;
441 unsigned Mid6 = (
Value >> 5) & 0x3f;
442 unsigned Lo4 = (
Value >> 1) & 0xf;
447 Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);
457 return UpperImm | ((LowerImm << 20) << 32);
461 unsigned Bit11 = (
Value >> 11) & 0x1;
462 unsigned Bit4 = (
Value >> 4) & 0x1;
463 unsigned Bit9_8 = (
Value >> 8) & 0
x3;
464 unsigned Bit10 = (
Value >> 10) & 0x1;
465 unsigned Bit6 = (
Value >> 6) & 0x1;
466 unsigned Bit7 = (
Value >> 7) & 0x1;
467 unsigned Bit3_1 = (
Value >> 1) & 0x7;
468 unsigned Bit5 = (
Value >> 5) & 0x1;
469 Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) |
470 (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5;
475 unsigned Bit8 = (
Value >> 8) & 0x1;
476 unsigned Bit7_6 = (
Value >> 6) & 0
x3;
477 unsigned Bit5 = (
Value >> 5) & 0x1;
478 unsigned Bit4_3 = (
Value >> 3) & 0
x3;
479 unsigned Bit2_1 = (
Value >> 1) & 0
x3;
480 Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) |
495 switch (
Fixup.getTargetKind()) {
505 AUIPCFixup = cast<RISCVMCExpr>(
Fixup.getValue())->getPCRelHiFixup(&AUIPCDF);
507 Asm.getContext().reportError(
Fixup.getLoc(),
508 "could not find corresponding %pcrel_hi");
525 const MCSymbol &SA = A->getSymbol();
529 auto *Writer =
Asm.getWriterPtr();
533 bool IsResolved = Writer->isSymbolRefDifferenceFullyResolvedImpl(
534 Asm, SA, *AUIPCDF,
false,
true);
567 unsigned Offset =
Fixup.getOffset();
568 unsigned NumBytes =
alignTo(
Info.TargetSize +
Info.TargetOffset, 8) / 8;
570 assert(Offset + NumBytes <=
Data.size() &&
"Invalid fixup offset!");
574 for (
unsigned i = 0;
i != NumBytes; ++
i) {
575 Data[Offset +
i] |= uint8_t((
Value >> (
i * 8)) & 0xff);
591 unsigned MinNopLen = HasStdExtC ? 2 : 4;
629 Asm.getWriter().recordRelocation(
Asm, Layout, &AF,
Fixup, NopBytes,
635 std::unique_ptr<MCObjectTargetWriter>
StringSwitch & Case(StringLiteral S, T Value)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
@ fixup_riscv_pcrel_lo12_i
uint64_t tell() const
tell - Return the current offset with the file.
This is an optimization pass for GlobalISel generic memory operations.
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
Context object for machine code objects.
LLVM_NODISCARD R Default(T Value)
unsigned getMinInstAlignment() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Target - Wrapper for Target specific information.
@ fixup_riscv_tls_gd_hi20
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Triple - Helper class for working with autoconf configuration names.
Optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
unsigned getRelaxedOpcode(unsigned Op) const
bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout, const bool WasForced) const override
Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...
The instances of the Type class are immutable: once they are created, they are never changed.
@ R_RISCV_64
A plain 64-bit pointer value relocation.
Instances of this class represent a single low-level machine instruction.
Binary assembler expressions.
bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, unsigned &Size) override
Hook to check if extra nop bytes must be inserted for alignment directive.
@ fixup_riscv_pcrel_lo12_s
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
void setOpcode(unsigned Op)
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
std::unique_ptr< MCObjectTargetWriter > createObjectTargetWriter() const override
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
const MCExpr * getValue() const
@ FK_Data_4
A four-byte fixup.
MCAsmBackend * createRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Generic interface to target specific assembler backends.
@ FK_Data_6b
A six-bits fixup.
Represents a location in source code.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
@ fixup_riscv_tls_got_hi20
MCContext & getContext() const
(vector float) vec_cmpeq(*A, *B) C
const Triple & getTargetTriple() const
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
const FeatureBitset & getFeatureBits() const
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
@ R_RISCV_32
A plain 32-bit pointer value relocation.
raw_ostream & write(unsigned char C)
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
int64_t getConstant() const
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
Analysis containing CSE Info
const MCSymbolRefExpr * getSymA() const
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, MCAsmLayout &Layout, bool &WasRelaxed) const override
void addOperand(const MCOperand Op)
bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override
Check whether the given instruction may need relaxation.
constexpr bool isUInt< 16 >(uint64_t x)
bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, MCAsmLayout &Layout, bool &WasRelaxed) const override
const MCAsmInfo * getAsmInfo() const
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
@ fixup_riscv_tprel_lo12_s
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext &Ctx)
constexpr bool isUInt< 32 >(uint64_t x)
std::unique_ptr< MCObjectTargetWriter > createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ fixup_riscv_tprel_lo12_i
constexpr bool isUInt< 8 >(uint64_t x)
Target independent information on a fixup kind.
void reportError(SMLoc L, const Twine &Msg)
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, const MCAsmLayout &Layout, MCAlignFragment &AF) override
Hook which indicates if the target requires a fixup to be generated when handling an align directive ...
@ FK_Data_1
A one-byte fixup.
Represent a reference to a symbol from inside an expression.
@ FKF_IsTarget
Should this fixup be evaluated in a target dependent manner?
PowerPC TLS Dynamic Call Fixup
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static MCOperand createReg(unsigned Reg)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
unsigned const MachineRegisterInfo * MRI
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Encapsulates the layout of an assembly file at a particular point in time.
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
bool evaluateTargetFixup(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, const MCValue &Target, uint64_t &Value, bool &WasForced) override
unsigned getOpcode() const
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
unsigned getAlignment() const
bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const override
Write an (optimal) nop sequence of Count bytes to the given output.
const MCSubtargetInfo * getSubtargetInfo() const
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FK_Data_8
A eight-byte fixup.
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override
Hook to check if a relocation is needed for some target specific reason.
void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override
Relax the instruction in the given fragment to the next wider instruction.
const MCOperand & getOperand(unsigned i) const
A raw_ostream that writes to an SmallVector or SmallString.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
A switch()-like statement whose cases are string literals.
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
This represents an "assembler immediate".
@ FK_Data_2
A two-byte fixup.
Generic base class for all target subtargets.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
LLVM Value Representation.
Base class for the full range of assembler expressions which are needed for parsing.
const MCSymbolRefExpr * getSymB() const
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
uint32_t getOffset() const