19constexpr unsigned HalfwordBits = 16;
20constexpr unsigned MaxPointerJumpStubInstructions = 9;
27enum class Opcode : uint32_t {
42constexpr unsigned RSShift = 21;
43constexpr unsigned RTShift = 16;
44constexpr unsigned RDShift = 11;
45constexpr unsigned ShiftAmountShift = 6;
48 return (
static_cast<uint32_t
>(
Op) << OpcodeShift) |
49 (
static_cast<uint32_t
>(
RS) << RSShift) |
50 (
static_cast<uint32_t
>(RT) << RTShift);
54 Register RD,
unsigned ShiftAmount = 0) {
55 return (
static_cast<uint32_t
>(RS) << RSShift) |
56 (
static_cast<uint32_t
>(RT) << RTShift) |
57 (
static_cast<uint32_t
>(RD) << RDShift) |
58 (ShiftAmount << ShiftAmountShift) | static_cast<uint32_t>(Fn);
61constexpr uint32_t encodeLui(
Register RT) {
62 return encodeIType(Opcode::Lui, Register::Zero, RT);
66 return encodeIType(Opcode::Addiu, RS, RT);
70 return encodeIType(Opcode::Daddiu, RS, RT);
74 return encodeIType(Opcode::Lw,
Base, RT);
78 return encodeIType(Opcode::Ld,
Base, RT);
81constexpr uint32_t encodeDsll(
Register RD,
Register RT,
unsigned ShiftAmount) {
82 return encodeRType(Function::Dsll, Register::Zero, RT, RD, ShiftAmount);
85constexpr uint32_t encodeIndirectJump(
Register Target,
bool R6) {
87 return encodeRType(
R6 ? Function::Jalr : Function::Jr, Target, Register::Zero,
91constexpr uint32_t encodeNop() {
return 0; }
95 unsigned InstructionIndex;
98constexpr StubFixup Pointer32StubFixups[] = {{
Hi16, 0}, {
Lo16, 1}};
99constexpr StubFixup Pointer64StubFixups[] = {
106#define KIND_NAME(K) \
160 const auto &Features =
G.getFeatures().getFeatures();
175 Edge::AddendT InitialAddend) {
180 return G.addAnonymousSymbol(
B, 0,
G.getPointerSize(),
false,
false);
186 unsigned PointerSize =
G.getPointerSize();
190 if (PointerSize == 8) {
192 encodeLui(Register::T9),
193 encodeDaddiu(Register::T9, Register::T9),
194 encodeDsll(Register::T9, Register::T9, HalfwordBits),
195 encodeDaddiu(Register::T9, Register::T9),
196 encodeDsll(Register::T9, Register::T9, HalfwordBits),
197 encodeDaddiu(Register::T9, Register::T9),
198 encodeLoadPointer64(Register::T9, Register::T9),
200 Fixups = Pointer64StubFixups;
203 encodeLui(Register::T9),
204 encodeAddiu(Register::T9, Register::T9),
205 encodeLoadPointer32(Register::T9, Register::T9),
207 Fixups = Pointer32StubFixups;
209 Instructions.push_back(encodeIndirectJump(Register::T9,
isR6(
G)));
210 Instructions.push_back(encodeNop());
219 for (
const StubFixup &
F : Fixups)
221 return G.addAnonymousSymbol(
B, 0, Content.size(),
true,
false);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Promote Memory to Register
Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represents an object file section.
Represents an address in the executor process.
@ RequestGOTAndTransformToOffsetHi16
Create an exact-address GOT entry and rewrite to its high/low GP offset.
@ Higher16
Fixup[15:0] <- (Target + Addend + 0x80008000) >> 32.
@ RequestGOTAndTransformToOffsetLo16
@ Lo16
Fixup[15:0] <- Target + Addend.
@ Jump26
J/JAL target. The target must be aligned and in the same 256-MiB region.
@ RequestTLSGDAndTransformToOffset16
Create a two-word general/local-dynamic TLS descriptor.
@ DTPRelHi16
Fixup <- Target + Addend - start-of-ORC-TLS-template.
@ Delta32
Fixup <- Target - Fixup + Addend : int32.
@ Abs16
Fixup[15:0] <- Target + Addend : int16.
@ PCHi16
Paired PC-relative high and low halves.
@ PC32
Fixup <- Target - Fixup + Addend : int32.
@ GPRel16
Fixup <- Target + Addend - _gp.
@ Highest16
Fixup[15:0] <- (Target + Addend + 0x800080008000) >> 48.
@ Pointer64
Fixup <- Target + Addend : uint64.
@ GOTPageOffset16
Low offset complementary to a rounded 64-KiB GOT page entry.
@ RequestGOTAndTransformToOffset16
Create an exact-address GOT entry and rewrite to GOTOffset16.
@ RequestTLSLDMAndTransformToOffset16
@ Pointer32
Fixup <- Target + Addend, checked as an unsigned 32-bit pointer.
@ NegGPRelHi16
Compound N32/N64 neg(gp_rel(Target + Addend)) fixups.
@ Delta64
Fixup <- Target - Fixup + Addend : int64.
@ PC18S3
Release-6 compact branch immediate fields.
@ PC16
Fixup[15:0] <- (Target - Fixup + Addend) >> 2 : int16.
@ PagePointer32
Pointer containing the rounded 64-KiB page of Target + Addend.
@ NegDelta32
Fixup <- Fixup - Target + Addend : int32 (used by .eh_frame).
@ GOTOffset16
Fixup <- address of GOT entry - _gp.
@ RequestGOTPageAndTransformToOffset16
Create a rounded 64-KiB page GOT entry and rewrite to GOTOffset16.
@ Hi16
Fixup[15:0] <- (Target + Addend + 0x8000) >> 16.
@ GPDispHi16
_gp_disp high/low expressions. The O32 low half uses Fixup - 4 as P.
LLVM_ABI Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, Edge::AddendT InitialAddend=0)
Creates an anonymous pointer, optionally initialized to InitialTarget.
LLVM_ABI Edge::Kind getPointerEdgeKind(const LinkGraph &G)
Returns Pointer32 or Pointer64, according to G's pointer ABI.
LLVM_ABI Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)
Creates a stub that materializes PointerSymbol, loads its value into $t9, and jumps to $t9.
LLVM_ABI const char * getEdgeKindName(Edge::Kind K)
constexpr unsigned InstructionSize
LLVM_ABI ArrayRef< char > getPointerBlockContent(const LinkGraph &G)
Returns zero-filled pointer contents in the graph's pointer width.
LLVM_ABI bool isR6(const LinkGraph &G)
Returns true if G uses the MIPS release-6 ISA.
static const char NullPointerContent[sizeof(uint64_t)]
LLVM_ABI const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
void write32(void *P, uint32_t V, endianness E)
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.