1 // [AsmJit]
2 // Complete JIT Assembler for C++ Language.
3 //
4 // [License]
5 // Zlib - See COPYING file in this package.
6 
7 // [Guard]
8 #ifndef _ASMJIT_CORE_DEFS_H
9 #define _ASMJIT_CORE_DEFS_H
10 
11 // [Dependencies - AsmJit]
12 #include "../core/build.h"
13 
14 // [Api-Begin]
15 #include "../core/apibegin.h"
16 
17 namespace AsmJit {
18 
19 //! @addtogroup AsmJit_Core
20 //! @{
21 
22 // ============================================================================
23 // [AsmJit::Global]
24 // ============================================================================
25 
26 enum
27 {
28   //! @brief Invalid operand identifier.
29   kInvalidValue = 0xFFFFFFFFU,
30   //! @brief Minimum reserved bytes in @ref Buffer.
31   kBufferGrow = 32U
32 };
33 
34 static const size_t kInvalidSize = (size_t)-1;
35 
36 // ============================================================================
37 // [AsmJit::kStringBuilderOpType]
38 // ============================================================================
39 
40 //! @brief String builder operation.
41 enum kStringBuilderOpType
42 {
43   //! @brief Replace the current content by a given content.
44   kStringBuilderOpSet = 0,
45   //! @brief Append a given content to the current content.
46   kStringBuilderOpAppend = 1
47 };
48 
49 // ============================================================================
50 // [AsmJit::kStringBuilderNumType]
51 // ============================================================================
52 
53 enum kStringBuilderNumFlags
54 {
55   kStringBuilderNumShowSign = (1U << 0),
56   kStringBuilderNumShowSpace = (1U << 1),
57   kStringBuilderNumAlternate = (1U << 2),
58   kStringBuilderNumSigned = (1U << 31)
59 };
60 
61 // ============================================================================
62 // [AsmJit::kLoggerOption]
63 // ============================================================================
64 
65 enum kLoggerFlag
66 {
67   //! @brief Whether logger is enabled or disabled.
68   //!
69   //! Default @c true.
70   kLoggerIsEnabled = 0x00000001,
71 
72   //! @brief Whether logger is enabled and can be used.
73   //!
74   //! This value can be set by inherited classes to inform @c Logger that
75   //! assigned stream (or something that can log output) is invalid. If
76   //! @c _used is false it means that there is no logging output and AsmJit
77   //! shouldn't use this logger (because all messages will be lost).
78   //!
79   //! This is designed only to optimize cases that logger exists, but its
80   //! configured not to output messages. The API inside Logging and AsmJit
81   //! should only check this value when needed. The API outside AsmJit should
82   //! check only whether logging is @c _enabled.
83   //!
84   //! Default @c true.
85   kLoggerIsUsed = 0x00000002,
86 
87   //! @brief Whether to output instructions also in binary form.
88   kLoggerOutputBinary = 0x00000010,
89   //! @brief Whether to output immediates as hexadecimal numbers.
90   kLoggerOutputHexImmediate = 0x00000020,
91   //! @brief Whether to output displacements as hexadecimal numbers.
92   kLoggerOutputHexDisplacement = 0x00000040
93 };
94 
95 // ============================================================================
96 // [AsmJit::kCpu]
97 // ============================================================================
98 
99 //! @brief Cpu vendor IDs.
100 //!
101 //! Cpu vendor IDs are specific for AsmJit library. Vendor ID is not directly
102 //! read from cpuid result, instead it's based on CPU vendor string.
103 enum kCpu
104 {
105   //! @brief Unknown CPU vendor.
106   kCpuUnknown = 0,
107 
108   //! @brief Intel CPU vendor.
109   kCpuIntel = 1,
110   //! @brief AMD CPU vendor.
111   kCpuAmd = 2,
112   //! @brief National Semiconductor CPU vendor (applies also to Cyrix processors).
113   kCpuNSM = 3,
114   //! @brief Transmeta CPU vendor.
115   kCpuTransmeta = 4,
116   //! @brief VIA CPU vendor.
117   kCpuVia = 5
118 };
119 
120 // ============================================================================
121 // [AsmJit::kMemAllocType]
122 // ============================================================================
123 
124 //! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method.
125 enum kMemAllocType
126 {
127   //! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free()
128   //! method.
129   kMemAllocFreeable = 0,
130   //! @brief Allocate permanent memory that will be never freed.
131   kMemAllocPermanent = 1
132 };
133 
134 // ============================================================================
135 // [AsmJit::kOperandType]
136 // ============================================================================
137 
138 //! @brief Operand types that can be encoded in @c Op operand.
139 enum kOperandType
140 {
141   //! @brief Operand is none, used only internally (not initialized Operand).
142   //!
143   //! This operand is not valid.
144   kOperandNone = 0x00,
145   //! @brief Operand is label.
146   kOperandLabel = 0x01,
147   //! @brief Operand is register.
148   kOperandReg = 0x02,
149   //! @brief Operand is variable.
150   kOperandVar = 0x04,
151   //! @brief Operand is memory.
152   kOperandMem = 0x08,
153   //! @brief Operand is immediate.
154   kOperandImm = 0x10
155 };
156 
157 // ============================================================================
158 // [AsmJit::kOperandMemType]
159 // ============================================================================
160 
161 //! @brief Type of memory operand.
162 enum kOperandMemType
163 {
164   //! @brief Operand is combination of register(s) and displacement (native).
165   kOperandMemNative = 0,
166   //! @brief Operand is label.
167   kOperandMemLabel = 1,
168   //! @brief Operand is absolute memory location (supported mainly in 32-bit mode)
169   kOperandMemAbsolute = 2,
170 };
171 
172 // ============================================================================
173 // [AsmJit::kOperandId]
174 // ============================================================================
175 
176 //! @brief Operand ID masks used to determine the operand type.
177 enum kOperandId
178 {
179   //! @brief Operand id type mask (part used for operand type).
180   kOperandIdTypeMask = 0xC0000000,
181   //! @brief Label operand mark id.
182   kOperandIdTypeLabel = 0x40000000,
183   //! @brief Variable operand mark id.
184   kOperandIdTypeVar = 0x80000000,
185 
186   //! @brief Operand id value mask (part used for IDs).
187   kOperandIdValueMask = 0x3FFFFFFF
188 };
189 
190 // ============================================================================
191 // [AsmJit::kRegType / kRegIndex]
192 // ============================================================================
193 
194 enum
195 {
196   //! @brief Mask for register type.
197   kRegTypeMask = 0xFF00,
198 
199   //! @brief Mask for register code (index).
200   kRegIndexMask = 0xFF,
201   //! @brief Invalid register index.
202   kRegIndexInvalid = 0xFF
203 };
204 
205 // ============================================================================
206 // [AsmJit::kCondHint]
207 // ============================================================================
208 
209 //! @brief Condition hint.
210 enum kCondHint
211 {
212   //! @brief No hint.
213   kCondHintNone = 0x00,
214   //! @brief Condition is likely to be taken.
215   kCondHintLikely = 0x01,
216   //! @brief Condition is unlikely to be taken.
217   kCondHintUnlikely = 0x02
218 };
219 
220 // ============================================================================
221 // [AsmJit::kFuncAnonymous]
222 // ============================================================================
223 
224 enum
225 {
226   //! @brief Maximum allowed arguments per function declaration / call.
227   kFuncArgsMax = 32,
228   //! @brief Invalid stack offset in function or function parameter.
229   kFuncStackInvalid = -1
230 };
231 
232 // ============================================================================
233 // [AsmJit::kFuncConv]
234 // ============================================================================
235 
236 enum kFuncConv
237 {
238   //! @brief Calling convention is invalid (can't be used).
239   kFuncConvNone = 0
240 };
241 
242 // ============================================================================
243 // [AsmJit::kFuncHint]
244 // ============================================================================
245 
246 //! @brief Function hints.
247 enum kFuncHint
248 {
249   //! @brief Make naked function (without using ebp/erp in prolog / epilog).
250   kFuncHintNaked = 0
251 };
252 
253 // ============================================================================
254 // [AsmJit::kFuncFlags]
255 // ============================================================================
256 
257 //! @brief Function flags.
258 enum kFuncFlags
259 {
260   //! @brief Whether another function is called from this function.
261   //!
262   //! If another function is called from this function, it's needed to prepare
263   //! stack for it. If this member is true then it's likely that true will be
264   //! also @c _isEspAdjusted one.
265   kFuncFlagIsCaller = (1U << 0),
266 
267   //! @brief Whether the function is finished using @c Compiler::endFunc().
268   kFuncFlagIsFinished = (1U << 1),
269 
270   //! @brief Whether the function is using naked (minimal) prolog / epilog.
271   kFuncFlagIsNaked = (1U << 2)
272 };
273 
274 // ============================================================================
275 // [AsmJit::kFuncArgsDirection]
276 // ============================================================================
277 
278 //! @brief Function arguments direction.
279 enum kFuncArgsDirection
280 {
281   //! @brief Arguments are passed left to right.
282   //!
283   //! This arguments direction is unusual to C programming, it's used by pascal
284   //! compilers and in some calling conventions by Borland compiler).
285   kFuncArgsLTR = 0,
286   //! @brief Arguments are passed right ro left
287   //!
288   //! This is default argument direction in C programming.
289   kFuncArgsRTL = 1
290 };
291 
292 // ============================================================================
293 // [AsmJit::kInstCode]
294 // ============================================================================
295 
296 enum kInstCode
297 {
298   //! @brief No instruction.
299   kInstNone = 0
300 };
301 
302 // ============================================================================
303 // [AsmJit::kVarAllocFlags]
304 // ============================================================================
305 
306 //! @brief Variable alloc mode.
307 enum kVarAllocFlags
308 {
309   //! @brief Allocating variable to read only.
310   //!
311   //! Read only variables are used to optimize variable spilling. If variable
312   //! is some time ago deallocated and it's not marked as changed (so it was
313   //! all the life time read only) then spill is simply NOP (no mov instruction
314   //! is generated to move it to it's home memory location).
315   kVarAllocRead = 0x01,
316   //! @brief Allocating variable to write only (overwrite).
317   //!
318   //! Overwriting means that if variable is in memory, there is no generated
319   //! instruction to move variable from memory to register, because that
320   //! register will be overwritten by next instruction. This is used as a
321   //! simple optimization to improve generated code by @c Compiler.
322   kVarAllocWrite = 0x02,
323   //! @brief Allocating variable to read / write.
324   //!
325   //! Variable allocated for read / write is marked as changed. This means that
326   //! if variable must be later spilled into memory, mov (or similar)
327   //! instruction will be generated.
328   kVarAllocReadWrite = 0x03,
329 
330   //! @brief Variable can be allocated in register.
331   kVarAllocRegister = 0x04,
332   //! @brief Variable can be allocated only to a special register.
333   kVarAllocSpecial = 0x08,
334 
335   //! @brief Variable can be allocated in memory.
336   kVarAllocMem = 0x10,
337 
338   //! @brief Unuse the variable after use.
339   kVarAllocUnuseAfterUse = 0x20
340 };
341 
342 // ============================================================================
343 // [AsmJit::kVarHint]
344 // ============================================================================
345 
346 //! @brief Variable hint (used by @ref Compiler).
347 //!
348 //! @sa @ref Compiler.
349 enum kVarHint
350 {
351   //! @brief Alloc variable.
352   kVarHintAlloc = 0,
353   //! @brief Spill variable.
354   kVarHintSpill = 1,
355   //! @brief Save variable if modified.
356   kVarHintSave = 2,
357   //! @brief Save variable if modified and mark it as unused.
358   kVarHintSaveAndUnuse = 3,
359   //! @brief Mark variable as unused.
360   kVarHintUnuse = 4
361 };
362 
363 // ============================================================================
364 // [AsmJit::kVarPolicy]
365 // ============================================================================
366 
367 //! @brief Variable allocation method.
368 //!
369 //! Variable allocation method is used by compiler and it means if compiler
370 //! should first allocate preserved registers or not. Preserved registers are
371 //! registers that must be saved / restored by generated function.
372 //!
373 //! This option is for people who are calling C/C++ functions from JIT code so
374 //! Compiler can recude generating push/pop sequences before and after call,
375 //! respectively.
376 enum kVarPolicy
377 {
378   //! @brief Allocate preserved registers first.
379   kVarPolicyPreservedFirst = 0,
380   //! @brief Allocate preserved registers last (default).
381   kVarPolicyPreservedLast = 1
382 };
383 
384 // ============================================================================
385 // [AsmJit::kVarState]
386 // ============================================================================
387 
388 //! @brief State of variable.
389 //!
390 //! @note State of variable is used only during make process and it's not
391 //! visible to the developer.
392 enum kVarState
393 {
394   //! @brief Variable is currently not used.
395   kVarStateUnused = 0,
396   //! @brief Variable is in register.
397   //!
398   //! Variable is currently allocated in register.
399   kVarStateReg = 1,
400   //! @brief Variable is in memory location or spilled.
401   //!
402   //! Variable was spilled from register to memory or variable is used for
403   //! memory only storage.
404   kVarStateMem = 2
405 };
406 
407 // ============================================================================
408 // [AsmJit::kVarType]
409 // ============================================================================
410 
411 enum kVarType
412 {
413   //! @brief Invalid variable type.
414   kVarTypeInvalid = 0xFF
415 };
416 
417 // ============================================================================
418 // [AsmJit::kScale]
419 // ============================================================================
420 
421 //! @brief Scale which can be used for addressing (it the target instruction
422 //! supports it).
423 //!
424 //! See @c Op and addressing methods like @c byte_ptr(), @c word_ptr(),
425 //! @c dword_ptr(), etc...
426 enum kScale
427 {
428   //! @brief No scale.
429   kScaleNone = 0,
430   //! @brief Scale 2 times (same as shifting to left by 1).
431   kScale2Times = 1,
432   //! @brief Scale 4 times (same as shifting to left by 2).
433   kScale4Times = 2,
434   //! @brief Scale 8 times (same as shifting to left by 3).
435   kScale8Times = 3
436 };
437 
438 // ============================================================================
439 // [AsmJit::kSize]
440 // ============================================================================
441 
442 //! @brief Size of registers and pointers.
443 enum kSize
444 {
445   //! @brief 1 byte size.
446   kSizeByte   = 1,
447   //! @brief 2 bytes size.
448   kSizeWord   = 2,
449   //! @brief 4 bytes size.
450   kSizeDWord  = 4,
451   //! @brief 8 bytes size.
452   kSizeQWord  = 8,
453   //! @brief 10 bytes size.
454   kSizeTWord  = 10,
455   //! @brief 16 bytes size.
456   kSizeDQWord = 16
457 };
458 
459 // ============================================================================
460 // [AsmJit::kRelocMode]
461 // ============================================================================
462 
463 enum kRelocMode
464 {
465   kRelocAbsToAbs = 0,
466   kRelocRelToAbs = 1,
467   kRelocAbsToRel = 2,
468   kRelocTrampoline = 3
469 };
470 
471 // ============================================================================
472 // [AsmJit::kCompilerItem]
473 // ============================================================================
474 
475 //! @brief Type of @ref CompilerItem.
476 //!
477 //! Each @c CompilerItem contains information about its type. Compiler can
478 //! optimize instruction stream by analyzing items and each type is hint
479 //! for it. The most used/serialized items are instructions
480 //! (@c kCompilerItemInst).
481 enum kCompilerItem
482 {
483   //! @brief Invalid item (can't be used).
484   kCompilerItemNone = 0,
485   //! @brief Item is mark, see @ref CompilerMark.
486   kCompilerItemMark,
487   //! @brief Item is comment, see @ref CompilerComment.
488   kCompilerItemComment,
489   //! @brief Item is embedded data, see @ref CompilerEmbed.
490   kCompilerItemEmbed,
491   //! @brief Item is .align directive, see @ref CompilerAlign.
492   kCompilerItemAlign,
493   //! @brief Item is variable hint (alloc, spill, use, unuse), see @ref CompilerHint.
494   kCompilerItemHint,
495   //! @brief Item is instruction, see @ref CompilerInst.
496   kCompilerItemInst,
497   //! @brief Item is target, see @ref CompilerTarget.
498   kCompilerItemTarget,
499   //! @brief Item is function call, see @ref CompilerFuncCall.
500   kCompilerItemFuncCall,
501   //! @brief Item is function declaration, see @ref CompilerFuncDecl.
502   kCompilerItemFuncDecl,
503   //! @brief Item is an end of the function, see @ref CompilerFuncEnd.
504   kCompilerItemFuncEnd,
505   //! @brief Item is function return, see @ref CompilerFuncRet.
506   kCompilerItemFuncRet
507 };
508 
509 // ============================================================================
510 // [AsmJit::kError]
511 // ============================================================================
512 
513 //! @brief Error codes.
514 enum kError
515 {
516   //! @brief No error (success).
517   //!
518   //! This is default state and state you want.
519   kErrorOk = 0,
520 
521   //! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL).
522   kErrorNoHeapMemory = 1,
523   //! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL).
524   kErrorNoVirtualMemory = 2,
525 
526   //! @brief Unknown instruction. This happens only if instruction code is
527   //! out of bounds. Shouldn't happen.
528   kErrorUnknownInstruction = 3,
529   //! @brief Illegal instruction, usually generated by AsmJit::Assembler
530   //! class when emitting instruction opcode. If this error is generated the
531   //! target buffer is not affected by this invalid instruction.
532   //!
533   //! You can also get this error code if you are under x64 (64-bit x86) and
534   //! you tried to decode instruction using AH, BH, CH or DH register with REX
535   //! prefix. These registers can't be accessed if REX prefix is used and AsmJit
536   //! didn't check for this situation in intrinsics (@c Compiler takes care of
537   //! this and rearrange registers if needed).
538   //!
539   //! Examples that will raise @c kErrorIllegalInstruction error (a is
540   //! @c Assembler instance):
541   //!
542   //! @code
543   //! a.mov(dword_ptr(eax), al); // Invalid address size.
544   //! a.mov(byte_ptr(r10), ah);  // Undecodable instruction (AH used with r10
545   //!                            // which can be encoded only using REX prefix)
546   //! @endcode
547   //!
548   //! @note In debug mode you get assertion failure instead of setting error
549   //! code.
550   kErrorIllegalInstruction = 4,
551   //! @brief Illegal addressing used (unencodable).
552   kErrorIllegalAddressing = 5,
553   //! @brief Short jump instruction used, but displacement is out of bounds.
554   kErrorIllegalShortJump = 6,
555 
556   //! @brief No function defined.
557   kErrorNoFunction = 7,
558   //! @brief Function generation is not finished by using @c Compiler::endFunc()
559   //! or something bad happened during generation related to function. This can
560   //! be missing compiler item, etc...
561   kErrorIncompleteFunction = 8,
562 
563   //! @brief Compiler can't allocate registers, because all of them are used.
564   //!
565   //! @note AsmJit is able to spill registers so this error really shouldn't
566   //! happen unless all registers have priority 0 (which means never spill).
567   kErrorNoRegisters = 9,
568   //! @brief Compiler can't allocate one register to multiple destinations.
569   //!
570   //! This error can only happen using special instructions like cmpxchg8b and
571   //! others where there are more destination operands (implicit).
572   kErrorOverlappedRegisters = 10,
573 
574   //! @brief Tried to call function using incompatible argument.
575   kErrorIncompatibleArgumentType = 11,
576   //! @brief Incompatible return value.
577   kErrorIncompatibleReturnType = 12,
578 
579   //! @brief Count of error codes by AsmJit. Can grow in future.
580   kErrorCount
581 };
582 
583 // ============================================================================
584 // [AsmJit::API]
585 // ============================================================================
586 
587 //! @brief Translates error code (see @c kError) into text representation.
588 ASMJIT_API const char* getErrorString(uint32_t error);
589 
590 //! @}
591 
592 } // AsmJit namespace
593 
594 // [Api-End]
595 #include "../core/apiend.h"
596 
597 // [Guard]
598 #endif // _ASMJIT_CORE_DEFS_H
599