LCOV - code coverage report
Current view: top level - asmjit - codeemitter.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 9 11 81.8 %
Date: 2024-10-11 08:09:49 Functions: 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_codeemitter_h
      21             : #define __PLUMED_asmjit_codeemitter_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_CODEEMITTER_H
      33             : #define _ASMJIT_BASE_CODEEMITTER_H
      34             : 
      35             : // [Dependencies]
      36             : #include "./arch.h"
      37             : #include "./codeholder.h"
      38             : #include "./operand.h"
      39             : 
      40             : // [Api-Begin]
      41             : #include "./asmjit_apibegin.h"
      42             : 
      43             : namespace PLMD {
      44             : namespace asmjit {
      45             : 
      46             : //! \addtogroup asmjit_base
      47             : //! \{
      48             : 
      49             : // ============================================================================
      50             : // [Forward Declarations]
      51             : // ============================================================================
      52             : 
      53             : class ConstPool;
      54             : 
      55             : // ============================================================================
      56             : // [asmjit::CodeEmitter]
      57             : // ============================================================================
      58             : 
      59             : //! Provides a base foundation to emit code - specialized by \ref Assembler and
      60             : //! \ref CodeBuilder.
      61             : class ASMJIT_VIRTAPI CodeEmitter {
      62             : public:
      63             :   //! CodeEmitter type.
      64             :   ASMJIT_ENUM(Type) {
      65             :     kTypeNone       = 0,
      66             :     kTypeAssembler  = 1,
      67             :     kTypeBuilder    = 2,
      68             :     kTypeCompiler   = 3,
      69             :     kTypeCount      = 4
      70             :   };
      71             : 
      72             :   //! CodeEmitter hints - global settings that affect machine-code generation.
      73             :   ASMJIT_ENUM(Hints) {
      74             :     //! Emit optimized code-alignment sequences.
      75             :     //!
      76             :     //! Default `true`.
      77             :     //!
      78             :     //! X86/X64 Specific
      79             :     //! ----------------
      80             :     //!
      81             :     //! Default align sequence used by X86/X64 architecture is one-byte (0x90)
      82             :     //! opcode that is often shown by disassemblers as nop. However there are
      83             :     //! more optimized align sequences for 2-11 bytes that may execute faster.
      84             :     //! If this feature is enabled AsmJit will generate specialized sequences
      85             :     //! for alignment between 2 to 11 bytes.
      86             :     kHintOptimizedAlign = 0x00000001U,
      87             : 
      88             :     //! Emit jump-prediction hints.
      89             :     //!
      90             :     //! Default `false`.
      91             :     //!
      92             :     //! X86/X64 Specific
      93             :     //! ----------------
      94             :     //!
      95             :     //! Jump prediction is usually based on the direction of the jump. If the
      96             :     //! jump is backward it is usually predicted as taken; and if the jump is
      97             :     //! forward it is usually predicted as not-taken. The reason is that loops
      98             :     //! generally use backward jumps and conditions usually use forward jumps.
      99             :     //! However this behavior can be overridden by using instruction prefixes.
     100             :     //! If this option is enabled these hints will be emitted.
     101             :     //!
     102             :     //! This feature is disabled by default, because the only processor that
     103             :     //! used to take into consideration prediction hints was P4. Newer processors
     104             :     //! implement heuristics for branch prediction that ignores any static hints.
     105             :     kHintPredictedJumps = 0x00000002U
     106             :   };
     107             : 
     108             :   //! CodeEmitter options that are merged with instruction options.
     109             :   ASMJIT_ENUM(Options) {
     110             :     //! Reserved, used to check for errors in `Assembler::_emit()`. In addition,
     111             :     //! if an emitter is in error state it will have `kOptionMaybeFailureCase`
     112             :     //! set
     113             :     kOptionMaybeFailureCase = 0x00000001U,
     114             : 
     115             :     //! Perform a strict validation before the instruction is emitted.
     116             :     kOptionStrictValidation = 0x00000002U,
     117             : 
     118             :     //! Logging is enabled and `CodeHolder::getLogger()` should return a valid
     119             :     //! \ref Logger pointer.
     120             :     kOptionLoggingEnabled   = 0x00000004U,
     121             : 
     122             :     //! Mask of all internal options that are not used to represent instruction
     123             :     //! options, but are used to instrument Assembler and CodeBuilder. These
     124             :     //! options are internal and should not be used outside of AsmJit itself.
     125             :     //!
     126             :     //! NOTE: Reserved options should never appear in `CBInst` options.
     127             :     kOptionReservedMask = 0x00000007U,
     128             : 
     129             :     //! Used only by Assembler to mark `_op4` and `_op5` are used.
     130             :     kOptionOp4Op5Used = 0x00000008U,
     131             : 
     132             :     //! Prevents following a jump during compilation (CodeCompiler).
     133             :     kOptionUnfollow = 0x00000010U,
     134             : 
     135             :     //! Overwrite the destination operand (CodeCompiler).
     136             :     //!
     137             :     //! Hint that is important for register liveness analysis. It tells the
     138             :     //! compiler that the destination operand will be overwritten now or by
     139             :     //! adjacent instructions. CodeCompiler knows when a register is completely
     140             :     //! overwritten by a single instruction, for example you don't have to
     141             :     //! mark "movaps" or "pxor x, x", however, if a pair of instructions is
     142             :     //! used and the first of them doesn't completely overwrite the content
     143             :     //! of the destination, CodeCompiler fails to mark that register as dead.
     144             :     //!
     145             :     //! X86/X64 Specific
     146             :     //! ----------------
     147             :     //!
     148             :     //!   - All instructions that always overwrite at least the size of the
     149             :     //!     register the virtual-register uses , for example "mov", "movq",
     150             :     //!     "movaps" don't need the overwrite option to be used - conversion,
     151             :     //!     shuffle, and other miscellaneous instructions included.
     152             :     //!
     153             :     //!   - All instructions that clear the destination register if all operands
     154             :     //!     are the same, for example "xor x, x", "pcmpeqb x x", etc...
     155             :     //!
     156             :     //!   - Consecutive instructions that partially overwrite the variable until
     157             :     //!     there is no old content require the `overwrite()` to be used. Some
     158             :     //!     examples (not always the best use cases thought):
     159             :     //!
     160             :     //!     - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa
     161             :     //!     - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa
     162             :     //!     - `mov al, ?` followed by `and ax, 0xFF`
     163             :     //!     - `mov al, ?` followed by `mov ah, al`
     164             :     //!     - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1`
     165             :     //!
     166             :     //!   - If allocated variable is used temporarily for scalar operations. For
     167             :     //!     example if you allocate a full vector like `X86Compiler::newXmm()`
     168             :     //!     and then use that vector for scalar operations you should use
     169             :     //!     `overwrite()` directive:
     170             :     //!
     171             :     //!     - `sqrtss x, y` - only LO element of `x` is changed, if you don't use
     172             :     //!       HI elements, use `X86Compiler.overwrite().sqrtss(x, y)`.
     173             :     kOptionOverwrite = 0x00000020U
     174             :   };
     175             : 
     176             :   // --------------------------------------------------------------------------
     177             :   // [Construction / Destruction]
     178             :   // --------------------------------------------------------------------------
     179             : 
     180             :   ASMJIT_API CodeEmitter(uint32_t type) noexcept;
     181             :   ASMJIT_API virtual ~CodeEmitter() noexcept;
     182             : 
     183             :   // --------------------------------------------------------------------------
     184             :   // [Events]
     185             :   // --------------------------------------------------------------------------
     186             : 
     187             :   //! Called after the \ref CodeEmitter was attached to the \ref CodeHolder.
     188             :   virtual Error onAttach(CodeHolder* code) noexcept = 0;
     189             :   //! Called after the \ref CodeEmitter was detached from the \ref CodeHolder.
     190             :   virtual Error onDetach(CodeHolder* code) noexcept = 0;
     191             : 
     192             :   // --------------------------------------------------------------------------
     193             :   // [Code-Generation]
     194             :   // --------------------------------------------------------------------------
     195             : 
     196             :   //! Emit instruction having max 4 operands.
     197             :   virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) = 0;
     198             :   //! Emit instruction having max 6 operands.
     199             :   virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) = 0;
     200             :   //! Emit instruction having operands stored in array.
     201             :   virtual Error _emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount);
     202             : 
     203             :   //! Create a new label.
     204             :   virtual Label newLabel() = 0;
     205             :   //! Create a new named label.
     206             :   virtual Label newNamedLabel(
     207             :     const char* name,
     208             :     size_t nameLength = Globals::kInvalidIndex,
     209             :     uint32_t type = Label::kTypeGlobal,
     210             :     uint32_t parentId = 0) = 0;
     211             : 
     212             :   //! Get a label by name.
     213             :   //!
     214             :   //! Returns invalid Label in case that the name is invalid or label was not found.
     215             :   //!
     216             :   //! NOTE: This function doesn't trigger ErrorHandler in case the name is
     217             :   //! invalid or no such label exist. You must always check the validity of the
     218             :   //! \ref Label returned.
     219             :   ASMJIT_API Label getLabelByName(
     220             :     const char* name,
     221             :     size_t nameLength = Globals::kInvalidIndex,
     222             :     uint32_t parentId = 0) noexcept;
     223             : 
     224             :   //! Bind the `label` to the current position of the current section.
     225             :   //!
     226             :   //! NOTE: Attempt to bind the same label multiple times will return an error.
     227             :   virtual Error bind(const Label& label) = 0;
     228             : 
     229             :   //! Align to the `alignment` specified.
     230             :   //!
     231             :   //! The sequence that is used to fill the gap between the aligned location
     232             :   //! and the current location depends on the align `mode`, see \ref AlignMode.
     233             :   virtual Error align(uint32_t mode, uint32_t alignment) = 0;
     234             : 
     235             :   //! Embed raw data into the code-buffer.
     236             :   virtual Error embed(const void* data, uint32_t size) = 0;
     237             : 
     238             :   //! Embed absolute label address as data (4 or 8 bytes).
     239             :   virtual Error embedLabel(const Label& label) = 0;
     240             : 
     241             :   //! Embed a constant pool into the code-buffer in the following steps:
     242             :   //!   1. Align by using kAlignData to the minimum `pool` alignment.
     243             :   //!   2. Bind `label` so it's bound to an aligned location.
     244             :   //!   3. Emit constant pool data.
     245             :   virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0;
     246             : 
     247             :   //! Emit a comment string `s` with an optional `len` parameter.
     248             :   virtual Error comment(const char* s, size_t len = Globals::kInvalidIndex) = 0;
     249             : 
     250             :   // --------------------------------------------------------------------------
     251             :   // [Code-Generation Status]
     252             :   // --------------------------------------------------------------------------
     253             : 
     254             :   //! Get if the CodeEmitter is initialized (i.e. attached to a \ref CodeHolder).
     255             :   ASMJIT_INLINE bool isInitialized() const noexcept { return _code != nullptr; }
     256             : 
     257             :   ASMJIT_API virtual Error finalize();
     258             : 
     259             :   // --------------------------------------------------------------------------
     260             :   // [Code Information]
     261             :   // --------------------------------------------------------------------------
     262             : 
     263             :   //! Get information about the code, see \ref CodeInfo.
     264             :   ASMJIT_INLINE const CodeInfo& getCodeInfo() const noexcept { return _codeInfo; }
     265             :   //! Get \ref CodeHolder this CodeEmitter is attached to.
     266           0 :   ASMJIT_INLINE CodeHolder* getCode() const noexcept { return _code; }
     267             : 
     268             :   //! Get information about the architecture, see \ref ArchInfo.
     269             :   ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _codeInfo.getArchInfo(); }
     270             : 
     271             :   //! Get if the target architecture is 32-bit.
     272             :   ASMJIT_INLINE bool is32Bit() const noexcept { return getArchInfo().is32Bit(); }
     273             :   //! Get if the target architecture is 64-bit.
     274             :   ASMJIT_INLINE bool is64Bit() const noexcept { return getArchInfo().is64Bit(); }
     275             : 
     276             :   //! Get the target architecture type.
     277             :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return getArchInfo().getType(); }
     278             :   //! Get the target architecture sub-type.
     279             :   ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return getArchInfo().getSubType(); }
     280             :   //! Get the target architecture's GP register size (4 or 8 bytes).
     281             :   ASMJIT_INLINE uint32_t getGpSize() const noexcept { return getArchInfo().getGpSize(); }
     282             :   //! Get the number of target GP registers.
     283             :   ASMJIT_INLINE uint32_t getGpCount() const noexcept { return getArchInfo().getGpCount(); }
     284             : 
     285             :   // --------------------------------------------------------------------------
     286             :   // [Code-Emitter Type]
     287             :   // --------------------------------------------------------------------------
     288             : 
     289             :   //! Get the type of this CodeEmitter, see \ref Type.
     290        7776 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
     291             : 
     292             :   ASMJIT_INLINE bool isAssembler() const noexcept { return _type == kTypeAssembler; }
     293             :   ASMJIT_INLINE bool isCodeBuilder() const noexcept { return _type == kTypeBuilder; }
     294             :   ASMJIT_INLINE bool isCodeCompiler() const noexcept { return _type == kTypeCompiler; }
     295             : 
     296             :   // --------------------------------------------------------------------------
     297             :   // [Global Information]
     298             :   // --------------------------------------------------------------------------
     299             : 
     300             :   //! Get global hints.
     301             :   ASMJIT_INLINE uint32_t getGlobalHints() const noexcept { return _globalHints; }
     302             : 
     303             :   //! Get global options.
     304             :   //!
     305             :   //! Global options are merged with instruction options before the instruction
     306             :   //! is encoded. These options have some bits reserved that are used for error
     307             :   //! checking, logging, and strict validation. Other options are globals that
     308             :   //! affect each instruction, for example if VEX3 is set globally, it will all
     309             :   //! instructions, even those that don't have such option set.
     310       98760 :   ASMJIT_INLINE uint32_t getGlobalOptions() const noexcept { return _globalOptions; }
     311             : 
     312             :   // --------------------------------------------------------------------------
     313             :   // [Error Handling]
     314             :   // --------------------------------------------------------------------------
     315             : 
     316             :   //! Get if the object is in error state.
     317             :   //!
     318             :   //! Error state means that it does not consume anything unless the error
     319             :   //! state is reset by calling `resetLastError()`. Use `getLastError()` to
     320             :   //! get the last error that put the object into the error state.
     321             :   ASMJIT_INLINE bool isInErrorState() const noexcept { return _lastError != kErrorOk; }
     322             : 
     323             :   //! Get the last error code.
     324             :   ASMJIT_INLINE Error getLastError() const noexcept { return _lastError; }
     325             :   //! Set the last error code and propagate it through the error handler.
     326             :   ASMJIT_API Error setLastError(Error error, const char* message = nullptr);
     327             :   //! Clear the last error code and return `kErrorOk`.
     328             :   ASMJIT_INLINE Error resetLastError() noexcept { return setLastError(kErrorOk); }
     329             : 
     330             :   // --------------------------------------------------------------------------
     331             :   // [Accessors That Affect the Next Instruction]
     332             :   // --------------------------------------------------------------------------
     333             : 
     334             :   //! Get options of the next instruction.
     335       94872 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; }
     336             :   //! Set options of the next instruction.
     337       48254 :   ASMJIT_INLINE void setOptions(uint32_t options) noexcept { _options = options; }
     338             :   //! Add options of the next instruction.
     339             :   ASMJIT_INLINE void addOptions(uint32_t options) noexcept { _options |= options; }
     340             :   //! Reset options of the next instruction.
     341       94872 :   ASMJIT_INLINE void resetOptions() noexcept { _options = 0; }
     342             : 
     343             :   //! Get if the extra register operand is valid.
     344             :   ASMJIT_INLINE bool hasExtraReg() const noexcept { return _extraReg.isValid(); }
     345             :   //! Get an extra operand that will be used by the next instruction (architecture specific).
     346             :   ASMJIT_INLINE const RegOnly& getExtraReg() const noexcept { return _extraReg; }
     347             :   //! Set an extra operand that will be used by the next instruction (architecture specific).
     348             :   ASMJIT_INLINE void setExtraReg(const Reg& reg) noexcept { _extraReg.init(reg); }
     349             :   //! Set an extra operand that will be used by the next instruction (architecture specific).
     350             :   ASMJIT_INLINE void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
     351             :   //! Reset an extra operand that will be used by the next instruction (architecture specific).
     352             :   ASMJIT_INLINE void resetExtraReg() noexcept { _extraReg.reset(); }
     353             : 
     354             :   //! Get annotation of the next instruction.
     355       46618 :   ASMJIT_INLINE const char* getInlineComment() const noexcept { return _inlineComment; }
     356             :   //! Set annotation of the next instruction.
     357             :   //!
     358             :   //! NOTE: This string is set back to null by `_emit()`, but until that it has
     359             :   //! to remain valid as `CodeEmitter` is not required to make a copy of it (and
     360             :   //! it would be slow to do that for each instruction).
     361       65114 :   ASMJIT_INLINE void setInlineComment(const char* s) noexcept { _inlineComment = s; }
     362             :   //! Reset annotation of the next instruction to null.
     363       98760 :   ASMJIT_INLINE void resetInlineComment() noexcept { _inlineComment = nullptr; }
     364             : 
     365             :   // --------------------------------------------------------------------------
     366             :   // [Helpers]
     367             :   // --------------------------------------------------------------------------
     368             : 
     369             :   //! Get if the `label` is valid (i.e. registered).
     370             :   ASMJIT_INLINE bool isLabelValid(const Label& label) const noexcept {
     371           0 :     return isLabelValid(label.getId());
     372             :   }
     373             : 
     374             :   //! Get if the label `id` is valid (i.e. registered).
     375             :   ASMJIT_API bool isLabelValid(uint32_t id) const noexcept;
     376             : 
     377             :   //! Emit a formatted string `fmt`.
     378             :   ASMJIT_API Error commentf(const char* fmt, ...);
     379             :   //! Emit a formatted string `fmt` (va_list version).
     380             :   ASMJIT_API Error commentv(const char* fmt, va_list ap);
     381             : 
     382             :   // --------------------------------------------------------------------------
     383             :   // [Emit]
     384             :   // --------------------------------------------------------------------------
     385             : 
     386             :   // NOTE: These `emit()` helpers are designed to address a code-bloat generated
     387             :   // by C++ compilers to call a function having many arguments. Each parameter to
     388             :   // `_emit()` requires code to pass it, which means that if we default to 4
     389             :   // operand parameters in `_emit()` and instId the C++ compiler would have to
     390             :   // generate a virtual function call having 5 parameters, which is quite a lot.
     391             :   // Since by default asm instructions have 2 to 3 operands it's better to
     392             :   // introduce helpers that pass those and fill all the remaining with `_none`.
     393             : 
     394             :   //! Emit an instruction.
     395             :   ASMJIT_API Error emit(uint32_t instId);
     396             :   //! \overload
     397             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0);
     398             :   //! \overload
     399             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1);
     400             :   //! \overload
     401             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2);
     402             :   //! \overload
     403             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
     404             :   //! \overload
     405             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4);
     406             :   //! \overload
     407             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5);
     408             : 
     409             :   //! Emit an instruction that has a 32-bit signed immediate operand.
     410             :   ASMJIT_API Error emit(uint32_t instId, int o0);
     411             :   //! \overload
     412             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, int o1);
     413             :   //! \overload
     414             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, int o2);
     415             :   //! \overload
     416             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, int o3);
     417             :   //! \overload
     418             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, int o4);
     419             :   //! \overload
     420             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, int o5);
     421             : 
     422             :   //! Emit an instruction that has a 64-bit signed immediate operand.
     423             :   ASMJIT_API Error emit(uint32_t instId, int64_t o0);
     424             :   //! \overload
     425             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, int64_t o1);
     426             :   //! \overload
     427             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, int64_t o2);
     428             :   //! \overload
     429             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, int64_t o3);
     430             :   //! \overload
     431             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, int64_t o4);
     432             :   //! \overload
     433             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, int64_t o5);
     434             : 
     435             :   //! \overload
     436             :   ASMJIT_INLINE Error emit(uint32_t instId, unsigned int o0) {
     437             :     return emit(instId, static_cast<int64_t>(o0));
     438             :   }
     439             :   //! \overload
     440             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, unsigned int o1) {
     441             :     return emit(instId, o0, static_cast<int64_t>(o1));
     442             :   }
     443             :   //! \overload
     444             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, unsigned int o2) {
     445             :     return emit(instId, o0, o1, static_cast<int64_t>(o2));
     446             :   }
     447             :   //! \overload
     448             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, unsigned int o3) {
     449             :     return emit(instId, o0, o1, o2, static_cast<int64_t>(o3));
     450             :   }
     451             :   //! \overload
     452             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, unsigned int o4) {
     453             :     return emit(instId, o0, o1, o2, o3, static_cast<int64_t>(o4));
     454             :   }
     455             :   //! \overload
     456             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, unsigned int o5) {
     457             :     return emit(instId, o0, o1, o2, o3, o4, static_cast<int64_t>(o5));
     458             :   }
     459             : 
     460             :   //! \overload
     461             :   ASMJIT_INLINE Error emit(uint32_t instId, uint64_t o0) {
     462             :     return emit(instId, static_cast<int64_t>(o0));
     463             :   }
     464             :   //! \overload
     465             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, uint64_t o1) {
     466             :     return emit(instId, o0, static_cast<int64_t>(o1));
     467             :   }
     468             :   //! \overload
     469             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, uint64_t o2) {
     470             :     return emit(instId, o0, o1, static_cast<int64_t>(o2));
     471             :   }
     472             :   //! \overload
     473             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, uint64_t o3) {
     474             :     return emit(instId, o0, o1, o2, static_cast<int64_t>(o3));
     475             :   }
     476             :   //! \overload
     477             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, uint64_t o4) {
     478             :     return emit(instId, o0, o1, o2, o3, static_cast<int64_t>(o4));
     479             :   }
     480             :   //! \overload
     481             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, uint64_t o5) {
     482             :     return emit(instId, o0, o1, o2, o3, o4, static_cast<int64_t>(o5));
     483             :   }
     484             : 
     485             :   ASMJIT_INLINE Error emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
     486       48254 :     return _emitOpArray(instId, opArray, opCount);
     487             :   }
     488             : 
     489             :   // --------------------------------------------------------------------------
     490             :   // [Members]
     491             :   // --------------------------------------------------------------------------
     492             : 
     493             :   CodeInfo _codeInfo;                    //!< Basic information about the code (matches CodeHolder::_codeInfo).
     494             :   CodeHolder* _code;                     //!< CodeHolder the CodeEmitter is attached to.
     495             :   CodeEmitter* _nextEmitter;             //!< Linked list of `CodeEmitter`s attached to the same \ref CodeHolder.
     496             : 
     497             :   uint8_t _type;                         //!< See CodeEmitter::Type.
     498             :   uint8_t _destroyed;                    //!< Set by ~CodeEmitter() before calling `_code->detach()`.
     499             :   uint8_t _finalized;                    //!< True if the CodeEmitter is finalized (CodeBuilder & CodeCompiler).
     500             :   uint8_t _reserved;                     //!< \internal
     501             :   Error _lastError;                      //!< Last error code.
     502             : 
     503             :   uint32_t _privateData;                 //!< Internal private data used freely by any CodeEmitter.
     504             :   uint32_t _globalHints;                 //!< Global hints, always in sync with CodeHolder.
     505             :   uint32_t _globalOptions;               //!< Global options, combined with `_options` before used by each instruction.
     506             : 
     507             :   uint32_t _options;                     //!< Used to pass instruction options        (affects the next instruction).
     508             :   RegOnly _extraReg;                     //!< Extra register (op-mask {k} on AVX-512) (affects the next instruction).
     509             :   const char* _inlineComment;            //!< Inline comment of the next instruction  (affects the next instruction).
     510             : 
     511             :   Operand_ _none;                        //!< Used to pass unused operands to `_emit()` instead of passing null.
     512             :   Reg _nativeGpReg;                      //!< Native GP register with zero id.
     513             :   const Reg* _nativeGpArray;             //!< Array of native registers indexed from zero.
     514             : };
     515             : 
     516             : //! \}
     517             : 
     518             : } // asmjit namespace
     519             : } // namespace PLMD
     520             : 
     521             : // [Api-End]
     522             : #include "./asmjit_apiend.h"
     523             : 
     524             : // [Guard]
     525             : #endif // _ASMJIT_BASE_CODEEMITTER_H
     526             : #pragma GCC diagnostic pop
     527             : #endif // __PLUMED_HAS_ASMJIT
     528             : #endif

Generated by: LCOV version 1.15