LCOV - code coverage report
Current view: top level - asmjit - x86compiler.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 4 6 66.7 %
Date: 2024-10-18 14:00:27 Functions: 0 2 0.0 %

          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_x86compiler_h
      21             : #define __PLUMED_asmjit_x86compiler_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_X86_X86COMPILER_H
      33             : #define _ASMJIT_X86_X86COMPILER_H
      34             : 
      35             : #include "./asmjit_build.h"
      36             : #if !defined(ASMJIT_DISABLE_COMPILER)
      37             : 
      38             : // [Dependencies]
      39             : #include "./codecompiler.h"
      40             : #include "./simdtypes.h"
      41             : #include "./x86emitter.h"
      42             : #include "./x86misc.h"
      43             : 
      44             : // [Api-Begin]
      45             : #include "./asmjit_apibegin.h"
      46             : 
      47             : namespace PLMD {
      48             : namespace asmjit {
      49             : 
      50             : //! \addtogroup asmjit_x86
      51             : //! \{
      52             : 
      53             : // ============================================================================
      54             : // [asmjit::X86Compiler]
      55             : // ============================================================================
      56             : 
      57             : //! Architecture-dependent \ref CodeCompiler targeting X86 and X64.
      58             : class ASMJIT_VIRTAPI X86Compiler
      59             :   : public CodeCompiler,
      60             :     public X86EmitterExplicitT<X86Compiler> {
      61             : 
      62             : public:
      63             :   ASMJIT_NONCOPYABLE(X86Compiler)
      64             :   typedef CodeCompiler Base;
      65             : 
      66             :   // --------------------------------------------------------------------------
      67             :   // [Construction / Destruction]
      68             :   // --------------------------------------------------------------------------
      69             : 
      70             :   //! Create a `X86Compiler` instance.
      71             :   ASMJIT_API X86Compiler(CodeHolder* code = nullptr) noexcept;
      72             :   //! Destroy the `X86Compiler` instance.
      73             :   ASMJIT_API ~X86Compiler() noexcept;
      74             : 
      75             :   // --------------------------------------------------------------------------
      76             :   // [Compatibility]
      77             :   // --------------------------------------------------------------------------
      78             : 
      79             :   //! Explicit cast to `X86Emitter`.
      80             :   ASMJIT_INLINE X86Emitter* asEmitter() noexcept { return reinterpret_cast<X86Emitter*>(this); }
      81             :   //! Explicit cast to `X86Emitter` (const).
      82             :   ASMJIT_INLINE const X86Emitter* asEmitter() const noexcept { return reinterpret_cast<const X86Emitter*>(this); }
      83             : 
      84             :   //! Implicit cast to `X86Emitter`.
      85             :   ASMJIT_INLINE operator X86Emitter&() noexcept { return *asEmitter(); }
      86             :   //! Implicit cast to `X86Emitter` (const).
      87             :   ASMJIT_INLINE operator const X86Emitter&() const noexcept { return *asEmitter(); }
      88             : 
      89             :   // --------------------------------------------------------------------------
      90             :   // [Events]
      91             :   // --------------------------------------------------------------------------
      92             : 
      93             :   ASMJIT_API virtual Error onAttach(CodeHolder* code) noexcept override;
      94             : 
      95             :   // --------------------------------------------------------------------------
      96             :   // [Code-Generation]
      97             :   // --------------------------------------------------------------------------
      98             : 
      99             :   ASMJIT_API virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override;
     100             :   ASMJIT_API virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override;
     101             : 
     102             :   // -------------------------------------------------------------------------
     103             :   // [Finalize]
     104             :   // -------------------------------------------------------------------------
     105             : 
     106             :   ASMJIT_API virtual Error finalize() override;
     107             : 
     108             :   // --------------------------------------------------------------------------
     109             :   // [VirtReg]
     110             :   // --------------------------------------------------------------------------
     111             : 
     112             : #if !defined(ASMJIT_DISABLE_LOGGING)
     113             : #define ASMJIT_NEW_REG(OUT, PARAM, NAME_FMT)            \
     114             :   va_list ap;                                           \
     115             :   va_start(ap, NAME_FMT);                               \
     116             :   _newReg(OUT, PARAM, NAME_FMT, ap);                    \
     117             :   va_end(ap)
     118             : #else
     119             : #define ASMJIT_NEW_REG(OUT, PARAM, NAME_FMT)            \
     120             :   ASMJIT_UNUSED(NAME_FMT);                              \
     121             :   _newReg(OUT, PARAM, nullptr)
     122             : #endif
     123             : 
     124             : #define ASMJIT_NEW_REG_USER(FUNC, REG)                  \
     125             :   ASMJIT_INLINE REG FUNC(uint32_t typeId) {             \
     126             :     REG reg(NoInit);                                    \
     127             :     _newReg(reg, typeId, nullptr);                      \
     128             :     return reg;                                         \
     129             :   }                                                     \
     130             :                                                         \
     131             :   REG FUNC(uint32_t typeId, const char* nameFmt, ...) { \
     132             :     REG reg(NoInit);                                    \
     133             :     ASMJIT_NEW_REG(reg, typeId, nameFmt);               \
     134             :     return reg;                                         \
     135             :   }
     136             : 
     137             : #define ASMJIT_NEW_REG_AUTO(FUNC, REG, TYPE_ID)         \
     138             :   ASMJIT_INLINE REG FUNC() {                            \
     139             :     REG reg(NoInit);                                    \
     140             :     _newReg(reg, TYPE_ID, nullptr);                     \
     141             :     return reg;                                         \
     142             :   }                                                     \
     143             :                                                         \
     144             :   REG FUNC(const char* nameFmt, ...) {                  \
     145             :     REG reg(NoInit);                                    \
     146             :     ASMJIT_NEW_REG(reg, TYPE_ID, nameFmt);              \
     147             :     return reg;                                         \
     148             :   }
     149             : 
     150             :   template<typename RegT>
     151             :   ASMJIT_INLINE RegT newSimilarReg(const RegT& ref) {
     152             :     RegT reg(NoInit);
     153             :     _newReg(reg, ref, nullptr);
     154             :     return reg;
     155             :   }
     156             : 
     157             :   template<typename RegT>
     158             :   RegT newSimilarReg(const RegT& ref, const char* nameFmt, ...) {
     159             :     RegT reg(NoInit);
     160             :     ASMJIT_NEW_REG(reg, ref, nameFmt);
     161             :     return reg;
     162             :   }
     163             : 
     164           0 :   ASMJIT_NEW_REG_USER(newReg    , X86Reg )
     165             :   ASMJIT_NEW_REG_USER(newGpReg  , X86Gp  )
     166             :   ASMJIT_NEW_REG_USER(newMmReg  , X86Mm  )
     167             :   ASMJIT_NEW_REG_USER(newKReg   , X86KReg)
     168             :   ASMJIT_NEW_REG_USER(newXmmReg , X86Xmm )
     169             :   ASMJIT_NEW_REG_USER(newYmmReg , X86Ymm )
     170             :   ASMJIT_NEW_REG_USER(newZmmReg , X86Zmm )
     171             : 
     172             :   ASMJIT_NEW_REG_AUTO(newI8     , X86Gp  , TypeId::kI8     )
     173             :   ASMJIT_NEW_REG_AUTO(newU8     , X86Gp  , TypeId::kU8     )
     174             :   ASMJIT_NEW_REG_AUTO(newI16    , X86Gp  , TypeId::kI16    )
     175             :   ASMJIT_NEW_REG_AUTO(newU16    , X86Gp  , TypeId::kU16    )
     176             :   ASMJIT_NEW_REG_AUTO(newI32    , X86Gp  , TypeId::kI32    )
     177             :   ASMJIT_NEW_REG_AUTO(newU32    , X86Gp  , TypeId::kU32    )
     178             :   ASMJIT_NEW_REG_AUTO(newI64    , X86Gp  , TypeId::kI64    )
     179             :   ASMJIT_NEW_REG_AUTO(newU64    , X86Gp  , TypeId::kU64    )
     180             :   ASMJIT_NEW_REG_AUTO(newInt8   , X86Gp  , TypeId::kI8     )
     181             :   ASMJIT_NEW_REG_AUTO(newUInt8  , X86Gp  , TypeId::kU8     )
     182             :   ASMJIT_NEW_REG_AUTO(newInt16  , X86Gp  , TypeId::kI16    )
     183             :   ASMJIT_NEW_REG_AUTO(newUInt16 , X86Gp  , TypeId::kU16    )
     184             :   ASMJIT_NEW_REG_AUTO(newInt32  , X86Gp  , TypeId::kI32    )
     185             :   ASMJIT_NEW_REG_AUTO(newUInt32 , X86Gp  , TypeId::kU32    )
     186             :   ASMJIT_NEW_REG_AUTO(newInt64  , X86Gp  , TypeId::kI64    )
     187             :   ASMJIT_NEW_REG_AUTO(newUInt64 , X86Gp  , TypeId::kU64    )
     188      105486 :   ASMJIT_NEW_REG_AUTO(newIntPtr , X86Gp  , TypeId::kIntPtr )
     189             :   ASMJIT_NEW_REG_AUTO(newUIntPtr, X86Gp  , TypeId::kUIntPtr)
     190             : 
     191             :   ASMJIT_NEW_REG_AUTO(newGpb    , X86Gp  , TypeId::kU8     )
     192             :   ASMJIT_NEW_REG_AUTO(newGpw    , X86Gp  , TypeId::kU16    )
     193             :   ASMJIT_NEW_REG_AUTO(newGpd    , X86Gp  , TypeId::kU32    )
     194             :   ASMJIT_NEW_REG_AUTO(newGpq    , X86Gp  , TypeId::kU64    )
     195           0 :   ASMJIT_NEW_REG_AUTO(newGpz    , X86Gp  , TypeId::kUIntPtr)
     196             :   ASMJIT_NEW_REG_AUTO(newKb     , X86KReg, TypeId::kMask8  )
     197             :   ASMJIT_NEW_REG_AUTO(newKw     , X86KReg, TypeId::kMask16 )
     198             :   ASMJIT_NEW_REG_AUTO(newKd     , X86KReg, TypeId::kMask32 )
     199             :   ASMJIT_NEW_REG_AUTO(newKq     , X86KReg, TypeId::kMask64 )
     200             :   ASMJIT_NEW_REG_AUTO(newMm     , X86Mm  , TypeId::kMmx64  )
     201             :   ASMJIT_NEW_REG_AUTO(newXmm    , X86Xmm , TypeId::kI32x4  )
     202             :   ASMJIT_NEW_REG_AUTO(newXmmSs  , X86Xmm , TypeId::kF32x1  )
     203      212326 :   ASMJIT_NEW_REG_AUTO(newXmmSd  , X86Xmm , TypeId::kF64x1  )
     204             :   ASMJIT_NEW_REG_AUTO(newXmmPs  , X86Xmm , TypeId::kF32x4  )
     205             :   ASMJIT_NEW_REG_AUTO(newXmmPd  , X86Xmm , TypeId::kF64x2  )
     206             :   ASMJIT_NEW_REG_AUTO(newYmm    , X86Ymm , TypeId::kI32x8  )
     207             :   ASMJIT_NEW_REG_AUTO(newYmmPs  , X86Ymm , TypeId::kF32x8  )
     208             :   ASMJIT_NEW_REG_AUTO(newYmmPd  , X86Ymm , TypeId::kF64x4  )
     209             :   ASMJIT_NEW_REG_AUTO(newZmm    , X86Zmm , TypeId::kI32x16 )
     210             :   ASMJIT_NEW_REG_AUTO(newZmmPs  , X86Zmm , TypeId::kF32x16 )
     211             :   ASMJIT_NEW_REG_AUTO(newZmmPd  , X86Zmm , TypeId::kF64x8  )
     212             : 
     213             : #undef ASMJIT_NEW_REG_AUTO
     214             : #undef ASMJIT_NEW_REG_USER
     215             : #undef ASMJIT_NEW_REG
     216             : 
     217             :   // --------------------------------------------------------------------------
     218             :   // [Stack]
     219             :   // --------------------------------------------------------------------------
     220             : 
     221             :   //! Create a new memory chunk allocated on the current function's stack.
     222             :   ASMJIT_INLINE X86Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
     223             :     X86Mem m(NoInit);
     224             :     _newStack(m, size, alignment, name);
     225             :     return m;
     226             :   }
     227             : 
     228             :   // --------------------------------------------------------------------------
     229             :   // [Const]
     230             :   // --------------------------------------------------------------------------
     231             : 
     232             :   //! Put data to a constant-pool and get a memory reference to it.
     233             :   ASMJIT_INLINE X86Mem newConst(uint32_t scope, const void* data, size_t size) {
     234             :     X86Mem m(NoInit);
     235             :     _newConst(m, scope, data, size);
     236             :     return m;
     237             :   }
     238             : 
     239             :   //! Put a BYTE `val` to a constant-pool.
     240             :   ASMJIT_INLINE X86Mem newByteConst(uint32_t scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
     241             :   //! Put a WORD `val` to a constant-pool.
     242             :   ASMJIT_INLINE X86Mem newWordConst(uint32_t scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
     243             :   //! Put a DWORD `val` to a constant-pool.
     244             :   ASMJIT_INLINE X86Mem newDWordConst(uint32_t scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
     245             :   //! Put a QWORD `val` to a constant-pool.
     246             :   ASMJIT_INLINE X86Mem newQWordConst(uint32_t scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
     247             : 
     248             :   //! Put a WORD `val` to a constant-pool.
     249             :   ASMJIT_INLINE X86Mem newInt16Const(uint32_t scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
     250             :   //! Put a WORD `val` to a constant-pool.
     251             :   ASMJIT_INLINE X86Mem newUInt16Const(uint32_t scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
     252             :   //! Put a DWORD `val` to a constant-pool.
     253             :   ASMJIT_INLINE X86Mem newInt32Const(uint32_t scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
     254             :   //! Put a DWORD `val` to a constant-pool.
     255             :   ASMJIT_INLINE X86Mem newUInt32Const(uint32_t scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
     256             :   //! Put a QWORD `val` to a constant-pool.
     257             :   ASMJIT_INLINE X86Mem newInt64Const(uint32_t scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
     258             :   //! Put a QWORD `val` to a constant-pool.
     259             :   ASMJIT_INLINE X86Mem newUInt64Const(uint32_t scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
     260             : 
     261             :   //! Put a SP-FP `val` to a constant-pool.
     262             :   ASMJIT_INLINE X86Mem newFloatConst(uint32_t scope, float val) noexcept { return newConst(scope, &val, 4); }
     263             :   //! Put a DP-FP `val` to a constant-pool.
     264             :   ASMJIT_INLINE X86Mem newDoubleConst(uint32_t scope, double val) noexcept { return newConst(scope, &val, 8); }
     265             : 
     266             :   //! Put a MMX `val` to a constant-pool.
     267             :   ASMJIT_INLINE X86Mem newMmConst(uint32_t scope, const Data64& val) noexcept { return newConst(scope, &val, 8); }
     268             :   //! Put a XMM `val` to a constant-pool.
     269             :   ASMJIT_INLINE X86Mem newXmmConst(uint32_t scope, const Data128& val) noexcept { return newConst(scope, &val, 16); }
     270             :   //! Put a YMM `val` to a constant-pool.
     271             :   ASMJIT_INLINE X86Mem newYmmConst(uint32_t scope, const Data256& val) noexcept { return newConst(scope, &val, 32); }
     272             : 
     273             :   // -------------------------------------------------------------------------
     274             :   // [Instruction Options]
     275             :   // -------------------------------------------------------------------------
     276             : 
     277             :   //! Force the compiler to not follow the conditional or unconditional jump.
     278             :   ASMJIT_INLINE X86Compiler& unfollow() noexcept { _options |= kOptionUnfollow; return *this; }
     279             :   //! Tell the compiler that the destination variable will be overwritten.
     280             :   ASMJIT_INLINE X86Compiler& overwrite() noexcept { _options |= kOptionOverwrite; return *this; }
     281             : 
     282             :   // --------------------------------------------------------------------------
     283             :   // [Emit]
     284             :   // --------------------------------------------------------------------------
     285             : 
     286             :   //! Call a function.
     287       13122 :   ASMJIT_INLINE CCFuncCall* call(const X86Gp& dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, dst, sign); }
     288             :   //! \overload
     289             :   ASMJIT_INLINE CCFuncCall* call(const X86Mem& dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, dst, sign); }
     290             :   //! \overload
     291             :   ASMJIT_INLINE CCFuncCall* call(const Label& label, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, label, sign); }
     292             :   //! \overload
     293             :   ASMJIT_INLINE CCFuncCall* call(const Imm& dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, dst, sign); }
     294             :   //! \overload
     295             :   ASMJIT_INLINE CCFuncCall* call(uint64_t dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, Imm(dst), sign); }
     296             : 
     297             :   //! Return.
     298             :   ASMJIT_INLINE CCFuncRet* ret() { return addRet(Operand(), Operand()); }
     299             :   //! \overload
     300             :   ASMJIT_INLINE CCFuncRet* ret(const X86Gp& o0) { return addRet(o0, Operand()); }
     301             :   //! \overload
     302             :   ASMJIT_INLINE CCFuncRet* ret(const X86Gp& o0, const X86Gp& o1) { return addRet(o0, o1); }
     303             :   //! \overload
     304       32111 :   ASMJIT_INLINE CCFuncRet* ret(const X86Xmm& o0) { return addRet(o0, Operand()); }
     305             :   //! \overload
     306             :   ASMJIT_INLINE CCFuncRet* ret(const X86Xmm& o0, const X86Xmm& o1) { return addRet(o0, o1); }
     307             : };
     308             : 
     309             : //! \}
     310             : 
     311             : } // asmjit namespace
     312             : } // namespace PLMD
     313             : 
     314             : // [Api-End]
     315             : #include "./asmjit_apiend.h"
     316             : 
     317             : // [Guard]
     318             : #endif // !ASMJIT_DISABLE_COMPILER
     319             : #endif // _ASMJIT_X86_X86COMPILER_H
     320             : #pragma GCC diagnostic pop
     321             : #endif // __PLUMED_HAS_ASMJIT
     322             : #endif

Generated by: LCOV version 1.16