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 3888 : CodeEmitter::CodeEmitter(uint32_t type) noexcept
56 : : _codeInfo(),
57 3888 : _code(nullptr),
58 3888 : _nextEmitter(nullptr),
59 3888 : _type(static_cast<uint8_t>(type)),
60 3888 : _destroyed(false),
61 3888 : _finalized(false),
62 3888 : _reserved(false),
63 3888 : _lastError(kErrorNotInitialized),
64 3888 : _privateData(0),
65 3888 : _globalHints(0),
66 3888 : _globalOptions(kOptionMaybeFailureCase),
67 3888 : _options(0),
68 3888 : _extraReg(),
69 3888 : _inlineComment(nullptr),
70 3888 : _none(),
71 : _nativeGpReg(),
72 3888 : _nativeGpArray(nullptr) {}
73 :
74 3888 : CodeEmitter::~CodeEmitter() noexcept {
75 3888 : if (_code) {
76 3888 : _destroyed = true;
77 3888 : _code->detach(this);
78 : }
79 3888 : }
80 :
81 : // ============================================================================
82 : // [asmjit::CodeEmitter - Events]
83 : // ============================================================================
84 :
85 3888 : Error CodeEmitter::onAttach(CodeHolder* code) noexcept {
86 : _codeInfo = code->getCodeInfo();
87 3888 : _lastError = kErrorOk;
88 :
89 3888 : _globalHints = code->getGlobalHints();
90 3888 : _globalOptions = code->getGlobalOptions();
91 :
92 3888 : 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 1944 : Error CodeEmitter::emit(uint32_t instId) { return _emit(instId, _none, _none, _none, _none); }
232 2216 : Error CodeEmitter::emit(uint32_t instId, OP o0) { return _emit(instId, o0, _none, _none, _none); }
233 40474 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1) { return _emit(instId, o0, o1, _none, _none); }
234 120 : 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 932 : 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 932 : 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
|