38#define ELF_RELOC(X, Y) .Case(#X, Y)
39#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
41 .
Case(
"BFD_RELOC_NONE", ELF::R_RISCV_NONE)
42 .
Case(
"BFD_RELOC_32", ELF::R_RISCV_32)
43 .
Case(
"BFD_RELOC_64", ELF::R_RISCV_64)
58 {
"fixup_riscv_hi20", 12, 20, 0},
59 {
"fixup_riscv_lo12_i", 20, 12, 0},
60 {
"fixup_riscv_12_i", 20, 12, 0},
61 {
"fixup_riscv_lo12_s", 0, 32, 0},
62 {
"fixup_riscv_pcrel_hi20", 12, 20,
64 {
"fixup_riscv_pcrel_lo12_i", 20, 12,
66 {
"fixup_riscv_pcrel_lo12_s", 0, 32,
69 {
"fixup_riscv_tprel_hi20", 12, 20, 0},
70 {
"fixup_riscv_tprel_lo12_i", 20, 12, 0},
71 {
"fixup_riscv_tprel_lo12_s", 0, 32, 0},
72 {
"fixup_riscv_tprel_add", 0, 0, 0},
81 {
"fixup_riscv_relax", 0, 0, 0},
82 {
"fixup_riscv_align", 0, 0, 0},
85 "Not all fixup kinds added to Infos array");
108 switch (
Fixup.getTargetKind()) {
124 return STI.
hasFeature(RISCV::FeatureRelax) || ForceRelocs;
132 const bool WasForced)
const {
137 unsigned Kind =
Fixup.getTargetKind();
143 if (!Resolved && !WasForced)
160 return !isInt<13>(
Offset);
191 Inst = std::move(Res);
196 bool &WasRelaxed)
const {
199 int64_t LineDelta =
DF.getLineDelta();
200 const MCExpr &AddrDelta =
DF.getAddrDelta();
203 size_t OldSize =
Data.size();
207 assert(IsAbsolute &&
"CFA with invalid expression");
216 OS << uint8_t(dwarf::DW_LNS_advance_line);
221 std::pair<MCFixupKind, MCFixupKind>
Fixup;
227 unsigned PtrSize =
C.getAsmInfo()->getCodePointerSize();
229 OS << uint8_t(dwarf::DW_LNS_extended_op);
232 OS << uint8_t(dwarf::DW_LNE_set_address);
234 assert((PtrSize == 4 || PtrSize == 8) &&
"Unexpected pointer size");
238 OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);
244 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
249 OS << uint8_t(dwarf::DW_LNS_extended_op);
251 OS << uint8_t(dwarf::DW_LNE_end_sequence);
253 OS << uint8_t(dwarf::DW_LNS_copy);
256 WasRelaxed = OldSize !=
Data.size();
262 bool &WasRelaxed)
const {
263 const MCExpr &AddrDelta =
DF.getAddrDelta();
266 size_t OldSize =
Data.size();
272 assert(IsAbsolute &&
"CFA with invalid expression");
282 "expected 1-byte alignment");
284 WasRelaxed = OldSize !=
Data.size();
288 auto AddFixups = [&Fixups, &AddrDelta](
unsigned Offset,
289 std::pair<unsigned, unsigned>
Fixup) {
290 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
294 std::get<0>(
Fixup))));
298 std::get<1>(
Fixup))));
302 OS << uint8_t(dwarf::DW_CFA_advance_loc);
303 AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
304 }
else if (isUInt<8>(
Value)) {
305 OS << uint8_t(dwarf::DW_CFA_advance_loc1);
307 AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
308 }
else if (isUInt<16>(
Value)) {
309 OS << uint8_t(dwarf::DW_CFA_advance_loc2);
311 AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
312 }
else if (isUInt<32>(
Value)) {
313 OS << uint8_t(dwarf::DW_CFA_advance_loc4);
315 AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
320 WasRelaxed = OldSize !=
Data.size();
338 return RISCV::PseudoLongBEQ;
340 return RISCV::PseudoLongBNE;
342 return RISCV::PseudoLongBLT;
344 return RISCV::PseudoLongBGE;
346 return RISCV::PseudoLongBLTU;
348 return RISCV::PseudoLongBGEU;
370 bool UseCompressedNop = STI->
hasFeature(RISCV::FeatureStdExtC) ||
373 if (Count % 4 == 2) {
374 OS.
write(UseCompressedNop ?
"\x01\0" :
"\0\0", 2);
379 for (; Count >= 4; Count -= 4)
387 switch (
Fixup.getTargetKind()) {
402 return Value & 0xfff;
404 if (!isInt<12>(
Value)) {
406 "operand must be a constant 12-bit integer");
408 return Value & 0xfff;
412 return (((
Value >> 5) & 0x7f) << 25) | ((
Value & 0x1f) << 7);
417 return ((
Value + 0x800) >> 12) & 0xfffff;
419 if (!isInt<21>(
Value))
424 unsigned Sbit = (
Value >> 20) & 0x1;
425 unsigned Hi8 = (
Value >> 12) & 0xff;
426 unsigned Mid1 = (
Value >> 11) & 0x1;
427 unsigned Lo10 = (
Value >> 1) & 0x3ff;
432 Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
436 if (!isInt<13>(
Value))
442 unsigned Sbit = (
Value >> 12) & 0x1;
443 unsigned Hi1 = (
Value >> 11) & 0x1;
444 unsigned Mid6 = (
Value >> 5) & 0x3f;
445 unsigned Lo4 = (
Value >> 1) & 0xf;
450 Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);
460 return UpperImm | ((LowerImm << 20) << 32);
463 if (!isInt<12>(
Value))
466 unsigned Bit11 = (
Value >> 11) & 0x1;
467 unsigned Bit4 = (
Value >> 4) & 0x1;
468 unsigned Bit9_8 = (
Value >> 8) & 0x3;
469 unsigned Bit10 = (
Value >> 10) & 0x1;
470 unsigned Bit6 = (
Value >> 6) & 0x1;
471 unsigned Bit7 = (
Value >> 7) & 0x1;
472 unsigned Bit3_1 = (
Value >> 1) & 0x7;
473 unsigned Bit5 = (
Value >> 5) & 0x1;
474 Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) |
475 (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5;
479 if (!isInt<9>(
Value))
482 unsigned Bit8 = (
Value >> 8) & 0x1;
483 unsigned Bit7_6 = (
Value >> 6) & 0x3;
484 unsigned Bit5 = (
Value >> 5) & 0x1;
485 unsigned Bit4_3 = (
Value >> 3) & 0x3;
486 unsigned Bit2_1 = (
Value >> 1) & 0x3;
487 Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) |
502 switch (
Fixup.getTargetKind()) {
512 AUIPCFixup = cast<RISCVMCExpr>(
Fixup.getValue())->getPCRelHiFixup(&AUIPCDF);
514 Asm.getContext().reportError(
Fixup.getLoc(),
515 "could not find corresponding %pcrel_hi");
536 auto *Writer = Asm.getWriterPtr();
540 bool IsResolved = Writer->isSymbolRefDifferenceFullyResolvedImpl(
541 Asm, SA, *AUIPCDF,
false,
true);
562 unsigned TA = 0, TB = 0;
563 switch (
Fixup.getKind()) {
565 TA = ELF::R_RISCV_ADD8;
566 TB = ELF::R_RISCV_SUB8;
569 TA = ELF::R_RISCV_ADD16;
570 TB = ELF::R_RISCV_SUB16;
573 TA = ELF::R_RISCV_ADD32;
574 TB = ELF::R_RISCV_SUB32;
577 TA = ELF::R_RISCV_ADD64;
578 TB = ELF::R_RISCV_SUB64;
586 Fixup.getOffset(),
nullptr,
589 Fixup.getOffset(),
nullptr,
592 Asm.getWriter().recordRelocation(Asm, Layout, &
F, FA,
A, FixedValueA);
593 Asm.getWriter().recordRelocation(Asm, Layout, &
F, FB,
B, FixedValueB);
594 FixedValue = FixedValueA - FixedValueB;
617 unsigned NumBytes =
alignTo(
Info.TargetSize +
Info.TargetOffset, 8) / 8;
623 for (
unsigned i = 0; i != NumBytes; ++i) {
639 bool UseCompressedNop = STI->
hasFeature(RISCV::FeatureStdExtC) ||
641 unsigned MinNopLen = UseCompressedNop ? 2 : 4;
679 Asm.getWriter().recordRelocation(Asm, Layout, &AF,
Fixup, NopBytes,
685std::unique_ptr<MCObjectTargetWriter>
unsigned const MachineRegisterInfo * MRI
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
PowerPC TLS Dynamic Call Fixup
static cl::opt< bool > RelaxBranches("riscv-asm-relax-branches", cl::init(true), cl::Hidden)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents an Operation in the Expression.
Align getAlignment() const
const MCSubtargetInfo * getSubtargetInfo() const
Generic interface to target specific assembler backends.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
unsigned getMinInstAlignment() const
Encapsulates the layout of an assembly file at a particular point in time.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
MCContext & getContext() const
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCAsmInfo * getAsmInfo() const
void reportError(SMLoc L, const Twine &Msg)
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const MCExpr * getValue() const
uint32_t getOffset() const
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
Represent a reference to a symbol from inside an expression.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
This represents an "assembler immediate".
int64_t getConstant() const
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
std::unique_ptr< MCObjectTargetWriter > createObjectTargetWriter() const override
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...
void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override
Relax the instruction in the given fragment to the next wider instruction.
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 ...
bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, MCAsmLayout &Layout, bool &WasRelaxed) const override
bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, MCAsmLayout &Layout, bool &WasRelaxed) const override
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, unsigned &Size) override
Hook to check if extra nop bytes must be inserted for alignment directive.
bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override
Check whether the given instruction may need relaxation.
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.
bool handleAddSubRelocations(const MCAsmLayout &Layout, const MCFragment &F, const MCFixup &Fixup, const MCValue &Target, uint64_t &FixedValue) const override
unsigned getRelaxedOpcode(unsigned Op) const
bool evaluateTargetFixup(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, const MCValue &Target, uint64_t &Value, bool &WasForced) override
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...
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
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.
std::optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
Represents a location in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static std::pair< MCFixupKind, MCFixupKind > getRelocPairForSize(unsigned Size)
@ fixup_riscv_tprel_lo12_s
@ fixup_riscv_tls_got_hi20
@ fixup_riscv_tls_gd_hi20
@ fixup_riscv_pcrel_lo12_i
@ fixup_riscv_pcrel_lo12_s
@ fixup_riscv_tprel_lo12_i
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< MCObjectTargetWriter > createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
@ FK_Data_8
A eight-byte fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_Data_2
A two-byte fixup.
MCAsmBackend * createRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
uint64_t value() const
This is a hole in the type system and should not be abused.
Target independent information on a fixup kind.
@ FKF_IsTarget
Should this fixup be evaluated in a target dependent manner?
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...