llvm/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h

//===------ aarch32.h - Generic JITLink arm/thumb utilities -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Generic utilities for graphs representing arm/thumb objects.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_JITLINK_AARCH32
#define LLVM_EXECUTIONENGINE_JITLINK_AARCH32

#include "TableManager.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Error.h"

namespace llvm {
namespace jitlink {
namespace aarch32 {

/// Check whether the given target flags are set for this Symbol.
bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags);

/// JITLink-internal AArch32 fixup kinds
enum EdgeKind_aarch32 : Edge::Kind {};

/// Flags enum for AArch32-specific symbol properties
enum TargetFlags_aarch32 : TargetFlagsType {};

/// Human-readable name for a given CPU architecture kind
const char *getCPUArchName(ARMBuildAttrs::CPUArch K);

/// Get a human-readable name for the given AArch32 edge kind.
const char *getEdgeKindName(Edge::Kind K);

/// AArch32 uses stubs for a number of purposes, like branch range extension
/// or interworking between Arm and Thumb instruction subsets.
///
/// Stub implementations vary depending on CPU architecture (v4, v6, v7),
/// instruction subset and branch type (absolute/PC-relative).
///
/// For each kind of stub, the StubsFlavor defines one concrete form that is
/// used throughout the LinkGraph.
///
/// Stubs are often called "veneers" in the official docs and online.
///
enum class StubsFlavor {};

/// JITLink sub-arch configuration for Arm CPU models
struct ArmConfig {};

/// Obtain the sub-arch configuration for a given Arm CPU model.
inline ArmConfig getArmConfigForCPUArch(ARMBuildAttrs::CPUArch CPUArch) {}

/// Immutable pair of halfwords, Hi and Lo, with overflow check
struct HalfWords {};

/// FixupInfo base class is required for dynamic lookups.
struct FixupInfoBase {};

/// FixupInfo checks for Arm edge kinds work on 32-bit words
struct FixupInfoArm : public FixupInfoBase {};

/// FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
struct FixupInfoThumb : public FixupInfoBase {};

/// 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 {};

struct FixupInfoArmBranch : public FixupInfoArm {};

template <> struct FixupInfo<Arm_Jump24> : public FixupInfoArmBranch {};

template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch {};

struct FixupInfoArmMov : public FixupInfoArm {};

template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov {};

template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov {};

template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {};

template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {};

struct FixupInfoThumbMov : public FixupInfoThumb {};

template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov {};

template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov {};

template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov {};

template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov {};

/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
                                 Edge::Kind Kind);

/// Helper function to read the initial addend for Arm-class relocations.
Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, Edge::OffsetT Offset,
                                Edge::Kind Kind);

/// Helper function to read the initial addend for Thumb-class relocations.
Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, Edge::OffsetT Offset,
                                  Edge::Kind Kind, const ArmConfig &ArmCfg);

/// Read the initial addend for a REL-type relocation. It's the value encoded
/// in the immediate field of the fixup location by the compiler.
inline Expected<int64_t> readAddend(LinkGraph &G, Block &B,
                                    Edge::OffsetT Offset, Edge::Kind Kind,
                                    const ArmConfig &ArmCfg) {}

/// Helper function to apply the fixup for Data-class relocations.
Error applyFixupData(LinkGraph &G, Block &B, const Edge &E);

/// Helper function to apply the fixup for Arm-class relocations.
Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E);

/// Helper function to apply the fixup for Thumb-class relocations.
Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
                      const ArmConfig &ArmCfg);

/// Apply fixup expression for edge to block content.
inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
                        const ArmConfig &ArmCfg) {}

/// Populate a Global Offset Table from edges that request it.
class GOTBuilder : public TableManager<GOTBuilder> {};

/// Stubs builder emits non-position-independent Arm stubs for pre-v7 CPUs.
/// These architectures have no MovT/MovW instructions and don't support Thumb2.
/// BL is the only Thumb instruction that can generate stubs and they can always
/// be transformed into BLX.
class StubsManager_prev7 {};

/// Stubs builder for v7 emits non-position-independent Arm and Thumb stubs.
class StubsManager_v7 {};

} // namespace aarch32
} // namespace jitlink
} // namespace llvm

#endif // LLVM_EXECUTIONENGINE_JITLINK_AARCH32