Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2008-2017, Petr Kobalicek 3 : 4 : This software is provided 'as-is', without any express or implied 5 : warranty. In no event will the authors be held liable for any damages 6 : arising from the use of this software. 7 : 8 : Permission is granted to anyone to use this software for any purpose, 9 : including commercial applications, and to alter it and redistribute it 10 : freely, subject to the following restrictions: 11 : 12 : 1. The origin of this software must not be misrepresented; you must not 13 : claim that you wrote the original software. If you use this software 14 : in a product, an acknowledgment in the product documentation would be 15 : appreciated but is not required. 16 : 2. Altered source versions must be plainly marked as such, and must not be 17 : misrepresented as being the original software. 18 : 3. This notice may not be removed or altered from any source distribution. 19 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 20 : #ifndef __PLUMED_asmjit_arch_h 21 : #define __PLUMED_asmjit_arch_h 22 : #ifdef __PLUMED_HAS_ASMJIT 23 : #pragma GCC diagnostic push 24 : #pragma GCC diagnostic ignored "-Wpedantic" 25 : // [AsmJit] 26 : // Complete x86/x64 JIT and Remote Assembler for C++. 27 : // 28 : // [License] 29 : // Zlib - See LICENSE.md file in the package. 30 : 31 : // [Guard] 32 : #ifndef _ASMJIT_BASE_ARCH_H 33 : #define _ASMJIT_BASE_ARCH_H 34 : 35 : // [Dependencies] 36 : #include "./globals.h" 37 : #include "./operand.h" 38 : 39 : // [Api-Begin] 40 : #include "./asmjit_apibegin.h" 41 : 42 : namespace PLMD { 43 : namespace asmjit { 44 : 45 : //! \addtogroup asmjit_base 46 : //! \{ 47 : 48 : // ============================================================================ 49 : // [asmjit::ArchInfo] 50 : // ============================================================================ 51 : 52 : class ArchInfo { 53 : public: 54 : //! Architecture type. 55 : ASMJIT_ENUM(Type) { 56 : kTypeNone = 0, //!< No/Unknown architecture. 57 : 58 : // X86 architectures. 59 : kTypeX86 = 1, //!< X86 architecture (32-bit). 60 : kTypeX64 = 2, //!< X64 architecture (64-bit) (AMD64). 61 : kTypeX32 = 3, //!< X32 architecture (DEAD-END). 62 : 63 : // ARM architectures. 64 : kTypeA32 = 4, //!< ARM 32-bit architecture (AArch32/ARM/THUMB). 65 : kTypeA64 = 5, //!< ARM 64-bit architecture (AArch64). 66 : 67 : //! Architecture detected at compile-time (architecture of the host). 68 : kTypeHost = ASMJIT_ARCH_X86 ? kTypeX86 : 69 : ASMJIT_ARCH_X64 ? kTypeX64 : 70 : ASMJIT_ARCH_ARM32 ? kTypeA32 : 71 : ASMJIT_ARCH_ARM64 ? kTypeA64 : kTypeNone 72 : }; 73 : 74 : //! Architecture sub-type or execution mode. 75 : ASMJIT_ENUM(SubType) { 76 : kSubTypeNone = 0, //!< Default mode (or no specific mode). 77 : 78 : // X86 sub-types. 79 : kSubTypeX86_AVX = 1, //!< Code generation uses AVX by default (VEC instructions). 80 : kSubTypeX86_AVX2 = 2, //!< Code generation uses AVX2 by default (VEC instructions). 81 : kSubTypeX86_AVX512 = 3, //!< Code generation uses AVX-512F by default (+32 vector regs). 82 : kSubTypeX86_AVX512VL = 4, //!< Code generation uses AVX-512F-VL by default (+VL extensions). 83 : 84 : // ARM sub-types. 85 : kSubTypeA32_Thumb = 8, //!< THUMB|THUMB2 sub-type (only ARM in 32-bit mode). 86 : 87 : #if (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX512VL__) 88 : kSubTypeHost = kSubTypeX86_AVX512VL 89 : #elif (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX512F__) 90 : kSubTypeHost = kSubTypeX86_AVX512 91 : #elif (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX2__) 92 : kSubTypeHost = kSubTypeX86_AVX2 93 : #elif (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX__) 94 : kSubTypeHost = kSubTypeX86_AVX 95 : #elif (ASMJIT_ARCH_ARM32) && (defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__)) 96 : kSubTypeHost = kSubTypeA32_Thumb 97 : #else 98 : kSubTypeHost = 0 99 : #endif 100 : }; 101 : 102 : // -------------------------------------------------------------------------- 103 : // [Utilities] 104 : // -------------------------------------------------------------------------- 105 : 106 31516 : static ASMJIT_INLINE bool isX86Family(uint32_t archType) noexcept { return archType >= kTypeX86 && archType <= kTypeX32; } 107 : static ASMJIT_INLINE bool isArmFamily(uint32_t archType) noexcept { return archType >= kTypeA32 && archType <= kTypeA64; } 108 : 109 : // -------------------------------------------------------------------------- 110 : // [Construction / Destruction] 111 : // -------------------------------------------------------------------------- 112 : 113 7873 : ASMJIT_INLINE ArchInfo() noexcept : _signature(0) {} 114 : ASMJIT_INLINE ArchInfo(const ArchInfo& other) noexcept = default; 115 : explicit ASMJIT_INLINE ArchInfo(uint32_t type, uint32_t subType = kSubTypeNone) noexcept { init(type, subType); } 116 : 117 : ASMJIT_INLINE static ArchInfo host() noexcept { return ArchInfo(kTypeHost, kSubTypeHost); } 118 : 119 : // -------------------------------------------------------------------------- 120 : // [Init / Reset] 121 : // -------------------------------------------------------------------------- 122 : 123 : ASMJIT_INLINE bool isInitialized() const noexcept { return _type != kTypeNone; } 124 : 125 : ASMJIT_API void init(uint32_t type, uint32_t subType = kSubTypeNone) noexcept; 126 1944 : ASMJIT_INLINE void reset() noexcept { _signature = 0; } 127 : 128 : // -------------------------------------------------------------------------- 129 : // [Accessors] 130 : // -------------------------------------------------------------------------- 131 : 132 : //! Get if the architecture is 32-bit. 133 0 : ASMJIT_INLINE bool is32Bit() const noexcept { return _gpSize == 4; } 134 : //! Get if the architecture is 64-bit. 135 0 : ASMJIT_INLINE bool is64Bit() const noexcept { return _gpSize == 8; } 136 : 137 : //! Get architecture type, see \ref Type. 138 31516 : ASMJIT_INLINE uint32_t getType() const noexcept { return _type; } 139 : 140 : //! Get architecture sub-type, see \ref SubType. 141 : //! 142 : //! X86 & X64 143 : //! --------- 144 : //! 145 : //! Architecture subtype describe the highest instruction-set level that can 146 : //! be used. 147 : //! 148 : //! ARM32 149 : //! ----- 150 : //! 151 : //! Architecture mode means the instruction encoding to be used when generating 152 : //! machine code, thus mode can be used to force generation of THUMB and THUMB2 153 : //! encoding or regular ARM encoding. 154 : //! 155 : //! ARM64 156 : //! ----- 157 : //! 158 : //! No meaning yet. 159 : ASMJIT_INLINE uint32_t getSubType() const noexcept { return _subType; } 160 : 161 : //! Get if the architecture is X86, X64, or X32. 162 3888 : ASMJIT_INLINE bool isX86Family() const noexcept { return isX86Family(_type); } 163 : //! Get if the architecture is ARM32 or ARM64. 164 : ASMJIT_INLINE bool isArmFamily() const noexcept { return isArmFamily(_type); } 165 : 166 : //! Get a size of a general-purpose register. 167 1944 : ASMJIT_INLINE uint32_t getGpSize() const noexcept { return _gpSize; } 168 : //! Get number of general-purpose registers. 169 : ASMJIT_INLINE uint32_t getGpCount() const noexcept { return _gpCount; } 170 : 171 : // -------------------------------------------------------------------------- 172 : // [Operator Overload] 173 : // -------------------------------------------------------------------------- 174 : 175 : ASMJIT_INLINE ArchInfo& operator=(const ArchInfo& other) noexcept = default; 176 : ASMJIT_INLINE bool operator==(const ArchInfo& other) const noexcept { return _signature == other._signature; } 177 : ASMJIT_INLINE bool operator!=(const ArchInfo& other) const noexcept { return _signature != other._signature; } 178 : 179 : // -------------------------------------------------------------------------- 180 : // [Members] 181 : // -------------------------------------------------------------------------- 182 : 183 : union { 184 : struct { 185 : uint8_t _type; //!< Architecture type. 186 : uint8_t _subType; //!< Architecture sub-type. 187 : uint8_t _gpSize; //!< Default size of a general purpose register. 188 : uint8_t _gpCount; //!< Count of all general purpose registers. 189 : }; 190 : uint32_t _signature; //!< Architecture signature (32-bit int). 191 : }; 192 : }; 193 : 194 : // ============================================================================ 195 : // [asmjit::ArchRegs] 196 : // ============================================================================ 197 : 198 : //! Information about all architecture registers. 199 : struct ArchRegs { 200 : //! Register information and signatures indexed by \ref Reg::Type. 201 : RegInfo regInfo[Reg::kRegMax + 1]; 202 : //! Count (maximum) of registers per \ref Reg::Type. 203 : uint8_t regCount[Reg::kRegMax + 1]; 204 : //! Converts RegType to TypeId, see \ref TypeId::Id. 205 : uint8_t regTypeToTypeId[Reg::kRegMax + 1]; 206 : }; 207 : 208 : // ============================================================================ 209 : // [asmjit::ArchUtils] 210 : // ============================================================================ 211 : 212 : struct ArchUtils { 213 : ASMJIT_API static Error typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept; 214 : }; 215 : 216 : //! \} 217 : 218 : } // asmjit namespace 219 : } // namespace PLMD 220 : 221 : // [Api-End] 222 : #include "./asmjit_apiend.h" 223 : 224 : // [Guard] 225 : #endif // _ASMJIT_BASE_ARCH_H 226 : #pragma GCC diagnostic pop 227 : #endif // __PLUMED_HAS_ASMJIT 228 : #endif