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_logging_h 21 : #define __PLUMED_asmjit_logging_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_LOGGING_H 33 : #define _ASMJIT_BASE_LOGGING_H 34 : 35 : // [Dependencies] 36 : #include "./inst.h" 37 : #include "./moved_string.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 : #if !defined(ASMJIT_DISABLE_LOGGING) 49 : 50 : // ============================================================================ 51 : // [Forward Declarations] 52 : // ============================================================================ 53 : 54 : class CodeEmitter; 55 : class Reg; 56 : struct Operand_; 57 : 58 : #if !defined(ASMJIT_DISABLE_BUILDER) 59 : class CodeBuilder; 60 : class CBNode; 61 : #endif // !ASMJIT_DISABLE_BUILDER 62 : 63 : // ============================================================================ 64 : // [asmjit::Logger] 65 : // ============================================================================ 66 : 67 : //! Abstract logging interface and helpers. 68 : //! 69 : //! This class can be inherited and reimplemented to fit into your logging 70 : //! subsystem. When reimplementing use `Logger::_log()` method to log into 71 : //! a custom stream. 72 : //! 73 : //! There are two \ref Logger implementations offered by AsmJit: 74 : //! - \ref FileLogger - allows to log into a `FILE*` stream. 75 : //! - \ref StringLogger - logs into a \ref StringBuilder. 76 : class ASMJIT_VIRTAPI Logger { 77 : public: 78 : ASMJIT_NONCOPYABLE(Logger) 79 : 80 : // -------------------------------------------------------------------------- 81 : // [Options] 82 : // -------------------------------------------------------------------------- 83 : 84 : //! Logger options. 85 : ASMJIT_ENUM(Options) { 86 : kOptionBinaryForm = 0x00000001, //! Output instructions also in binary form. 87 : kOptionImmExtended = 0x00000002, //! Output a meaning of some immediates. 88 : kOptionHexImmediate = 0x00000004, //! Output constants in hexadecimal form. 89 : kOptionHexDisplacement = 0x00000008 //! Output displacements in hexadecimal form. 90 : }; 91 : 92 : // -------------------------------------------------------------------------- 93 : // [Construction / Destruction] 94 : // -------------------------------------------------------------------------- 95 : 96 : //! Create a `Logger` instance. 97 : ASMJIT_API Logger() noexcept; 98 : //! Destroy the `Logger` instance. 99 : ASMJIT_API virtual ~Logger() noexcept; 100 : 101 : // -------------------------------------------------------------------------- 102 : // [Logging] 103 : // -------------------------------------------------------------------------- 104 : 105 : //! Log `str` - must be reimplemented. 106 : virtual Error _log(const char* str, size_t len) noexcept = 0; 107 : 108 : //! Log a string `str`, which is either null terminated or having `len` length. 109 0 : ASMJIT_INLINE Error log(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _log(str, len); } 110 : //! Log a content of a `StringBuilder` `str`. 111 : ASMJIT_INLINE Error log(const StringBuilder& str) noexcept { return _log(str.getData(), str.getLength()); } 112 : 113 : //! Format the message by using `sprintf()` and then send to `log()`. 114 : ASMJIT_API Error logf(const char* fmt, ...) noexcept; 115 : //! Format the message by using `vsprintf()` and then send to `log()`. 116 : ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept; 117 : //! Log binary data. 118 : ASMJIT_API Error logBinary(const void* data, size_t size) noexcept; 119 : 120 : // -------------------------------------------------------------------------- 121 : // [Options] 122 : // -------------------------------------------------------------------------- 123 : 124 : //! Get all logger options as a single integer. 125 0 : ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; } 126 : //! Get the given logger option. 127 0 : ASMJIT_INLINE bool hasOption(uint32_t option) const noexcept { return (_options & option) != 0; } 128 : ASMJIT_INLINE void addOptions(uint32_t options) noexcept { _options |= options; } 129 : ASMJIT_INLINE void clearOptions(uint32_t options) noexcept { _options &= ~options; } 130 : 131 : // -------------------------------------------------------------------------- 132 : // [Indentation] 133 : // -------------------------------------------------------------------------- 134 : 135 : //! Get indentation. 136 0 : ASMJIT_INLINE const char* getIndentation() const noexcept { return _indentation; } 137 : //! Set indentation. 138 : ASMJIT_API void setIndentation(const char* indentation) noexcept; 139 : //! Reset indentation. 140 : ASMJIT_INLINE void resetIndentation() noexcept { setIndentation(nullptr); } 141 : 142 : // -------------------------------------------------------------------------- 143 : // [Members] 144 : // -------------------------------------------------------------------------- 145 : 146 : //! Options, see \ref LoggerOption. 147 : uint32_t _options; 148 : 149 : //! Indentation. 150 : char _indentation[12]; 151 : }; 152 : 153 : // ============================================================================ 154 : // [asmjit::FileLogger] 155 : // ============================================================================ 156 : 157 : //! Logger that can log to a `FILE*` stream. 158 : class ASMJIT_VIRTAPI FileLogger : public Logger { 159 : public: 160 : ASMJIT_NONCOPYABLE(FileLogger) 161 : 162 : // -------------------------------------------------------------------------- 163 : // [Construction / Destruction] 164 : // -------------------------------------------------------------------------- 165 : 166 : //! Create a new `FileLogger` that logs to a `FILE` stream. 167 : ASMJIT_API FileLogger(FILE* stream = nullptr) noexcept; 168 : //! Destroy the `FileLogger`. 169 : ASMJIT_API virtual ~FileLogger() noexcept; 170 : 171 : // -------------------------------------------------------------------------- 172 : // [Accessors] 173 : // -------------------------------------------------------------------------- 174 : 175 : //! Get the logging out put stream or null. 176 : ASMJIT_INLINE FILE* getStream() const noexcept { return _stream; } 177 : 178 : //! Set the logging output stream to `stream` or null. 179 : //! 180 : //! NOTE: If the `stream` is null it will disable logging, but it won't 181 : //! stop calling `log()` unless the logger is detached from the 182 : //! \ref Assembler. 183 0 : ASMJIT_INLINE void setStream(FILE* stream) noexcept { _stream = stream; } 184 : 185 : // -------------------------------------------------------------------------- 186 : // [Logging] 187 : // -------------------------------------------------------------------------- 188 : 189 : ASMJIT_API Error _log(const char* buf, size_t len = Globals::kInvalidIndex) noexcept override; 190 : 191 : // -------------------------------------------------------------------------- 192 : // [Members] 193 : // -------------------------------------------------------------------------- 194 : 195 : //! C file stream. 196 : FILE* _stream; 197 : }; 198 : 199 : // ============================================================================ 200 : // [asmjit::StringLogger] 201 : // ============================================================================ 202 : 203 : //! Logger that stores everything in an internal string buffer. 204 : class ASMJIT_VIRTAPI StringLogger : public Logger { 205 : public: 206 : ASMJIT_NONCOPYABLE(StringLogger) 207 : 208 : // -------------------------------------------------------------------------- 209 : // [Construction / Destruction] 210 : // -------------------------------------------------------------------------- 211 : 212 : //! Create new `StringLogger`. 213 : ASMJIT_API StringLogger() noexcept; 214 : //! Destroy the `StringLogger`. 215 : ASMJIT_API virtual ~StringLogger() noexcept; 216 : 217 : // -------------------------------------------------------------------------- 218 : // [Accessors] 219 : // -------------------------------------------------------------------------- 220 : 221 : //! Get `char*` pointer which represents the resulting string. 222 : //! 223 : //! The pointer is owned by `StringLogger`, it can't be modified or freed. 224 : ASMJIT_INLINE const char* getString() const noexcept { return _stringBuilder.getData(); } 225 : //! Clear the resulting string. 226 : ASMJIT_INLINE void clearString() noexcept { _stringBuilder.clear(); } 227 : 228 : //! Get the length of the string returned by `getString()`. 229 : ASMJIT_INLINE size_t getLength() const noexcept { return _stringBuilder.getLength(); } 230 : 231 : // -------------------------------------------------------------------------- 232 : // [Logging] 233 : // -------------------------------------------------------------------------- 234 : 235 : ASMJIT_API Error _log(const char* buf, size_t len = Globals::kInvalidIndex) noexcept override; 236 : 237 : // -------------------------------------------------------------------------- 238 : // [Members] 239 : // -------------------------------------------------------------------------- 240 : 241 : //! Output string. 242 : StringBuilder _stringBuilder; 243 : }; 244 : 245 : // ============================================================================ 246 : // [asmjit::Logging] 247 : // ============================================================================ 248 : 249 : struct Logging { 250 : ASMJIT_API static Error formatRegister( 251 : StringBuilder& sb, 252 : uint32_t logOptions, 253 : const CodeEmitter* emitter, 254 : uint32_t archType, 255 : uint32_t regType, 256 : uint32_t regId) noexcept; 257 : 258 : ASMJIT_API static Error formatLabel( 259 : StringBuilder& sb, 260 : uint32_t logOptions, 261 : const CodeEmitter* emitter, 262 : uint32_t labelId) noexcept; 263 : 264 : ASMJIT_API static Error formatOperand( 265 : StringBuilder& sb, 266 : uint32_t logOptions, 267 : const CodeEmitter* emitter, 268 : uint32_t archType, 269 : const Operand_& op) noexcept; 270 : 271 : ASMJIT_API static Error formatInstruction( 272 : StringBuilder& sb, 273 : uint32_t logOptions, 274 : const CodeEmitter* emitter, 275 : uint32_t archType, 276 : const Inst::Detail& detail, const Operand_* opArray, uint32_t opCount) noexcept; 277 : 278 : #if !defined(ASMJIT_DISABLE_BUILDER) 279 : ASMJIT_API static Error formatNode( 280 : StringBuilder& sb, 281 : uint32_t logOptions, 282 : const CodeBuilder* cb, 283 : const CBNode* node_) noexcept; 284 : #endif // !ASMJIT_DISABLE_BUILDER 285 : 286 : // Only used by AsmJit internals, not available to users. 287 : #if defined(ASMJIT_EXPORTS) 288 : enum { 289 : // Has to be big to be able to hold all metadata compiler can assign to a 290 : // single instruction. 291 : kMaxCommentLength = 512, 292 : kMaxInstLength = 40, 293 : kMaxBinaryLength = 26 294 : }; 295 : 296 : static Error formatLine( 297 : StringBuilder& sb, 298 : const uint8_t* binData, size_t binLen, size_t dispLen, size_t imLen, const char* comment) noexcept; 299 : #endif // ASMJIT_EXPORTS 300 : }; 301 : #else 302 : class Logger; 303 : #endif // !ASMJIT_DISABLE_LOGGING 304 : 305 : //! \} 306 : 307 : } // asmjit namespace 308 : } // namespace PLMD 309 : 310 : // [Api-End] 311 : #include "./asmjit_apiend.h" 312 : 313 : // [Guard] 314 : #endif // _ASMJIT_BASE_LOGGER_H 315 : #pragma GCC diagnostic pop 316 : #endif // __PLUMED_HAS_ASMJIT 317 : #endif