Skip to content

[JITLink][AArch32] Add dynamic lookup for relocation fixup infos #71649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 59 additions & 16 deletions llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum EdgeKind_aarch32 : Edge::Kind {
Thumb_MovtPrel,

LastThumbRelocation = Thumb_MovtPrel,
LastRelocation = LastThumbRelocation,
};

/// Flags enum for AArch32-specific symbol properties
Expand Down Expand Up @@ -163,65 +164,107 @@ struct HalfWords {
const uint16_t Lo; // Second halfword
};

/// Collection of named constants per fixup kind. It may contain but is not
/// limited to the following entries:
/// FixupInfo base class is required for dynamic lookups.
struct FixupInfoBase {
static const FixupInfoBase *getDynFixupInfo(Edge::Kind K);
virtual ~FixupInfoBase() {}
};

/// FixupInfo checks for Arm edge kinds work on 32-bit words
struct FixupInfoArm : public FixupInfoBase {
bool (*checkOpcode)(uint32_t Wd) = nullptr;
};

/// FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
struct FixupInfoThumb : public FixupInfoBase {
bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr;
};

/// Collection of named constants per fixup kind
///
/// Mandatory entries:
/// Opcode - Values of the op-code bits in the instruction, with
/// unaffected bits nulled
/// OpcodeMask - Mask with all bits set that encode the op-code
///
/// Other common entries:
/// ImmMask - Mask with all bits set that encode the immediate value
/// RegMask - Mask with all bits set that encode the register
///
/// Specializations can add further custom fields without restrictions.
///
template <EdgeKind_aarch32 Kind> struct FixupInfo {};

template <> struct FixupInfo<Arm_Jump24> {
namespace {
struct FixupInfoArmBranch : public FixupInfoArm {
static constexpr uint32_t Opcode = 0x0a000000;
static constexpr uint32_t OpcodeMask = 0x0f000000;
static constexpr uint32_t ImmMask = 0x00ffffff;
static constexpr uint32_t Unconditional = 0xe0000000;
static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
};
} // namespace

template <> struct FixupInfo<Arm_Jump24> : public FixupInfoArmBranch {
static constexpr uint32_t OpcodeMask = 0x0f000000;
};

template <> struct FixupInfo<Arm_Call> : public FixupInfo<Arm_Jump24> {
template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch {
static constexpr uint32_t OpcodeMask = 0x0e000000;
static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
static constexpr uint32_t Unconditional = 0xe0000000;
static constexpr uint32_t BitH = 0x01000000;
static constexpr uint32_t BitBlx = 0x10000000;
};

template <> struct FixupInfo<Arm_MovtAbs> {
static constexpr uint32_t Opcode = 0x03400000;
namespace {
struct FixupInfoArmMov : public FixupInfoArm {
static constexpr uint32_t OpcodeMask = 0x0ff00000;
static constexpr uint32_t ImmMask = 0x000f0fff;
static constexpr uint32_t RegMask = 0x0000f000;
};
} // namespace

template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov {
static constexpr uint32_t Opcode = 0x03400000;
};

template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfo<Arm_MovtAbs> {
template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov {
static constexpr uint32_t Opcode = 0x03000000;
};

template <> struct FixupInfo<Thumb_Jump24> {
template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {
static constexpr HalfWords Opcode{0xf000, 0x9000};
static constexpr HalfWords OpcodeMask{0xf800, 0x9000};
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
};

template <> struct FixupInfo<Thumb_Call> {
template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
static constexpr HalfWords Opcode{0xf000, 0xc000};
static constexpr HalfWords OpcodeMask{0xf800, 0xc000};
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
static constexpr uint16_t LoBitH = 0x0001;
static constexpr uint16_t LoBitNoBlx = 0x1000;
};

template <> struct FixupInfo<Thumb_MovtAbs> {
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
namespace {
struct FixupInfoThumbMov : public FixupInfoThumb {
static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
static constexpr HalfWords ImmMask{0x040f, 0x70ff};
static constexpr HalfWords RegMask{0x0000, 0x0f00};
};
} // namespace

template <>
struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfo<Thumb_MovtAbs> {
template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
};

template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
};

template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf240, 0x0000};
};

template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf240, 0x0000};
};

Expand Down
Loading