1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
|
// AsmJit - Complete JIT Assembler for C++ Language.
// Copyright (c) 2008-2010, Petr Kobalicek <kobalicek.petr@gmail.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// [Guard]
#ifndef _ASMJIT_DEFS_H
#define _ASMJIT_DEFS_H
// [Dependencies]
#include "Build.h"
namespace AsmJit {
//! @addtogroup AsmJit_Core
//! @{
// ============================================================================
// [AsmJit::MEMORY_ALLOC_TYPE]
// ============================================================================
//! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method.
enum MEMORY_ALLOC_TYPE
{
//! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free()
//! method.
MEMORY_ALLOC_FREEABLE,
//! @brief Allocate permanent memory that will be never freed.
MEMORY_ALLOC_PERMANENT
};
// ============================================================================
// [AsmJit::ERROR_CODE]
// ============================================================================
//! @brief AsmJit error codes.
enum ERROR_CODE
{
//! @brief No error (success).
//!
//! This is default state and state you want.
ERROR_NONE = 0,
//! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL).
ERROR_NO_HEAP_MEMORY = 1,
//! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL).
ERROR_NO_VIRTUAL_MEMORY = 2,
//! @brief Unknown instruction. This happens only if instruction code is
//! out of bounds. Shouldn't happen.
ERROR_UNKNOWN_INSTRUCTION = 3,
//! @brief Illegal instruction, usually generated by AsmJit::AssemblerCore
//! class when emitting instruction opcode. If this error is generated the
//! target buffer is not affected by this invalid instruction.
//!
//! You can also get this error code if you are under x64 (64-bit x86) and
//! you tried to decode instruction using AH, BH, CH or DH register with REX
//! prefix. These registers can't be accessed if REX prefix is used and AsmJit
//! didn't check for this situation in intrinsics (@c Compiler takes care of
//! this and rearrange registers if needed).
//!
//! Examples that will raise @c ERROR_ILLEGAL_INSTRUCTION error (a is
//! @c Assembler instance):
//!
//! @code
//! a.mov(dword_ptr(eax), al); // Invalid address size.
//! a.mov(byte_ptr(r10), ah); // Undecodable instruction (AH used with r10
//! // which can be encoded only using REX prefix)
//! @endcode
//!
//! @note In debug mode you get assertion failure instead of setting error
//! code.
ERROR_ILLEGAL_INSTRUCTION = 4,
//! @brief Illegal addressing used (unencodable).
ERROR_ILLEGAL_ADDRESING = 5,
//! @brief Short jump instruction used, but displacement is out of bounds.
ERROR_ILLEGAL_SHORT_JUMP = 6,
//! @brief No function defined.
ERROR_NO_FUNCTION = 7,
//! @brief Function generation is not finished by using @c Compiler::endFunction()
//! or something bad happened during generation related to function. This can
//! be missing emittable, etc...
ERROR_INCOMPLETE_FUNCTION = 8,
//! @brief Compiler can't allocate registers, because all of them are used.
//!
//! @note AsmJit is able to spill registers so this error really shouldn't
//! happen unless all registers have priority 0 (which means never spill).
ERROR_NOT_ENOUGH_REGISTERS = 9,
//! @brief Compiler can't allocate one register to multiple destinations.
//!
//! This error can only happen using special instructions like cmpxchg8b and
//! others where there are more destination operands (implicit).
ERROR_REGISTERS_OVERLAP = 10,
//! @brief Tried to call function using incompatible argument.
ERROR_INCOMPATIBLE_ARGUMENT = 11,
//! @brief Incompatible return value.
ERROR_INCOMPATIBLE_RETURN_VALUE = 12,
//! @brief Count of error codes by AsmJit. Can grow in future.
_ERROR_COUNT
};
// ============================================================================
// [AsmJit::OPERAND_TYPE]
// ============================================================================
//! @brief Operand types that can be encoded in @c Op operand.
enum OPERAND_TYPE
{
//! @brief Operand is none, used only internally (not initialized Operand).
//!
//! This operand is not valid.
OPERAND_NONE = 0x00,
//! @brief Operand is register.
OPERAND_REG = 0x01,
//! @brief Operand is memory.
OPERAND_MEM = 0x02,
//! @brief Operand is immediate.
OPERAND_IMM = 0x04,
//! @brief Operand is label.
OPERAND_LABEL = 0x08,
//! @brief Operand is variable.
OPERAND_VAR = 0x10
};
// ============================================================================
// [AsmJit::OPERAND_MEM_TYPE]
// ============================================================================
//! @brief Type of memory operand.
enum OPERAND_MEM_TYPE
{
//! @brief Operand is combination of register(s) and displacement (native).
OPERAND_MEM_NATIVE = 0,
//! @brief Operand is label.
OPERAND_MEM_LABEL = 1,
//! @brief Operand is absolute memory location (supported mainly in 32-bit
//! mode)
OPERAND_MEM_ABSOLUTE = 2,
};
// ============================================================================
// [AsmJit::PROPERTY]
// ============================================================================
//! @brief @c Assembler/Compiler properties.
enum PROPERTY
{
//! @brief Optimize align for current processor.
//!
//! Default: @c true.
PROPERTY_OPTIMIZE_ALIGN = 0,
//! @brief Emit hints added to jcc() instructions.
//!
//! Default: @c true.
//!
//! @note This is X86/X64 property only.
PROPERTY_JUMP_HINTS = 1
};
// ============================================================================
// [AsmJit::SIZE]
// ============================================================================
//! @brief Size of registers and pointers.
enum SIZE
{
//! @brief 1 byte size.
SIZE_BYTE = 1,
//! @brief 2 bytes size.
SIZE_WORD = 2,
//! @brief 4 bytes size.
SIZE_DWORD = 4,
//! @brief 8 bytes size.
SIZE_QWORD = 8,
//! @brief 10 bytes size.
SIZE_TWORD = 10,
//! @brief 16 bytes size.
SIZE_DQWORD = 16
};
// ============================================================================
// [EMITTABLE_TYPE]
// ============================================================================
//! @brief Emmitable type.
//!
//! For each emittable that is used by @c Compiler must be defined it's type.
//! Compiler can optimize instruction stream by analyzing emittables and each
//! type is hint for it. The most used emittables are instructions
//! (@c EMITTABLE_INSTRUCTION).
enum EMITTABLE_TYPE
{
//! @brief Emittable is invalid (can't be used).
EMITTABLE_NONE = 0,
//! @brief Emittable is dummy (used as a mark) (@ref EDummy).
EMITTABLE_DUMMY,
//! @brief Emittable is comment (no code) (@ref EComment).
EMITTABLE_COMMENT,
//! @brief Emittable is embedded data (@ref EData).
EMITTABLE_EMBEDDED_DATA,
//! @brief Emittable is .align directive (@ref EAlign).
EMITTABLE_ALIGN,
//! @brief Emittable is variable hint (alloc, spill, use, unuse, ...) (@ref EVariableHint).
EMITTABLE_VARIABLE_HINT,
//! @brief Emittable is single instruction (@ref EInstruction).
EMITTABLE_INSTRUCTION,
//! @brief Emittable is block of instructions.
EMITTABLE_BLOCK,
//! @brief Emittable is function declaration (@ref EFunction).
EMITTABLE_FUNCTION,
//! @brief Emittable is function prolog (@ref EProlog).
EMITTABLE_PROLOG,
//! @brief Emittable is function epilog (@ref EEpilog).
EMITTABLE_EPILOG,
//! @brief Emittable is end of function (@ref EFunctionEnd).
EMITTABLE_FUNCTION_END,
//! @brief Emittable is target (bound label).
EMITTABLE_TARGET,
//! @brief Emittable is jump table (@ref EJmp).
EMITTABLE_JUMP_TABLE,
//! @brief Emittable is function call (@ref ECall).
EMITTABLE_CALL,
//! @brief Emittable is return (@ref ERet).
EMITTABLE_RET
};
// ============================================================================
// [AsmJit::VARIABLE_STATE]
// ============================================================================
//! @brief State of variable.
//!
//! @note State of variable is used only during make process and it's not
//! visible to the developer.
enum VARIABLE_STATE
{
//! @brief Variable is currently not used.
VARIABLE_STATE_UNUSED = 0,
//! @brief Variable is in register.
//!
//! Variable is currently allocated in register.
VARIABLE_STATE_REGISTER = 1,
//! @brief Variable is in memory location or spilled.
//!
//! Variable was spilled from register to memory or variable is used for
//! memory only storage.
VARIABLE_STATE_MEMORY = 2
};
// ============================================================================
// [AsmJit::VARIABLE_ALLOC_FLAGS]
// ============================================================================
//! @brief Variable alloc mode.
enum VARIABLE_ALLOC
{
//! @brief Allocating variable to read only.
//!
//! Read only variables are used to optimize variable spilling. If variable
//! is some time ago deallocated and it's not marked as changed (so it was
//! all the life time read only) then spill is simply NOP (no mov instruction
//! is generated to move it to it's home memory location).
VARIABLE_ALLOC_READ = 0x01,
//! @brief Allocating variable to write only (overwrite).
//!
//! Overwriting means that if variable is in memory, there is no generated
//! instruction to move variable from memory to register, because that
//! register will be overwritten by next instruction. This is used as a
//! simple optimization to improve generated code by @c Compiler.
VARIABLE_ALLOC_WRITE = 0x02,
//! @brief Allocating variable to read / write.
//!
//! Variable allocated for read / write is marked as changed. This means that
//! if variable must be later spilled into memory, mov (or similar)
//! instruction will be generated.
VARIABLE_ALLOC_READWRITE = 0x03,
//! @brief Variable can be allocated in register.
VARIABLE_ALLOC_REGISTER = 0x04,
//! @brief Variable can be allocated in memory.
VARIABLE_ALLOC_MEMORY = 0x08,
//! @brief Unuse the variable after use.
VARIABLE_ALLOC_UNUSE_AFTER_USE = 0x10,
//! @brief Variable can be allocated only to one register (special allocation).
VARIABLE_ALLOC_SPECIAL = 0x20
};
// ============================================================================
// [AsmJit::VARIABLE_ALLOC_POLICY]
// ============================================================================
//! @brief Variable allocation method.
//!
//! Variable allocation method is used by compiler and it means if compiler
//! should first allocate preserved registers or not. Preserved registers are
//! registers that must be saved / restored by generated function.
//!
//! This option is for people who are calling C/C++ functions from JIT code so
//! Compiler can recude generating push/pop sequences before and after call,
//! respectively.
enum VARIABLE_ALLOC_POLICY
{
//! @brief Allocate preserved registers first.
VARIABLE_ALLOC_PRESERVED_FIRST,
//! @brief Allocate preserved registers last (default).
VARIABLE_ALLOC_PRESERVED_LAST
};
// ============================================================================
// [AsmJit::FUNCTION_HINT]
// ============================================================================
//! @brief Function hints.
enum FUNCTION_HINT
{
//! @brief Use push/pop sequences instead of mov sequences in function prolog
//! and epilog.
FUNCTION_HINT_PUSH_POP_SEQUENCE = 0,
//! @brief Make naked function (without using ebp/erp in prolog / epilog).
FUNCTION_HINT_NAKED = 1,
//! @brief Add emms instruction to the function epilog.
FUNCTION_HINT_EMMS = 2,
//! @brief Add sfence instruction to the function epilog.
FUNCTION_HINT_SFENCE = 3,
//! @brief Add lfence instruction to the function epilog.
FUNCTION_HINT_LFENCE = 4
};
// ============================================================================
// [AsmJit::ARGUMENT_DIR]
// ============================================================================
//! @brief Arguments direction used by @c Function.
enum ARGUMENT_DIR
{
//! @brief Arguments are passed left to right.
//!
//! This arguments direction is unusual to C programming, it's used by pascal
//! compilers and in some calling conventions by Borland compiler).
ARGUMENT_DIR_LEFT_TO_RIGHT = 0,
//! @brief Arguments are passer right ro left
//!
//! This is default argument direction in C programming.
ARGUMENT_DIR_RIGHT_TO_LEFT = 1
};
// ============================================================================
// [AsmJit::Constants]
// ============================================================================
enum {
//! @brief Invalid operand identifier.
INVALID_VALUE = 0xFFFFFFFF,
//! @brief Operand id value mask (part used for IDs).
OPERAND_ID_VALUE_MASK = 0x3FFFFFFF,
//! @brief Operand id type mask (part used for operand type).
OPERAND_ID_TYPE_MASK = 0xC0000000,
//! @brief Label operand mark id.
OPERAND_ID_TYPE_LABEL = 0x40000000,
//! @brief Variable operand mark id.
OPERAND_ID_TYPE_VAR = 0x80000000,
};
enum {
//! @brief Maximum allowed arguments per function declaration / call.
FUNC_MAX_ARGS = 32
};
// ============================================================================
// [AsmJit::API]
// ============================================================================
//! @brief Translates error code (see @c ERROR_CODE) into text representation.
ASMJIT_API const char* getErrorCodeAsString(uint32_t error) ASMJIT_NOTHROW;
//! @}
} // AsmJit namespace
// ============================================================================
// [Platform Specific]
//
// Following enums must be declared by platform specific header:
// - CALL_CONV - Calling convention.
// - VARIABLE_TYPE - Variable type.
// ============================================================================
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
#include "DefsX86X64.h"
#endif // ASMJIT_X86 || ASMJIT_X64
// [Guard]
#endif // _ASMJIT_DEFS_H
|