summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src/asmjit/core/archtraits.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src/asmjit/core/archtraits.h')
-rw-r--r--3rdparty/asmjit/src/asmjit/core/archtraits.h290
1 files changed, 290 insertions, 0 deletions
diff --git a/3rdparty/asmjit/src/asmjit/core/archtraits.h b/3rdparty/asmjit/src/asmjit/core/archtraits.h
new file mode 100644
index 00000000000..192a826e511
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/archtraits.h
@@ -0,0 +1,290 @@
+// This file is part of AsmJit project <https://asmjit.com>
+//
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+
+#ifndef ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
+#define ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
+
+#include "../core/operand.h"
+#include "../core/support.h"
+#include "../core/type.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \addtogroup asmjit_core
+//! \{
+
+//! Instruction set architecture (ISA).
+enum class Arch : uint8_t {
+ //! Unknown or uninitialized ISA.
+ kUnknown = 0,
+
+ //! 32-bit X86 ISA.
+ kX86 = 1,
+ //! 64-bit X86 ISA also known as X64, X86_64, and AMD64.
+ kX64 = 2,
+
+ //! 32-bit RISC-V ISA.
+ kRISCV32 = 3,
+ //! 64-bit RISC-V ISA.
+ kRISCV64 = 4,
+
+ //! 32-bit ARM ISA (little endian).
+ kARM = 5,
+ //! 64-bit ARM ISA in (little endian).
+ kAArch64 = 6,
+ //! 32-bit ARM ISA in Thumb mode (little endian).
+ kThumb = 7,
+
+ // 8 is not used at the moment, even numbers are 64-bit architectures.
+
+ //! 32-bit MIPS ISA in (little endian).
+ kMIPS32_LE = 9,
+ //! 64-bit MIPS ISA in (little endian).
+ kMIPS64_LE = 10,
+
+ //! 32-bit ARM ISA (big endian).
+ kARM_BE = 11,
+ //! 64-bit ARM ISA in (big endian).
+ kAArch64_BE = 12,
+ //! 32-bit ARM ISA in Thumb mode (big endian).
+ kThumb_BE = 13,
+
+ // 14 is not used at the moment, even numbers are 64-bit architectures.
+
+ //! 32-bit MIPS ISA in (big endian).
+ kMIPS32_BE = 15,
+ //! 64-bit MIPS ISA in (big endian).
+ kMIPS64_BE = 16,
+
+ //! Maximum value of `Arch`.
+ kMaxValue = kMIPS64_BE,
+
+ //! Mask used by 32-bit ISAs (odd are 32-bit, even are 64-bit).
+ k32BitMask = 0x01,
+ //! First big-endian architecture.
+ kBigEndian = kARM_BE,
+
+ //! ISA detected at compile-time (ISA of the host).
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#else
+ ASMJIT_ARCH_X86 == 32 ? kX86 :
+ ASMJIT_ARCH_X86 == 64 ? kX64 :
+
+ ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kARM :
+ ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kARM_BE :
+ ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kAArch64 :
+ ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kAArch64_BE :
+
+ ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kMIPS32_LE :
+ ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kMIPS32_BE :
+ ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kMIPS64_LE :
+ ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kMIPS64_BE :
+
+ kUnknown
+#endif
+};
+
+//! Sub-architecture.
+enum class SubArch : uint8_t {
+ //! Unknown or uninitialized architecture sub-type.
+ kUnknown = 0,
+
+ //! Maximum value of `SubArch`.
+ kMaxValue = kUnknown,
+
+ //! Sub-architecture detected at compile-time (sub-architecture of the host).
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#else
+ kUnknown
+#endif
+};
+
+//! Identifier used to represent names of different data types across architectures.
+enum class ArchTypeNameId : uint8_t {
+ //! Describes 'db' (X86/X86_64 convention, always 8-bit quantity).
+ kDB = 0,
+ //! Describes 'dw' (X86/X86_64 convention, always 16-bit word).
+ kDW,
+ //! Describes 'dd' (X86/X86_64 convention, always 32-bit word).
+ kDD,
+ //! Describes 'dq' (X86/X86_64 convention, always 64-bit word).
+ kDQ,
+ //! Describes 'byte' (always 8-bit quantity).
+ kByte,
+ //! Describes 'half' (most likely 16-bit word).
+ kHalf,
+ //! Describes 'word' (either 16-bit or 32-bit word).
+ kWord,
+ //! Describes 'hword' (most likely 16-bit word).
+ kHWord,
+ //! Describes 'dword' (either 32-bit or 64-bit word).
+ kDWord,
+ //! Describes 'qword' (64-bit word).
+ kQWord,
+ //! Describes 'xword' (64-bit word).
+ kXWord,
+ //! Describes 'short' (always 16-bit word).
+ kShort,
+ //! Describes 'long' (most likely 32-bit word).
+ kLong,
+ //! Describes 'quad' (64-bit word).
+ kQuad,
+
+ //! Maximum value of `ArchTypeNameId`.
+ kMaxValue = kQuad
+};
+
+//! Instruction feature hints for each register group provided by \ref ArchTraits.
+//!
+//! Instruction feature hints describe miscellaneous instructions provided by the architecture that can be used by
+//! register allocator to make certain things simpler - like register swaps or emitting register push/pop sequences.
+//!
+//! \remarks Instruction feature hints are only defined for register groups that can be used with \ref
+//! asmjit_compiler infrastructure. Register groups that are not managed by Compiler are not provided by
+//! \ref ArchTraits and cannot be queried.
+enum class InstHints : uint8_t {
+ //! No feature hints.
+ kNoHints = 0,
+
+ //! Architecture supports a register swap by using a single instruction.
+ kRegSwap = 0x01u,
+ //! Architecture provides push/pop instructions.
+ kPushPop = 0x02u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(InstHints)
+
+//! Architecture traits used by Function API and Compiler's register allocator.
+struct ArchTraits {
+ //! \name Members
+ //! \{
+
+ //! Stack pointer register id.
+ uint8_t _spRegId;
+ //! Frame pointer register id.
+ uint8_t _fpRegId;
+ //! Link register id.
+ uint8_t _linkRegId;
+ //! Instruction pointer (or program counter) register id, if accessible.
+ uint8_t _ipRegId;
+
+ // Reserved.
+ uint8_t _reserved[3];
+ //! Hardware stack alignment requirement.
+ uint8_t _hwStackAlignment;
+
+ //! Minimum addressable offset on stack guaranteed for all instructions.
+ uint32_t _minStackOffset;
+ //! Maximum addressable offset on stack depending on specific instruction.
+ uint32_t _maxStackOffset;
+
+ //! Flags for each virtual register group.
+ Support::Array<InstHints, Globals::kNumVirtGroups> _instHints;
+
+ //! Maps register type into a signature, that provides group, size and can be used to construct register operands.
+ Support::Array<OperandSignature, uint32_t(RegType::kMaxValue) + 1> _regSignature;
+ //! Maps a register to type-id, see \ref TypeId.
+ Support::Array<TypeId, uint32_t(RegType::kMaxValue) + 1> _regTypeToTypeId;
+ //! Maps scalar TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref TypeId.
+ Support::Array<RegType, 32> _typeIdToRegType;
+
+ //! Word name identifiers of 8-bit, 16-bit, 32-biit, and 64-bit quantities that appear in formatted text.
+ ArchTypeNameId _typeNameIdTable[4];
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns stack pointer register id.
+ inline uint32_t spRegId() const noexcept { return _spRegId; }
+ //! Returns stack frame register id.
+ inline uint32_t fpRegId() const noexcept { return _fpRegId; }
+ //! Returns link register id, if the architecture provides it.
+ inline uint32_t linkRegId() const noexcept { return _linkRegId; }
+ //! Returns instruction pointer register id, if the architecture provides it.
+ inline uint32_t ipRegId() const noexcept { return _ipRegId; }
+
+ //! Returns a hardware stack alignment requirement.
+ //!
+ //! \note This is a hardware constraint. Architectures that don't constrain it would return the lowest alignment
+ //! (1), however, some architectures may constrain the alignment, for example AArch64 requires 16-byte alignment.
+ inline uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; }
+
+ //! Tests whether the architecture provides link register, which is used across function calls. If the link
+ //! register is not provided then a function call pushes the return address on stack (X86/X64).
+ inline bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
+
+ //! Returns minimum addressable offset on stack guaranteed for all instructions.
+ inline uint32_t minStackOffset() const noexcept { return _minStackOffset; }
+ //! Returns maximum addressable offset on stack depending on specific instruction.
+ inline uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
+
+ //! Returns ISA flags of the given register `group`.
+ inline InstHints instFeatureHints(RegGroup group) const noexcept { return _instHints[group]; }
+ //! Tests whether the given register `group` has the given `flag` set.
+ inline bool hasInstHint(RegGroup group, InstHints feature) const noexcept { return Support::test(_instHints[group], feature); }
+ //! Tests whether the ISA provides register swap instruction for the given register `group`.
+ inline bool hasInstRegSwap(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kRegSwap); }
+ //! Tests whether the ISA provides push/pop instructions for the given register `group`.
+ inline bool hasInstPushPop(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kPushPop); }
+
+ inline bool hasRegType(RegType type) const noexcept {
+ return type <= RegType::kMaxValue && _regSignature[type].isValid();
+ }
+
+ //! Returns an operand signature from the given register `type` of this architecture.
+ inline OperandSignature regTypeToSignature(RegType type) const noexcept { return _regSignature[type]; }
+ //! Returns a register from the given register `type` of this architecture.
+ inline RegGroup regTypeToGroup(RegType type) const noexcept { return _regSignature[type].regGroup(); }
+ //! Returns a register size the given register `type` of this architecture.
+ inline uint32_t regTypeToSize(RegType type) const noexcept { return _regSignature[type].size(); }
+ //! Returns a corresponding `TypeId` from the given register `type` of this architecture.
+ inline TypeId regTypeToTypeId(RegType type) const noexcept { return _regTypeToTypeId[type]; }
+
+ //! Returns a table of ISA word names that appear in formatted text. Word names are ISA dependent.
+ //!
+ //! The index of this table is log2 of the size:
+ //! - [0] 8-bits
+ //! - [1] 16-bits
+ //! - [2] 32-bits
+ //! - [3] 64-bits
+ inline const ArchTypeNameId* typeNameIdTable() const noexcept { return _typeNameIdTable; }
+
+ //! Returns an ISA word name identifier of the given `index`, see \ref typeNameIdTable() for more details.
+ inline ArchTypeNameId typeNameIdByIndex(uint32_t index) const noexcept { return _typeNameIdTable[index]; }
+
+ //! \}
+
+ //! \name Statics
+ //! \{
+
+ //! Returns a const reference to `ArchTraits` for the given architecture `arch`.
+ static inline const ArchTraits& byArch(Arch arch) noexcept;
+
+ //! \}
+};
+
+ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1];
+
+//! \cond
+inline const ArchTraits& ArchTraits::byArch(Arch arch) noexcept { return _archTraits[uint32_t(arch)]; }
+//! \endcond
+
+//! Architecture utilities.
+namespace ArchUtils {
+
+ASMJIT_API Error typeIdToRegSignature(Arch arch, TypeId typeId, TypeId* typeIdOut, OperandSignature* regSignatureOut) noexcept;
+
+} // {ArchUtils}
+
+//! \}
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_ARCHTRAITS_H_INCLUDED