LCOV - code coverage report
Current view: top level - asmjit - codeemitter.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 32 95 33.7 %
Date: 2024-10-18 14:00:27 Functions: 9 31 29.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             : #ifdef __PLUMED_HAS_ASMJIT
      21             : #pragma GCC diagnostic push
      22             : #pragma GCC diagnostic ignored "-Wpedantic"
      23             : // [AsmJit]
      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
      25             : //
      26             : // [License]
      27             : // Zlib - See LICENSE.md file in the package.
      28             : 
      29             : // [Export]
      30             : #define ASMJIT_EXPORTS
      31             : 
      32             : // [Dependencies]
      33             : #include "./assembler.h"
      34             : #include "./utils.h"
      35             : #include "./vmem.h"
      36             : 
      37             : #if defined(ASMJIT_BUILD_X86)
      38             : #include "./x86inst.h"
      39             : #endif // ASMJIT_BUILD_X86
      40             : 
      41             : #if defined(ASMJIT_BUILD_ARM)
      42             : #include "./arminst.h"
      43             : #endif // ASMJIT_BUILD_ARM
      44             : 
      45             : // [Api-Begin]
      46             : #include "./asmjit_apibegin.h"
      47             : 
      48             : namespace PLMD {
      49             : namespace asmjit {
      50             : 
      51             : // ============================================================================
      52             : // [asmjit::CodeEmitter - Construction / Destruction]
      53             : // ============================================================================
      54             : 
      55       64222 : CodeEmitter::CodeEmitter(uint32_t type) noexcept
      56             :   : _codeInfo(),
      57       64222 :     _code(nullptr),
      58       64222 :     _nextEmitter(nullptr),
      59       64222 :     _type(static_cast<uint8_t>(type)),
      60       64222 :     _destroyed(false),
      61       64222 :     _finalized(false),
      62       64222 :     _reserved(false),
      63       64222 :     _lastError(kErrorNotInitialized),
      64       64222 :     _privateData(0),
      65       64222 :     _globalHints(0),
      66       64222 :     _globalOptions(kOptionMaybeFailureCase),
      67       64222 :     _options(0),
      68       64222 :     _extraReg(),
      69       64222 :     _inlineComment(nullptr),
      70       64222 :     _none(),
      71             :     _nativeGpReg(),
      72       64222 :     _nativeGpArray(nullptr) {}
      73             : 
      74       64222 : CodeEmitter::~CodeEmitter() noexcept {
      75       64222 :   if (_code) {
      76       64222 :     _destroyed = true;
      77       64222 :     _code->detach(this);
      78             :   }
      79       64222 : }
      80             : 
      81             : // ============================================================================
      82             : // [asmjit::CodeEmitter - Events]
      83             : // ============================================================================
      84             : 
      85       64222 : Error CodeEmitter::onAttach(CodeHolder* code) noexcept {
      86             :   _codeInfo = code->getCodeInfo();
      87       64222 :   _lastError = kErrorOk;
      88             : 
      89       64222 :   _globalHints = code->getGlobalHints();
      90       64222 :   _globalOptions = code->getGlobalOptions();
      91             : 
      92       64222 :   return kErrorOk;
      93             : }
      94             : 
      95           0 : Error CodeEmitter::onDetach(CodeHolder* code) noexcept {
      96             :   _codeInfo.reset();
      97           0 :   _finalized = false;
      98           0 :   _lastError = kErrorNotInitialized;
      99             : 
     100           0 :   _privateData = 0;
     101           0 :   _globalHints = 0;
     102           0 :   _globalOptions = kOptionMaybeFailureCase;
     103             : 
     104           0 :   _options = 0;
     105             :   _extraReg.reset();
     106           0 :   _inlineComment = nullptr;
     107             : 
     108             :   _nativeGpReg.reset();
     109           0 :   _nativeGpArray = nullptr;
     110             : 
     111           0 :   return kErrorOk;
     112             : }
     113             : 
     114             : // ============================================================================
     115             : // [asmjit::CodeEmitter - Code-Generation]
     116             : // ============================================================================
     117             : 
     118           0 : Error CodeEmitter::_emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
     119             :   const Operand_* op = opArray;
     120           0 :   switch (opCount) {
     121           0 :     case 0: return _emit(instId, _none, _none, _none, _none);
     122           0 :     case 1: return _emit(instId, op[0], _none, _none, _none);
     123           0 :     case 2: return _emit(instId, op[0], op[1], _none, _none);
     124           0 :     case 3: return _emit(instId, op[0], op[1], op[2], _none);
     125           0 :     case 4: return _emit(instId, op[0], op[1], op[2], op[3]);
     126           0 :     case 5: return _emit(instId, op[0], op[1], op[2], op[3], op[4], _none);
     127           0 :     case 6: return _emit(instId, op[0], op[1], op[2], op[3], op[4], op[5]);
     128             : 
     129             :     default:
     130             :       return DebugUtils::errored(kErrorInvalidArgument);
     131             :   }
     132             : }
     133             : 
     134             : // ============================================================================
     135             : // [asmjit::CodeEmitter - Finalize]
     136             : // ============================================================================
     137             : 
     138           0 : Label CodeEmitter::getLabelByName(const char* name, size_t nameLength, uint32_t parentId) noexcept {
     139           0 :   return Label(_code ? _code->getLabelIdByName(name, nameLength, parentId) : static_cast<uint32_t>(0));
     140             : }
     141             : 
     142             : // ============================================================================
     143             : // [asmjit::CodeEmitter - Finalize]
     144             : // ============================================================================
     145             : 
     146           0 : Error CodeEmitter::finalize() {
     147             :   // Finalization does nothing by default, overridden by `CodeBuilder`.
     148           0 :   return kErrorOk;
     149             : }
     150             : 
     151             : // ============================================================================
     152             : // [asmjit::CodeEmitter - Error Handling]
     153             : // ============================================================================
     154             : 
     155           0 : Error CodeEmitter::setLastError(Error error, const char* message) {
     156             :   // This is fatal, CodeEmitter can't set error without being attached to `CodeHolder`.
     157             :   ASMJIT_ASSERT(_code != nullptr);
     158             : 
     159             :   // Special case used to reset the last error.
     160           0 :   if (error == kErrorOk) {
     161           0 :     _lastError = kErrorOk;
     162           0 :     _globalOptions &= ~kOptionMaybeFailureCase;
     163           0 :     return kErrorOk;
     164             :   }
     165             : 
     166           0 :   if (!message)
     167           0 :     message = DebugUtils::errorAsString(error);
     168             : 
     169             :   // Logging is skipped if the error is handled by `ErrorHandler`.
     170           0 :   ErrorHandler* handler = _code->_errorHandler;
     171           0 :   if (handler && handler->handleError(error, message, this))
     172             :     return error;
     173             : 
     174             :   // The handler->handleError() function may throw an exception or longjmp()
     175             :   // to terminate the execution of `setLastError()`. This is the reason why
     176             :   // we have delayed changing the `_error` member until now.
     177           0 :   _lastError = error;
     178           0 :   _globalOptions |= kOptionMaybeFailureCase;
     179             : 
     180           0 :   return error;
     181             : }
     182             : 
     183             : // ============================================================================
     184             : // [asmjit::CodeEmitter - Helpers]
     185             : // ============================================================================
     186             : 
     187           0 : bool CodeEmitter::isLabelValid(uint32_t id) const noexcept {
     188           0 :   size_t index = Operand::unpackId(id);
     189           0 :   return _code && index < _code->_labels.getLength();
     190             : }
     191             : 
     192           0 : Error CodeEmitter::commentf(const char* fmt, ...) {
     193           0 :   Error err = _lastError;
     194           0 :   if (err) return err;
     195             : 
     196             : #if !defined(ASMJIT_DISABLE_LOGGING)
     197           0 :   if (_globalOptions & kOptionLoggingEnabled) {
     198             :     va_list ap;
     199           0 :     va_start(ap, fmt);
     200           0 :     err = _code->_logger->logv(fmt, ap);
     201           0 :     va_end(ap);
     202             :   }
     203             : #else
     204             :   ASMJIT_UNUSED(fmt);
     205             : #endif
     206             : 
     207             :   return err;
     208             : }
     209             : 
     210           0 : Error CodeEmitter::commentv(const char* fmt, va_list ap) {
     211           0 :   Error err = _lastError;
     212           0 :   if (err) return err;
     213             : 
     214             : #if !defined(ASMJIT_DISABLE_LOGGING)
     215           0 :   if (_globalOptions & kOptionLoggingEnabled)
     216           0 :     err = _code->_logger->logv(fmt, ap);
     217             : #else
     218             :   ASMJIT_UNUSED(fmt);
     219             :   ASMJIT_UNUSED(ap);
     220             : #endif
     221             : 
     222             :   return err;
     223             : }
     224             : 
     225             : // ============================================================================
     226             : // [asmjit::CodeEmitter - Emit]
     227             : // ============================================================================
     228             : 
     229             : #define OP const Operand_&
     230             : 
     231       32111 : Error CodeEmitter::emit(uint32_t instId) { return _emit(instId, _none, _none, _none, _none); }
     232       14312 : Error CodeEmitter::emit(uint32_t instId, OP o0) { return _emit(instId, o0, _none, _none, _none); }
     233      522061 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1) { return _emit(instId, o0, o1, _none, _none); }
     234        2270 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2) { return _emit(instId, o0, o1, o2, _none); }
     235           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3) { return _emit(instId, o0, o1, o2, o3); }
     236           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4) { return _emit(instId, o0, o1, o2, o3, o4, _none); }
     237           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, OP o5) { return _emit(instId, o0, o1, o2, o3, o4, o5); }
     238             : 
     239           0 : Error CodeEmitter::emit(uint32_t instId, int o0) { return _emit(instId, Imm(o0), _none, _none, _none); }
     240        4712 : Error CodeEmitter::emit(uint32_t instId, OP o0, int o1) { return _emit(instId, o0, Imm(o1), _none, _none); }
     241           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, int o2) { return _emit(instId, o0, o1, Imm(o2), _none); }
     242           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, int o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
     243           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), _none); }
     244           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
     245             : 
     246           0 : Error CodeEmitter::emit(uint32_t instId, int64_t o0) { return _emit(instId, Imm(o0), _none, _none, _none); }
     247        4712 : Error CodeEmitter::emit(uint32_t instId, OP o0, int64_t o1) { return _emit(instId, o0, Imm(o1), _none, _none); }
     248           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, int64_t o2) { return _emit(instId, o0, o1, Imm(o2), _none); }
     249           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, int64_t o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
     250             : 
     251           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int64_t o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), _none); }
     252           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int64_t o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
     253             : 
     254             : #undef OP
     255             : 
     256             : } // asmjit namespace
     257             : } // namespace PLMD
     258             : 
     259             : // [Api-End]
     260             : #include "./asmjit_apiend.h"
     261             : #pragma GCC diagnostic pop
     262             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16