30 auto checkBrFixup = [&](
unsigned Bits) {
31 int64_t SVal = int64_t(
Value);
32 if ((
Value & 3) != 0) {
33 Ctx.reportError(
Fixup.getLoc(),
"branch target not a multiple of four (" +
40 Ctx.reportError(
Fixup.getLoc(),
"branch target out of range (" +
41 Twine(SVal) +
" not between " +
59 return Value & 0xfffc;
64 return Value & 0x3fffffc;
66 return Value & 0xffff;
69 return Value & 0xfffc;
72 return Value & 0xffffffff;
75 return Value & 0x3ffffffff;
114 PPCAsmBackend(
const Target &
T,
const Triple &TT)
119 MCFixupKindInfo getFixupKindInfo(
MCFixupKind Kind)
const override;
122 const MCValue &Target, uint8_t *
Data, uint64_t
Value,
123 bool IsResolved)
override;
128 if (
Target.getSpecifier())
131 switch ((
unsigned)Kind) {
140 if (
const auto *
A =
Target.getAddSym()) {
145 unsigned Other =
static_cast<const MCSymbolELF *
>(
A)->getOther() << 2;
149 auto *S =
static_cast<const MCSymbolXCOFF *
>(
A);
150 return !
Target.isAbsolute() && S->isExternal() &&
158 bool writeNopData(raw_ostream &OS, uint64_t
Count,
159 const MCSubtargetInfo *STI)
const override {
160 uint64_t NumNops =
Count / 4;
161 for (uint64_t i = 0; i != NumNops; ++i)
175 {
"fixup_ppc_br24", 6, 24, 0},
176 {
"fixup_ppc_br24_notoc", 6, 24, 0},
177 {
"fixup_ppc_brcond14", 16, 14, 0},
178 {
"fixup_ppc_br24abs", 6, 24, 0},
179 {
"fixup_ppc_brcond14abs", 16, 14, 0},
180 {
"fixup_ppc_half16", 0, 16, 0},
181 {
"fixup_ppc_half16ds", 0, 14, 0},
182 {
"fixup_ppc_pcrel32", 0, 32, 0},
183 {
"fixup_ppc_imm32", 0, 32, 0},
184 {
"fixup_ppc_pcrel34", 0, 34, 0},
185 {
"fixup_ppc_imm34", 0, 34, 0},
186 {
"fixup_ppc_nofixup", 0, 0, 0}};
189 {
"fixup_ppc_br24", 2, 24, 0},
190 {
"fixup_ppc_br24_notoc", 2, 24, 0},
191 {
"fixup_ppc_brcond14", 2, 14, 0},
192 {
"fixup_ppc_br24abs", 2, 24, 0},
193 {
"fixup_ppc_brcond14abs", 2, 14, 0},
194 {
"fixup_ppc_half16", 0, 16, 0},
195 {
"fixup_ppc_half16ds", 2, 14, 0},
196 {
"fixup_ppc_pcrel32", 0, 32, 0},
197 {
"fixup_ppc_imm32", 0, 32, 0},
198 {
"fixup_ppc_pcrel34", 0, 34, 0},
199 {
"fixup_ppc_imm34", 0, 34, 0},
200 {
"fixup_ppc_nofixup", 0, 0, 0}};
218void PPCAsmBackend::applyFixup(
const MCFragment &
F,
const MCFixup &
Fixup,
219 const MCValue &TargetVal, uint8_t *
Data,
220 uint64_t
Value,
bool IsResolved) {
225 Target.setAddSym(
nullptr);
243 for (
unsigned i = 0; i != NumBytes; ++i) {
245 Data[i] |= uint8_t((
Value >> (Idx * 8)) & 0xff);
252class ELFPPCAsmBackend :
public PPCAsmBackend {
254 ELFPPCAsmBackend(
const Target &
T,
const Triple &TT) : PPCAsmBackend(
T,
TT) {}
256 std::unique_ptr<MCObjectTargetWriter>
257 createObjectTargetWriter()
const override {
259 bool Is64 =
TT.isPPC64();
263 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override;
266class XCOFFPPCAsmBackend :
public PPCAsmBackend {
268 XCOFFPPCAsmBackend(
const Target &
T,
const Triple &TT)
269 : PPCAsmBackend(
T,
TT) {}
271 std::unique_ptr<MCObjectTargetWriter>
272 createObjectTargetWriter()
const override {
279std::optional<MCFixupKind>
280ELFPPCAsmBackend::getFixupKind(StringRef Name)
const {
281 if (
TT.isOSBinFormatELF()) {
284 Type = llvm::StringSwitch<unsigned>(Name)
285#define ELF_RELOC(X, Y) .Case(#X, Y)
286#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
288 .Case(
"BFD_RELOC_NONE", ELF::R_PPC64_NONE)
289 .Case(
"BFD_RELOC_16", ELF::R_PPC64_ADDR16)
290 .Case(
"BFD_RELOC_32", ELF::R_PPC64_ADDR32)
291 .Case(
"BFD_RELOC_64", ELF::R_PPC64_ADDR64)
294 Type = llvm::StringSwitch<unsigned>(Name)
295#define ELF_RELOC(X, Y) .Case(#X, Y)
296#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
298 .Case(
"BFD_RELOC_NONE", ELF::R_PPC_NONE)
299 .Case(
"BFD_RELOC_16", ELF::R_PPC_ADDR16)
300 .Case(
"BFD_RELOC_32", ELF::R_PPC_ADDR32)
314 if (TT.isOSBinFormatXCOFF())
315 return new XCOFFPPCAsmBackend(
T, TT);
317 return new ELFPPCAsmBackend(
T, TT);
unsigned const MachineRegisterInfo * MRI
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
static bool shouldForceRelocation(const MCFixup &Fixup)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static uint64_t adjustFixupValue(MCContext &Ctx, const MCFixup &Fixup, unsigned Kind, uint64_t Value)
static unsigned getFixupKindNumBytes(unsigned Kind)
PowerPC TLS Dynamic Call Fixup
Generic interface to target specific assembler backends.
virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Context object for machine code objects.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_ppc_brcond14abs
14-bit absolute relocation for conditional branches.
@ fixup_ppc_half16
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like 'li' or 'addis'.
@ fixup_ppc_brcond14
14-bit PC relative relocation for conditional branches.
@ fixup_ppc_half16dq
A 16-bit fixup corresponding to lo16(_foo) with implied 3 zero bits for instrs like 'lxv'.
@ fixup_ppc_half16ds
A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like 'std'.
@ fixup_ppc_nofixup
Not a true fixup, but ties a symbol to a call to __tls_get_addr for the TLS general and local dynamic...
@ fixup_ppc_br24abs
24-bit absolute relocation for direct branches like 'ba' and 'bla'.
VE::Fixups getFixupKind(uint8_t S)
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
bool isRelocation(MCFixupKind FixupKind)
Context & getContext() const
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
constexpr int64_t minIntN(int64_t N)
Gets the minimum value for a N-bit signed integer.
MCAsmBackend * createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
std::unique_ptr< MCObjectTargetWriter > createPPCXCOFFObjectWriter(bool Is64Bit)
Construct a PPC XCOFF object writer.
FunctionAddr VTableAddr Count
@ FirstLiteralRelocationKind
@ 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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
constexpr int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
std::unique_ptr< MCObjectTargetWriter > createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
Construct an PPC ELF object writer.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target independent information on a fixup kind.