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_X86OPERAND_H
9 #define _ASMJIT_X86_X86OPERAND_H
10 
11 // [Dependencies - AsmJit]
12 #include "../core/defs.h"
13 #include "../core/operand.h"
14 
15 #include "../x86/x86defs.h"
16 
17 namespace AsmJit {
18 
19 // ============================================================================
20 // [Forward Declarations]
21 // ============================================================================
22 
23 struct GpReg;
24 struct GpVar;
25 struct Mem;
26 struct MmReg;
27 struct MmVar;
28 struct Var;
29 struct X87Reg;
30 struct X87Var;
31 struct XmmReg;
32 struct XmmVar;
33 
34 struct SegmentReg;
35 
36 //! @addtogroup AsmJit_X86
37 //! @{
38 
39 // ============================================================================
40 // [AsmJit::MmData]
41 // ============================================================================
42 
43 //! @brief Structure used for MMX specific data (64-bit).
44 //!
45 //! This structure can be used to load / store data from / to MMX register.
46 union MmData
47 {
48   // --------------------------------------------------------------------------
49   // [Methods]
50   // --------------------------------------------------------------------------
51 
52   //! @brief Set all eight signed 8-bit integers.
setSB(int8_t x0,int8_t x1,int8_t x2,int8_t x3,int8_t x4,int8_t x5,int8_t x6,int8_t x7)53   inline void setSB(
54     int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
55   {
56     sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3; sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7;
57   }
58 
59   //! @brief Set all eight unsigned 8-bit integers.
setUB(uint8_t x0,uint8_t x1,uint8_t x2,uint8_t x3,uint8_t x4,uint8_t x5,uint8_t x6,uint8_t x7)60   inline void setUB(
61     uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
62   {
63     ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3; ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7;
64   }
65 
66   //! @brief Set all four signed 16-bit integers.
setSW(int16_t x0,int16_t x1,int16_t x2,int16_t x3)67   inline void setSW(
68     int16_t x0, int16_t x1, int16_t x2, int16_t x3)
69   {
70     sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
71   }
72 
73   //! @brief Set all four unsigned 16-bit integers.
setUW(uint16_t x0,uint16_t x1,uint16_t x2,uint16_t x3)74   inline void setUW(
75     uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
76   {
77     uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
78   }
79 
80   //! @brief Set all two signed 32-bit integers.
setSD(int32_t x0,int32_t x1)81   inline void setSD(
82     int32_t x0, int32_t x1)
83   {
84     sd[0] = x0; sd[1] = x1;
85   }
86 
87   //! @brief Set all two unsigned 32-bit integers.
setUD(uint32_t x0,uint32_t x1)88   inline void setUD(
89     uint32_t x0, uint32_t x1)
90   {
91     ud[0] = x0; ud[1] = x1;
92   }
93 
94   //! @brief Set signed 64-bit integer.
setSQ(int64_t x0)95   inline void setSQ(
96     int64_t x0)
97   {
98     sq[0] = x0;
99   }
100 
101   //! @brief Set unsigned 64-bit integer.
setUQ(uint64_t x0)102   inline void setUQ(
103     uint64_t x0)
104   {
105     uq[0] = x0;
106   }
107 
108   //! @brief Set all two SP-FP values.
setSF(float x0,float x1)109   inline void setSF(
110     float x0, float x1)
111   {
112     sf[0] = x0; sf[1] = x1;
113   }
114 
115   // --------------------------------------------------------------------------
116   // [Members]
117   // --------------------------------------------------------------------------
118 
119   //! @brief Array of eight signed 8-bit integers.
120   int8_t sb[8];
121   //! @brief Array of eight unsigned 8-bit integers.
122   uint8_t ub[8];
123   //! @brief Array of four signed 16-bit integers.
124   int16_t sw[4];
125   //! @brief Array of four unsigned 16-bit integers.
126   uint16_t uw[4];
127   //! @brief Array of two signed 32-bit integers.
128   int32_t sd[2];
129   //! @brief Array of two unsigned 32-bit integers.
130   uint32_t ud[2];
131   //! @brief Array of one signed 64-bit integer.
132   int64_t sq[1];
133   //! @brief Array of one unsigned 64-bit integer.
134   uint64_t uq[1];
135 
136   //! @brief Array of two SP-FP values.
137   float sf[2];
138 };
139 
140 // ============================================================================
141 // [AsmJit::XmmData]
142 // ============================================================================
143 
144 //! @brief Structure used for SSE specific data (128-bit).
145 //!
146 //! This structure can be used to load / store data from / to SSE register.
147 //!
148 //! @note Always align SSE data to 16-bytes.
149 union XmmData
150 {
151   // --------------------------------------------------------------------------
152   // [Methods]
153   // --------------------------------------------------------------------------
154 
155   //! @brief Set all sixteen signed 8-bit integers.
setSB(int8_t x0,int8_t x1,int8_t x2,int8_t x3,int8_t x4,int8_t x5,int8_t x6,int8_t x7,int8_t x8,int8_t x9,int8_t x10,int8_t x11,int8_t x12,int8_t x13,int8_t x14,int8_t x15)156   inline void setSB(
157     int8_t x0, int8_t x1, int8_t x2 , int8_t x3 , int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
158     int8_t x8, int8_t x9, int8_t x10, int8_t x11, int8_t x12, int8_t x13, int8_t x14, int8_t x15)
159   {
160     sb[0] = x0; sb[1] = x1; sb[ 2] = x2 ; sb[3 ] = x3 ; sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ;
161     sb[8] = x8; sb[9] = x9; sb[10] = x10; sb[11] = x11; sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
162   }
163 
164   //! @brief Set all sixteen unsigned 8-bit integers.
setUB(uint8_t x0,uint8_t x1,uint8_t x2,uint8_t x3,uint8_t x4,uint8_t x5,uint8_t x6,uint8_t x7,uint8_t x8,uint8_t x9,uint8_t x10,uint8_t x11,uint8_t x12,uint8_t x13,uint8_t x14,uint8_t x15)165   inline void setUB(
166     uint8_t x0, uint8_t x1, uint8_t x2 , uint8_t x3 , uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
167     uint8_t x8, uint8_t x9, uint8_t x10, uint8_t x11, uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15)
168   {
169     ub[0] = x0; ub[1] = x1; ub[ 2] = x2 ; ub[3 ] = x3 ; ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ;
170     ub[8] = x8; ub[9] = x9; ub[10] = x10; ub[11] = x11; ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
171   }
172 
173   //! @brief Set all eight signed 16-bit integers.
setSW(int16_t x0,int16_t x1,int16_t x2,int16_t x3,int16_t x4,int16_t x5,int16_t x6,int16_t x7)174   inline void setSW(
175     int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
176   {
177     sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7;
178   }
179 
180   //! @brief Set all eight unsigned 16-bit integers.
setUW(uint16_t x0,uint16_t x1,uint16_t x2,uint16_t x3,uint16_t x4,uint16_t x5,uint16_t x6,uint16_t x7)181   inline void setUW(
182     uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
183   {
184     uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7;
185   }
186 
187   //! @brief Set all four signed 32-bit integers.
setSD(int32_t x0,int32_t x1,int32_t x2,int32_t x3)188   inline void setSD(
189     int32_t x0, int32_t x1, int32_t x2, int32_t x3)
190   {
191     sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
192   }
193 
194   //! @brief Set all four unsigned 32-bit integers.
setUD(uint32_t x0,uint32_t x1,uint32_t x2,uint32_t x3)195   inline void setUD(
196     uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
197   {
198     ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
199   }
200 
201   //! @brief Set all two signed 64-bit integers.
setSQ(int64_t x0,int64_t x1)202   inline void setSQ(
203     int64_t x0, int64_t x1)
204   {
205     sq[0] = x0; sq[1] = x1;
206   }
207 
208   //! @brief Set all two unsigned 64-bit integers.
setUQ(uint64_t x0,uint64_t x1)209   inline void setUQ(
210     uint64_t x0, uint64_t x1)
211   {
212     uq[0] = x0; uq[1] = x1;
213   }
214 
215   //! @brief Set all four SP-FP floats.
setSF(float x0,float x1,float x2,float x3)216   inline void setSF(
217     float x0, float x1, float x2, float x3)
218   {
219     sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
220   }
221 
222   //! @brief Set all two DP-FP floats.
setDF(double x0,double x1)223   inline void setDF(
224     double x0, double x1)
225   {
226     df[0] = x0; df[1] = x1;
227   }
228 
229   // --------------------------------------------------------------------------
230   // [Members]
231   // --------------------------------------------------------------------------
232 
233   //! @brief Array of sixteen signed 8-bit integers.
234   int8_t sb[16];
235   //! @brief Array of sixteen unsigned 8-bit integers.
236   uint8_t ub[16];
237   //! @brief Array of eight signed 16-bit integers.
238   int16_t sw[8];
239   //! @brief Array of eight unsigned 16-bit integers.
240   uint16_t uw[8];
241   //! @brief Array of four signed 32-bit integers.
242   int32_t sd[4];
243   //! @brief Array of four unsigned 32-bit integers.
244   uint32_t ud[4];
245   //! @brief Array of two signed 64-bit integers.
246   int64_t sq[2];
247   //! @brief Array of two unsigned 64-bit integers.
248   uint64_t uq[2];
249 
250   //! @brief Array of four 32-bit single precision floating points.
251   float sf[4];
252   //! @brief Array of two 64-bit double precision floating points.
253   double df[2];
254 };
255 
256 // ============================================================================
257 // [AsmJit::GpReg]
258 // ============================================================================
259 
260 //! @brief General purpose register.
261 //!
262 //! This class is for all general purpose registers (64, 32, 16 and 8-bit).
263 struct GpReg : public Reg
264 {
265   // --------------------------------------------------------------------------
266   // [Construction / Destruction]
267   // --------------------------------------------------------------------------
268 
269   //! @brief Create non-initialized general purpose register.
GpRegGpReg270   inline GpReg() : Reg(kInvalidValue, 0) {}
271   //! @brief Create a reference to @a other general purpose register.
GpRegGpReg272   inline GpReg(const GpReg& other) : Reg(other) {}
273 
274 #if !defined(ASMJIT_NODOC)
GpRegGpReg275   inline GpReg(const _DontInitialize& dontInitialize) : Reg(dontInitialize) {}
GpRegGpReg276   inline GpReg(const _Initialize&, uint32_t code) : Reg(code, static_cast<uint32_t>(1U << ((code & kRegTypeMask) >> 12))) {}
277 #endif // ASMJIT_NODOC
278 
279   // --------------------------------------------------------------------------
280   // [Reg Specific]
281   // --------------------------------------------------------------------------
282 
283   //! @brief Set register code to @a code.
setCodeGpReg284   inline GpReg& setCode(uint32_t code)
285   {
286     _reg.code = code;
287     return *this;
288   }
289 
290   //! @brief Set register size to @a size.
setSizeGpReg291   inline GpReg& setSize(uint32_t size)
292   {
293     _reg.size = static_cast<uint8_t>(size);
294     return *this;
295   }
296 
297   // --------------------------------------------------------------------------
298   // [GpReg Specific]
299   // --------------------------------------------------------------------------
300 
301   //! @brief Get whether the general purpose register is BYTE (8-bit) type.
isGpbGpReg302   inline bool isGpb() const { return (_reg.code & kRegTypeMask) <= kX86RegTypeGpbHi; }
303   //! @brief Get whether the general purpose register is LO-BYTE (8-bit) type.
isGpbLoGpReg304   inline bool isGpbLo() const { return (_reg.code & kRegTypeMask) == kX86RegTypeGpbLo; }
305   //! @brief Get whether the general purpose register is HI-BYTE (8-bit) type.
isGpbHiGpReg306   inline bool isGpbHi() const { return (_reg.code & kRegTypeMask) == kX86RegTypeGpbHi; }
307 
308   //! @brief Get whether the general purpose register is WORD (16-bit) type.
isGpwGpReg309   inline bool isGpw() const { return (_reg.code & kRegTypeMask) == kX86RegTypeGpw; }
310   //! @brief Get whether the general purpose register is DWORD (32-bit) type.
311   //!
312   //! This is default type for 32-bit platforms.
isGpdGpReg313   inline bool isGpd() const { return (_reg.code & kRegTypeMask) == kX86RegTypeGpd; }
314   //! @brief Get whether the general purpose register is QWORD (64-bit) type.
315   //!
316   //! This is default type for 64-bit platforms.
isGpqGpReg317   inline bool isGpq() const { return (_reg.code & kRegTypeMask) == kX86RegTypeGpq; }
318 
319   // --------------------------------------------------------------------------
320   // [Operator Overload]
321   // --------------------------------------------------------------------------
322 
323 #if !defined(ASMJIT_NODOC)
324   inline GpReg& operator=(const GpReg& other) { _copy(other); return *this; }
325   inline bool operator==(const GpReg& other) const { return getRegCode() == other.getRegCode(); }
326   inline bool operator!=(const GpReg& other) const { return getRegCode() != other.getRegCode(); }
327 #endif // ASMJIT_NODOC
328 };
329 
330 // ============================================================================
331 // [AsmJit::X87Reg]
332 // ============================================================================
333 
334 //! @brief 80-bit x87 floating point register.
335 //!
336 //! To create instance of x87 register, use @c st() function.
337 struct X87Reg : public Reg
338 {
339   // --------------------------------------------------------------------------
340   // [Construction / Destruction]
341   // --------------------------------------------------------------------------
342 
343   //! @brief Create non-initialized x87 register.
X87RegX87Reg344   inline X87Reg() : Reg(kInvalidValue, 10) {}
345   //! @brief Create a reference to @a other x87 register.
X87RegX87Reg346   inline X87Reg(const X87Reg& other) : Reg(other) {}
347 
348 #if !defined(ASMJIT_NODOC)
X87RegX87Reg349   inline X87Reg(const _DontInitialize& dontInitialize) : Reg(dontInitialize) {}
X87RegX87Reg350   inline X87Reg(const _Initialize&, uint32_t code) : Reg(code | kX86RegTypeX87, 10) {}
351 #endif // ASMJIT_NODOC
352 
353   // --------------------------------------------------------------------------
354   // [Reg Specific]
355   // --------------------------------------------------------------------------
356 
357   //! @brief Set register code to @a code.
setCodeX87Reg358   inline X87Reg& setCode(uint32_t code)
359   {
360     _reg.code = code;
361     return *this;
362   }
363 
364   //! @brief Set register size to @a size.
setSizeX87Reg365   inline X87Reg& setSize(uint32_t size)
366   {
367     _reg.size = static_cast<uint8_t>(size);
368     return *this;
369   }
370 
371   // --------------------------------------------------------------------------
372   // [Operator Overload]
373   // --------------------------------------------------------------------------
374 
375 #if !defined(ASMJIT_NODOC)
376   inline X87Reg& operator=(const X87Reg& other) { _copy(other); return *this; }
377   inline bool operator==(const X87Reg& other) const { return getRegCode() == other.getRegCode(); }
378   inline bool operator!=(const X87Reg& other) const { return getRegCode() != other.getRegCode(); }
379 #endif // ASMJIT_NODOC
380 };
381 
382 // ============================================================================
383 // [AsmJit::MmReg]
384 // ============================================================================
385 
386 //! @brief 64-bit MMX register.
387 struct MmReg : public Reg
388 {
389   // --------------------------------------------------------------------------
390   // [Construction / Destruction]
391   // --------------------------------------------------------------------------
392 
393   //! @brief Create non-initialized MM register.
MmRegMmReg394   inline MmReg() : Reg(kInvalidValue, 8) {}
395   //! @brief Create a reference to @a other MM register.
MmRegMmReg396   inline MmReg(const MmReg& other) : Reg(other) {}
397 
398 #if !defined(ASMJIT_NODOC)
MmRegMmReg399   inline MmReg(const _DontInitialize& dontInitialize) : Reg(dontInitialize) {}
MmRegMmReg400   inline MmReg(const _Initialize&, uint32_t code) : Reg(code, 8) {}
401 #endif // ASMJIT_NODOC
402 
403   // --------------------------------------------------------------------------
404   // [Reg Specific]
405   // --------------------------------------------------------------------------
406 
407   //! @brief Set register code to @a code.
setCodeMmReg408   inline MmReg& setCode(uint32_t code)
409   {
410     _reg.code = code;
411     return *this;
412   }
413 
414   //! @brief Set register size to @a size.
setSizeMmReg415   inline MmReg& setSize(uint32_t size)
416   {
417     _reg.size = static_cast<uint8_t>(size);
418     return *this;
419   }
420 
421   // --------------------------------------------------------------------------
422   // [Operator Overload]
423   // --------------------------------------------------------------------------
424 
425 #if !defined(ASMJIT_NODOC)
426   inline MmReg& operator=(const MmReg& other) { _copy(other); return *this; }
427   inline bool operator==(const MmReg& other) const { return getRegCode() == other.getRegCode(); }
428   inline bool operator!=(const MmReg& other) const { return getRegCode() != other.getRegCode(); }
429 #endif // ASMJIT_NODOC
430 };
431 
432 // ============================================================================
433 // [AsmJit::XmmReg]
434 // ============================================================================
435 
436 //! @brief 128-bit SSE register.
437 struct XmmReg : public Reg
438 {
439   // --------------------------------------------------------------------------
440   // [Construction / Destruction]
441   // --------------------------------------------------------------------------
442 
443   //! @brief Create non-initialized XMM register.
XmmRegXmmReg444   inline XmmReg() : Reg(kInvalidValue, 16) {}
445   //! @brief Create a reference to @a other XMM register.
XmmRegXmmReg446   inline XmmReg(const _Initialize&, uint32_t code) : Reg(code, 16) {}
447 
448 #if !defined(ASMJIT_NODOC)
XmmRegXmmReg449   inline XmmReg(const _DontInitialize& dontInitialize) : Reg(dontInitialize) {}
XmmRegXmmReg450   inline XmmReg(const XmmReg& other) : Reg(other) {}
451 #endif // ASMJIT_NODOC
452 
453   // --------------------------------------------------------------------------
454   // [Reg Specific]
455   // --------------------------------------------------------------------------
456 
457   //! @brief Set register code to @a code.
setCodeXmmReg458   inline XmmReg& setCode(uint32_t code)
459   {
460     _reg.code = code;
461     return *this;
462   }
463 
464   //! @brief Set register size to @a size.
setSizeXmmReg465   inline XmmReg& setSize(uint32_t size)
466   {
467     _reg.size = static_cast<uint8_t>(size);
468     return *this;
469   }
470 
471   // --------------------------------------------------------------------------
472   // [Operator Overload]
473   // --------------------------------------------------------------------------
474 
475 #if !defined(ASMJIT_NODOC)
476   inline XmmReg& operator=(const XmmReg& other) { _copy(other); return *this; }
477   inline bool operator==(const XmmReg& other) const { return getRegCode() == other.getRegCode(); }
478   inline bool operator!=(const XmmReg& other) const { return getRegCode() != other.getRegCode(); }
479 #endif // ASMJIT_NODOC
480 };
481 
482 // ============================================================================
483 // [AsmJit::SegmentReg]
484 // ============================================================================
485 
486 //! @brief Segment register.
487 struct SegmentReg : public Reg
488 {
489   // --------------------------------------------------------------------------
490   // [Construction / Destruction]
491   // --------------------------------------------------------------------------
492 
493   //! @brief Create non-initialized segment register.
SegmentRegSegmentReg494   inline SegmentReg() : Reg(kInvalidValue, 2) {}
495   //! @brief Create a reference to @a other segment register.
SegmentRegSegmentReg496   inline SegmentReg(const _Initialize&, uint32_t code) : Reg(code, 2) {}
497 
498 #if !defined(ASMJIT_NODOC)
SegmentRegSegmentReg499   inline SegmentReg(const _DontInitialize& dontInitialize) : Reg(dontInitialize) {}
SegmentRegSegmentReg500   inline SegmentReg(const SegmentReg& other) : Reg(other) {}
501 #endif // ASMJIT_NODOC
502 
503   // --------------------------------------------------------------------------
504   // [Reg Specific]
505   // --------------------------------------------------------------------------
506 
507   //! @brief Set register code to @a code.
setCodeSegmentReg508   inline SegmentReg& setCode(uint32_t code)
509   {
510     _reg.code = code;
511     return *this;
512   }
513 
514   //! @brief Set register size to @a size.
setSizeSegmentReg515   inline SegmentReg& setSize(uint32_t size)
516   {
517     _reg.size = static_cast<uint8_t>(size);
518     return *this;
519   }
520 
521   // --------------------------------------------------------------------------
522   // [Operator Overload]
523   // --------------------------------------------------------------------------
524 
525 #if !defined(ASMJIT_NODOC)
526   inline SegmentReg& operator=(const SegmentReg& other) { _copy(other); return *this; }
527   inline bool operator==(const SegmentReg& other) const { return getRegCode() == other.getRegCode(); }
528   inline bool operator!=(const SegmentReg& other) const { return getRegCode() != other.getRegCode(); }
529 #endif // ASMJIT_NODOC
530 };
531 
532 // ============================================================================
533 // [AsmJit::Registers - no_reg]
534 // ============================================================================
535 
536 //! @brief No register, can be used only in @c Mem operand.
537 ASMJIT_VAR const GpReg no_reg;
538 
539 // ============================================================================
540 // [AsmJit::Registers - 8-bit]
541 // ============================================================================
542 
543 //! @brief 8-bit General purpose register.
544 ASMJIT_VAR const GpReg al;
545 //! @brief 8-bit General purpose register.
546 ASMJIT_VAR const GpReg cl;
547 //! @brief 8-bit General purpose register.
548 ASMJIT_VAR const GpReg dl;
549 //! @brief 8-bit General purpose register.
550 ASMJIT_VAR const GpReg bl;
551 
552 #if defined(ASMJIT_X64)
553 //! @brief 8-bit General purpose register (64-bit mode only).
554 ASMJIT_VAR const GpReg spl;
555 //! @brief 8-bit General purpose register (64-bit mode only).
556 ASMJIT_VAR const GpReg bpl;
557 //! @brief 8-bit General purpose register (64-bit mode only).
558 ASMJIT_VAR const GpReg sil;
559 //! @brief 8-bit General purpose register (64-bit mode only).
560 ASMJIT_VAR const GpReg dil;
561 
562 //! @brief 8-bit General purpose register (64-bit mode only).
563 ASMJIT_VAR const GpReg r8b;
564 //! @brief 8-bit General purpose register (64-bit mode only).
565 ASMJIT_VAR const GpReg r9b;
566 //! @brief 8-bit General purpose register (64-bit mode only).
567 ASMJIT_VAR const GpReg r10b;
568 //! @brief 8-bit General purpose register (64-bit mode only).
569 ASMJIT_VAR const GpReg r11b;
570 //! @brief 8-bit General purpose register (64-bit mode only).
571 ASMJIT_VAR const GpReg r12b;
572 //! @brief 8-bit General purpose register (64-bit mode only).
573 ASMJIT_VAR const GpReg r13b;
574 //! @brief 8-bit General purpose register (64-bit mode only).
575 ASMJIT_VAR const GpReg r14b;
576 //! @brief 8-bit General purpose register (64-bit mode only).
577 ASMJIT_VAR const GpReg r15b;
578 #endif // ASMJIT_X64
579 
580 //! @brief 8-bit General purpose register.
581 ASMJIT_VAR const GpReg ah;
582 //! @brief 8-bit General purpose register.
583 ASMJIT_VAR const GpReg ch;
584 //! @brief 8-bit General purpose register.
585 ASMJIT_VAR const GpReg dh;
586 //! @brief 8-bit General purpose register.
587 ASMJIT_VAR const GpReg bh;
588 
589 // ============================================================================
590 // [AsmJit::Registers - 16-bit]
591 // ============================================================================
592 
593 //! @brief 16-bit General purpose register.
594 ASMJIT_VAR const GpReg ax;
595 //! @brief 16-bit General purpose register.
596 ASMJIT_VAR const GpReg cx;
597 //! @brief 16-bit General purpose register.
598 ASMJIT_VAR const GpReg dx;
599 //! @brief 16-bit General purpose register.
600 ASMJIT_VAR const GpReg bx;
601 //! @brief 16-bit General purpose register.
602 ASMJIT_VAR const GpReg sp;
603 //! @brief 16-bit General purpose register.
604 ASMJIT_VAR const GpReg bp;
605 //! @brief 16-bit General purpose register.
606 ASMJIT_VAR const GpReg si;
607 //! @brief 16-bit General purpose register.
608 ASMJIT_VAR const GpReg di;
609 
610 #if defined(ASMJIT_X64)
611 //! @brief 16-bit General purpose register (64-bit mode only).
612 ASMJIT_VAR const GpReg r8w;
613 //! @brief 16-bit General purpose register (64-bit mode only).
614 ASMJIT_VAR const GpReg r9w;
615 //! @brief 16-bit General purpose register (64-bit mode only).
616 ASMJIT_VAR const GpReg r10w;
617 //! @brief 16-bit General purpose register (64-bit mode only).
618 ASMJIT_VAR const GpReg r11w;
619 //! @brief 16-bit General purpose register (64-bit mode only).
620 ASMJIT_VAR const GpReg r12w;
621 //! @brief 16-bit General purpose register (64-bit mode only).
622 ASMJIT_VAR const GpReg r13w;
623 //! @brief 16-bit General purpose register (64-bit mode only).
624 ASMJIT_VAR const GpReg r14w;
625 //! @brief 16-bit General purpose register (64-bit mode only).
626 ASMJIT_VAR const GpReg r15w;
627 #endif // ASMJIT_X64
628 
629 // ============================================================================
630 // [AsmJit::Registers - 32-bit]
631 // ============================================================================
632 
633 //! @brief 32-bit General purpose register.
634 ASMJIT_VAR const GpReg eax;
635 //! @brief 32-bit General purpose register.
636 ASMJIT_VAR const GpReg ecx;
637 //! @brief 32-bit General purpose register.
638 ASMJIT_VAR const GpReg edx;
639 //! @brief 32-bit General purpose register.
640 ASMJIT_VAR const GpReg ebx;
641 //! @brief 32-bit General purpose register.
642 ASMJIT_VAR const GpReg esp;
643 //! @brief 32-bit General purpose register.
644 ASMJIT_VAR const GpReg ebp;
645 //! @brief 32-bit General purpose register.
646 ASMJIT_VAR const GpReg esi;
647 //! @brief 32-bit General purpose register.
648 ASMJIT_VAR const GpReg edi;
649 
650 #if defined(ASMJIT_X64)
651 //! @brief 32-bit General purpose register.
652 ASMJIT_VAR const GpReg r8d;
653 //! @brief 32-bit General purpose register.
654 ASMJIT_VAR const GpReg r9d;
655 //! @brief 32-bit General purpose register.
656 ASMJIT_VAR const GpReg r10d;
657 //! @brief 32-bit General purpose register.
658 ASMJIT_VAR const GpReg r11d;
659 //! @brief 32-bit General purpose register.
660 ASMJIT_VAR const GpReg r12d;
661 //! @brief 32-bit General purpose register.
662 ASMJIT_VAR const GpReg r13d;
663 //! @brief 32-bit General purpose register.
664 ASMJIT_VAR const GpReg r14d;
665 //! @brief 32-bit General purpose register.
666 ASMJIT_VAR const GpReg r15d;
667 #endif // ASMJIT_X64
668 
669 // ============================================================================
670 // [AsmJit::Registers - 64-bit]
671 // ============================================================================
672 
673 #if defined(ASMJIT_X64)
674 //! @brief 64-bit General purpose register (64-bit mode only).
675 ASMJIT_VAR const GpReg rax;
676 //! @brief 64-bit General purpose register (64-bit mode only).
677 ASMJIT_VAR const GpReg rcx;
678 //! @brief 64-bit General purpose register (64-bit mode only).
679 ASMJIT_VAR const GpReg rdx;
680 //! @brief 64-bit General purpose register (64-bit mode only).
681 ASMJIT_VAR const GpReg rbx;
682 //! @brief 64-bit General purpose register (64-bit mode only).
683 ASMJIT_VAR const GpReg rsp;
684 //! @brief 64-bit General purpose register (64-bit mode only).
685 ASMJIT_VAR const GpReg rbp;
686 //! @brief 64-bit General purpose register (64-bit mode only).
687 ASMJIT_VAR const GpReg rsi;
688 //! @brief 64-bit General purpose register (64-bit mode only).
689 ASMJIT_VAR const GpReg rdi;
690 
691 //! @brief 64-bit General purpose register (64-bit mode only).
692 ASMJIT_VAR const GpReg r8;
693 //! @brief 64-bit General purpose register (64-bit mode only).
694 ASMJIT_VAR const GpReg r9;
695 //! @brief 64-bit General purpose register (64-bit mode only).
696 ASMJIT_VAR const GpReg r10;
697 //! @brief 64-bit General purpose register (64-bit mode only).
698 ASMJIT_VAR const GpReg r11;
699 //! @brief 64-bit General purpose register (64-bit mode only).
700 ASMJIT_VAR const GpReg r12;
701 //! @brief 64-bit General purpose register (64-bit mode only).
702 ASMJIT_VAR const GpReg r13;
703 //! @brief 64-bit General purpose register (64-bit mode only).
704 ASMJIT_VAR const GpReg r14;
705 //! @brief 64-bit General purpose register (64-bit mode only).
706 ASMJIT_VAR const GpReg r15;
707 #endif // ASMJIT_X64
708 
709 // ============================================================================
710 // [AsmJit::Registers - Native (AsmJit extension)]
711 // ============================================================================
712 
713 //! @brief 32-bit or 64-bit General purpose register.
714 ASMJIT_VAR const GpReg zax;
715 //! @brief 32-bit or 64-bit General purpose register.
716 ASMJIT_VAR const GpReg zcx;
717 //! @brief 32-bit or 64-bit General purpose register.
718 ASMJIT_VAR const GpReg zdx;
719 //! @brief 32-bit or 64-bit General purpose register.
720 ASMJIT_VAR const GpReg zbx;
721 //! @brief 32-bit or 64-bit General purpose register.
722 ASMJIT_VAR const GpReg zsp;
723 //! @brief 32-bit or 64-bit General purpose register.
724 ASMJIT_VAR const GpReg zbp;
725 //! @brief 32-bit or 64-bit General purpose register.
726 ASMJIT_VAR const GpReg zsi;
727 //! @brief 32-bit or 64-bit General purpose register.
728 ASMJIT_VAR const GpReg zdi;
729 
730 // ============================================================================
731 // [AsmJit::Registers - MM]
732 // ============================================================================
733 
734 //! @brief 64-bit MM register.
735 ASMJIT_VAR const MmReg mm0;
736 //! @brief 64-bit MM register.
737 ASMJIT_VAR const MmReg mm1;
738 //! @brief 64-bit MM register.
739 ASMJIT_VAR const MmReg mm2;
740 //! @brief 64-bit MM register.
741 ASMJIT_VAR const MmReg mm3;
742 //! @brief 64-bit MM register.
743 ASMJIT_VAR const MmReg mm4;
744 //! @brief 64-bit MM register.
745 ASMJIT_VAR const MmReg mm5;
746 //! @brief 64-bit MM register.
747 ASMJIT_VAR const MmReg mm6;
748 //! @brief 64-bit MM register.
749 ASMJIT_VAR const MmReg mm7;
750 
751 // ============================================================================
752 // [AsmJit::Registers - XMM]
753 // ============================================================================
754 
755 //! @brief 128-bit XMM register.
756 ASMJIT_VAR const XmmReg xmm0;
757 //! @brief 128-bit XMM register.
758 ASMJIT_VAR const XmmReg xmm1;
759 //! @brief 128-bit XMM register.
760 ASMJIT_VAR const XmmReg xmm2;
761 //! @brief 128-bit XMM register.
762 ASMJIT_VAR const XmmReg xmm3;
763 //! @brief 128-bit XMM register.
764 ASMJIT_VAR const XmmReg xmm4;
765 //! @brief 128-bit XMM register.
766 ASMJIT_VAR const XmmReg xmm5;
767 //! @brief 128-bit XMM register.
768 ASMJIT_VAR const XmmReg xmm6;
769 //! @brief 128-bit XMM register.
770 ASMJIT_VAR const XmmReg xmm7;
771 
772 #if defined(ASMJIT_X64)
773 //! @brief 128-bit XMM register (64-bit mode only).
774 ASMJIT_VAR const XmmReg xmm8;
775 //! @brief 128-bit XMM register (64-bit mode only).
776 ASMJIT_VAR const XmmReg xmm9;
777 //! @brief 128-bit XMM register (64-bit mode only).
778 ASMJIT_VAR const XmmReg xmm10;
779 //! @brief 128-bit XMM register (64-bit mode only).
780 ASMJIT_VAR const XmmReg xmm11;
781 //! @brief 128-bit XMM register (64-bit mode only).
782 ASMJIT_VAR const XmmReg xmm12;
783 //! @brief 128-bit XMM register (64-bit mode only).
784 ASMJIT_VAR const XmmReg xmm13;
785 //! @brief 128-bit XMM register (64-bit mode only).
786 ASMJIT_VAR const XmmReg xmm14;
787 //! @brief 128-bit XMM register (64-bit mode only).
788 ASMJIT_VAR const XmmReg xmm15;
789 #endif // ASMJIT_X64
790 
791 // ============================================================================
792 // [AsmJit::Registers - Segment]
793 // ============================================================================
794 
795 //! @brief CS segment register.
796 ASMJIT_VAR const SegmentReg cs;
797 //! @brief SS segment register.
798 ASMJIT_VAR const SegmentReg ss;
799 //! @brief DS segment register.
800 ASMJIT_VAR const SegmentReg ds;
801 //! @brief ES segment register.
802 ASMJIT_VAR const SegmentReg es;
803 //! @brief FS segment register.
804 ASMJIT_VAR const SegmentReg fs;
805 //! @brief GS segment register.
806 ASMJIT_VAR const SegmentReg gs;
807 
808 // ============================================================================
809 // [AsmJit::Registers - Register From Index]
810 // ============================================================================
811 
812 //! @brief Get general purpose register of byte size.
gpb_lo(uint32_t index)813 static inline GpReg gpb_lo(uint32_t index)
814 { return GpReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeGpbLo)); }
815 
816 //! @brief Get general purpose register of byte size.
gpb_hi(uint32_t index)817 static inline GpReg gpb_hi(uint32_t index)
818 { return GpReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeGpbHi)); }
819 
820 //! @brief Get general purpose register of word size.
gpw(uint32_t index)821 static inline GpReg gpw(uint32_t index)
822 { return GpReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeGpw)); }
823 
824 //! @brief Get general purpose register of dword size.
gpd(uint32_t index)825 static inline GpReg gpd(uint32_t index)
826 { return GpReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeGpd)); }
827 
828 #if defined(ASMJIT_X64)
829 //! @brief Get general purpose register of qword size (64-bit only).
gpq(uint32_t index)830 static inline GpReg gpq(uint32_t index)
831 { return GpReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeGpq)); }
832 #endif
833 
834 //! @brief Get general purpose dword/qword register (depending to architecture).
gpz(uint32_t index)835 static inline GpReg gpz(uint32_t index)
836 { return GpReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeGpz)); }
837 
838 //! @brief Get MMX (MM) register .
mm(uint32_t index)839 static inline MmReg mm(uint32_t index)
840 { return MmReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeMm)); }
841 
842 //! @brief Get SSE (XMM) register.
xmm(uint32_t index)843 static inline XmmReg xmm(uint32_t index)
844 { return XmmReg(_Initialize(), static_cast<uint32_t>(index | kX86RegTypeXmm)); }
845 
846 //! @brief Get x87 register with index @a i.
st(uint32_t i)847 static inline X87Reg st(uint32_t i)
848 {
849   ASMJIT_ASSERT(i < 8);
850   return X87Reg(_Initialize(), static_cast<uint32_t>(i));
851 }
852 
853 // ============================================================================
854 // [AsmJit::Mem]
855 // ============================================================================
856 
857 //! @brief Memory operand.
858 struct Mem : public Operand
859 {
860   // --------------------------------------------------------------------------
861   // [Construction / Destruction]
862   // --------------------------------------------------------------------------
863 
MemMem864   inline Mem() :
865     Operand(_DontInitialize())
866   {
867     _mem.op = kOperandMem;
868     _mem.size = 0;
869     _mem.type = kOperandMemNative;
870     _mem.segment = kX86SegNone;
871     _mem.sizePrefix = 0;
872     _mem.shift = 0;
873 
874     _mem.id = kInvalidValue;
875     _mem.base = kInvalidValue;
876     _mem.index = kInvalidValue;
877 
878     _mem.target = NULL;
879     _mem.displacement = 0;
880   }
881 
882   inline Mem(const Label& label, sysint_t displacement, uint32_t size = 0) :
OperandMem883     Operand(_DontInitialize())
884   {
885     _mem.op = kOperandMem;
886     _mem.size = (uint8_t)size;
887     _mem.type = kOperandMemLabel;
888     _mem.segment = kX86SegNone;
889     _mem.sizePrefix = 0;
890     _mem.shift = 0;
891 
892     _mem.id = kInvalidValue;
893     _mem.base = reinterpret_cast<const Operand&>(label)._base.id;
894     _mem.index = kInvalidValue;
895 
896     _mem.target = NULL;
897     _mem.displacement = displacement;
898   }
899 
900   inline Mem(const GpReg& base, sysint_t displacement, uint32_t size = 0) :
OperandMem901     Operand(_DontInitialize())
902   {
903     _mem.op = kOperandMem;
904     _mem.size = (uint8_t)size;
905     _mem.type = kOperandMemNative;
906     _mem.segment = kX86SegNone;
907 
908 #if defined(ASMJIT_X86)
909     _mem.sizePrefix = base.getSize() != 4;
910 #else
911     _mem.sizePrefix = base.getSize() != 8;
912 #endif
913 
914     _mem.shift = 0;
915 
916     _mem.id = kInvalidValue;
917     _mem.base = base.getRegCode() & kRegIndexMask;
918     _mem.index = kInvalidValue;
919 
920     _mem.target = NULL;
921     _mem.displacement = displacement;
922   }
923 
924   inline Mem(const GpVar& base, sysint_t displacement, uint32_t size = 0) :
OperandMem925     Operand(_DontInitialize())
926   {
927     _mem.op = kOperandMem;
928     _mem.size = (uint8_t)size;
929     _mem.type = kOperandMemNative;
930     _mem.segment = kX86SegNone;
931 
932 #if defined(ASMJIT_X86)
933     _mem.sizePrefix = (reinterpret_cast<const Operand&>(base)._var.size) != 4;
934 #else
935     _mem.sizePrefix = (reinterpret_cast<const Operand&>(base)._var.size) != 8;
936 #endif
937 
938     _mem.shift = 0;
939 
940     _mem.id = kInvalidValue;
941     _mem.base = reinterpret_cast<const Operand&>(base).getId();
942     _mem.index = kInvalidValue;
943 
944     _mem.target = NULL;
945     _mem.displacement = displacement;
946   }
947 
948   inline Mem(const GpReg& base, const GpReg& index, uint32_t shift, sysint_t displacement, uint32_t size = 0) :
OperandMem949     Operand(_DontInitialize())
950   {
951     ASMJIT_ASSERT(shift <= 3);
952 
953     _mem.op = kOperandMem;
954     _mem.size = (uint8_t)size;
955     _mem.type = kOperandMemNative;
956     _mem.segment = kX86SegNone;
957 
958 #if defined(ASMJIT_X86)
959     _mem.sizePrefix = (base.getSize() | index.getSize()) != 4;
960 #else
961     _mem.sizePrefix = (base.getSize() | index.getSize()) != 8;
962 #endif
963 
964     _mem.shift = (uint8_t)shift;
965 
966     _mem.id = kInvalidValue;
967     _mem.base = base.getRegIndex();
968     _mem.index = index.getRegIndex();
969 
970     _mem.target = NULL;
971     _mem.displacement = displacement;
972   }
973 
974   inline Mem(const GpVar& base, const GpVar& index, uint32_t shift, sysint_t displacement, uint32_t size = 0) :
OperandMem975     Operand(_DontInitialize())
976   {
977     ASMJIT_ASSERT(shift <= 3);
978 
979     _mem.op = kOperandMem;
980     _mem.size = (uint8_t)size;
981     _mem.type = kOperandMemNative;
982     _mem.segment = kX86SegNone;
983 
984 #if defined(ASMJIT_X86)
985     _mem.sizePrefix = (reinterpret_cast<const Operand&>(base )._var.size |
986                        reinterpret_cast<const Operand&>(index)._var.size ) != 4;
987 #else
988     _mem.sizePrefix = (reinterpret_cast<const Operand&>(base )._var.size |
989                        reinterpret_cast<const Operand&>(index)._var.size ) != 8;
990 #endif
991 
992     _mem.shift = (uint8_t)shift;
993 
994     _mem.id = kInvalidValue;
995     _mem.base = reinterpret_cast<const Operand&>(base).getId();
996     _mem.index = reinterpret_cast<const Operand&>(index).getId();
997 
998     _mem.target = NULL;
999     _mem.displacement = displacement;
1000   }
1001 
MemMem1002   inline Mem(const Mem& other) :
1003     Operand(other)
1004   {
1005   }
1006 
MemMem1007   inline Mem(const _DontInitialize& dontInitialize) :
1008     Operand(dontInitialize)
1009   {
1010   }
1011 
1012   // --------------------------------------------------------------------------
1013   // [Mem Specific]
1014   // --------------------------------------------------------------------------
1015 
1016   //! @brief Get type of memory operand, see @c kOperandMemType.
getMemTypeMem1017   inline uint32_t getMemType() const
1018   { return _mem.type; }
1019 
1020   //! @brief Get memory operand segment, see @c kX86Seg.
getSegmentMem1021   inline uint32_t getSegment() const
1022   { return _mem.segment; }
1023 
1024   //! @brief Set memory operand segment, see @c kX86Seg.
setSegmentMem1025   inline Mem& setSegment(uint32_t seg)
1026   {
1027     _mem.segment = static_cast<uint8_t>(seg);
1028     return *this;
1029   }
1030 
1031   //! @brief Set memory operand segment, see @c kX86Seg.
setSegmentMem1032   inline Mem& setSegment(const SegmentReg& seg)
1033   {
1034     _mem.segment = static_cast<uint8_t>(seg.getRegIndex());
1035     return *this;
1036   }
1037 
1038   //! @brief Get whether the memory operand has segment override prefix.
hasSegmentMem1039   inline bool hasSegment() const
1040   { return _mem.segment >= kX86SegCount; }
1041 
1042   //! @brief Get whether the memory operand has base register.
hasBaseMem1043   inline bool hasBase() const
1044   { return _mem.base != kInvalidValue; }
1045 
1046   //! @brief Get whether the memory operand has index.
hasIndexMem1047   inline bool hasIndex() const
1048   { return _mem.index != kInvalidValue; }
1049 
1050   //! @brief Get whether the memory operand has shift used.
hasShiftMem1051   inline bool hasShift() const
1052   { return _mem.shift != 0; }
1053 
1054   //! @brief Get memory operand base register or @c kInvalidValue.
getBaseMem1055   inline uint32_t getBase() const
1056   { return _mem.base; }
1057 
1058   //! @brief Get memory operand index register or @c kInvalidValue.
getIndexMem1059   inline uint32_t getIndex() const
1060   { return _mem.index; }
1061 
1062   //! @brief Get memory operand index scale (0, 1, 2 or 3).
getShiftMem1063   inline uint32_t getShift() const
1064   { return _mem.shift; }
1065 
1066   //! @brief Get whether to use size-override prefix.
1067   //!
1068   //! @note This is useful only for MOV and LEA type of instructions.
getSizePrefixMem1069   inline bool getSizePrefix() const
1070   { return _mem.sizePrefix; }
1071 
1072   //! @brief Set whether to use size-override prefix.
setSizePrefixMem1073   inline Mem& setSizePrefix(bool b)
1074   {
1075     _mem.sizePrefix = b;
1076     return *this;
1077   }
1078 
1079   //! @brief Get absolute target address.
1080   //!
1081   //! @note You should always check if operand contains address by @c getMemType().
getTargetMem1082   inline void* getTarget() const
1083   { return _mem.target; }
1084 
1085   //! @brief Set absolute target address.
setTargetMem1086   inline Mem& setTarget(void* target)
1087   {
1088     _mem.target = target;
1089     return *this;
1090   }
1091 
1092   //! @brief Set memory operand size.
setSizeMem1093   inline Mem& setSize(uint32_t size)
1094   {
1095     _mem.size = size;
1096     return *this;
1097   }
1098 
1099   //! @brief Get memory operand relative displacement.
getDisplacementMem1100   inline sysint_t getDisplacement() const
1101   { return _mem.displacement; }
1102 
1103   //! @brief Set memory operand relative displacement.
setDisplacementMem1104   inline Mem& setDisplacement(sysint_t displacement)
1105   {
1106     _mem.displacement = displacement;
1107     return *this;
1108   }
1109 
1110   //! @brief Adjust memory operand relative displacement by @a displacement.
adjustMem1111   inline Mem& adjust(sysint_t displacement)
1112   {
1113     _mem.displacement += displacement;
1114     return *this;
1115   }
1116 
1117   //! @brief Get new memory operand adjusted by @a displacement.
adjustedMem1118   inline Mem adjusted(sysint_t displacement) const
1119   {
1120     Mem result(*this);
1121     result.adjust(displacement);
1122     return result;
1123   }
1124 
1125   // --------------------------------------------------------------------------
1126   // [Operator Overload]
1127   // --------------------------------------------------------------------------
1128 
1129 #if !defined(ASMJIT_NODOC)
1130   inline Mem& operator=(const Mem& other)
1131   {
1132     _copy(other);
1133     return *this;
1134   }
1135 
1136   inline bool operator==(const Mem& other) const
1137   {
1138     return _bin.u32[0] == other._bin.u32[0] &&
1139            _bin.u32[1] == other._bin.u32[1] &&
1140            _bin.u32[2] == other._bin.u32[2] &&
1141            _bin.u32[3] == other._bin.u32[3] &&
1142            _bin.uptr[0] == other._bin.uptr[0] &&
1143            _bin.uptr[1] == other._bin.uptr[1];
1144   }
1145 
1146   inline bool operator!=(const Mem& other) const
1147   {
1148     return !(*this == other);
1149   }
1150 #endif // ASMJIT_NODOC
1151 };
1152 
1153 // ============================================================================
1154 // [AsmJit::Var]
1155 // ============================================================================
1156 
1157 ASMJIT_API Mem _BaseVarMem(const Var& var, uint32_t size);
1158 ASMJIT_API Mem _BaseVarMem(const Var& var, uint32_t size, sysint_t disp);
1159 ASMJIT_API Mem _BaseVarMem(const Var& var, uint32_t size, const GpVar& index, uint32_t shift, sysint_t disp);
1160 
1161 //! @brief Base class for all variables.
1162 struct Var : public Operand
1163 {
1164   // --------------------------------------------------------------------------
1165   // [Construction / Destruction]
1166   // --------------------------------------------------------------------------
1167 
1168 #if !defined(ASMJIT_NODOC)
VarVar1169   inline Var(const _DontInitialize& dontInitialize) :
1170     Operand(dontInitialize)
1171   {
1172   }
1173 #endif // ASMJIT_NODOC
1174 
VarVar1175   inline Var() :
1176     Operand(_DontInitialize())
1177   {
1178     _var.op = kOperandVar;
1179     _var.size = 0;
1180     _var.regCode = kInvalidValue;
1181     _var.varType = kInvalidValue;
1182     _var.id = kInvalidValue;
1183   }
1184 
VarVar1185   inline Var(const Var& other) :
1186     Operand(other)
1187   {
1188   }
1189 
1190   // --------------------------------------------------------------------------
1191   // [Type]
1192   // --------------------------------------------------------------------------
1193 
getVarTypeVar1194   inline uint32_t getVarType() const
1195   { return _var.varType; }
1196 
isGpVarVar1197   inline bool isGpVar() const
1198   { return _var.varType <= kX86VarTypeGpq; }
1199 
isX87VarVar1200   inline bool isX87Var() const
1201   { return _var.varType >= kX86VarTypeX87 && _var.varType <= kX86VarTypeX87SD; }
1202 
isMmVarVar1203   inline bool isMmVar() const
1204   { return _var.varType == kX86VarTypeMm; }
1205 
isXmmVarVar1206   inline bool isXmmVar() const
1207   { return _var.varType >= kX86VarTypeXmm && _var.varType <= kX86VarTypeXmmPD; }
1208 
1209   // --------------------------------------------------------------------------
1210   // [Memory Cast]
1211   // --------------------------------------------------------------------------
1212 
1213   //! @brief Cast this variable to memory operand.
1214   //!
1215   //! @note Size of operand depends on native variable type, you can use other
1216   //! variants if you want specific one.
mVar1217   inline Mem m() const
1218   { return _BaseVarMem(*this, kInvalidValue); }
1219 
1220   //! @overload.
mVar1221   inline Mem m(sysint_t disp) const
1222   { return _BaseVarMem(*this, kInvalidValue, disp); }
1223 
1224   //! @overload.
1225   inline Mem m(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1226   { return _BaseVarMem(*this, kInvalidValue, index, shift, disp); }
1227 
1228   //! @brief Cast this variable to 8-bit memory operand.
m8Var1229   inline Mem m8() const
1230   { return _BaseVarMem(*this, 1); }
1231 
1232   //! @overload.
m8Var1233   inline Mem m8(sysint_t disp) const
1234   { return _BaseVarMem(*this, 1, disp); }
1235 
1236   //! @overload.
1237   inline Mem m8(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1238   { return _BaseVarMem(*this, 1, index, shift, disp); }
1239 
1240   //! @brief Cast this variable to 16-bit memory operand.
m16Var1241   inline Mem m16() const
1242   { return _BaseVarMem(*this, 2); }
1243 
1244   //! @overload.
m16Var1245   inline Mem m16(sysint_t disp) const
1246   { return _BaseVarMem(*this, 2, disp); }
1247 
1248   //! @overload.
1249   inline Mem m16(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1250   { return _BaseVarMem(*this, 2, index, shift, disp); }
1251 
1252   //! @brief Cast this variable to 32-bit memory operand.
m32Var1253   inline Mem m32() const
1254   { return _BaseVarMem(*this, 4); }
1255 
1256   //! @overload.
m32Var1257   inline Mem m32(sysint_t disp) const
1258   { return _BaseVarMem(*this, 4, disp); }
1259 
1260   //! @overload.
1261   inline Mem m32(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1262   { return _BaseVarMem(*this, 4, index, shift, disp); }
1263 
1264   //! @brief Cast this variable to 64-bit memory operand.
m64Var1265   inline Mem m64() const
1266   { return _BaseVarMem(*this, 8); }
1267 
1268   //! @overload.
m64Var1269   inline Mem m64(sysint_t disp) const
1270   { return _BaseVarMem(*this, 8, disp); }
1271 
1272   //! @overload.
1273   inline Mem m64(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1274   { return _BaseVarMem(*this, 8, index, shift, disp); }
1275 
1276   //! @brief Cast this variable to 80-bit memory operand (long double).
m80Var1277   inline Mem m80() const
1278   { return _BaseVarMem(*this, 10); }
1279 
1280   //! @overload.
m80Var1281   inline Mem m80(sysint_t disp) const
1282   { return _BaseVarMem(*this, 10, disp); }
1283 
1284   //! @overload.
1285   inline Mem m80(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1286   { return _BaseVarMem(*this, 10, index, shift, disp); }
1287 
1288   //! @brief Cast this variable to 128-bit memory operand.
m128Var1289   inline Mem m128() const
1290   { return _BaseVarMem(*this, 16); }
1291 
1292   //! @overload.
m128Var1293   inline Mem m128(sysint_t disp) const
1294   { return _BaseVarMem(*this, 16, disp); }
1295 
1296   //! @overload.
1297   inline Mem m128(const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) const
1298   { return _BaseVarMem(*this, 16, index, shift, disp); }
1299 
1300   // --------------------------------------------------------------------------
1301   // [Operator Overload]
1302   // --------------------------------------------------------------------------
1303 
1304 #if !defined(ASMJIT_NODOC)
1305   inline Var& operator=(const Var& other)
1306   { _copy(other); return *this; }
1307 
1308   inline bool operator==(const Var& other) const { return _base.id == other._base.id && _var.regCode == other._var.regCode; }
1309   inline bool operator!=(const Var& other) const { return _base.id != other._base.id || _var.regCode != other._var.regCode; }
1310 #endif // ASMJIT_NODOC
1311 
1312   // --------------------------------------------------------------------------
1313   // [Private]
1314   // --------------------------------------------------------------------------
1315 
1316 protected:
VarVar1317   inline Var(const Var& other, uint32_t regCode, uint32_t size) :
1318     Operand(_DontInitialize())
1319   {
1320     _var.op = kOperandVar;
1321     _var.size = (uint8_t)size;
1322     _var.id = other._base.id;
1323     _var.regCode = regCode;
1324     _var.varType = other._var.varType;
1325   }
1326 };
1327 
1328 // ============================================================================
1329 // [AsmJit::X87Var]
1330 // ============================================================================
1331 
1332 //! @brief X87 Variable operand.
1333 struct X87Var : public Var
1334 {
1335   // --------------------------------------------------------------------------
1336   // [Construction / Destruction]
1337   // --------------------------------------------------------------------------
1338 
X87VarX87Var1339   inline X87Var(const _DontInitialize& dontInitialize) :
1340     Var(dontInitialize)
1341   {
1342   }
1343 
X87VarX87Var1344   inline X87Var() :
1345     Var(_DontInitialize())
1346   {
1347     _var.op = kOperandVar;
1348     _var.size = 12;
1349     _var.id = kInvalidValue;
1350 
1351     _var.regCode = kX86RegTypeX87;
1352     _var.varType = kX86VarTypeX87;
1353   }
1354 
X87VarX87Var1355   inline X87Var(const X87Var& other) :
1356     Var(other) {}
1357 
1358   // --------------------------------------------------------------------------
1359   // [Operator Overload]
1360   // --------------------------------------------------------------------------
1361 
1362 #if !defined(ASMJIT_NODOC)
1363   inline X87Var& operator=(const X87Var& other)
1364   { _copy(other); return *this; }
1365 
1366   inline bool operator==(const X87Var& other) const { return _base.id == other._base.id; }
1367   inline bool operator!=(const X87Var& other) const { return _base.id != other._base.id; }
1368 #endif // ASMJIT_NODOC
1369 };
1370 
1371 // ============================================================================
1372 // [AsmJit::GpVar]
1373 // ============================================================================
1374 
1375 //! @brief GP variable operand.
1376 struct GpVar : public Var
1377 {
1378   // --------------------------------------------------------------------------
1379   // [Construction / Destruction]
1380   // --------------------------------------------------------------------------
1381 
1382   //! @brief Create new uninitialized @c GpVar instance (internal constructor).
GpVarGpVar1383   inline GpVar(const _DontInitialize& dontInitialize) :
1384     Var(dontInitialize)
1385   {
1386   }
1387 
1388   //! @brief Create new uninitialized @c GpVar instance.
GpVarGpVar1389   inline GpVar() :
1390     Var(_DontInitialize())
1391   {
1392     _var.op = kOperandVar;
1393     _var.size = sizeof(sysint_t);
1394     _var.id = kInvalidValue;
1395 
1396     _var.regCode = kX86RegTypeGpz;
1397     _var.varType = kX86VarTypeGpz;
1398   }
1399 
1400   //! @brief Create new @c GpVar instance using @a other.
1401   //!
1402   //! Note this will not create a different variable, use @c Compiler::newGpVar()
1403   //! if you want to do so. This is only copy-constructor that allows to store
1404   //! the same variable in different places.
GpVarGpVar1405   inline GpVar(const GpVar& other) :
1406     Var(other) {}
1407 
1408   // --------------------------------------------------------------------------
1409   // [GpVar Specific]
1410   // --------------------------------------------------------------------------
1411 
1412   //! @brief Get whether this variable is general purpose BYTE register.
isGpbGpVar1413   inline bool isGpb() const { return (_var.regCode & kRegTypeMask) <= kX86RegTypeGpbHi; }
1414   //! @brief Get whether this variable is general purpose BYTE.LO register.
isGpbLoGpVar1415   inline bool isGpbLo() const { return (_var.regCode & kRegTypeMask) == kX86RegTypeGpbLo; }
1416   //! @brief Get whether this variable is general purpose BYTE.HI register.
isGpbHiGpVar1417   inline bool isGpbHi() const { return (_var.regCode & kRegTypeMask) == kX86RegTypeGpbHi; }
1418 
1419   //! @brief Get whether this variable is general purpose WORD register.
isGpwGpVar1420   inline bool isGpw() const { return (_var.regCode & kRegTypeMask) == kX86RegTypeGpw; }
1421   //! @brief Get whether this variable is general purpose DWORD register.
isGpdGpVar1422   inline bool isGpd() const { return (_var.regCode & kRegTypeMask) == kX86RegTypeGpd; }
1423   //! @brief Get whether this variable is general purpose QWORD (only 64-bit) register.
isGpqGpVar1424   inline bool isGpq() const { return (_var.regCode & kRegTypeMask) == kX86RegTypeGpq; }
1425 
1426   // --------------------------------------------------------------------------
1427   // [GpVar Cast]
1428   // --------------------------------------------------------------------------
1429 
1430   //! @brief Cast this variable to 8-bit (LO) part of variable
r8GpVar1431   inline GpVar r8() const { return GpVar(*this, kX86RegTypeGpbLo, 1); }
1432   //! @brief Cast this variable to 8-bit (LO) part of variable
r8LoGpVar1433   inline GpVar r8Lo() const { return GpVar(*this, kX86RegTypeGpbLo, 1); }
1434   //! @brief Cast this variable to 8-bit (HI) part of variable
r8HiGpVar1435   inline GpVar r8Hi() const { return GpVar(*this, kX86RegTypeGpbHi, 1); }
1436 
1437   //! @brief Cast this variable to 16-bit part of variable
r16GpVar1438   inline GpVar r16() const { return GpVar(*this, kX86RegTypeGpw, 2); }
1439   //! @brief Cast this variable to 32-bit part of variable
r32GpVar1440   inline GpVar r32() const { return GpVar(*this, kX86RegTypeGpd, 4); }
1441 #if defined(ASMJIT_X64)
1442   //! @brief Cast this variable to 64-bit part of variable
r64GpVar1443   inline GpVar r64() const { return GpVar(*this, kX86RegTypeGpq, 8); }
1444 #endif // ASMJIT_X64
1445 
1446   // --------------------------------------------------------------------------
1447   // [Operator Overload]
1448   // --------------------------------------------------------------------------
1449 
1450 #if !defined(ASMJIT_NODOC)
1451   inline GpVar& operator=(const GpVar& other)
1452   { _copy(other); return *this; }
1453 
1454   inline bool operator==(const GpVar& other) const { return _base.id == other._base.id && _var.regCode == other._var.regCode; }
1455   inline bool operator!=(const GpVar& other) const { return _base.id != other._base.id || _var.regCode != other._var.regCode; }
1456 #endif // ASMJIT_NODOC
1457 
1458   // --------------------------------------------------------------------------
1459   // [Private]
1460   // --------------------------------------------------------------------------
1461 
1462 protected:
GpVarGpVar1463   inline GpVar(const GpVar& other, uint32_t regCode, uint32_t size) :
1464     Var(other, regCode, size)
1465   {
1466   }
1467 };
1468 
1469 // ============================================================================
1470 // [AsmJit::MmVar]
1471 // ============================================================================
1472 
1473 //! @brief MM variable operand.
1474 struct MmVar : public Var
1475 {
1476   // --------------------------------------------------------------------------
1477   // [Construction / Destruction]
1478   // --------------------------------------------------------------------------
1479 
1480   //! @brief Create new uninitialized @c MmVar instance (internal constructor).
MmVarMmVar1481   inline MmVar(const _DontInitialize& dontInitialize) :
1482     Var(dontInitialize)
1483   {
1484   }
1485 
1486   //! @brief Create new uninitialized @c MmVar instance.
MmVarMmVar1487   inline MmVar() :
1488     Var(_DontInitialize())
1489   {
1490     _var.op = kOperandVar;
1491     _var.size = 8;
1492     _var.id = kInvalidValue;
1493 
1494     _var.regCode = kX86RegTypeMm;
1495     _var.varType = kX86VarTypeMm;
1496   }
1497 
1498   //! @brief Create new @c MmVar instance using @a other.
1499   //!
1500   //! Note this will not create a different variable, use @c Compiler::newMmVar()
1501   //! if you want to do so. This is only copy-constructor that allows to store
1502   //! the same variable in different places.
MmVarMmVar1503   inline MmVar(const MmVar& other) :
1504     Var(other) {}
1505 
1506   // --------------------------------------------------------------------------
1507   // [MmVar Cast]
1508   // --------------------------------------------------------------------------
1509 
1510   // --------------------------------------------------------------------------
1511   // [Operator Overload]
1512   // --------------------------------------------------------------------------
1513 
1514 #if !defined(ASMJIT_NODOC)
1515   inline MmVar& operator=(const MmVar& other)
1516   { _copy(other); return *this; }
1517 
1518   inline bool operator==(const MmVar& other) const { return _base.id == other._base.id; }
1519   inline bool operator!=(const MmVar& other) const { return _base.id != other._base.id; }
1520 #endif // ASMJIT_NODOC
1521 };
1522 
1523 // ============================================================================
1524 // [AsmJit::XmmVar]
1525 // ============================================================================
1526 
1527 //! @brief XMM Variable operand.
1528 struct XmmVar : public Var
1529 {
1530   // --------------------------------------------------------------------------
1531   // [Construction / Destruction]
1532   // --------------------------------------------------------------------------
1533 
XmmVarXmmVar1534   inline XmmVar(const _DontInitialize& dontInitialize) :
1535     Var(dontInitialize)
1536   {
1537   }
1538 
XmmVarXmmVar1539   inline XmmVar() :
1540     Var(_DontInitialize())
1541   {
1542     _var.op = kOperandVar;
1543     _var.size = 16;
1544     _var.id = kInvalidValue;
1545 
1546     _var.regCode = kX86RegTypeXmm;
1547     _var.varType = kX86VarTypeXmm;
1548   }
1549 
XmmVarXmmVar1550   inline XmmVar(const XmmVar& other) :
1551     Var(other) {}
1552 
1553   // --------------------------------------------------------------------------
1554   // [XmmVar Access]
1555   // --------------------------------------------------------------------------
1556 
1557   // --------------------------------------------------------------------------
1558   // [Operator Overload]
1559   // --------------------------------------------------------------------------
1560 
1561 #if !defined(ASMJIT_NODOC)
1562   inline XmmVar& operator=(const XmmVar& other)
1563   { _copy(other); return *this; }
1564 
1565   inline bool operator==(const XmmVar& other) const { return _base.id == other._base.id; }
1566   inline bool operator!=(const XmmVar& other) const { return _base.id != other._base.id; }
1567 #endif // ASMJIT_NODOC
1568 };
1569 
1570 // ============================================================================
1571 // [AsmJit::Mem - [label + displacement]]
1572 // ============================================================================
1573 
1574 //! @brief Create a custom pointer operand.
1575 ASMJIT_API Mem ptr(const Label& label, sysint_t disp = 0, uint32_t size = 0);
1576 //! @brief Create a byte pointer operand.
1577 static inline Mem byte_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeByte); }
1578 //! @brief Create a word pointer operand.
1579 static inline Mem word_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeWord); }
1580 //! @brief Create a dword pointer operand.
1581 static inline Mem dword_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeDWord); }
1582 //! @brief Create a qword pointer operand.
1583 static inline Mem qword_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeQWord); }
1584 //! @brief Create a tword pointer operand.
1585 static inline Mem tword_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeTWord); }
1586 //! @brief Create a dqword pointer operand.
1587 static inline Mem dqword_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeDQWord); }
1588 //! @brief Create a mmword pointer operand.
1589 static inline Mem mmword_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeQWord); }
1590 //! @brief Create a xmmword pointer operand.
1591 static inline Mem xmmword_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, kSizeDQWord); }
1592 //! @brief Create an intptr_t pointer operand.
1593 static inline Mem sysint_ptr(const Label& label, sysint_t disp = 0) { return ptr(label, disp, sizeof(sysint_t)); }
1594 
1595 // ============================================================================
1596 // [AsmJit::Mem - [label + index << shift + displacement]]
1597 // ============================================================================
1598 
1599 //! @brief Create a custom pointer operand.
1600 ASMJIT_API Mem ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
1601 //! @brief Create a byte pointer operand.
1602 static inline Mem byte_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeByte); }
1603 //! @brief Create a word pointer operand.
1604 static inline Mem word_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeWord); }
1605 //! @brief Create a dword pointer operand.
1606 static inline Mem dword_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDWord); }
1607 //! @brief Create a qword pointer operand.
1608 static inline Mem qword_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
1609 //! @brief Create a tword pointer operand.
1610 static inline Mem tword_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeTWord); }
1611 //! @brief Create a dqword pointer operand.
1612 static inline Mem dqword_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
1613 //! @brief Create a mmword pointer operand.
1614 static inline Mem mmword_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
1615 //! @brief Create a xmmword pointer operand.
1616 static inline Mem xmmword_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
1617 //! @brief Create an intptr_t pointer operand.
1618 static inline Mem sysint_ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, sizeof(sysint_t)); }
1619 
1620 //! @brief Create a custom pointer operand.
1621 ASMJIT_API Mem ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
1622 //! @brief Create a byte pointer operand.
1623 static inline Mem byte_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeByte); }
1624 //! @brief Create a word pointer operand.
1625 static inline Mem word_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeWord); }
1626 //! @brief Create a dword pointer operand.
1627 static inline Mem dword_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDWord); }
1628 //! @brief Create a qword pointer operand.
1629 static inline Mem qword_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
1630 //! @brief Create a tword pointer operand.
1631 static inline Mem tword_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeTWord); }
1632 //! @brief Create a dqword pointer operand.
1633 static inline Mem dqword_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
1634 //! @brief Create a mmword pointer operand.
1635 static inline Mem mmword_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
1636 //! @brief Create a xmmword pointer operand.
1637 static inline Mem xmmword_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
1638 //! @brief Create an intptr_t pointer operand.
1639 static inline Mem sysint_ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, sizeof(sysint_t)); }
1640 
1641 // ============================================================================
1642 // [AsmJit::Mem - segment[target + displacement]
1643 // ============================================================================
1644 
1645 //! @brief Create a custom pointer operand.
1646 ASMJIT_API Mem ptr_abs(void* target, sysint_t disp = 0, uint32_t size = 0);
1647 //! @brief Create a byte pointer operand.
1648 static inline Mem byte_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeByte); }
1649 //! @brief Create a word pointer operand.
1650 static inline Mem word_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeWord); }
1651 //! @brief Create a dword pointer operand.
1652 static inline Mem dword_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeDWord); }
1653 //! @brief Create a qword pointer operand.
1654 static inline Mem qword_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeQWord); }
1655 //! @brief Create a tword pointer operand (used for 80-bit floating points).
1656 static inline Mem tword_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeTWord); }
1657 //! @brief Create a dqword pointer operand.
1658 static inline Mem dqword_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeDQWord); }
1659 //! @brief Create a mmword pointer operand.
1660 static inline Mem mmword_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeQWord); }
1661 //! @brief Create a xmmword pointer operand.
1662 static inline Mem xmmword_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeDQWord); }
1663 //! @brief Create an intptr_t pointer operand.
1664 static inline Mem sysint_ptr_abs(void* target, sysint_t disp = 0) { return ptr_abs(target, disp, sizeof(sysint_t)); }
1665 
1666 // ============================================================================
1667 // [AsmJit::Mem - segment[target + index << shift + displacement]
1668 // ============================================================================
1669 
1670 //! @brief Create a custom pointer operand.
1671 ASMJIT_API Mem ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
1672 //! @brief Create a byte pointer operand.
1673 static inline Mem byte_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeByte); }
1674 //! @brief Create a word pointer operand.
1675 static inline Mem word_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeWord); }
1676 //! @brief Create a dword pointer operand.
1677 static inline Mem dword_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDWord); }
1678 //! @brief Create a qword pointer operand.
1679 static inline Mem qword_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
1680 //! @brief Create a tword pointer operand.
1681 static inline Mem tword_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeTWord); }
1682 //! @brief Create a dqword pointer operand.
1683 static inline Mem dqword_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
1684 //! @brief Create a mmword pointer operand.
1685 static inline Mem mmword_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
1686 //! @brief Create a xmmword pointer operand.
1687 static inline Mem xmmword_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
1688 //! @brief Create an intptr_t pointer operand.
1689 static inline Mem sysint_ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, sizeof(sysint_t)); }
1690 
1691 //! @brief Create a custom pointer operand.
1692 ASMJIT_API Mem ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
1693 //! @brief Create a byte pointer operand.
1694 static inline Mem byte_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeByte); }
1695 //! @brief Create a word pointer operand.
1696 static inline Mem word_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeWord); }
1697 //! @brief Create a dword pointer operand.
1698 static inline Mem dword_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDWord); }
1699 //! @brief Create a qword pointer operand.
1700 static inline Mem qword_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
1701 //! @brief Create a tword pointer operand.
1702 static inline Mem tword_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeTWord); }
1703 //! @brief Create a dqword pointer operand.
1704 static inline Mem dqword_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
1705 //! @brief Create a mmword pointer operand.
1706 static inline Mem mmword_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
1707 //! @brief Create a xmmword pointer operand.
1708 static inline Mem xmmword_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
1709 //! @brief Create an intptr_t pointer operand.
1710 static inline Mem sysint_ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, sizeof(sysint_t)); }
1711 
1712 // ============================================================================
1713 // [AsmJit::Mem - ptr[base + displacement]]
1714 // ============================================================================
1715 
1716 //! @brief Create a custom pointer operand.
1717 ASMJIT_API Mem ptr(const GpReg& base, sysint_t disp = 0, uint32_t size = 0);
1718 //! @brief Create a byte pointer operand.
1719 static inline Mem byte_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeByte); }
1720 //! @brief Create a word pointer operand.
1721 static inline Mem word_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeWord); }
1722 //! @brief Create a dword pointer operand.
1723 static inline Mem dword_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeDWord); }
1724 //! @brief Create a qword pointer operand.
1725 static inline Mem qword_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
1726 //! @brief Create a tword pointer operand.
1727 static inline Mem tword_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeTWord); }
1728 //! @brief Create a dqword pointer operand.
1729 static inline Mem dqword_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
1730 //! @brief Create a mmword pointer operand.
1731 static inline Mem mmword_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
1732 //! @brief Create a xmmword pointer operand.
1733 static inline Mem xmmword_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
1734 //! @brief Create an intptr_t pointer operand.
1735 static inline Mem sysint_ptr(const GpReg& base, sysint_t disp = 0) { return ptr(base, disp, sizeof(sysint_t)); }
1736 
1737 //! @brief Create a custom pointer operand.
1738 ASMJIT_API Mem ptr(const GpVar& base, sysint_t disp = 0, uint32_t size = 0);
1739 //! @brief Create a byte pointer operand.
1740 static inline Mem byte_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeByte); }
1741 //! @brief Create a word pointer operand.
1742 static inline Mem word_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeWord); }
1743 //! @brief Create a dword pointer operand.
1744 static inline Mem dword_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeDWord); }
1745 //! @brief Create a qword pointer operand.
1746 static inline Mem qword_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
1747 //! @brief Create a tword pointer operand.
1748 static inline Mem tword_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeTWord); }
1749 //! @brief Create a dqword pointer operand.
1750 static inline Mem dqword_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
1751 //! @brief Create a mmword pointer operand.
1752 static inline Mem mmword_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
1753 //! @brief Create a xmmword pointer operand.
1754 static inline Mem xmmword_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
1755 //! @brief Create an intptr_t pointer operand.
1756 static inline Mem sysint_ptr(const GpVar& base, sysint_t disp = 0) { return ptr(base, disp, sizeof(sysint_t)); }
1757 
1758 // ============================================================================
1759 // [AsmJit::Mem - ptr[base + (index << shift) + displacement]]
1760 // ============================================================================
1761 
1762 //! @brief Create a custom pointer operand.
1763 ASMJIT_API Mem ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0, uint32_t size = 0);
1764 //! @brief Create a byte pointer operand.
1765 static inline Mem byte_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeByte); }
1766 //! @brief Create a word pointer operand.
1767 static inline Mem word_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeWord); }
1768 //! @brief Create a dword pointer operand.
1769 static inline Mem dword_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDWord); }
1770 //! @brief Create a qword pointer operand.
1771 static inline Mem qword_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
1772 //! @brief Create a tword pointer operand.
1773 static inline Mem tword_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeTWord); }
1774 //! @brief Create a dqword pointer operand.
1775 static inline Mem dqword_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
1776 //! @brief Create a mmword pointer operand.
1777 static inline Mem mmword_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
1778 //! @brief Create a xmmword pointer operand.
1779 static inline Mem xmmword_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
1780 //! @brief Create an intptr_t pointer operand.
1781 static inline Mem sysint_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, sizeof(sysint_t)); }
1782 
1783 //! @brief Create a custom pointer operand.
1784 ASMJIT_API Mem ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0, uint32_t size = 0);
1785 //! @brief Create a byte pointer operand.
1786 static inline Mem byte_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeByte); }
1787 //! @brief Create a word pointer operand.
1788 static inline Mem word_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeWord); }
1789 //! @brief Create a dword pointer operand.
1790 static inline Mem dword_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDWord); }
1791 //! @brief Create a qword pointer operand.
1792 static inline Mem qword_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
1793 //! @brief Create a tword pointer operand.
1794 static inline Mem tword_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeTWord); }
1795 //! @brief Create a dqword pointer operand.
1796 static inline Mem dqword_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
1797 //! @brief Create a mmword pointer operand.
1798 static inline Mem mmword_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
1799 //! @brief Create a xmmword pointer operand.
1800 static inline Mem xmmword_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
1801 //! @brief Create an intptr_t pointer operand.
1802 static inline Mem sysint_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, sizeof(sysint_t)); }
1803 
1804 // ============================================================================
1805 // [AsmJit::Macros]
1806 // ============================================================================
1807 
1808 //! @brief Create Shuffle Constant for MMX/SSE shuffle instrutions.
1809 //! @param z First component position, number at interval [0, 3] inclusive.
1810 //! @param x Second component position, number at interval [0, 3] inclusive.
1811 //! @param y Third component position, number at interval [0, 3] inclusive.
1812 //! @param w Fourth component position, number at interval [0, 3] inclusive.
1813 //!
1814 //! Shuffle constants can be used to make immediate value for these intrinsics:
1815 //! - @ref X86Assembler::pshufw()
1816 //! - @ref X86Assembler::pshufd()
1817 //! - @ref X86Assembler::pshufhw()
1818 //! - @ref X86Assembler::pshuflw()
1819 //! - @ref X86Assembler::shufps()
mm_shuffle(uint8_t z,uint8_t y,uint8_t x,uint8_t w)1820 static inline uint8_t mm_shuffle(uint8_t z, uint8_t y, uint8_t x, uint8_t w)
1821 { return (z << 6) | (y << 4) | (x << 2) | w; }
1822 
1823 //! @}
1824 
1825 } // AsmJit namespace
1826 
1827 // [Guard]
1828 #endif // _ASMJIT_X86_X86OPERAND_H
1829