LCOV - code coverage report
Current view: top level - asmjit - archtraits.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 7 11 63.6 %
Date: 2026-11-05 10:19:06 Functions: 0 1 0.0 %

          Line data    Source code
       1             : #ifdef __PLUMED_HAS_ASMJIT
       2             : // This file is part of AsmJit project <https://asmjit.com>
       3             : //
       4             : // See asmjit.h or LICENSE.md for license and copyright information
       5             : // SPDX-License-Identifier: Zlib
       6             : 
       7             : #ifndef ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
       8             : #define ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
       9             : 
      10             : #include "operand.h"
      11             : #include "support.h"
      12             : #include "type.h"
      13             : 
      14             : ASMJIT_BEGIN_NAMESPACE
      15             : 
      16             : //! \addtogroup asmjit_core
      17             : //! \{
      18             : 
      19             : //! Instruction set architecture (ISA).
      20             : enum class Arch : uint8_t {
      21             :   //! Unknown or uninitialized ISA.
      22             :   kUnknown = 0,
      23             : 
      24             :   //! 32-bit X86 ISA.
      25             :   kX86 = 1,
      26             :   //! 64-bit X86 ISA also known as X64, X86_64, and AMD64.
      27             :   kX64 = 2,
      28             : 
      29             :   //! 32-bit RISC-V ISA.
      30             :   kRISCV32 = 3,
      31             :   //! 64-bit RISC-V ISA.
      32             :   kRISCV64 = 4,
      33             : 
      34             :   //! 32-bit ARM ISA (little endian).
      35             :   kARM = 5,
      36             :   //! 64-bit ARM ISA in (little endian).
      37             :   kAArch64 = 6,
      38             :   //! 32-bit ARM ISA in Thumb mode (little endian).
      39             :   kThumb = 7,
      40             : 
      41             :   // 8 is not used at the moment, even numbers are 64-bit architectures.
      42             : 
      43             :   //! 32-bit MIPS ISA in (little endian).
      44             :   kMIPS32_LE = 9,
      45             :   //! 64-bit MIPS ISA in (little endian).
      46             :   kMIPS64_LE = 10,
      47             : 
      48             :   //! 32-bit ARM ISA (big endian).
      49             :   kARM_BE = 11,
      50             :   //! 64-bit ARM ISA in (big endian).
      51             :   kAArch64_BE = 12,
      52             :   //! 32-bit ARM ISA in Thumb mode (big endian).
      53             :   kThumb_BE = 13,
      54             : 
      55             :   // 14 is not used at the moment, even numbers are 64-bit architectures.
      56             : 
      57             :   //! 32-bit MIPS ISA in (big endian).
      58             :   kMIPS32_BE = 15,
      59             :   //! 64-bit MIPS ISA in (big endian).
      60             :   kMIPS64_BE = 16,
      61             : 
      62             :   //! Maximum value of `Arch`.
      63             :   kMaxValue = kMIPS64_BE,
      64             : 
      65             :   //! Mask used by 32-bit ISAs (odd are 32-bit, even are 64-bit).
      66             :   k32BitMask = 0x01,
      67             :   //! First big-endian architecture.
      68             :   kBigEndian = kARM_BE,
      69             : 
      70             :   //! ISA detected at compile-time (ISA of the host).
      71             :   kHost =
      72             : #if defined(_DOXYGEN)
      73             :     DETECTED_AT_COMPILE_TIME
      74             : #else
      75             :     ASMJIT_ARCH_X86 == 32 ? kX86 :
      76             :     ASMJIT_ARCH_X86 == 64 ? kX64 :
      77             : 
      78             :     ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kARM :
      79             :     ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kARM_BE :
      80             :     ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kAArch64 :
      81             :     ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kAArch64_BE :
      82             : 
      83             :     ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kMIPS32_LE :
      84             :     ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kMIPS32_BE :
      85             :     ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kMIPS64_LE :
      86             :     ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kMIPS64_BE :
      87             : 
      88             :     kUnknown
      89             : #endif
      90             : };
      91             : 
      92             : //! Sub-architecture.
      93             : enum class SubArch : uint8_t {
      94             :   //! Unknown or uninitialized architecture sub-type.
      95             :   kUnknown = 0,
      96             : 
      97             :   //! Maximum value of `SubArch`.
      98             :   kMaxValue = kUnknown,
      99             : 
     100             :   //! Sub-architecture detected at compile-time (sub-architecture of the host).
     101             :   kHost =
     102             : #if defined(_DOXYGEN)
     103             :     DETECTED_AT_COMPILE_TIME
     104             : #else
     105             :     kUnknown
     106             : #endif
     107             : };
     108             : 
     109             : //! Identifier used to represent names of different data types across architectures.
     110             : enum class ArchTypeNameId : uint8_t {
     111             :   //! Describes 'db' (X86/X86_64 convention, always 8-bit quantity).
     112             :   kDB = 0,
     113             :   //! Describes 'dw' (X86/X86_64 convention, always 16-bit word).
     114             :   kDW,
     115             :   //! Describes 'dd' (X86/X86_64 convention, always 32-bit word).
     116             :   kDD,
     117             :   //! Describes 'dq' (X86/X86_64 convention, always 64-bit word).
     118             :   kDQ,
     119             :   //! Describes 'byte' (always 8-bit quantity).
     120             :   kByte,
     121             :   //! Describes 'half' (most likely 16-bit word).
     122             :   kHalf,
     123             :   //! Describes 'word' (either 16-bit or 32-bit word).
     124             :   kWord,
     125             :   //! Describes 'hword' (most likely 16-bit word).
     126             :   kHWord,
     127             :   //! Describes 'dword' (either 32-bit or 64-bit word).
     128             :   kDWord,
     129             :   //! Describes 'qword' (64-bit word).
     130             :   kQWord,
     131             :   //! Describes 'xword' (64-bit word).
     132             :   kXWord,
     133             :   //! Describes 'short' (always 16-bit word).
     134             :   kShort,
     135             :   //! Describes 'long' (most likely 32-bit word).
     136             :   kLong,
     137             :   //! Describes 'quad' (64-bit word).
     138             :   kQuad,
     139             : 
     140             :   //! Maximum value of `ArchTypeNameId`.
     141             :   kMaxValue = kQuad
     142             : };
     143             : 
     144             : //! Instruction feature hints for each register group provided by \ref ArchTraits.
     145             : //!
     146             : //! Instruction feature hints describe miscellaneous instructions provided by the architecture that can be used by
     147             : //! register allocator to make certain things simpler - like register swaps or emitting register push/pop sequences.
     148             : //!
     149             : //! \remarks Instruction feature hints are only defined for register groups that can be used with \ref
     150             : //! asmjit_compiler infrastructure. Register groups that are not managed by Compiler are not provided by
     151             : //! \ref ArchTraits and cannot be queried.
     152             : enum class InstHints : uint8_t {
     153             :   //! No feature hints.
     154             :   kNoHints = 0,
     155             : 
     156             :   //! Architecture supports a register swap by using a single instruction.
     157             :   kRegSwap = 0x01u,
     158             :   //! Architecture provides push/pop instructions.
     159             :   kPushPop = 0x02u
     160             : };
     161             : ASMJIT_DEFINE_ENUM_FLAGS(InstHints)
     162             : 
     163             : //! Architecture traits used by Function API and Compiler's register allocator.
     164             : struct ArchTraits {
     165             :   //! \name Members
     166             :   //! \{
     167             : 
     168             :   //! Stack pointer register id.
     169             :   uint8_t _spRegId;
     170             :   //! Frame pointer register id.
     171             :   uint8_t _fpRegId;
     172             :   //! Link register id.
     173             :   uint8_t _linkRegId;
     174             :   //! Instruction pointer (or program counter) register id, if accessible.
     175             :   uint8_t _ipRegId;
     176             : 
     177             :   // Reserved.
     178             :   uint8_t _reserved[3];
     179             :   //! Hardware stack alignment requirement.
     180             :   uint8_t _hwStackAlignment;
     181             : 
     182             :   //! Minimum addressable offset on stack guaranteed for all instructions.
     183             :   uint32_t _minStackOffset;
     184             :   //! Maximum addressable offset on stack depending on specific instruction.
     185             :   uint32_t _maxStackOffset;
     186             : 
     187             :   //! Flags for each virtual register group.
     188             :   Support::Array<InstHints, Globals::kNumVirtGroups> _instHints;
     189             : 
     190             :   //! Maps register type into a signature, that provides group, size and can be used to construct register operands.
     191             :   Support::Array<OperandSignature, uint32_t(RegType::kMaxValue) + 1> _regSignature;
     192             :   //! Maps a register to type-id, see \ref TypeId.
     193             :   Support::Array<TypeId, uint32_t(RegType::kMaxValue) + 1> _regTypeToTypeId;
     194             :   //! Maps scalar TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref TypeId.
     195             :   Support::Array<RegType, 32> _typeIdToRegType;
     196             : 
     197             :   //! Word name identifiers of 8-bit, 16-bit, 32-biit, and 64-bit quantities that appear in formatted text.
     198             :   ArchTypeNameId _typeNameIdTable[4];
     199             : 
     200             :   //! \}
     201             : 
     202             :   //! \name Accessors
     203             :   //! \{
     204             : 
     205             :   //! Returns stack pointer register id.
     206       82476 :   inline uint32_t spRegId() const noexcept { return _spRegId; }
     207             :   //! Returns stack frame register id.
     208       27492 :   inline uint32_t fpRegId() const noexcept { return _fpRegId; }
     209             :   //! Returns link register id, if the architecture provides it.
     210       27492 :   inline uint32_t linkRegId() const noexcept { return _linkRegId; }
     211             :   //! Returns instruction pointer register id, if the architecture provides it.
     212             :   inline uint32_t ipRegId() const noexcept { return _ipRegId; }
     213             : 
     214             :   //! Returns a hardware stack alignment requirement.
     215             :   //!
     216             :   //! \note This is a hardware constraint. Architectures that don't constrain it would return the lowest alignment
     217             :   //! (1), however, some architectures may constrain the alignment, for example AArch64 requires 16-byte alignment.
     218             :   inline uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; }
     219             : 
     220             :   //! Tests whether the architecture provides link register, which is used across function calls. If the link
     221             :   //! register is not provided then a function call pushes the return address on stack (X86/X64).
     222       27492 :   inline bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
     223             : 
     224             :   //! Returns minimum addressable offset on stack guaranteed for all instructions.
     225             :   inline uint32_t minStackOffset() const noexcept { return _minStackOffset; }
     226             :   //! Returns maximum addressable offset on stack depending on specific instruction.
     227             :   inline uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
     228             : 
     229             :   //! Returns ISA flags of the given register `group`.
     230             :   inline InstHints instFeatureHints(RegGroup group) const noexcept { return _instHints[group]; }
     231             :   //! Tests whether the given register `group` has the given `flag` set.
     232      109968 :   inline bool hasInstHint(RegGroup group, InstHints feature) const noexcept { return Support::test(_instHints[group], feature); }
     233             :   //! Tests whether the ISA provides register swap instruction for the given register `group`.
     234             :   inline bool hasInstRegSwap(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kRegSwap); }
     235             :   //! Tests whether the ISA provides push/pop instructions for the given register `group`.
     236             :   inline bool hasInstPushPop(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kPushPop); }
     237             : 
     238           0 :   inline bool hasRegType(RegType type) const noexcept {
     239           0 :     return type <= RegType::kMaxValue && _regSignature[type].isValid();
     240             :   }
     241             : 
     242             :   //! Returns an operand signature from the given register `type` of this architecture.
     243      356253 :   inline OperandSignature regTypeToSignature(RegType type) const noexcept { return _regSignature[type]; }
     244             :   //! Returns a register from the given register `type` of this architecture.
     245             :   inline RegGroup regTypeToGroup(RegType type) const noexcept { return _regSignature[type].regGroup(); }
     246             :   //! Returns a register size the given register `type` of this architecture.
     247             :   inline uint32_t regTypeToSize(RegType type) const noexcept { return _regSignature[type].size(); }
     248             :   //! Returns a corresponding `TypeId` from the given register `type` of this architecture.
     249           0 :   inline TypeId regTypeToTypeId(RegType type) const noexcept { return _regTypeToTypeId[type]; }
     250             : 
     251             :   //! Returns a table of ISA word names that appear in formatted text. Word names are ISA dependent.
     252             :   //!
     253             :   //! The index of this table is log2 of the size:
     254             :   //!   - [0] 8-bits
     255             :   //!   - [1] 16-bits
     256             :   //!   - [2] 32-bits
     257             :   //!   - [3] 64-bits
     258             :   inline const ArchTypeNameId* typeNameIdTable() const noexcept { return _typeNameIdTable; }
     259             : 
     260             :   //! Returns an ISA word name identifier of the given `index`, see \ref typeNameIdTable() for more details.
     261           0 :   inline ArchTypeNameId typeNameIdByIndex(uint32_t index) const noexcept { return _typeNameIdTable[index]; }
     262             : 
     263             :   //! \}
     264             : 
     265             :   //! \name Statics
     266             :   //! \{
     267             : 
     268             :   //! Returns a const reference to `ArchTraits` for the given architecture `arch`.
     269             :   static inline const ArchTraits& byArch(Arch arch) noexcept;
     270             : 
     271             :   //! \}
     272             : };
     273             : 
     274             : ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1];
     275             : 
     276             : //! \cond
     277      521205 : inline const ArchTraits& ArchTraits::byArch(Arch arch) noexcept { return _archTraits[uint32_t(arch)]; }
     278             : //! \endcond
     279             : 
     280             : //! Architecture utilities.
     281             : namespace ArchUtils {
     282             : 
     283             : ASMJIT_API Error typeIdToRegSignature(Arch arch, TypeId typeId, TypeId* typeIdOut, OperandSignature* regSignatureOut) noexcept;
     284             : 
     285             : } // {ArchUtils}
     286             : 
     287             : //! \}
     288             : 
     289             : ASMJIT_END_NAMESPACE
     290             : 
     291             : #endif // ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
     292             : 
     293             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16