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_X86_X86DEFS_H
9 #define _ASMJIT_X86_X86DEFS_H
10 
11 // [Dependencies - AsmJit]
12 #include "../core/assert.h"
13 #include "../core/defs.h"
14 
15 // [Api-Begin]
16 #include "../core/apibegin.h"
17 
18 namespace AsmJit {
19 
20 //! @addtogroup AsmJit_X86
21 //! @{
22 
23 // ============================================================================
24 // [AsmJit::kX86Feature]
25 // ============================================================================
26 
27 //! @brief X86 CPU features.
28 enum kX86Feature
29 {
30   //! @brief Cpu has RDTSC instruction.
31   kX86FeatureRdtsc = 1U << 0,
32   //! @brief Cpu has RDTSCP instruction.
33   kX86FeatureRdtscP = 1U << 1,
34   //! @brief Cpu has CMOV instruction (conditional move)
35   kX86FeatureCMov = 1U << 2,
36   //! @brief Cpu has CMPXCHG8B instruction
37   kX86FeatureCmpXchg8B = 1U << 3,
38   //! @brief Cpu has CMPXCHG16B instruction (64-bit processors)
39   kX86FeatureCmpXchg16B = 1U << 4,
40   //! @brief Cpu has CLFUSH instruction
41   kX86FeatureClFlush = 1U << 5,
42   //! @brief Cpu has PREFETCH instruction
43   kX86FeaturePrefetch = 1U << 6,
44   //! @brief Cpu supports LAHF and SAHF instrictions.
45   kX86FeatureLahfSahf = 1U << 7,
46   //! @brief Cpu supports FXSAVE and FXRSTOR instructions.
47   kX86FeatureFXSR = 1U << 8,
48   //! @brief Cpu supports FXSAVE and FXRSTOR instruction optimizations (FFXSR).
49   kX86FeatureFFXSR = 1U << 9,
50   //! @brief Cpu has MMX.
51   kX86FeatureMmx = 1U << 10,
52   //! @brief Cpu has extended MMX.
53   kX86FeatureMmxExt = 1U << 11,
54   //! @brief Cpu has 3dNow!
55   kX86Feature3dNow = 1U << 12,
56   //! @brief Cpu has enchanced 3dNow!
57   kX86Feature3dNowExt = 1U << 13,
58   //! @brief Cpu has SSE.
59   kX86FeatureSse = 1U << 14,
60   //! @brief Cpu has SSE2.
61   kX86FeatureSse2 = 1U << 15,
62   //! @brief Cpu has SSE3.
63   kX86FeatureSse3 = 1U << 16,
64   //! @brief Cpu has Supplemental SSE3 (SSSE3).
65   kX86FeatureSsse3 = 1U << 17,
66   //! @brief Cpu has SSE4.A.
67   kX86FeatureSse4A = 1U << 18,
68   //! @brief Cpu has SSE4.1.
69   kX86FeatureSse41 = 1U << 19,
70   //! @brief Cpu has SSE4.2.
71   kX86FeatureSse42 = 1U << 20,
72   //! @brief Cpu has AVX.
73   kX86FeatureAvx = 1U << 22,
74   //! @brief Cpu has Misaligned SSE (MSSE).
75   kX86FeatureMSse = 1U << 23,
76   //! @brief Cpu supports MONITOR and MWAIT instructions.
77   kX86FeatureMonitorMWait = 1U << 24,
78   //! @brief Cpu supports MOVBE instruction.
79   kX86FeatureMovBE = 1U << 25,
80   //! @brief Cpu supports POPCNT instruction.
81   kX86FeaturePopCnt = 1U << 26,
82   //! @brief Cpu supports LZCNT instruction.
83   kX86FeatureLzCnt = 1U << 27,
84   //! @brief Cpu supports PCLMULDQ set of instructions.
85   kX86FeaturePclMulDQ  = 1U << 28,
86   //! @brief Cpu supports multithreading.
87   kX86FeatureMultiThreading = 1U << 29,
88   //! @brief Cpu supports execute disable bit (execute protection).
89   kX86FeatureExecuteDisableBit = 1U << 30,
90   //! @brief 64-bit CPU.
91   kX86Feature64Bit = 1U << 31
92 };
93 
94 // ============================================================================
95 // [AsmJit::kX86Bug]
96 // ============================================================================
97 
98 //! @brief X86 CPU bugs.
99 enum kX86Bug
100 {
101   //! @brief Whether the processor contains bug seen in some
102   //! AMD-Opteron processors.
103   kX86BugAmdLockMB = 1U << 0
104 };
105 
106 // ============================================================================
107 // [AsmJit::kX86Property]
108 // ============================================================================
109 
110 //! @brief @ref X86Assembler and @ref X86Compiler properties.
111 enum kX86Property
112 {
113   //! @brief Optimize align for current processor.
114   //!
115   //! Default: @c true.
116   kX86PropertyOptimizedAlign = 0,
117 
118   //! @brief Emit hints added to jcc() instructions.
119   //!
120   //! Default: @c true.
121   kX86PropertyJumpHints = 1
122 };
123 
124 // ============================================================================
125 // [AsmJit::kX86Seg]
126 // ============================================================================
127 
128 //! @brief X86 segment codes.
129 enum kX86Seg
130 {
131   // DO NOT MODIFY INDEX CODES - They are used by _emitSegmentPrefix() and
132   // by logger in the following order:
133 
134   //! @brief ES segment.
135   kX86SegEs = 0,
136   //! @brief CS segment.
137   kX86SegCs = 1,
138   //! @brief SS segment.
139   kX86SegSs = 2,
140   //! @brief DS segment.
141   kX86SegDs = 3,
142   //! @brief FS segment.
143   kX86SegFs = 4,
144   //! @brief GS segment.
145   kX86SegGs = 5,
146   //! @brief Count of segments.
147   kX86SegCount = 6,
148 
149   //! @brief No segment override prefix.
150   kX86SegNone = 0xF
151 };
152 
153 // ============================================================================
154 // [AsmJit::kX86RegNum]
155 // ============================================================================
156 
157 //! @brief X86 registers count.
158 //!
159 //! Count of general purpose registers and XMM registers depends on current
160 //! mode. If application is compiled for 32-bit platform then this number is 8,
161 //! 64-bit platforms have 8 extra general purpose and XMM registers (16 total).
162 enum kX86RegNum
163 {
164   //! @var kX86RegNumBase
165   //!
166   //! Count of general purpose registers and XMM registers depends on current
167   //! bit-mode. If application is compiled for 32-bit platform then this number
168   //! is 8, 64-bit platforms have 8 extra general purpose and XMM registers (16
169   //! total).
170 #if defined(ASMJIT_X86)
171   kX86RegNumBase = 8,
172 #else
173   kX86RegNumBase = 16,
174 #endif // ASMJIT
175 
176   //! @brief Count of general purpose registers.
177   //!
178   //! 8 in 32-bit mode and 16 in 64-bit mode.
179   kX86RegNumGp = kX86RegNumBase,
180 
181   //! @brief Count of FPU stack registers (always 8).
182   kX86RegNumX87 = 8,
183   //! @brief Count of MM registers (always 8).
184   kX86RegNumMm = 8,
185 
186   //! @brief Count of XMM registers.
187   //!
188   //! 8 in 32-bit mode and 16 in 64-bit mode.
189   kX86RegNumXmm = kX86RegNumBase,
190   //! @brief Count of YMM registers.
191   //!
192   //! 8 in 32-bit mode and 16 in 64-bit mode.
193   kX86RegNumYmm = kX86RegNumBase,
194 
195   //! @brief Count of segment registers, including no segment (AsmJit specific).
196   //!
197   //! @note There are 6 segment registers, but AsmJit uses 0 as no segment, and
198   //! 1...6 as segment registers, this means that there are 7 segment registers
199   //! in AsmJit API, but only 6 can be used through @c Assembler or @c Compiler
200   //! API.
201   kX86RegNumSeg = 7
202 };
203 
204 //! @brief X86 register types.
205 enum kX86RegType
206 {
207   // First byte contains register type (mask 0xFF00), Second byte contains
208   // register index code.
209 
210   // --------------------------------------------------------------------------
211   // [GP Register Types]
212   // --------------------------------------------------------------------------
213 
214   //! @brief 8-bit general purpose register type (LO).
215   kX86RegTypeGpbLo = 0x0100,
216   //! @brief 8-bit general purpose register type (HI, only AH, BH, CH, DH).
217   kX86RegTypeGpbHi = 0x0200,
218   //! @brief 16-bit general purpose register type.
219   kX86RegTypeGpw = 0x1000,
220   //! @brief 32-bit general purpose register type.
221   kX86RegTypeGpd = 0x2000,
222   //! @brief 64-bit general purpose register type.
223   kX86RegTypeGpq = 0x3000,
224 
225   //! @var kX86RegTypeGpz
226   //! @brief 32-bit or 64-bit general purpose register type.
227 #if defined(ASMJIT_X86)
228   kX86RegTypeGpz = kX86RegTypeGpd,
229 #else
230   kX86RegTypeGpz = kX86RegTypeGpq,
231 #endif
232 
233   //! @brief X87 (FPU) register type.
234   kX86RegTypeX87 = 0x5000,
235   //! @brief 64-bit MM register type.
236   kX86RegTypeMm = 0x6000,
237 
238   //! @brief 128-bit XMM register type.
239   kX86RegTypeXmm = 0x7000,
240   //! @brief 256-bit YMM register type.
241   kX86RegTypeYmm = 0x8000,
242 
243   //! @brief 16-bit segment register type.
244   kX86RegTypeSeg = 0xD000
245 };
246 
247 // ============================================================================
248 // [AsmJit::kX86RegIndex]
249 // ============================================================================
250 
251 //! @brief X86 register indices.
252 //!
253 //! These codes are real, don't miss with @c REG enum! and don't use these
254 //! values if you are not writing AsmJit code.
255 enum kX86RegIndex
256 {
257   //! @brief ID for AX/EAX/RAX registers.
258   kX86RegIndexEax = 0,
259   //! @brief ID for CX/ECX/RCX registers.
260   kX86RegIndexEcx = 1,
261   //! @brief ID for DX/EDX/RDX registers.
262   kX86RegIndexEdx = 2,
263   //! @brief ID for BX/EBX/RBX registers.
264   kX86RegIndexEbx = 3,
265   //! @brief ID for SP/ESP/RSP registers.
266   kX86RegIndexEsp = 4,
267   //! @brief ID for BP/EBP/RBP registers.
268   kX86RegIndexEbp = 5,
269   //! @brief ID for SI/ESI/RSI registers.
270   kX86RegIndexEsi = 6,
271   //! @brief ID for DI/EDI/RDI registers.
272   kX86RegIndexEdi = 7,
273 
274   //! @brief ID for AX/EAX/RAX registers.
275   kX86RegIndexRax = 0,
276   //! @brief ID for CX/ECX/RCX registers.
277   kX86RegIndexRcx = 1,
278   //! @brief ID for DX/EDX/RDX registers.
279   kX86RegIndexRdx = 2,
280   //! @brief ID for BX/EBX/RBX registers.
281   kX86RegIndexRbx = 3,
282   //! @brief ID for SP/ESP/RSP registers.
283   kX86RegIndexRsp = 4,
284   //! @brief ID for BP/EBP/RBP registers.
285   kX86RegIndexRbp = 5,
286   //! @brief ID for SI/ESI/RSI registers.
287   kX86RegIndexRsi = 6,
288   //! @brief ID for DI/EDI/RDI registers.
289   kX86RegIndexRdi = 7,
290 
291   //! @brief ID for r8 register (additional register introduced by 64-bit architecture).
292   kX86RegIndexR8 = 8,
293   //! @brief ID for R9 register (additional register introduced by 64-bit architecture).
294   kX86RegIndexR9 = 9,
295   //! @brief ID for R10 register (additional register introduced by 64-bit architecture).
296   kX86RegIndexR10 = 10,
297   //! @brief ID for R11 register (additional register introduced by 64-bit architecture).
298   kX86RegIndexR11 = 11,
299   //! @brief ID for R12 register (additional register introduced by 64-bit architecture).
300   kX86RegIndexR12 = 12,
301   //! @brief ID for R13 register (additional register introduced by 64-bit architecture).
302   kX86RegIndexR13 = 13,
303   //! @brief ID for R14 register (additional register introduced by 64-bit architecture).
304   kX86RegIndexR14 = 14,
305   //! @brief ID for R15 register (additional register introduced by 64-bit architecture).
306   kX86RegIndexR15 = 15,
307 
308   //! @brief ID for mm0 register.
309   kX86RegIndexMm0 = 0,
310   //! @brief ID for mm1 register.
311   kX86RegIndexMm1 = 1,
312   //! @brief ID for mm2 register.
313   kX86RegIndexMm2 = 2,
314   //! @brief ID for mm3 register.
315   kX86RegIndexMm3 = 3,
316   //! @brief ID for mm4 register.
317   kX86RegIndexMm4 = 4,
318   //! @brief ID for mm5 register.
319   kX86RegIndexMm5 = 5,
320   //! @brief ID for mm6 register.
321   kX86RegIndexMm6 = 6,
322   //! @brief ID for mm7 register.
323   kX86RegIndexMm7 = 7,
324 
325   //! @brief ID for xmm0 register.
326   kX86RegIndexXmm0 = 0,
327   //! @brief ID for xmm1 register.
328   kX86RegIndexXmm1 = 1,
329   //! @brief ID for xmm2 register.
330   kX86RegIndexXmm2 = 2,
331   //! @brief ID for xmm3 register.
332   kX86RegIndexXmm3 = 3,
333   //! @brief ID for xmm4 register.
334   kX86RegIndexXmm4 = 4,
335   //! @brief ID for xmm5 register.
336   kX86RegIndexXmm5 = 5,
337   //! @brief ID for xmm6 register.
338   kX86RegIndexXmm6 = 6,
339   //! @brief ID for xmm7 register.
340   kX86RegIndexXmm7 = 7,
341 
342   //! @brief ID for xmm8 register (additional register introduced by 64-bit architecture).
343   kX86RegIndexXmm8 = 8,
344   //! @brief ID for xmm9 register (additional register introduced by 64-bit architecture).
345   kX86RegIndexXmm9 = 9,
346   //! @brief ID for xmm10 register (additional register introduced by 64-bit architecture).
347   kX86RegIndexXmm10 = 10,
348   //! @brief ID for xmm11 register (additional register introduced by 64-bit architecture).
349   kX86RegIndexXmm11 = 11,
350   //! @brief ID for xmm12 register (additional register introduced by 64-bit architecture).
351   kX86RegIndexXmm12 = 12,
352   //! @brief ID for xmm13 register (additional register introduced by 64-bit architecture).
353   kX86RegIndexXmm13 = 13,
354   //! @brief ID for xmm14 register (additional register introduced by 64-bit architecture).
355   kX86RegIndexXmm14 = 14,
356   //! @brief ID for xmm15 register (additional register introduced by 64-bit architecture).
357   kX86RegIndexXmm15 = 15,
358 
359   //! @brief ID for ES segment register.
360   kX86RegIndexEs = 0,
361   //! @brief ID for CS segment register.
362   kX86RegIndexCs = 1,
363   //! @brief ID for SS segment register.
364   kX86RegIndexSs = 2,
365   //! @brief ID for DS segment register.
366   kX86RegIndexDs = 3,
367   //! @brief ID for FS segment register.
368   kX86RegIndexFs = 4,
369   //! @brief ID for GS segment register.
370   kX86RegIndexGs = 5
371 };
372 
373 // ============================================================================
374 // [AsmJit::kX86RegCode]
375 // ============================================================================
376 
377 //! @brief X86 pseudo (not real X86) register codes used for generating opcodes.
378 //!
379 //! From this register code can be generated real x86 register ID, type of
380 //! register and size of register.
381 enum kX86RegCode
382 {
383   // --------------------------------------------------------------------------
384   // [8-bit Registers]
385   // --------------------------------------------------------------------------
386 
387   kX86RegAl = kX86RegTypeGpbLo,
388   kX86RegCl,
389   kX86RegDl,
390   kX86RegBl,
391 #if defined(ASMJIT_X64)
392   kX86RegSpl,
393   kX86RegBpl,
394   kX86RegSil,
395   kX86RegDil,
396 #endif // ASMJIT_X64
397 
398 #if defined(ASMJIT_X64)
399   kX86RegR8b,
400   kX86RegR9b,
401   kX86RegR10b,
402   kX86RegR11b,
403   kX86RegR12b,
404   kX86RegR13b,
405   kX86RegR14b,
406   kX86RegR15b,
407 #endif // ASMJIT_X64
408 
409   kX86RegAh = kX86RegTypeGpbHi,
410   kX86RegCh,
411   kX86RegDh,
412   kX86RegBh,
413 
414   // --------------------------------------------------------------------------
415   // [16-bit Registers]
416   // --------------------------------------------------------------------------
417 
418   kX86RegAx = kX86RegTypeGpw,
419   kX86RegCx,
420   kX86RegDx,
421   kX86RegBx,
422   kX86RegSp,
423   kX86RegBp,
424   kX86RegSi,
425   kX86RegDi,
426 #if defined(ASMJIT_X64)
427   kX86RegR8w,
428   kX86RegR9w,
429   kX86RegR10w,
430   kX86RegR11w,
431   kX86RegR12w,
432   kX86RegR13w,
433   kX86RegR14w,
434   kX86RegR15w,
435 #endif // ASMJIT_X64
436 
437   // --------------------------------------------------------------------------
438   // [32-bit Registers]
439   // --------------------------------------------------------------------------
440 
441   kX86RegEax = kX86RegTypeGpd,
442   kX86RegEcx,
443   kX86RegEdx,
444   kX86RegEbx,
445   kX86RegEsp,
446   kX86RegEbp,
447   kX86RegEsi,
448   kX86RegEdi,
449 #if defined(ASMJIT_X64)
450   kX86RegR8d,
451   kX86RegR9d,
452   kX86RegR10d,
453   kX86RegR11d,
454   kX86RegR12d,
455   kX86RegR13d,
456   kX86RegR14d,
457   kX86RegR15d,
458 #endif // ASMJIT_X64
459 
460   // --------------------------------------------------------------------------
461   // [64-bit Registers]
462   // --------------------------------------------------------------------------
463 
464 #if defined(ASMJIT_X64)
465   kX86RegRax = kX86RegTypeGpq,
466   kX86RegRcx,
467   kX86RegRdx,
468   kX86RegRbx,
469   kX86RegRsp,
470   kX86RegRbp,
471   kX86RegRsi,
472   kX86RegRdi,
473   kX86RegR8,
474   kX86RegR9,
475   kX86RegR10,
476   kX86RegR11,
477   kX86RegR12,
478   kX86RegR13,
479   kX86RegR14,
480   kX86RegR15,
481 #endif // ASMJIT_X64
482 
483   // --------------------------------------------------------------------------
484   // [MM Registers]
485   // --------------------------------------------------------------------------
486 
487   kX86RegMm0 = kX86RegTypeMm,
488   kX86RegMm1,
489   kX86RegMm2,
490   kX86RegMm3,
491   kX86RegMm4,
492   kX86RegMm5,
493   kX86RegMm6,
494   kX86RegMm7,
495 
496   // --------------------------------------------------------------------------
497   // [XMM Registers]
498   // --------------------------------------------------------------------------
499 
500   kX86RegXmm0 = kX86RegTypeXmm,
501   kX86RegXmm1,
502   kX86RegXmm2,
503   kX86RegXmm3,
504   kX86RegXmm4,
505   kX86RegXmm5,
506   kX86RegXmm6,
507   kX86RegXmm7,
508 #if defined(ASMJIT_X64)
509   kX86RegXmm8,
510   kX86RegXmm9,
511   kX86RegXmm10,
512   kX86RegXmm11,
513   kX86RegXmm12,
514   kX86RegXmm13,
515   kX86RegXmm14,
516   kX86RegXmm15,
517 #endif // ASMJIT_X64
518 
519   // --------------------------------------------------------------------------
520   // [Native registers (depends on 32-bit or 64-bit mode)]
521   // --------------------------------------------------------------------------
522 
523   kX86RegZax = kX86RegTypeGpz,
524   kX86RegZcx,
525   kX86RegZdx,
526   kX86RegZbx,
527   kX86RegZsp,
528   kX86RegZbp,
529   kX86RegZsi,
530   kX86RegZdi,
531 
532   // --------------------------------------------------------------------------
533   // [Segment registers]
534   // --------------------------------------------------------------------------
535 
536   //! @brief ES segment register.
537   kX86RegEs = kX86RegTypeSeg,
538   //! @brief CS segment register.
539   kX86RegCs,
540   //! @brief SS segment register.
541   kX86RegSs,
542   //! @brief DS segment register.
543   kX86RegDs,
544   //! @brief FS segment register.
545   kX86RegFs,
546   //! @brief GS segment register.
547   kX86RegGs
548 };
549 
550 // ============================================================================
551 // [AsmJit::kX86Cond]
552 // ============================================================================
553 
554 //! @brief X86 Condition codes.
555 enum kX86Cond
556 {
557   // Condition codes from processor manuals.
558   kX86CondA               = 0x07,
559   kX86CondAE              = 0x03,
560   kX86CondB               = 0x02,
561   kX86CondBE              = 0x06,
562   kX86CondC               = 0x02,
563   kX86CondE               = 0x04,
564   kX86CondG               = 0x0F,
565   kX86CondGE              = 0x0D,
566   kX86CondL               = 0x0C,
567   kX86CondLE              = 0x0E,
568   kX86CondNA              = 0x06,
569   kX86CondNAE             = 0x02,
570   kX86CondNB              = 0x03,
571   kX86CondNBE             = 0x07,
572   kX86CondNC              = 0x03,
573   kX86CondNE              = 0x05,
574   kX86CondNG              = 0x0E,
575   kX86CondNGE             = 0x0C,
576   kX86CondNL              = 0x0D,
577   kX86CondNLE             = 0x0F,
578   kX86CondNO              = 0x01,
579   kX86CondNP              = 0x0B,
580   kX86CondNS              = 0x09,
581   kX86CondNZ              = 0x05,
582   kX86CondO               = 0x00,
583   kX86CondP               = 0x0A,
584   kX86CondPE              = 0x0A,
585   kX86CondPO              = 0x0B,
586   kX86CondS               = 0x08,
587   kX86CondZ               = 0x04,
588 
589   // Simplified condition codes.
590   kX86CondOverflow        = 0x00,
591   kX86CondNotOverflow     = 0x01,
592   kX86CondBelow           = 0x02,
593   kX86CondAboveEqual      = 0x03,
594   kX86CondEqual           = 0x04,
595   kX86CondNotEqual        = 0x05,
596   kX86CondBelowEqual      = 0x06,
597   kX86CondAbove           = 0x07,
598   kX86CondSign            = 0x08,
599   kX86CondNotSign         = 0x09,
600   kX86CondParityEven      = 0x0A,
601   kX86CondParityOdd       = 0x0B,
602   kX86CondLess            = 0x0C,
603   kX86CondGreaterEqual    = 0x0D,
604   kX86CondLessEqual       = 0x0E,
605   kX86CondGreater         = 0x0F,
606 
607   // Aliases.
608   kX86CondZero            = 0x04,
609   kX86CondNotZero         = 0x05,
610   kX86CondNegative        = 0x08,
611   kX86CondPositive        = 0x09,
612 
613   // X87 floating point only.
614   kX86CondFpuUnordered    = 0x10,
615   kX86CondFpuNotUnordered = 0x11,
616 
617   //! @brief No condition code.
618   kX86CondNone            = 0x12
619 };
620 
621 // ============================================================================
622 // [AsmJit::kX86CondPrefix]
623 // ============================================================================
624 
625 //! @brief X86 condition hint prefix code, see @ref kCondHint.
626 enum kX86CondPrefix
627 {
628   //! @brief Condition is likely to be taken.
629   kX86CondPrefixLikely = 0x3E,
630   //! @brief Condition is unlikely to be taken.
631   kX86CondPrefixUnlikely = 0x2E
632 };
633 
634 // ============================================================================
635 // [AsmJit::kX86PrefetchHint]
636 // ============================================================================
637 
638 //! @brief X86 Prefetch hints.
639 enum kX86PrefetchHint
640 {
641   //! @brief Prefetch using NT hint.
642   kX86PrefetchNta = 0,
643   //! @brief Prefetch to L0 cache.
644   kX86PrefetchT0 = 1,
645   //! @brief Prefetch to L1 cache.
646   kX86PrefetchT1 = 2,
647   //! @brief Prefetch to L2 cache.
648   kX86PrefetchT2 = 3
649 };
650 
651 // ============================================================================
652 // [AsmJit::kX86FPSW]
653 // ============================================================================
654 
655 //! @brief X86 FPU status-word.
656 enum kX86FPSW
657 {
658   kX86FPSW_Invalid        = 0x0001,
659   kX86FPSW_Denormalized   = 0x0002,
660   kX86FPSW_DivByZero      = 0x0004,
661   kX86FPSW_Overflow       = 0x0008,
662   kX86FPSW_Underflow      = 0x0010,
663   kX86FPSW_Precision      = 0x0020,
664   kX86FPSW_StackFault     = 0x0040,
665   kX86FPSW_Interrupt      = 0x0080,
666   kX86FPSW_C0             = 0x0100,
667   kX86FPSW_C1             = 0x0200,
668   kX86FPSW_C2             = 0x0400,
669   kX86FPSW_Top            = 0x3800,
670   kX86FPSW_C3             = 0x4000,
671   kX86FPSW_Busy           = 0x8000
672 };
673 
674 // ============================================================================
675 // [AsmJit::kX86FPCW]
676 // ============================================================================
677 
678 //! @brief X86 FPU control-word.
679 enum kX86FPCW
680 {
681   // --------------------------------------------------------------------------
682   // [Exception-Mask]
683   // --------------------------------------------------------------------------
684 
685   kX86FPCW_EM_Mask        = 0x003F, // Bits 0-5.
686 
687   kX86FPCW_EM_Invalid     = 0x0001,
688   kX86FPCW_EM_Denormal    = 0x0002,
689   kX86FPCW_EM_DivByZero   = 0x0004,
690   kX86FPCW_EM_Overflow    = 0x0008,
691   kX86FPCW_EM_Underflow   = 0x0010,
692   kX86FPCW_EM_Inexact     = 0x0020,
693 
694   // --------------------------------------------------------------------------
695   // [Precision-Control]
696   // --------------------------------------------------------------------------
697 
698   kX86FPCW_PC_Mask        = 0x0300, // Bits 8-9.
699 
700   kX86FPCW_PC_Float       = 0x0000,
701   kX86FPCW_PC_Reserved    = 0x0100,
702   kX86FPCW_PC_Double      = 0x0200,
703   kX86FPCW_PC_Extended    = 0x0300,
704 
705   // --------------------------------------------------------------------------
706   // [Rounding-Control]
707   // --------------------------------------------------------------------------
708 
709   kX86FPCW_RC_Mask        = 0x0C00, // Bits 10-11.
710 
711   kX86FPCW_RC_Nearest     = 0x0000,
712   kX86FPCW_RC_Down        = 0x0400,
713   kX86FPCW_RC_Up          = 0x0800,
714   kX86FPCW_RC_Truncate    = 0x0C00,
715 
716   // --------------------------------------------------------------------------
717   // [Infinity-Control]
718   // --------------------------------------------------------------------------
719 
720   kX86FPCW_IC_Mask        = 0x1000, // Bit 12.
721 
722   kX86FPCW_IC_Projective  = 0x0000,
723   kX86FPCW_IC_Affine      = 0x1000
724 };
725 
726 // ============================================================================
727 // [AsmJit::kX86EmitOption]
728 // ============================================================================
729 
730 //! @brief Emit options, mainly for internal purposes.
731 enum kX86EmitOption
732 {
733   //! @brief Force REX prefix to be emitted.
734   //!
735   //! This option should be used carefully, because there are unencodable
736   //! combinations. If you want to access ah, bh, ch or dh registers then you
737   //! can't emit REX prefix and it will cause an illegal instruction error.
738   kX86EmitOptionRex = 0x1,
739 
740   //! @brief Tell @c Assembler or @c Compiler to emit and validate lock prefix.
741   //!
742   //! If this option is used and instruction doesn't support LOCK prefix then
743   //! invalid instruction error is generated.
744   kX86EmitOptionLock = 0x2,
745 
746   //! @brief Emit short/near jump or conditional jump instead of far one to
747   //! some bytes.
748   //!
749   //! @note This option could be dangerous in case that the short jump is not
750   //! possible (displacement can't fit into signed 8-bit integer). AsmJit can
751   //! automatically generate back short jumps, but always generates long forward
752   //! jumps, because the information about the code size between the instruction
753   //! and target is not known.
754   kX86EmitOptionShortJump = 0x4,
755 
756   //! @brief Emit full immediate instead of BYTE in all cases.
757   //!
758   //! @note AsmJit is able to emit both forms of immediate value. In case that
759   //! the instruction supports short form and immediate can fit into a signed
760   //! 8-bit integer short for is preferred, but if for any reason the full form
761   //! is required it can be overridden by using this option.
762   kX86EmitOptionFullImmediate = 0x8
763 };
764 
765 // ============================================================================
766 // [AsmJit::kX86InstCode]
767 // ============================================================================
768 
769 //! @brief X86 instruction codes.
770 //!
771 //! Note that these instruction codes are AsmJit specific. Each instruction is
772 //! unique ID into AsmJit instruction table. Instruction codes are used together
773 //! with AsmJit::Assembler and you can also use instruction codes to serialize
774 //! instructions by @ref Assembler::_emitInstruction() or
775 //! @ref Compiler::_emitInstruction()
776 enum kX86InstCode
777 {
778   kX86InstAdc = 1,         // X86/X64
779   kX86InstAdd,             // X86/X64
780   kX86InstAddPD,           // SSE2
781   kX86InstAddPS,           // SSE
782   kX86InstAddSD,           // SSE2
783   kX86InstAddSS,           // SSE
784   kX86InstAddSubPD,        // SSE3
785   kX86InstAddSubPS,        // SSE3
786   kX86InstAmdPrefetch,     // 3dNow!
787   kX86InstAmdPrefetchW,    // 3dNow!
788   kX86InstAnd,             // X86/X64
789   kX86InstAndnPD,          // SSE2
790   kX86InstAndnPS,          // SSE
791   kX86InstAndPD,           // SSE2
792   kX86InstAndPS,           // SSE
793   kX86InstBlendPD,         // SSE4.1
794   kX86InstBlendPS,         // SSE4.1
795   kX86InstBlendVPD,        // SSE4.1
796   kX86InstBlendVPS,        // SSE4.1
797   kX86InstBsf,             // X86/X64
798   kX86InstBsr,             // X86/X64
799   kX86InstBSwap,           // X86/X64 (i486)
800   kX86InstBt,              // X86/X64
801   kX86InstBtc,             // X86/X64
802   kX86InstBtr,             // X86/X64
803   kX86InstBts,             // X86/X64
804   kX86InstCall,            // X86/X64
805   kX86InstCbw,             // X86/X64
806   kX86InstCdq,             // X86/X64
807   kX86InstCdqe,            // X64 only
808   kX86InstClc,             // X86/X64
809   kX86InstCld,             // X86/X64
810   kX86InstClFlush,         // SSE2
811   kX86InstCmc,             // X86/X64
812 
813   kX86InstCMov,            // Begin (cmovcc) (i586)
814   kX86InstCMovA=kX86InstCMov,//X86/X64 (cmovcc) (i586)
815   kX86InstCMovAE,          // X86/X64 (cmovcc) (i586)
816   kX86InstCMovB,           // X86/X64 (cmovcc) (i586)
817   kX86InstCMovBE,          // X86/X64 (cmovcc) (i586)
818   kX86InstCMovC,           // X86/X64 (cmovcc) (i586)
819   kX86InstCMovE,           // X86/X64 (cmovcc) (i586)
820   kX86InstCMovG,           // X86/X64 (cmovcc) (i586)
821   kX86InstCMovGE,          // X86/X64 (cmovcc) (i586)
822   kX86InstCMovL,           // X86/X64 (cmovcc) (i586)
823   kX86InstCMovLE,          // X86/X64 (cmovcc) (i586)
824   kX86InstCMovNA,          // X86/X64 (cmovcc) (i586)
825   kX86InstCMovNAE,         // X86/X64 (cmovcc) (i586)
826   kX86InstCMovNB,          // X86/X64 (cmovcc) (i586)
827   kX86InstCMovNBE,         // X86/X64 (cmovcc) (i586)
828   kX86InstCMovNC,          // X86/X64 (cmovcc) (i586)
829   kX86InstCMovNE,          // X86/X64 (cmovcc) (i586)
830   kX86InstCMovNG,          // X86/X64 (cmovcc) (i586)
831   kX86InstCMovNGE,         // X86/X64 (cmovcc) (i586)
832   kX86InstCMovNL,          // X86/X64 (cmovcc) (i586)
833   kX86InstCMovNLE,         // X86/X64 (cmovcc) (i586)
834   kX86InstCMovNO,          // X86/X64 (cmovcc) (i586)
835   kX86InstCMovNP,          // X86/X64 (cmovcc) (i586)
836   kX86InstCMovNS,          // X86/X64 (cmovcc) (i586)
837   kX86InstCMovNZ,          // X86/X64 (cmovcc) (i586)
838   kX86InstCMovO,           // X86/X64 (cmovcc) (i586)
839   kX86InstCMovP,           // X86/X64 (cmovcc) (i586)
840   kX86InstCMovPE,          // X86/X64 (cmovcc) (i586)
841   kX86InstCMovPO,          // X86/X64 (cmovcc) (i586)
842   kX86InstCMovS,           // X86/X64 (cmovcc) (i586)
843   kX86InstCMovZ,           // X86/X64 (cmovcc) (i586)
844 
845   kX86InstCmp,             // X86/X64
846   kX86InstCmpPD,           // SSE2
847   kX86InstCmpPS,           // SSE
848   kX86InstCmpSD,           // SSE2
849   kX86InstCmpSS,           // SSE
850   kX86InstCmpXCHG,         // X86/X64 (i486)
851   kX86InstCmpXCHG16B,      // X64 only
852   kX86InstCmpXCHG8B,       // X86/X64 (i586)
853   kX86InstComISD,          // SSE2
854   kX86InstComISS,          // SSE
855   kX86InstCpuId,           // X86/X64 (i486)
856   kX86InstCqo,             // X64 only
857   kX86InstCrc32,           // SSE4.2
858   kX86InstCvtDQ2PD,        // SSE2
859   kX86InstCvtDQ2PS,        // SSE2
860   kX86InstCvtPD2DQ,        // SSE2
861   kX86InstCvtPD2PI,        // SSE2
862   kX86InstCvtPD2PS,        // SSE2
863   kX86InstCvtPI2PD,        // SSE2
864   kX86InstCvtPI2PS,        // SSE
865   kX86InstCvtPS2DQ,        // SSE2
866   kX86InstCvtPS2PD,        // SSE2
867   kX86InstCvtPS2PI,        // SSE
868   kX86InstCvtSD2SI,        // SSE2
869   kX86InstCvtSD2SS,        // SSE2
870   kX86InstCvtSI2SD,        // SSE2
871   kX86InstCvtSI2SS,        // SSE
872   kX86InstCvtSS2SD,        // SSE2
873   kX86InstCvtSS2SI,        // SSE
874   kX86InstCvttPD2DQ,       // SSE2
875   kX86InstCvttPD2PI,       // SSE2
876   kX86InstCvttPS2DQ,       // SSE2
877   kX86InstCvttPS2PI,       // SSE
878   kX86InstCvttSD2SI,       // SSE2
879   kX86InstCvttSS2SI,       // SSE
880   kX86InstCwd,             // X86/X64
881   kX86InstCwde,            // X86/X64
882   kX86InstDaa,             // X86 only
883   kX86InstDas,             // X86 only
884   kX86InstDec,             // X86/X64
885   kX86InstDiv,             // X86/X64
886   kX86InstDivPD,           // SSE2
887   kX86InstDivPS,           // SSE
888   kX86InstDivSD,           // SSE2
889   kX86InstDivSS,           // SSE
890   kX86InstDpPD,            // SSE4.1
891   kX86InstDpPS,            // SSE4.1
892   kX86InstEmms,            // MMX
893   kX86InstEnter,           // X86/X64
894   kX86InstExtractPS,       // SSE4.1
895   kX86InstF2XM1,           // X87
896   kX86InstFAbs,            // X87
897   kX86InstFAdd,            // X87
898   kX86InstFAddP,           // X87
899   kX86InstFBLd,            // X87
900   kX86InstFBStP,           // X87
901   kX86InstFCHS,            // X87
902   kX86InstFClex,           // X87
903   kX86InstFCMovB,          // X87
904   kX86InstFCMovBE,         // X87
905   kX86InstFCMovE,          // X87
906   kX86InstFCMovNB,         // X87
907   kX86InstFCMovNBE,        // X87
908   kX86InstFCMovNE,         // X87
909   kX86InstFCMovNU,         // X87
910   kX86InstFCMovU,          // X87
911   kX86InstFCom,            // X87
912   kX86InstFComI,           // X87
913   kX86InstFComIP,          // X87
914   kX86InstFComP,           // X87
915   kX86InstFComPP,          // X87
916   kX86InstFCos,            // X87
917   kX86InstFDecStP,         // X87
918   kX86InstFDiv,            // X87
919   kX86InstFDivP,           // X87
920   kX86InstFDivR,           // X87
921   kX86InstFDivRP,          // X87
922   kX86InstFEmms,           // 3dNow!
923   kX86InstFFree,           // X87
924   kX86InstFIAdd,           // X87
925   kX86InstFICom,           // X87
926   kX86InstFIComP,          // X87
927   kX86InstFIDiv,           // X87
928   kX86InstFIDivR,          // X87
929   kX86InstFILd,            // X87
930   kX86InstFIMul,           // X87
931   kX86InstFIncStP,         // X87
932   kX86InstFInit,           // X87
933   kX86InstFISt,            // X87
934   kX86InstFIStP,           // X87
935   kX86InstFISttP,          // SSE3
936   kX86InstFISub,           // X87
937   kX86InstFISubR,          // X87
938   kX86InstFLd,             // X87
939   kX86InstFLd1,            // X87
940   kX86InstFLdCw,           // X87
941   kX86InstFLdEnv,          // X87
942   kX86InstFLdL2E,          // X87
943   kX86InstFLdL2T,          // X87
944   kX86InstFLdLg2,          // X87
945   kX86InstFLdLn2,          // X87
946   kX86InstFLdPi,           // X87
947   kX86InstFLdZ,            // X87
948   kX86InstFMul,            // X87
949   kX86InstFMulP,           // X87
950   kX86InstFNClex,          // X87
951   kX86InstFNInit,          // X87
952   kX86InstFNop,            // X87
953   kX86InstFNSave,          // X87
954   kX86InstFNStCw,          // X87
955   kX86InstFNStEnv,         // X87
956   kX86InstFNStSw,          // X87
957   kX86InstFPAtan,          // X87
958   kX86InstFPRem,           // X87
959   kX86InstFPRem1,          // X87
960   kX86InstFPTan,           // X87
961   kX86InstFRndInt,         // X87
962   kX86InstFRstor,          // X87
963   kX86InstFSave,           // X87
964   kX86InstFScale,          // X87
965   kX86InstFSin,            // X87
966   kX86InstFSinCos,         // X87
967   kX86InstFSqrt,           // X87
968   kX86InstFSt,             // X87
969   kX86InstFStCw,           // X87
970   kX86InstFStEnv,          // X87
971   kX86InstFStP,            // X87
972   kX86InstFStSw,           // X87
973   kX86InstFSub,            // X87
974   kX86InstFSubP,           // X87
975   kX86InstFSubR,           // X87
976   kX86InstFSubRP,          // X87
977   kX86InstFTst,            // X87
978   kX86InstFUCom,           // X87
979   kX86InstFUComI,          // X87
980   kX86InstFUComIP,         // X87
981   kX86InstFUComP,          // X87
982   kX86InstFUComPP,         // X87
983   kX86InstFWait,           // X87
984   kX86InstFXam,            // X87
985   kX86InstFXch,            // X87
986   kX86InstFXRstor,         // X87
987   kX86InstFXSave,          // X87
988   kX86InstFXtract,         // X87
989   kX86InstFYL2X,           // X87
990   kX86InstFYL2XP1,         // X87
991   kX86InstHAddPD,          // SSE3
992   kX86InstHAddPS,          // SSE3
993   kX86InstHSubPD,          // SSE3
994   kX86InstHSubPS,          // SSE3
995   kX86InstIDiv,            // X86/X64
996   kX86InstIMul,            // X86/X64
997   kX86InstInc,             // X86/X64
998   kX86InstInt3,            // X86/X64
999   kX86InstJ,               // Begin (jcc)
1000   kX86InstJA = kX86InstJ,  // X86/X64 (jcc)
1001   kX86InstJAE,             // X86/X64 (jcc)
1002   kX86InstJB,              // X86/X64 (jcc)
1003   kX86InstJBE,             // X86/X64 (jcc)
1004   kX86InstJC,              // X86/X64 (jcc)
1005   kX86InstJE,              // X86/X64 (jcc)
1006   kX86InstJG,              // X86/X64 (jcc)
1007   kX86InstJGE,             // X86/X64 (jcc)
1008   kX86InstJL,              // X86/X64 (jcc)
1009   kX86InstJLE,             // X86/X64 (jcc)
1010   kX86InstJNA,             // X86/X64 (jcc)
1011   kX86InstJNAE,            // X86/X64 (jcc)
1012   kX86InstJNB,             // X86/X64 (jcc)
1013   kX86InstJNBE,            // X86/X64 (jcc)
1014   kX86InstJNC,             // X86/X64 (jcc)
1015   kX86InstJNE,             // X86/X64 (jcc)
1016   kX86InstJNG,             // X86/X64 (jcc)
1017   kX86InstJNGE,            // X86/X64 (jcc)
1018   kX86InstJNL,             // X86/X64 (jcc)
1019   kX86InstJNLE,            // X86/X64 (jcc)
1020   kX86InstJNO,             // X86/X64 (jcc)
1021   kX86InstJNP,             // X86/X64 (jcc)
1022   kX86InstJNS,             // X86/X64 (jcc)
1023   kX86InstJNZ,             // X86/X64 (jcc)
1024   kX86InstJO,              // X86/X64 (jcc)
1025   kX86InstJP,              // X86/X64 (jcc)
1026   kX86InstJPE,             // X86/X64 (jcc)
1027   kX86InstJPO,             // X86/X64 (jcc)
1028   kX86InstJS,              // X86/X64 (jcc)
1029   kX86InstJZ,              // X86/X64 (jcc)
1030   kX86InstJmp,             // X86/X64 (jmp)
1031   kX86InstLdDQU,           // SSE3
1032   kX86InstLdMXCSR,         // SSE
1033   kX86InstLahf,            // X86/X64 (CPUID NEEDED)
1034   kX86InstLea,             // X86/X64
1035   kX86InstLeave,           // X86/X64
1036   kX86InstLFence,          // SSE2
1037   kX86InstMaskMovDQU,      // SSE2
1038   kX86InstMaskMovQ,        // MMX-Ext
1039   kX86InstMaxPD,           // SSE2
1040   kX86InstMaxPS,           // SSE
1041   kX86InstMaxSD,           // SSE2
1042   kX86InstMaxSS,           // SSE
1043   kX86InstMFence,          // SSE2
1044   kX86InstMinPD,           // SSE2
1045   kX86InstMinPS,           // SSE
1046   kX86InstMinSD,           // SSE2
1047   kX86InstMinSS,           // SSE
1048   kX86InstMonitor,         // SSE3
1049   kX86InstMov,             // X86/X64
1050   kX86InstMovAPD,          // SSE2
1051   kX86InstMovAPS,          // SSE
1052   kX86InstMovBE,           // SSE3 - Intel-Atom
1053   kX86InstMovD,            // MMX/SSE2
1054   kX86InstMovDDup,         // SSE3
1055   kX86InstMovDQ2Q,         // SSE2
1056   kX86InstMovDQA,          // SSE2
1057   kX86InstMovDQU,          // SSE2
1058   kX86InstMovHLPS,         // SSE
1059   kX86InstMovHPD,          // SSE2
1060   kX86InstMovHPS,          // SSE
1061   kX86InstMovLHPS,         // SSE
1062   kX86InstMovLPD,          // SSE2
1063   kX86InstMovLPS,          // SSE
1064   kX86InstMovMskPD,        // SSE2
1065   kX86InstMovMskPS,        // SSE2
1066   kX86InstMovNTDQ,         // SSE2
1067   kX86InstMovNTDQA,        // SSE4.1
1068   kX86InstMovNTI,          // SSE2
1069   kX86InstMovNTPD,         // SSE2
1070   kX86InstMovNTPS,         // SSE
1071   kX86InstMovNTQ,          // MMX-Ext
1072   kX86InstMovQ,            // MMX/SSE/SSE2
1073   kX86InstMovQ2DQ,         // SSE2
1074   kX86InstMovSD,           // SSE2
1075   kX86InstMovSHDup,        // SSE3
1076   kX86InstMovSLDup,        // SSE3
1077   kX86InstMovSS,           // SSE
1078   kX86InstMovSX,           // X86/X64
1079   kX86InstMovSXD,          // X86/X64
1080   kX86InstMovUPD,          // SSE2
1081   kX86InstMovUPS,          // SSE
1082   kX86InstMovZX,           // X86/X64
1083   kX86InstMovPtr,          // X86/X64
1084   kX86InstMPSADBW,         // SSE4.1
1085   kX86InstMul,             // X86/X64
1086   kX86InstMulPD,           // SSE2
1087   kX86InstMulPS,           // SSE
1088   kX86InstMulSD,           // SSE2
1089   kX86InstMulSS,           // SSE
1090   kX86InstMWait,           // SSE3
1091   kX86InstNeg,             // X86/X64
1092   kX86InstNop,             // X86/X64
1093   kX86InstNot,             // X86/X64
1094   kX86InstOr,              // X86/X64
1095   kX86InstOrPD,            // SSE2
1096   kX86InstOrPS,            // SSE
1097   kX86InstPAbsB,           // SSSE3
1098   kX86InstPAbsD,           // SSSE3
1099   kX86InstPAbsW,           // SSSE3
1100   kX86InstPackSSDW,        // MMX/SSE2
1101   kX86InstPackSSWB,        // MMX/SSE2
1102   kX86InstPackUSDW,        // SSE4.1
1103   kX86InstPackUSWB,        // MMX/SSE2
1104   kX86InstPAddB,           // MMX/SSE2
1105   kX86InstPAddD,           // MMX/SSE2
1106   kX86InstPAddQ,           // SSE2
1107   kX86InstPAddSB,          // MMX/SSE2
1108   kX86InstPAddSW,          // MMX/SSE2
1109   kX86InstPAddUSB,         // MMX/SSE2
1110   kX86InstPAddUSW,         // MMX/SSE2
1111   kX86InstPAddW,           // MMX/SSE2
1112   kX86InstPAlignR,         // SSSE3
1113   kX86InstPAnd,            // MMX/SSE2
1114   kX86InstPAndN,           // MMX/SSE2
1115   kX86InstPause,           // SSE2.
1116   kX86InstPAvgB,           // MMX-Ext
1117   kX86InstPAvgW,           // MMX-Ext
1118   kX86InstPBlendVB,        // SSE4.1
1119   kX86InstPBlendW,         // SSE4.1
1120   kX86InstPCmpEqB,         // MMX/SSE2
1121   kX86InstPCmpEqD,         // MMX/SSE2
1122   kX86InstPCmpEqQ,         // SSE4.1
1123   kX86InstPCmpEqW,         // MMX/SSE2
1124   kX86InstPCmpEStrI,       // SSE4.2
1125   kX86InstPCmpEStrM,       // SSE4.2
1126   kX86InstPCmpGtB,         // MMX/SSE2
1127   kX86InstPCmpGtD,         // MMX/SSE2
1128   kX86InstPCmpGtQ,         // SSE4.2
1129   kX86InstPCmpGtW,         // MMX/SSE2
1130   kX86InstPCmpIStrI,       // SSE4.2
1131   kX86InstPCmpIStrM,       // SSE4.2
1132   kX86InstPExtrB,          // SSE4.1
1133   kX86InstPExtrD,          // SSE4.1
1134   kX86InstPExtrQ,          // SSE4.1
1135   kX86InstPExtrW,          // MMX-Ext/SSE2
1136   kX86InstPF2ID,           // 3dNow!
1137   kX86InstPF2IW,           // Enhanced 3dNow!
1138   kX86InstPFAcc,           // 3dNow!
1139   kX86InstPFAdd,           // 3dNow!
1140   kX86InstPFCmpEQ,         // 3dNow!
1141   kX86InstPFCmpGE,         // 3dNow!
1142   kX86InstPFCmpGT,         // 3dNow!
1143   kX86InstPFMax,           // 3dNow!
1144   kX86InstPFMin,           // 3dNow!
1145   kX86InstPFMul,           // 3dNow!
1146   kX86InstPFNAcc,          // Enhanced 3dNow!
1147   kX86InstPFPNAcc,         // Enhanced 3dNow!
1148   kX86InstPFRcp,           // 3dNow!
1149   kX86InstPFRcpIt1,        // 3dNow!
1150   kX86InstPFRcpIt2,        // 3dNow!
1151   kX86InstPFRSqIt1,        // 3dNow!
1152   kX86InstPFRSqrt,         // 3dNow!
1153   kX86InstPFSub,           // 3dNow!
1154   kX86InstPFSubR,          // 3dNow!
1155   kX86InstPHAddD,          // SSSE3
1156   kX86InstPHAddSW,         // SSSE3
1157   kX86InstPHAddW,          // SSSE3
1158   kX86InstPHMinPOSUW,      // SSE4.1
1159   kX86InstPHSubD,          // SSSE3
1160   kX86InstPHSubSW,         // SSSE3
1161   kX86InstPHSubW,          // SSSE3
1162   kX86InstPI2FD,           // 3dNow!
1163   kX86InstPI2FW,           // Enhanced 3dNow!
1164   kX86InstPInsRB,          // SSE4.1
1165   kX86InstPInsRD,          // SSE4.1
1166   kX86InstPInsRQ,          // SSE4.1
1167   kX86InstPInsRW,          // MMX-Ext
1168   kX86InstPMAddUBSW,       // SSSE3
1169   kX86InstPMAddWD,         // MMX/SSE2
1170   kX86InstPMaxSB,          // SSE4.1
1171   kX86InstPMaxSD,          // SSE4.1
1172   kX86InstPMaxSW,          // MMX-Ext
1173   kX86InstPMaxUB,          // MMX-Ext
1174   kX86InstPMaxUD,          // SSE4.1
1175   kX86InstPMaxUW,          // SSE4.1
1176   kX86InstPMinSB,          // SSE4.1
1177   kX86InstPMinSD,          // SSE4.1
1178   kX86InstPMinSW,          // MMX-Ext
1179   kX86InstPMinUB,          // MMX-Ext
1180   kX86InstPMinUD,          // SSE4.1
1181   kX86InstPMinUW,          // SSE4.1
1182   kX86InstPMovMskB,        // MMX-Ext
1183   kX86InstPMovSXBD,        // SSE4.1
1184   kX86InstPMovSXBQ,        // SSE4.1
1185   kX86InstPMovSXBW,        // SSE4.1
1186   kX86InstPMovSXDQ,        // SSE4.1
1187   kX86InstPMovSXWD,        // SSE4.1
1188   kX86InstPMovSXWQ,        // SSE4.1
1189   kX86InstPMovZXBD,        // SSE4.1
1190   kX86InstPMovZXBQ,        // SSE4.1
1191   kX86InstPMovZXBW,        // SSE4.1
1192   kX86InstPMovZXDQ,        // SSE4.1
1193   kX86InstPMovZXWD,        // SSE4.1
1194   kX86InstPMovZXWQ,        // SSE4.1
1195   kX86InstPMulDQ,          // SSE4.1
1196   kX86InstPMulHRSW,        // SSSE3
1197   kX86InstPMulHUW,         // MMX-Ext
1198   kX86InstPMulHW,          // MMX/SSE2
1199   kX86InstPMulLD,          // SSE4.1
1200   kX86InstPMulLW,          // MMX/SSE2
1201   kX86InstPMulUDQ,         // SSE2
1202   kX86InstPop,             // X86/X64
1203   kX86InstPopAD,           // X86 only
1204   kX86InstPopCnt,          // SSE4.2
1205   kX86InstPopFD,           // X86 only
1206   kX86InstPopFQ,           // X64 only
1207   kX86InstPOr,             // MMX/SSE2
1208   kX86InstPrefetch,        // MMX-Ext
1209   kX86InstPSADBW,          // MMX-Ext
1210   kX86InstPShufB,          // SSSE3
1211   kX86InstPShufD,          // SSE2
1212   kX86InstPShufW,          // MMX-Ext
1213   kX86InstPShufHW,         // SSE2
1214   kX86InstPShufLW,         // SSE2
1215   kX86InstPSignB,          // SSSE3
1216   kX86InstPSignD,          // SSSE3
1217   kX86InstPSignW,          // SSSE3
1218   kX86InstPSllD,           // MMX/SSE2
1219   kX86InstPSllDQ,          // SSE2
1220   kX86InstPSllQ,           // MMX/SSE2
1221   kX86InstPSllW,           // MMX/SSE2
1222   kX86InstPSraD,           // MMX/SSE2
1223   kX86InstPSraW,           // MMX/SSE2
1224   kX86InstPSrlD,           // MMX/SSE2
1225   kX86InstPSrlDQ,          // SSE2
1226   kX86InstPSrlQ,           // MMX/SSE2
1227   kX86InstPSrlW,           // MMX/SSE2
1228   kX86InstPSubB,           // MMX/SSE2
1229   kX86InstPSubD,           // MMX/SSE2
1230   kX86InstPSubQ,           // SSE2
1231   kX86InstPSubSB,          // MMX/SSE2
1232   kX86InstPSubSW,          // MMX/SSE2
1233   kX86InstPSubUSB,         // MMX/SSE2
1234   kX86InstPSubUSW,         // MMX/SSE2
1235   kX86InstPSubW,           // MMX/SSE2
1236   kX86InstPSwapD,          // Enhanced 3dNow!
1237   kX86InstPTest,           // SSE4.1
1238   kX86InstPunpckHBW,       // MMX/SSE2
1239   kX86InstPunpckHDQ,       // MMX/SSE2
1240   kX86InstPunpckHQDQ,      // SSE2
1241   kX86InstPunpckHWD,       // MMX/SSE2
1242   kX86InstPunpckLBW,       // MMX/SSE2
1243   kX86InstPunpckLDQ,       // MMX/SSE2
1244   kX86InstPunpckLQDQ,      // SSE2
1245   kX86InstPunpckLWD,       // MMX/SSE2
1246   kX86InstPush,            // X86/X64
1247   kX86InstPushAD,          // X86 only
1248   kX86InstPushFD,          // X86 only
1249   kX86InstPushFQ,          // X64 only
1250   kX86InstPXor,            // MMX/SSE2
1251   kX86InstRcl,             // X86/X64
1252   kX86InstRcpPS,           // SSE
1253   kX86InstRcpSS,           // SSE
1254   kX86InstRcr,             // X86/X64
1255   kX86InstRdtsc,           // X86/X64
1256   kX86InstRdtscP,          // X86/X64
1257   kX86InstRepLodSB,        // X86/X64 (REP)
1258   kX86InstRepLodSD,        // X86/X64 (REP)
1259   kX86InstRepLodSQ,        // X64 only (REP)
1260   kX86InstRepLodSW,        // X86/X64 (REP)
1261   kX86InstRepMovSB,        // X86/X64 (REP)
1262   kX86InstRepMovSD,        // X86/X64 (REP)
1263   kX86InstRepMovSQ,        // X64 only (REP)
1264   kX86InstRepMovSW,        // X86/X64 (REP)
1265   kX86InstRepStoSB,        // X86/X64 (REP)
1266   kX86InstRepStoSD,        // X86/X64 (REP)
1267   kX86InstRepStoSQ,        // X64 only (REP)
1268   kX86InstRepStoSW,        // X86/X64 (REP)
1269   kX86InstRepECmpSB,       // X86/X64 (REP)
1270   kX86InstRepECmpSD,       // X86/X64 (REP)
1271   kX86InstRepECmpSQ,       // X64 only (REP)
1272   kX86InstRepECmpSW,       // X86/X64 (REP)
1273   kX86InstRepEScaSB,       // X86/X64 (REP)
1274   kX86InstRepEScaSD,       // X86/X64 (REP)
1275   kX86InstRepEScaSQ,       // X64 only (REP)
1276   kX86InstRepEScaSW,       // X86/X64 (REP)
1277   kX86InstRepNECmpSB,      // X86/X64 (REP)
1278   kX86InstRepNECmpSD,      // X86/X64 (REP)
1279   kX86InstRepNECmpSQ,      // X64 only (REP)
1280   kX86InstRepNECmpSW,      // X86/X64 (REP)
1281   kX86InstRepNEScaSB,      // X86/X64 (REP)
1282   kX86InstRepNEScaSD,      // X86/X64 (REP)
1283   kX86InstRepNEScaSQ,      // X64 only (REP)
1284   kX86InstRepNEScaSW,      // X86/X64 (REP)
1285   kX86InstRet,             // X86/X64
1286   kX86InstRol,             // X86/X64
1287   kX86InstRor,             // X86/X64
1288   kX86InstRoundPD,         // SSE4.1
1289   kX86InstRoundPS,         // SSE4.1
1290   kX86InstRoundSD,         // SSE4.1
1291   kX86InstRoundSS,         // SSE4.1
1292   kX86InstRSqrtPS,         // SSE
1293   kX86InstRSqrtSS,         // SSE
1294   kX86InstSahf,            // X86/X64 (CPUID NEEDED)
1295   kX86InstSal,             // X86/X64
1296   kX86InstSar,             // X86/X64
1297   kX86InstSbb,             // X86/X64
1298   kX86InstSet,             // Begin (setcc)
1299   kX86InstSetA=kX86InstSet,// X86/X64 (setcc)
1300   kX86InstSetAE,           // X86/X64 (setcc)
1301   kX86InstSetB,            // X86/X64 (setcc)
1302   kX86InstSetBE,           // X86/X64 (setcc)
1303   kX86InstSetC,            // X86/X64 (setcc)
1304   kX86InstSetE,            // X86/X64 (setcc)
1305   kX86InstSetG,            // X86/X64 (setcc)
1306   kX86InstSetGE,           // X86/X64 (setcc)
1307   kX86InstSetL,            // X86/X64 (setcc)
1308   kX86InstSetLE,           // X86/X64 (setcc)
1309   kX86InstSetNA,           // X86/X64 (setcc)
1310   kX86InstSetNAE,          // X86/X64 (setcc)
1311   kX86InstSetNB,           // X86/X64 (setcc)
1312   kX86InstSetNBE,          // X86/X64 (setcc)
1313   kX86InstSetNC,           // X86/X64 (setcc)
1314   kX86InstSetNE,           // X86/X64 (setcc)
1315   kX86InstSetNG,           // X86/X64 (setcc)
1316   kX86InstSetNGE,          // X86/X64 (setcc)
1317   kX86InstSetNL,           // X86/X64 (setcc)
1318   kX86InstSetNLE,          // X86/X64 (setcc)
1319   kX86InstSetNO,           // X86/X64 (setcc)
1320   kX86InstSetNP,           // X86/X64 (setcc)
1321   kX86InstSetNS,           // X86/X64 (setcc)
1322   kX86InstSetNZ,           // X86/X64 (setcc)
1323   kX86InstSetO,            // X86/X64 (setcc)
1324   kX86InstSetP,            // X86/X64 (setcc)
1325   kX86InstSetPE,           // X86/X64 (setcc)
1326   kX86InstSetPO,           // X86/X64 (setcc)
1327   kX86InstSetS,            // X86/X64 (setcc)
1328   kX86InstSetZ,            // X86/X64 (setcc)
1329   kX86InstSFence,          // MMX-Ext/SSE
1330   kX86InstShl,             // X86/X64
1331   kX86InstShld,            // X86/X64
1332   kX86InstShr,             // X86/X64
1333   kX86InstShrd,            // X86/X64
1334   kX86InstShufPD,          // SSE2
1335   kX86InstShufPS,          // SSE
1336   kX86InstSqrtPD,          // SSE2
1337   kX86InstSqrtPS,          // SSE
1338   kX86InstSqrtSD,          // SSE2
1339   kX86InstSqrtSS,          // SSE
1340   kX86InstStc,             // X86/X64
1341   kX86InstStd,             // X86/X64
1342   kX86InstStMXCSR,         // SSE
1343   kX86InstSub,             // X86/X64
1344   kX86InstSubPD,           // SSE2
1345   kX86InstSubPS,           // SSE
1346   kX86InstSubSD,           // SSE2
1347   kX86InstSubSS,           // SSE
1348   kX86InstTest,            // X86/X64
1349   kX86InstUComISD,         // SSE2
1350   kX86InstUComISS,         // SSE
1351   kX86InstUd2,             // X86/X64
1352   kX86InstUnpckHPD,        // SSE2
1353   kX86InstUnpckHPS,        // SSE
1354   kX86InstUnpckLPD,        // SSE2
1355   kX86InstUnpckLPS,        // SSE
1356   kX86InstXadd,            // X86/X64 (i486)
1357   kX86InstXchg,            // X86/X64 (i386)
1358   kX86InstXor,             // X86/X64
1359   kX86InstXorPD,           // SSE2
1360   kX86InstXorPS,           // SSE
1361 
1362   _kX86InstCount,
1363 
1364   _kX86InstJBegin = kX86InstJ,
1365   _kX86InstJEnd = kX86InstJmp
1366 };
1367 
1368 // ============================================================================
1369 // [AsmJit::kX86InstGroup]
1370 // ============================================================================
1371 
1372 //! @brief X86 instruction groups.
1373 //!
1374 //! This should be only used by assembler, because it's @c AsmJit::Assembler
1375 //! specific grouping. Each group represents one 'case' in the Assembler's
1376 //! main emit method.
1377 enum kX86InstGroup
1378 {
1379   // Group categories.
1380   kX86InstGroupNone,
1381   kX86InstGroupEmit,
1382 
1383   kX86InstGroupArith,
1384   kX86InstGroupBSwap,
1385   kX86InstGroupBTest,
1386   kX86InstGroupCall,
1387   kX86InstGroupCrc32,
1388   kX86InstGroupEnter,
1389   kX86InstGroupIMul,
1390   kX86InstGroupIncDec,
1391   kX86InstGroupJcc,
1392   kX86InstGroupJmp,
1393   kX86InstGroupLea,
1394   kX86InstGroupMem,
1395   kX86InstGroupMov,
1396   kX86InstGroupMovPtr,
1397   kX86InstGroupMovSxMovZx,
1398   kX86InstGroupMovSxD,
1399   kX86InstGroupPush,
1400   kX86InstGroupPop,
1401   kX86InstGroupRegRm,
1402   kX86InstGroupRm,
1403   kX86InstGroupRmByte,
1404   kX86InstGroupRmReg,
1405   kX86InstGroupRep,
1406   kX86InstGroupRet,
1407   kX86InstGroupRot,
1408   kX86InstGroupShldShrd,
1409   kX86InstGroupTest,
1410   kX86InstGroupXchg,
1411 
1412   // Group for x87 FP instructions in format mem or st(i), st(i) (fadd, fsub, fdiv, ...)
1413   kX86InstGroupX87StM,
1414   // Group for x87 FP instructions in format st(i), st(i)
1415   kX86InstGroupX87StI,
1416   // Group for fld/fst/fstp instruction, internally uses @ref kX86InstGroupX87StM group.
1417   kX86InstGroupX87FldFst,
1418   // Group for x87 FP instructions that uses Word, DWord, QWord or TWord memory pointer.
1419   kX86InstGroupX87Mem,
1420   // Group for x87 FSTSW/FNSTSW instructions
1421   kX86InstGroupX87Status,
1422 
1423   // Group for movbe instruction
1424   kX86InstGroupMovBE,
1425 
1426   // Group for MMX/SSE instructions in format (X)MM|Reg|Mem <- (X)MM|Reg|Mem,
1427   // 0x66 prefix must be set manually in opcodes.
1428   // - Primary opcode is used for instructions in (X)MM <- (X)MM/Mem format,
1429   // - Secondary opcode is used for instructions in (X)MM/Mem <- (X)MM format.
1430   kX86InstGroupMmuMov,
1431   kX86InstGroupMmuMovD,
1432   kX86InstGroupMmuMovQ,
1433 
1434   // Group for pextrd, pextrq and pextrw instructions (it's special instruction
1435   // not similar to others)
1436   kX86InstGroupMmuExtract,
1437   // Group for prefetch instruction
1438   kX86InstGroupMmuPrefetch,
1439 
1440   // Group for MMX/SSE instructions in format (X)MM|Reg <- (X)MM|Reg|Mem|Imm,
1441   // 0x66 prefix is added for MMX instructions that used by SSE2 registers.
1442   // - Primary opcode is used for instructions in (X)MM|Reg <- (X)MM|Reg|Mem format,
1443   // - Secondary opcode is iused for instructions in (X)MM|Reg <- Imm format.
1444   kX86InstGroupMmuRmI,
1445   kX86InstGroupMmuRmImm8,
1446   // Group for 3dNow instructions
1447   kX86InstGroupMmuRm3dNow
1448 };
1449 
1450 // ============================================================================
1451 // [AsmJit::kX86InstFlags]
1452 // ============================================================================
1453 
1454 //! @brief X86 instruction type flags.
1455 enum kX86InstFlags
1456 {
1457   //! @brief No flags.
1458   kX86InstFlagNone = 0x00,
1459 
1460   //! @brief Instruction is jump, conditional jump, call or ret.
1461   kX86InstFlagJump = 0x01,
1462 
1463   //! @brief Instruction will overwrite first operand - o[0].
1464   kX86InstFlagMov = 0x02,
1465 
1466   //! @brief Instruction is X87 FPU.
1467   kX86InstFlagFpu = 0x04,
1468 
1469   //! @brief Instruction can be prepended using LOCK prefix
1470   //! (usable for multithreaded applications).
1471   kX86InstFlagLockable = 0x08,
1472 
1473   //! @brief Instruction is special, this is for @c Compiler.
1474   kX86InstFlagSpecial = 0x10,
1475 
1476   //! @brief Instruction always performs memory access.
1477   //!
1478   //! This flag is always combined with @c kX86InstFlagSpecial and signalizes
1479   //! that there is an implicit address which is accessed (usually EDI/RDI or
1480   //! ESI/EDI).
1481   kX86InstFlagSpecialMem = 0x20
1482 };
1483 
1484 // ============================================================================
1485 // [AsmJit::kX86InstOp]
1486 // ============================================================================
1487 
1488 //! @brief X86 instruction operand flags.
1489 enum kX86InstOp
1490 {
1491   // X86, MM, XMM
1492   kX86InstOpGb          = 0x0001,
1493   kX86InstOpGw          = 0x0002,
1494   kX86InstOpGd          = 0x0004,
1495   kX86InstOpGq          = 0x0008,
1496   kX86InstOpMm          = 0x0010,
1497   kX86InstOpXmm         = 0x0020,
1498   kX86InstOpMem         = 0x0040,
1499   kX86InstOpImm         = 0x0080,
1500 
1501   kX86InstOpGbMem       = kX86InstOpGb     | kX86InstOpMem,
1502   kX86InstOpGwMem       = kX86InstOpGw     | kX86InstOpMem,
1503   kX86InstOpGdMem       = kX86InstOpGd     | kX86InstOpMem,
1504   kX86InstOpGqMem       = kX86InstOpGq     | kX86InstOpMem,
1505 
1506   kX86InstOpGqdwb       = kX86InstOpGq     | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb,
1507   kX86InstOpGqdw        = kX86InstOpGq     | kX86InstOpGd | kX86InstOpGw,
1508   kX86InstOpGqd         = kX86InstOpGq     | kX86InstOpGd,
1509   kX86InstOpGwb         = kX86InstOpGw     | kX86InstOpGb,
1510 
1511   kX86InstOpGqdwbMem    = kX86InstOpGqdwb  | kX86InstOpMem,
1512   kX86InstOpGqdwMem     = kX86InstOpGqdw   | kX86InstOpMem,
1513   kX86InstOpGqdMem      = kX86InstOpGqd    | kX86InstOpMem,
1514   kX86InstOpGwbMem      = kX86InstOpGwb    | kX86InstOpMem,
1515 
1516   // MMX/XMM.
1517   kX86InstOpMmMem       = kX86InstOpMm     | kX86InstOpMem,
1518   kX86InstOpXmmMem      = kX86InstOpXmm    | kX86InstOpMem,
1519   kX86InstOpMmXmm       = kX86InstOpMm     | kX86InstOpXmm,
1520   kX86InstOpMmXmmMem    = kX86InstOpMmXmm  | kX86InstOpMem,
1521 
1522   // X87.
1523   kX86InstOpStM2        = kX86InstOpMem    | 0x0100,
1524   kX86InstOpStM4        = kX86InstOpMem    | 0x0200,
1525   kX86InstOpStM8        = kX86InstOpMem    | 0x0400,
1526   kX86InstOpStM10       = kX86InstOpMem    | 0x0800,
1527 
1528   kX86InstOpStM2_4      = kX86InstOpStM2   | kX86InstOpStM4,
1529   kX86InstOpStM2_4_8    = kX86InstOpStM2_4 | kX86InstOpStM8,
1530   kX86InstOpStM4_8      = kX86InstOpStM4   | kX86InstOpStM8,
1531   kX86InstOpStM4_8_10   = kX86InstOpStM4_8 | kX86InstOpStM10,
1532 
1533   // Don't emit REX prefix.
1534   kX86InstOpNoRex       = 0x2000
1535 };
1536 
1537 // ============================================================================
1538 // [AsmJit::x86InstName]
1539 // ============================================================================
1540 
1541 //! @internal
1542 //!
1543 //! @brief X86 instruction names.
1544 ASMJIT_VAR const char x86InstName[];
1545 
1546 // ============================================================================
1547 // [AsmJit::X86InstInfo]
1548 // ============================================================================
1549 
1550 //! @brief X86 instruction information.
1551 struct X86InstInfo
1552 {
1553   // --------------------------------------------------------------------------
1554   // [Accessors]
1555   // --------------------------------------------------------------------------
1556 
1557   //! @brief Get instruction code, see @ref kX86InstCode.
getCodeX86InstInfo1558   inline uint32_t getCode() const
1559   { return _code; }
1560 
1561   //! @brief Get instruction name string (null terminated string).
getNameX86InstInfo1562   inline const char* getName() const
1563   { return x86InstName + static_cast<uint32_t>(_nameIndex); }
1564 
1565   //! @brief Get instruction name index (index to @ref x86InstName array).
getNameIndexX86InstInfo1566   inline uint32_t getNameIndex() const
1567   { return _nameIndex; }
1568 
1569   //! @brief Get instruction group, see @ref kX86InstGroup.
getGroupX86InstInfo1570   inline uint32_t getGroup() const
1571   { return _group; }
1572 
1573   //! @brief Get instruction flags, see @ref kX86InstFlags.
getFlagsX86InstInfo1574   inline uint32_t getFlags() const
1575   { return _group; }
1576 
1577   //! @brief Get whether the instruction is conditional or standard jump.
isJumpX86InstInfo1578   inline bool isJump() const
1579   { return (_flags & kX86InstFlagJump) != 0; }
1580 
1581   //! @brief Get whether the instruction is MOV type.
isMovX86InstInfo1582   inline bool isMov() const
1583   { return (_flags & kX86InstFlagMov) != 0; }
1584 
1585   //! @brief Get whether the instruction is X87 FPU type.
isFpuX86InstInfo1586   inline bool isFpu() const
1587   { return (_flags & kX86InstFlagFpu) != 0; }
1588 
1589   //! @brief Get whether the instruction can be prefixed by LOCK prefix.
isLockableX86InstInfo1590   inline bool isLockable() const
1591   { return (_flags & kX86InstFlagLockable) != 0; }
1592 
1593   //! @brief Get whether the instruction is special type (this is used by
1594   //! @c Compiler to manage additional variables or functionality).
isSpecialX86InstInfo1595   inline bool isSpecial() const
1596   { return (_flags & kX86InstFlagSpecial) != 0; }
1597 
1598   //! @brief Get whether the instruction is special type and it performs
1599   //! memory access.
isSpecialMemX86InstInfo1600   inline bool isSpecialMem() const
1601   { return (_flags & kX86InstFlagSpecialMem) != 0; }
1602 
1603   // --------------------------------------------------------------------------
1604   // [Members]
1605   // --------------------------------------------------------------------------
1606 
1607   //! @brief Instruction code.
1608   uint16_t _code;
1609   //! @brief Instruction name index in x86InstName[] array.
1610   uint16_t _nameIndex;
1611   //! @brief Instruction group, used also by @c Compiler.
1612   uint8_t _group;
1613   //! @brief Instruction type flags.
1614   uint8_t _flags;
1615 
1616   //! @brief First and second operand flags (some groups depends on these settings, used also by @c Compiler).
1617   uint16_t _opFlags[2];
1618   //! @brief If instruction has only memory operand, this is register opcode.
1619   uint16_t _opCodeR;
1620   //! @brief Primary and secondary opcodes.
1621   uint32_t _opCode[2];
1622 };
1623 
1624 // ============================================================================
1625 // [AsmJit::x86InstInfo]
1626 // ============================================================================
1627 
1628 ASMJIT_VAR const X86InstInfo x86InstInfo[];
1629 
1630 // ============================================================================
1631 // [AsmJit::kX86FuncConv]
1632 // ============================================================================
1633 
1634 //! @brief X86 function calling conventions.
1635 //!
1636 //! Calling convention is scheme how function arguments are passed into
1637 //! function and how functions returns values. In assembler programming
1638 //! it's needed to always comply with function calling conventions, because
1639 //! even small inconsistency can cause undefined behavior or crash.
1640 //!
1641 //! List of calling conventions for 32-bit x86 mode:
1642 //! - @c kX86FuncConvCDecl - Calling convention for C runtime.
1643 //! - @c kX86FuncConvStdCall - Calling convention for WinAPI functions.
1644 //! - @c kX86FuncConvMsThisCall - Calling convention for C++ members under
1645 //!      Windows (produced by MSVC and all MSVC compatible compilers).
1646 //! - @c kX86FuncConvMsFastCall - Fastest calling convention that can be used
1647 //!      by MSVC compiler.
1648 //! - @c kX86FuncConv_BORNANDFASTCALL - Borland fastcall convention.
1649 //! - @c kX86FuncConvGccFastCall - GCC fastcall convention (2 register arguments).
1650 //! - @c kX86FuncConvGccRegParm1 - GCC regparm(1) convention.
1651 //! - @c kX86FuncConvGccRegParm2 - GCC regparm(2) convention.
1652 //! - @c kX86FuncConvGccRegParm3 - GCC regparm(3) convention.
1653 //!
1654 //! List of calling conventions for 64-bit x86 mode (x64):
1655 //! - @c kX86FuncConvX64W - Windows 64-bit calling convention (WIN64 ABI).
1656 //! - @c kX86FuncConvX64U - Unix 64-bit calling convention (AMD64 ABI).
1657 //!
1658 //! There is also @c kX86FuncConvDefault that is defined to fit best to your
1659 //! compiler.
1660 //!
1661 //! These types are used together with @c AsmJit::Compiler::newFunc()
1662 //! method.
1663 enum kX86FuncConv
1664 {
1665   // --------------------------------------------------------------------------
1666   // [X64]
1667   // --------------------------------------------------------------------------
1668 
1669   //! @brief X64 calling convention for Windows platform (WIN64 ABI).
1670   //!
1671   //! For first four arguments are used these registers:
1672   //! - 1. 32/64-bit integer or floating point argument - rcx/xmm0
1673   //! - 2. 32/64-bit integer or floating point argument - rdx/xmm1
1674   //! - 3. 32/64-bit integer or floating point argument - r8/xmm2
1675   //! - 4. 32/64-bit integer or floating point argument - r9/xmm3
1676   //!
1677   //! Note first four arguments here means arguments at positions from 1 to 4
1678   //! (included). For example if second argument is not passed by register then
1679   //! rdx/xmm1 register is unused.
1680   //!
1681   //! All other arguments are pushed on the stack in right-to-left direction.
1682   //! Stack is aligned by 16 bytes. There is 32-byte shadow space on the stack
1683   //! that can be used to save up to four 64-bit registers (probably designed to
1684   //! be used to save first four arguments passed in registers).
1685   //!
1686   //! Arguments direction:
1687   //! - Right to Left (except for first 4 parameters that's in registers)
1688   //!
1689   //! Stack is cleaned by:
1690   //! - Caller.
1691   //!
1692   //! Return value:
1693   //! - Integer types - RAX register.
1694   //! - Floating points - XMM0 register.
1695   //!
1696   //! Stack is always aligned by 16 bytes.
1697   //!
1698   //! More information about this calling convention can be found on MSDN:
1699   //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx .
1700   kX86FuncConvX64W = 1,
1701 
1702   //! @brief X64 calling convention for Unix platforms (AMD64 ABI).
1703   //!
1704   //! First six 32 or 64-bit integer arguments are passed in rdi, rsi, rdx,
1705   //! rcx, r8, r9 registers. First eight floating point or XMM arguments
1706   //! are passed in xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 registers.
1707   //! This means that in registers can be transferred up to 14 arguments total.
1708   //!
1709   //! There is also RED ZONE below the stack pointer that can be used for
1710   //! temporary storage. The red zone is the space from [rsp-128] to [rsp-8].
1711   //!
1712   //! Arguments direction:
1713   //! - Right to Left (Except for arguments passed in registers).
1714   //!
1715   //! Stack is cleaned by:
1716   //! - Caller.
1717   //!
1718   //! Return value:
1719   //! - Integer types - RAX register.
1720   //! - Floating points - XMM0 register.
1721   //!
1722   //! Stack is always aligned by 16 bytes.
1723   kX86FuncConvX64U = 2,
1724 
1725   // --------------------------------------------------------------------------
1726   // [X86]
1727   // --------------------------------------------------------------------------
1728 
1729   //! @brief Cdecl calling convention (used by C runtime).
1730   //!
1731   //! Compatible across MSVC and GCC.
1732   //!
1733   //! Arguments direction:
1734   //! - Right to Left
1735   //!
1736   //! Stack is cleaned by:
1737   //! - Caller.
1738   kX86FuncConvCDecl = 3,
1739 
1740   //! @brief Stdcall calling convention (used by WinAPI).
1741   //!
1742   //! Compatible across MSVC and GCC.
1743   //!
1744   //! Arguments direction:
1745   //! - Right to Left
1746   //!
1747   //! Stack is cleaned by:
1748   //! - Callee.
1749   //!
1750   //! Return value:
1751   //! - Integer types - EAX:EDX registers.
1752   //! - Floating points - st(0) register.
1753   kX86FuncConvStdCall = 4,
1754 
1755   //! @brief MSVC specific calling convention used by MSVC/Intel compilers
1756   //! for struct/class methods.
1757   //!
1758   //! This is MSVC (and Intel) only calling convention used in Windows
1759   //! world for C++ class methods. Implicit 'this' pointer is stored in
1760   //! ECX register instead of storing it on the stack.
1761   //!
1762   //! Arguments direction:
1763   //! - Right to Left (except this pointer in ECX)
1764   //!
1765   //! Stack is cleaned by:
1766   //! - Callee.
1767   //!
1768   //! Return value:
1769   //! - Integer types - EAX:EDX registers.
1770   //! - Floating points - st(0) register.
1771   //!
1772   //! C++ class methods that have variable count of arguments uses different
1773   //! calling convention called cdecl.
1774   //!
1775   //! @note This calling convention is always used by MSVC for class methods,
1776   //! it's implicit and there is no way how to override it.
1777   kX86FuncConvMsThisCall = 5,
1778 
1779   //! @brief MSVC specific fastcall.
1780   //!
1781   //! Two first parameters (evaluated from left-to-right) are in ECX:EDX
1782   //! registers, all others on the stack in right-to-left order.
1783   //!
1784   //! Arguments direction:
1785   //! - Right to Left (except to first two integer arguments in ECX:EDX)
1786   //!
1787   //! Stack is cleaned by:
1788   //! - Callee.
1789   //!
1790   //! Return value:
1791   //! - Integer types - EAX:EDX registers.
1792   //! - Floating points - st(0) register.
1793   //!
1794   //! @note This calling convention differs to GCC one in stack cleaning
1795   //! mechanism.
1796   kX86FuncConvMsFastCall = 6,
1797 
1798   //! @brief Borland specific fastcall with 2 parameters in registers.
1799   //!
1800   //! Two first parameters (evaluated from left-to-right) are in ECX:EDX
1801   //! registers, all others on the stack in left-to-right order.
1802   //!
1803   //! Arguments direction:
1804   //! - Left to Right (except to first two integer arguments in ECX:EDX)
1805   //!
1806   //! Stack is cleaned by:
1807   //! - Callee.
1808   //!
1809   //! Return value:
1810   //! - Integer types - EAX:EDX registers.
1811   //! - Floating points - st(0) register.
1812   //!
1813   //! @note Arguments on the stack are in left-to-right order that differs
1814   //! to other fastcall conventions used in different compilers.
1815   kX86FuncConvBorlandFastCall = 7,
1816 
1817   //! @brief GCC specific fastcall convention.
1818   //!
1819   //! Two first parameters (evaluated from left-to-right) are in ECX:EDX
1820   //! registers, all others on the stack in right-to-left order.
1821   //!
1822   //! Arguments direction:
1823   //! - Right to Left (except to first two integer arguments in ECX:EDX)
1824   //!
1825   //! Stack is cleaned by:
1826   //! - Callee.
1827   //!
1828   //! Return value:
1829   //! - Integer types - EAX:EDX registers.
1830   //! - Floating points - st(0) register.
1831   //!
1832   //! @note This calling convention should be compatible to
1833   //! @c kX86FuncConvMsFastCall.
1834   kX86FuncConvGccFastCall = 8,
1835 
1836   //! @brief GCC specific regparm(1) convention.
1837   //!
1838   //! The first parameter (evaluated from left-to-right) is in EAX register,
1839   //! all others on the stack in right-to-left order.
1840   //!
1841   //! Arguments direction:
1842   //! - Right to Left (except to first one integer argument in EAX)
1843   //!
1844   //! Stack is cleaned by:
1845   //! - Caller.
1846   //!
1847   //! Return value:
1848   //! - Integer types - EAX:EDX registers.
1849   //! - Floating points - st(0) register.
1850   kX86FuncConvGccRegParm1 = 9,
1851 
1852   //! @brief GCC specific regparm(2) convention.
1853   //!
1854   //! Two first parameters (evaluated from left-to-right) are in EAX:EDX
1855   //! registers, all others on the stack in right-to-left order.
1856   //!
1857   //! Arguments direction:
1858   //! - Right to Left (except to first two integer arguments in EAX:EDX)
1859   //!
1860   //! Stack is cleaned by:
1861   //! - Caller.
1862   //!
1863   //! Return value:
1864   //! - Integer types - EAX:EDX registers.
1865   //! - Floating points - st(0) register.
1866   kX86FuncConvGccRegParm2 = 10,
1867 
1868   //! @brief GCC specific fastcall with 3 parameters in registers.
1869   //!
1870   //! Three first parameters (evaluated from left-to-right) are in
1871   //! EAX:EDX:ECX registers, all others on the stack in right-to-left order.
1872   //!
1873   //! Arguments direction:
1874   //! - Right to Left (except to first three integer arguments in EAX:EDX:ECX)
1875   //!
1876   //! Stack is cleaned by:
1877   //! - Caller.
1878   //!
1879   //! Return value:
1880   //! - Integer types - EAX:EDX registers.
1881   //! - Floating points - st(0) register.
1882   kX86FuncConvGccRegParm3 = 11,
1883 
1884   // --------------------------------------------------------------------------
1885   // [Detect]
1886   // --------------------------------------------------------------------------
1887 
1888   //! @def kX86FuncConvDefault
1889   //! @brief Default calling convention for current platform / operating system.
1890 
1891   //! @def kX86FuncConvCompatFastCall
1892   //! @brief Compatibility for __fastcall calling convention.
1893   //!
1894   //! @note This enumeration is always set to a value which is compatible to
1895   //! current compilers __fastcall calling convention. In 64-bit mode the value
1896   //! is compatible to @ref kX86FuncConvX64W or @ref kX86FuncConvX64U.
1897 
1898   //! @def kX86FuncConvCompatStdCall
1899   //! @brief Compatibility for __stdcall calling convention.
1900   //!
1901   //! @note This enumeration is always set to a value which is compatible to
1902   //! current compilers __stdcall calling convention. In 64-bit mode the value
1903   //! is compatible to @ref kX86FuncConvX64W or @ref kX86FuncConvX64U.
1904 
1905   //! @def kX86FuncConvCompatCDecl
1906   //! @brief Default C calling convention based on current compiler's settings.
1907 
1908 #if defined(ASMJIT_X86)
1909 
1910   kX86FuncConvDefault = kX86FuncConvCDecl,
1911 
1912 # if defined(_MSC_VER)
1913   kX86FuncConvCompatFastCall = kX86FuncConvMsFastCall,
1914 # elif defined(__GNUC__)
1915   kX86FuncConvCompatFastCall = kX86FuncConvGccFastCall,
1916 # elif defined(__BORLANDC__)
1917   kX86FuncConvCompatFastCall = kX86FuncConvBorlandFastCall,
1918 # else
1919 #  error "AsmJit::kX86FuncConvCompatFastCall not supported."
1920 # endif
1921 
1922   kX86FuncConvCompatStdCall = kX86FuncConvStdCall,
1923   kX86FuncConvCompatCDecl = kX86FuncConvCDecl
1924 
1925 #else
1926 
1927 # if defined(ASMJIT_WINDOWS)
1928   kX86FuncConvDefault = kX86FuncConvX64W,
1929 # else
1930   kX86FuncConvDefault = kX86FuncConvX64U,
1931 # endif
1932 
1933   kX86FuncConvCompatFastCall = kX86FuncConvDefault,
1934   kX86FuncConvCompatStdCall = kX86FuncConvDefault,
1935   kX86FuncConvCompatCDecl = kX86FuncConvDefault
1936 
1937 #endif // ASMJIT_X86
1938 };
1939 
1940 // ============================================================================
1941 // [AsmJit::kX86FuncHint]
1942 // ============================================================================
1943 
1944 //! @brief X86 function hints.
1945 enum kX86FuncHint
1946 {
1947   //! @brief Use push/pop sequences instead of mov sequences in function prolog
1948   //! and epilog.
1949   kX86FuncHintPushPop = 8,
1950   //! @brief Add emms instruction to the function epilog.
1951   kX86FuncHintEmms = 9,
1952   //! @brief Add sfence instruction to the function epilog.
1953   kX86FuncHintSFence = 10,
1954   //! @brief Add lfence instruction to the function epilog.
1955   kX86FuncHintLFence = 11,
1956   //! @brief Assume that stack is aligned to 16-bytes.
1957   kX86FuncHintAssume16ByteAlignment = 12,
1958   //! @brief Perform 16-byte stack alignmend by function.
1959   kX86FuncHintPerform16ByteAlignment = 13
1960 };
1961 
1962 // ============================================================================
1963 // [AsmJit::kX86FuncFlags]
1964 // ============================================================================
1965 
1966 //! @brief X86 function flags.
1967 enum kX86FuncFlags
1968 {
1969   //! @brief Whether to emit prolog / epilog sequence using push & pop
1970   //! instructions (the default).
1971   kX86FuncFlagPushPop = (1U << 8),
1972 
1973   //! @brief Whether to emit EMMS instruction in epilog (auto-detected).
1974   kX86FuncFlagEmitEmms = (1U << 9),
1975 
1976   //! @brief Whether to emit SFence instruction in epilog (auto-detected).
1977   //!
1978   //! @note @ref kX86FuncFlagEmitSFence and @ref kX86FuncFlagEmitLFence
1979   //! combination will result in emitting mfence.
1980   kX86FuncFlagEmitSFence = (1U << 10),
1981 
1982   //! @brief Whether to emit LFence instruction in epilog (auto-detected).
1983   //!
1984   //! @note @ref kX86FuncFlagEmitSFence and @ref kX86FuncFlagEmitLFence
1985   //! combination will result in emitting mfence.
1986   kX86FuncFlagEmitLFence = (1U << 11),
1987 
1988   //! @brief Whether the function stack is aligned by 16-bytes by OS.
1989   //!
1990   //! This is always true for 64-bit mode and for linux.
1991   kX86FuncFlagAssume16ByteAlignment = (1U << 12),
1992 
1993   //! @brief Whether the function stack (for variables) is aligned manually
1994   //! by function to 16-bytes.
1995   //!
1996   //! This makes sense only if @ref kX86FuncFlagAssume16ByteAlignment is
1997   //! false and MOVDQA instruction or other SSE/SSE2 instructions are used to
1998   //! work with variables stored on the stack.
1999   //!
2000   //! Value is determined automatically by these factors, expectations are:
2001   //!
2002   //!   1. There is 16-byte wide variable which address was used (alloc, spill,
2003   //!      op).
2004   //!   2. Function can't be naked.
2005   kX86FuncFlagPerform16ByteAlignment = (1U << 13),
2006 
2007   //! @brief Whether the ESP register is adjusted by the stack size needed
2008   //! to save registers and function variables.
2009   //!
2010   //! Esp is adjusted by 'sub' instruction in prolog and by add function in
2011   //! epilog (only if function is not naked).
2012   kX86FuncFlagIsEspAdjusted = (1U << 14)
2013 };
2014 
2015 // ============================================================================
2016 // [AsmJit::kX86CompilerInst]
2017 // ============================================================================
2018 
2019 //! @brief Instruction flags used by @ref X86CompilerInst item.
2020 enum kX86CompilerInstFlag
2021 {
2022   //! @brief Whether the instruction is special.
2023   kX86CompilerInstFlagIsSpecial = (1U << 0),
2024   //! @brief Whether the instruction is FPU.
2025   kX86CompilerInstFlagIsFpu = (1U << 1),
2026   //! @brief Whether the one of the operands is GPB.Lo register.
2027   kX86CompilerInstFlagIsGpbLoUsed = (1U << 2),
2028   //! @brief Whether the one of the operands is GPB.Hi register.
2029   kX86CompilerInstFlagIsGpbHiUsed = (1U << 3),
2030 
2031   //! @brief Whether the jmp/jcc is likely to be taken.
2032   kX86CompilerInstFlagIsTaken = (1U << 7)
2033 };
2034 
2035 // ============================================================================
2036 // [AsmJit::kX86VarClass]
2037 // ============================================================================
2038 
2039 //! @brief X86 variable class.
2040 enum kX86VarClass
2041 {
2042   //! @brief No class (used internally).
2043   kX86VarClassNone = 0,
2044   //! @brief General purpose register.
2045   kX86VarClassGp = 1,
2046   //! @brief X87 floating point.
2047   kX86VarClassX87 = 2,
2048   //! @brief MMX register.
2049   kX86VarClassMm = 3,
2050   //! @brief XMM register.
2051   kX86VarClassXmm = 4,
2052 
2053   //! @brief Count of X86 variable classes.
2054   kX86VarClassCount = 5
2055 };
2056 
2057 // ============================================================================
2058 // [AsmJit::kX86VarFlags]
2059 // ============================================================================
2060 
2061 //! @brief X86 variable class.
2062 enum kX86VarFlags
2063 {
2064   //! @brief Variable contains single-precision floating-point(s).
2065   kX86VarFlagSP = 0x10,
2066   //! @brief Variable contains double-precision floating-point(s).
2067   kX86VarFlagDP = 0x20,
2068   //! @brief Variable is packed (for example float4x, double2x, ...).
2069   kX86VarFlagPacked = 0x40
2070 };
2071 
2072 // ============================================================================
2073 // [AsmJit::kX86VarType]
2074 // ============================================================================
2075 
2076 //! @brief X86 variable type.
2077 enum kX86VarType
2078 {
2079   // --------------------------------------------------------------------------
2080   // [Platform Dependent]
2081   // --------------------------------------------------------------------------
2082 
2083   //! @brief Variable is 32-bit general purpose register.
2084   kX86VarTypeGpd = 0,
2085   //! @brief Variable is 64-bit general purpose register.
2086   kX86VarTypeGpq = 1,
2087 
2088   //! @var kX86VarTypeGpz
2089   //! @brief Variable is system wide general purpose register (32-bit or 64-bit).
2090 #if defined(ASMJIT_X86)
2091   kX86VarTypeGpz = kX86VarTypeGpd,
2092 #else
2093   kX86VarTypeGpz = kX86VarTypeGpq,
2094 #endif
2095 
2096   //! @brief Variable is X87 (FPU).
2097   kX86VarTypeX87 = 2,
2098   //! @brief Variable is X87 (FPU) SP-FP number (float).
2099   kX86VarTypeX87SS = 3,
2100   //! @brief Variable is X87 (FPU) DP-FP number (double).
2101   kX86VarTypeX87SD = 4,
2102 
2103   //! @brief Variable is MM register / memory location.
2104   kX86VarTypeMm = 5,
2105   //! @brief Variable is XMM register / memory location.
2106   kX86VarTypeXmm = 6,
2107 
2108   //! @brief Variable is SSE scalar SP-FP number.
2109   kX86VarTypeXmmSS = 7,
2110   //! @brief Variable is SSE packed SP-FP number (4 floats).
2111   kX86VarTypeXmmPS = 8,
2112 
2113   //! @brief Variable is SSE2 scalar DP-FP number.
2114   kX86VarTypeXmmSD = 9,
2115   //! @brief Variable is SSE2 packed DP-FP number (2 doubles).
2116   kX86VarTypeXmmPD = 10,
2117 
2118   //! @brief Count of variable types.
2119   kX86VarTypeCount = 11,
2120 
2121   // --------------------------------------------------------------------------
2122   // [Platform Independent]
2123   // --------------------------------------------------------------------------
2124 
2125   //! @brief Variable is 32-bit integer.
2126   kX86VarTypeInt32 = kX86VarTypeGpd,
2127   //! @brief Variable is 64-bit integer.
2128   kX86VarTypeInt64 = kX86VarTypeGpq,
2129   //! @brief Variable is system dependent integer / pointer.
2130   kX86VarTypeIntPtr = kX86VarTypeGpz,
2131 
2132 #if defined(ASMJIT_X86)
2133   kX86VarTypeFloat = kX86VarTypeX87SS,
2134   kX86VarTypeDouble = kX86VarTypeX87SD
2135 #else
2136   kX86VarTypeFloat = kX86VarTypeXmmSS,
2137   kX86VarTypeDouble = kX86VarTypeXmmSD
2138 #endif
2139 };
2140 
2141 // ============================================================================
2142 // [AsmJit::X86VarInfo]
2143 // ============================================================================
2144 
2145 //! @brief X86 variable information.
2146 struct X86VarInfo
2147 {
2148   // --------------------------------------------------------------------------
2149   // [Accessors]
2150   // --------------------------------------------------------------------------
2151 
2152   //! @brief Get register code base, see @ref kX86RegCode.
getCodeX86VarInfo2153   inline uint32_t getCode() const
2154   { return _code; }
2155 
2156   //! @brief Get register size in bytes.
getSizeX86VarInfo2157   inline uint32_t getSize() const
2158   { return _size; }
2159 
2160   //! @brief Get variable class, see @ref kX86VarClass.
getClassX86VarInfo2161   inline uint32_t getClass() const
2162   { return _class; }
2163 
2164   //! @brief Get variable flags, see @ref kX86VarFlags.
getFlagsX86VarInfo2165   inline uint32_t getFlags() const
2166   { return _flags; }
2167 
2168   //! @brief Get variable type name.
getNameX86VarInfo2169   inline const char* getName() const
2170   { return _name; }
2171 
2172   // --------------------------------------------------------------------------
2173   // [Members]
2174   // --------------------------------------------------------------------------
2175 
2176   //! @brief Register code base, see @ref kX86RegCode.
2177   uint32_t _code;
2178   //! @brief Register size in bytes.
2179   uint16_t _size;
2180   //! @brief Variable class, see @ref kX86VarClass.
2181   uint8_t _class;
2182   //! @brief Variable flags, see @ref kX86VarFlags.
2183   uint8_t _flags;
2184   //! @brief Variable type name.
2185   char _name[8];
2186 };
2187 
2188 // ============================================================================
2189 // [AsmJit::x86VarInfo]
2190 // ============================================================================
2191 
2192 ASMJIT_VAR const X86VarInfo x86VarInfo[];
2193 
2194 //! @}
2195 
2196 } // AsmJit namespace
2197 
2198 // [Api-End]
2199 #include "../core/apiend.h"
2200 
2201 // [Guard]
2202 #endif // _ASMJIT_X86_X86DEFS_H
2203