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_CODEBUFFERWRITER_P_H_INCLUDED 8 : #define ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED 9 : 10 : #include "assembler.h" 11 : #include "codebuffer.h" 12 : #include "support.h" 13 : 14 : ASMJIT_BEGIN_NAMESPACE 15 : 16 : //! \cond INTERNAL 17 : //! \addtogroup asmjit_assembler 18 : //! \{ 19 : 20 : struct OffsetFormat; 21 : 22 : //! Helper that is used to write into a \ref CodeBuffer held by \ref BaseAssembler. 23 : class CodeWriter { 24 : public: 25 : uint8_t* _cursor; 26 : 27 : ASMJIT_FORCE_INLINE explicit CodeWriter(BaseAssembler* a) noexcept 28 392009 : : _cursor(a->_bufferPtr) {} 29 : 30 : ASMJIT_FORCE_INLINE Error ensureSpace(BaseAssembler* a, size_t n) noexcept { 31 0 : size_t remainingSpace = (size_t)(a->_bufferEnd - _cursor); 32 27492 : if (ASMJIT_UNLIKELY(remainingSpace < n)) { 33 27492 : CodeBuffer& buffer = a->_section->_buffer; 34 27492 : Error err = a->_code->growBuffer(&buffer, n); 35 27492 : if (ASMJIT_UNLIKELY(err)) 36 0 : return a->reportError(err); 37 27492 : _cursor = a->_bufferPtr; 38 : } 39 : return kErrorOk; 40 : } 41 : 42 : ASMJIT_FORCE_INLINE uint8_t* cursor() const noexcept { return _cursor; } 43 : ASMJIT_FORCE_INLINE void setCursor(uint8_t* cursor) noexcept { _cursor = cursor; } 44 0 : ASMJIT_FORCE_INLINE void advance(size_t n) noexcept { _cursor += n; } 45 : 46 : ASMJIT_FORCE_INLINE size_t offsetFrom(uint8_t* from) const noexcept { 47 : ASMJIT_ASSERT(_cursor >= from); 48 0 : return (size_t)(_cursor - from); 49 : } 50 : 51 : template<typename T> 52 : ASMJIT_FORCE_INLINE void emit8(T val) noexcept { 53 : typedef typename std::make_unsigned<T>::type U; 54 898415 : _cursor[0] = uint8_t(U(val) & U(0xFF)); 55 425059 : _cursor++; 56 335727 : } 57 : 58 : template<typename T, typename Y> 59 : ASMJIT_FORCE_INLINE void emit8If(T val, Y cond) noexcept { 60 : typedef typename std::make_unsigned<T>::type U; 61 : ASMJIT_ASSERT(size_t(cond) <= 1u); 62 : 63 412819 : _cursor[0] = uint8_t(U(val) & U(0xFF)); 64 277452 : _cursor += size_t(cond); 65 : } 66 : 67 : template<typename T> 68 : ASMJIT_FORCE_INLINE void emit16uLE(T val) noexcept { 69 : typedef typename std::make_unsigned<T>::type U; 70 : Support::writeU16uLE(_cursor, uint16_t(U(val) & 0xFFFFu)); 71 0 : _cursor += 2; 72 0 : } 73 : 74 : template<typename T> 75 : ASMJIT_FORCE_INLINE void emit16uBE(T val) noexcept { 76 : typedef typename std::make_unsigned<T>::type U; 77 : Support::writeU16uBE(_cursor, uint16_t(U(val) & 0xFFFFu)); 78 : _cursor += 2; 79 : } 80 : 81 : template<typename T> 82 : ASMJIT_FORCE_INLINE void emit32uLE(T val) noexcept { 83 : typedef typename std::make_unsigned<T>::type U; 84 88992 : Support::writeU32uLE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu)); 85 91602 : _cursor += 4; 86 36699 : } 87 : 88 : template<typename T> 89 : ASMJIT_FORCE_INLINE void emit32uBE(T val) noexcept { 90 : typedef typename std::make_unsigned<T>::type U; 91 : Support::writeU32uBE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu)); 92 : _cursor += 4; 93 : } 94 : 95 : ASMJIT_FORCE_INLINE void emitData(const void* data, size_t size) noexcept { 96 : ASMJIT_ASSERT(size != 0); 97 : memcpy(_cursor, data, size); 98 0 : _cursor += size; 99 : } 100 : 101 : template<typename T> 102 : ASMJIT_FORCE_INLINE void emitValueLE(const T& value, size_t size) noexcept { 103 : typedef typename std::make_unsigned<T>::type U; 104 : ASMJIT_ASSERT(size <= sizeof(T)); 105 : 106 : U v = U(value); 107 0 : for (uint32_t i = 0; i < size; i++) { 108 0 : _cursor[i] = uint8_t(v & 0xFFu); 109 0 : v >>= 8; 110 : } 111 0 : _cursor += size; 112 : } 113 : 114 : template<typename T> 115 : ASMJIT_FORCE_INLINE void emitValueBE(const T& value, size_t size) noexcept { 116 : typedef typename std::make_unsigned<T>::type U; 117 : ASMJIT_ASSERT(size <= sizeof(T)); 118 : 119 : U v = U(value); 120 : for (uint32_t i = 0; i < size; i++) { 121 : _cursor[i] = uint8_t(v >> (sizeof(T) - 8)); 122 : v <<= 8; 123 : } 124 : _cursor += size; 125 : } 126 : 127 : ASMJIT_FORCE_INLINE void emitZeros(size_t size) noexcept { 128 : ASMJIT_ASSERT(size != 0); 129 : memset(_cursor, 0, size); 130 0 : _cursor += size; 131 0 : } 132 : 133 : ASMJIT_FORCE_INLINE void remove8(uint8_t* where) noexcept { 134 : ASMJIT_ASSERT(where < _cursor); 135 : 136 : uint8_t* p = where; 137 0 : while (++p != _cursor) 138 0 : p[-1] = p[0]; 139 0 : _cursor--; 140 0 : } 141 : 142 : template<typename T> 143 : ASMJIT_FORCE_INLINE void insert8(uint8_t* where, T val) noexcept { 144 : uint8_t* p = _cursor; 145 : 146 0 : while (p != where) { 147 0 : p[0] = p[-1]; 148 0 : p--; 149 : } 150 : 151 0 : *p = uint8_t(val & 0xFF); 152 0 : _cursor++; 153 0 : } 154 : 155 : ASMJIT_FORCE_INLINE void done(BaseAssembler* a) noexcept { 156 392009 : CodeBuffer& buffer = a->_section->_buffer; 157 392009 : size_t newSize = (size_t)(_cursor - a->_bufferData); 158 : ASMJIT_ASSERT(newSize <= buffer.capacity()); 159 : 160 392009 : a->_bufferPtr = _cursor; 161 392009 : buffer._size = Support::max(buffer._size, newSize); 162 : } 163 : }; 164 : 165 : //! Code writer utilities. 166 : namespace CodeWriterUtils { 167 : 168 : bool encodeOffset32(uint32_t* dst, int64_t offset64, const OffsetFormat& format) noexcept; 169 : bool encodeOffset64(uint64_t* dst, int64_t offset64, const OffsetFormat& format) noexcept; 170 : 171 : bool writeOffset(void* dst, int64_t offset64, const OffsetFormat& format) noexcept; 172 : 173 : } // {CodeWriterUtils} 174 : 175 : //! \} 176 : //! \endcond 177 : 178 : ASMJIT_END_NAMESPACE 179 : 180 : #endif // ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED 181 : 182 : #endif // __PLUMED_HAS_ASMJIT