35 cl::desc(
"Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));
41#define ELF_RELOC(NAME, ID) .Case(#NAME, ID)
42#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
44#define ELF_RISCV_NONSTANDARD_RELOC(_VENDOR, NAME, ID) .Case(#NAME, ID)
45#include "llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def"
46#undef ELF_RISCV_NONSTANDARD_RELOC
47 .
Case(
"BFD_RELOC_NONE", ELF::R_RISCV_NONE)
48 .
Case(
"BFD_RELOC_32", ELF::R_RISCV_32)
49 .
Case(
"BFD_RELOC_64", ELF::R_RISCV_64)
64 {
"fixup_riscv_hi20", 12, 20, 0},
65 {
"fixup_riscv_lo12_i", 20, 12, 0},
66 {
"fixup_riscv_12_i", 20, 12, 0},
67 {
"fixup_riscv_lo12_s", 0, 32, 0},
68 {
"fixup_riscv_pcrel_hi20", 12, 20,
70 {
"fixup_riscv_pcrel_lo12_i", 20, 12,
72 {
"fixup_riscv_pcrel_lo12_s", 0, 32,
75 {
"fixup_riscv_tprel_hi20", 12, 20, 0},
76 {
"fixup_riscv_tprel_lo12_i", 20, 12, 0},
77 {
"fixup_riscv_tprel_lo12_s", 0, 32, 0},
78 {
"fixup_riscv_tprel_add", 0, 0, 0},
87 {
"fixup_riscv_relax", 0, 0, 0},
88 {
"fixup_riscv_align", 0, 0, 0},
90 {
"fixup_riscv_tlsdesc_hi20", 12, 20,
92 {
"fixup_riscv_tlsdesc_load_lo12", 20, 12, 0},
93 {
"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0},
94 {
"fixup_riscv_tlsdesc_call", 0, 0, 0},
97 "Not all fixup kinds added to Infos array");
121 switch (
Fixup.getTargetKind()) {
139 return STI->
hasFeature(RISCV::FeatureRelax) || ForceRelocs;
149 unsigned Kind =
Fixup.getTargetKind();
155 if (!Resolved && !WasForced)
172 return !isInt<13>(
Offset);
202 Inst = std::move(Res);
207 bool &WasRelaxed)
const {
210 int64_t LineDelta =
DF.getLineDelta();
211 const MCExpr &AddrDelta =
DF.getAddrDelta();
214 size_t OldSize =
Data.size();
217 [[maybe_unused]]
bool IsAbsolute =
219 assert(IsAbsolute &&
"CFA with invalid expression");
227 OS <<
uint8_t(dwarf::DW_LNS_advance_line);
232 std::pair<MCFixupKind, MCFixupKind>
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);
245 assert((PtrSize == 4 || PtrSize == 8) &&
"Unexpected pointer size");
249 OS <<
uint8_t(dwarf::DW_LNS_fixed_advance_pc);
255 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
260 OS <<
uint8_t(dwarf::DW_LNS_extended_op);
262 OS <<
uint8_t(dwarf::DW_LNE_end_sequence);
267 WasRelaxed = OldSize !=
Data.size();
273 bool &WasRelaxed)
const {
274 const MCExpr &AddrDelta =
DF.getAddrDelta();
277 size_t OldSize =
Data.size();
280 if (AddrDelta.evaluateAsAbsolute(
Value, Asm))
282 [[maybe_unused]]
bool IsAbsolute =
284 assert(IsAbsolute &&
"CFA with invalid expression");
290 assert(Asm.getContext().getAsmInfo()->getMinInstAlignment() == 1 &&
291 "expected 1-byte alignment");
293 WasRelaxed = OldSize !=
Data.size();
297 auto AddFixups = [&Fixups, &AddrDelta](
unsigned Offset,
298 std::pair<unsigned, unsigned>
Fixup) {
299 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
303 std::get<0>(
Fixup))));
307 std::get<1>(
Fixup))));
311 OS <<
uint8_t(dwarf::DW_CFA_advance_loc);
312 AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
313 }
else if (isUInt<8>(
Value)) {
314 OS <<
uint8_t(dwarf::DW_CFA_advance_loc1);
316 AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
317 }
else if (isUInt<16>(
Value)) {
318 OS <<
uint8_t(dwarf::DW_CFA_advance_loc2);
320 AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
321 }
else if (isUInt<32>(
Value)) {
322 OS <<
uint8_t(dwarf::DW_CFA_advance_loc4);
324 AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
329 WasRelaxed = OldSize !=
Data.size();
335 int64_t &
Value)
const {
337 return std::make_pair(
false,
false);
360 return RISCV::PseudoLongBEQ;
362 return RISCV::PseudoLongBNE;
364 return RISCV::PseudoLongBLT;
366 return RISCV::PseudoLongBGE;
368 return RISCV::PseudoLongBLTU;
370 return RISCV::PseudoLongBGEU;
392 bool UseCompressedNop = STI->
hasFeature(RISCV::FeatureStdExtC) ||
395 if (Count % 4 == 2) {
396 OS.
write(UseCompressedNop ?
"\x01\0" :
"\0\0", 2);
401 for (; Count >= 4; Count -= 4)
409 switch (
Fixup.getTargetKind()) {
427 return Value & 0xfff;
429 if (!isInt<12>(
Value)) {
431 "operand must be a constant 12-bit integer");
433 return Value & 0xfff;
437 return (((
Value >> 5) & 0x7f) << 25) | ((
Value & 0x1f) << 7);
442 return ((
Value + 0x800) >> 12) & 0xfffff;
444 if (!isInt<21>(
Value))
449 unsigned Sbit = (
Value >> 20) & 0x1;
450 unsigned Hi8 = (
Value >> 12) & 0xff;
451 unsigned Mid1 = (
Value >> 11) & 0x1;
452 unsigned Lo10 = (
Value >> 1) & 0x3ff;
457 Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
461 if (!isInt<13>(
Value))
467 unsigned Sbit = (
Value >> 12) & 0x1;
468 unsigned Hi1 = (
Value >> 11) & 0x1;
469 unsigned Mid6 = (
Value >> 5) & 0x3f;
470 unsigned Lo4 = (
Value >> 1) & 0xf;
475 Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);
485 return UpperImm | ((LowerImm << 20) << 32);
488 if (!isInt<12>(
Value))
491 unsigned Bit11 = (
Value >> 11) & 0x1;
492 unsigned Bit4 = (
Value >> 4) & 0x1;
493 unsigned Bit9_8 = (
Value >> 8) & 0x3;
494 unsigned Bit10 = (
Value >> 10) & 0x1;
495 unsigned Bit6 = (
Value >> 6) & 0x1;
496 unsigned Bit7 = (
Value >> 7) & 0x1;
497 unsigned Bit3_1 = (
Value >> 1) & 0x7;
498 unsigned Bit5 = (
Value >> 5) & 0x1;
499 Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) |
500 (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5;
504 if (!isInt<9>(
Value))
507 unsigned Bit8 = (
Value >> 8) & 0x1;
508 unsigned Bit7_6 = (
Value >> 6) & 0x3;
509 unsigned Bit5 = (
Value >> 5) & 0x1;
510 unsigned Bit4_3 = (
Value >> 3) & 0x3;
511 unsigned Bit2_1 = (
Value >> 1) & 0x3;
512 Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) |
529 switch (
Fixup.getTargetKind()) {
540 AUIPCFixup = cast<RISCVMCExpr>(
Fixup.getValue())->getPCRelHiFixup(&AUIPCDF);
542 Asm.getContext().reportError(
Fixup.getLoc(),
543 "could not find corresponding %pcrel_hi");
560 const MCSymbolELF &SA = cast<MCSymbolELF>(
A->getSymbol());
571 Value -= Asm.getFragmentOffset(*AUIPCDF) + AUIPCFixup->
getOffset();
587 unsigned TA = 0, TB = 0;
588 switch (
Fixup.getKind()) {
590 TA = ELF::R_RISCV_ADD8;
591 TB = ELF::R_RISCV_SUB8;
594 TA = ELF::R_RISCV_ADD16;
595 TB = ELF::R_RISCV_SUB16;
598 TA = ELF::R_RISCV_ADD32;
599 TB = ELF::R_RISCV_SUB32;
602 TA = ELF::R_RISCV_ADD64;
603 TB = ELF::R_RISCV_SUB64;
606 TA = ELF::R_RISCV_SET_ULEB128;
607 TB = ELF::R_RISCV_SUB_ULEB128;
615 Fixup.getOffset(),
nullptr,
618 Fixup.getOffset(),
nullptr,
621 Asm.getWriter().recordRelocation(Assembler, &
F, FA,
A, FixedValueA);
622 Asm.getWriter().recordRelocation(Assembler, &
F, FB,
B, FixedValueB);
623 FixedValue = FixedValueA - FixedValueB;
646 unsigned NumBytes =
alignTo(
Info.TargetSize +
Info.TargetOffset, 8) / 8;
652 for (
unsigned i = 0; i != NumBytes; ++i) {
668 bool UseCompressedNop = STI->
hasFeature(RISCV::FeatureStdExtC) ||
670 unsigned MinNopLen = UseCompressedNop ? 2 : 4;
707 Asm.getWriter().recordRelocation(Asm, &AF,
Fixup, NopBytes, FixedValue);
712std::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)
static cl::opt< bool > ULEB128Reloc("riscv-uleb128-reloc", cl::init(true), cl::Hidden, cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"))
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.
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.
void reportError(SMLoc L, const Twine &Msg)
SmallVectorImpl< MCFixup > & getFixups()
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const
Aggressive variant of evaluateAsRelocatable when relocations are unavailable (e.g.
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, 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())
MCSection * getParent() const
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
const MCExpr & getValue() 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
unsigned getBinding() const
Represent a reference to a symbol from inside an expression.
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
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...
bool relaxDwarfLineAddr(const MCAssembler &Asm, MCDwarfLineAddrFragment &DF, bool &WasRelaxed) const override
std::pair< bool, bool > relaxLEB128(const MCAssembler &Asm, MCLEBFragment &LF, int64_t &Value) const override
std::unique_ptr< MCObjectTargetWriter > createObjectTargetWriter() const override
bool relaxDwarfCFA(const MCAssembler &Asm, MCDwarfCallFrameFragment &DF, bool &WasRelaxed) 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 evaluateTargetFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCFragment *DF, const MCValue &Target, const MCSubtargetInfo *STI, uint64_t &Value, bool &WasForced) override
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm, const MCFixup &Fixup, bool Resolved, uint64_t Value, const MCRelaxableFragment *DF, const bool WasForced) const override
Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...
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.
unsigned getRelaxedOpcode(unsigned Op) const
bool handleAddSubRelocations(const MCAssembler &Asm, const MCFragment &F, const MCFixup &Fixup, const MCValue &Target, uint64_t &FixedValue) const override
bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, MCAlignFragment &AF) override
Hook which indicates if the target requires a fixup to be generated when handling an align directive ...
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, const MCSubtargetInfo *STI) override
Hook to check if a relocation is needed for some target specific reason.
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
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
@ fixup_riscv_tlsdesc_load_lo12
@ fixup_riscv_tlsdesc_hi20
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_leb128
A leb128 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...