1 // [AsmJit]
2 // Complete JIT Assembler for C++ Language.
3 //
4 // [License]
5 // Zlib - See COPYING file in this package.
6 
7 #define ASMJIT_EXPORTS
8 
9 // [Dependencies - AsmJit]
10 #include "../core/assert.h"
11 #include "../core/intutil.h"
12 #include "../core/stringutil.h"
13 
14 #include "../x86/x86defs.h"
15 #include "../x86/x86func.h"
16 #include "../x86/x86util.h"
17 
18 // [Api-Begin]
19 #include "../core/apibegin.h"
20 
21 namespace AsmJit {
22 
23 // ============================================================================
24 // [AsmJit::X86FuncDecl - Accessors]
25 // ============================================================================
26 
findArgumentByRegCode(uint32_t regCode) const27 uint32_t X86FuncDecl::findArgumentByRegCode(uint32_t regCode) const
28 {
29   uint32_t type = regCode & kRegTypeMask;
30   uint32_t idx = regCode & kRegIndexMask;
31 
32   uint32_t clazz;
33 
34   switch (type)
35   {
36     case kX86RegTypeGpd:
37     case kX86RegTypeGpq:
38       clazz = kX86VarClassGp;
39       break;
40 
41     case kX86RegTypeX87:
42       clazz = kX86VarClassX87;
43       break;
44 
45     case kX86RegTypeMm:
46       clazz = kX86VarClassMm;
47       break;
48 
49     case kX86RegTypeXmm:
50       clazz = kX86VarClassXmm;
51       break;
52 
53     default:
54       return kInvalidValue;
55   }
56 
57   for (uint32_t i = 0; i < _argumentsCount; i++)
58   {
59     const FuncArg& arg = _arguments[i];
60 
61     if (arg.getRegIndex() == idx && (X86Util::getVarClassFromVarType(arg.getVarType()) & clazz) != 0)
62       return i;
63   }
64 
65   return kInvalidValue;
66 }
67 
68 // ============================================================================
69 // [AsmJit::X86FuncDecl - SetPrototype - InitCallingConvention]
70 // ============================================================================
71 
X86FuncDecl_initCallingConvention(X86FuncDecl * self,uint32_t convention)72 static void X86FuncDecl_initCallingConvention(X86FuncDecl* self, uint32_t convention)
73 {
74   uint32_t i;
75 
76   // --------------------------------------------------------------------------
77   // [Inir]
78   // --------------------------------------------------------------------------
79 
80   self->_convention = convention;
81   self->_calleePopsStack = false;
82   self->_argumentsDirection = kFuncArgsRTL;
83 
84   for (i = 0; i < ASMJIT_ARRAY_SIZE(self->_gpList); i++)
85     self->_gpList[i] = kRegIndexInvalid;
86 
87   for (i = 0; i < ASMJIT_ARRAY_SIZE(self->_xmmList); i++)
88     self->_xmmList[i] = kRegIndexInvalid;
89 
90   self->_gpListMask = 0x0;
91   self->_mmListMask = 0x0;
92   self->_xmmListMask = 0x0;
93 
94   self->_gpPreservedMask = 0x0;
95   self->_mmPreservedMask = 0x0;
96   self->_xmmPreservedMask = 0x0;
97 
98   // --------------------------------------------------------------------------
99   // [X86 Calling Conventions]
100   // --------------------------------------------------------------------------
101 
102 #if defined(ASMJIT_X86)
103   self->_gpPreservedMask = static_cast<uint16_t>(
104     IntUtil::maskFromIndex(kX86RegIndexEbx) |
105     IntUtil::maskFromIndex(kX86RegIndexEsp) |
106     IntUtil::maskFromIndex(kX86RegIndexEbp) |
107     IntUtil::maskFromIndex(kX86RegIndexEsi) |
108     IntUtil::maskFromIndex(kX86RegIndexEdi));
109   self->_xmmPreservedMask = 0;
110 
111   switch (convention)
112   {
113     // ------------------------------------------------------------------------
114     // [CDecl]
115     // ------------------------------------------------------------------------
116 
117     case kX86FuncConvCDecl:
118       break;
119 
120     // ------------------------------------------------------------------------
121     // [StdCall]
122     // ------------------------------------------------------------------------
123 
124     case kX86FuncConvStdCall:
125       self->_calleePopsStack = true;
126       break;
127 
128     // ------------------------------------------------------------------------
129     // [MS-ThisCall]
130     // ------------------------------------------------------------------------
131 
132     case kX86FuncConvMsThisCall:
133       self->_calleePopsStack = true;
134 
135       self->_gpList[0] = kX86RegIndexEcx;
136 
137       self->_gpListMask = static_cast<uint16_t>(
138         IntUtil::maskFromIndex(kX86RegIndexEcx));
139       break;
140 
141     // ------------------------------------------------------------------------
142     // [MS-FastCall]
143     // ------------------------------------------------------------------------
144 
145     case kX86FuncConvMsFastCall:
146       self->_calleePopsStack = true;
147 
148       self->_gpList[0] = kX86RegIndexEcx;
149       self->_gpList[1] = kX86RegIndexEdx;
150 
151       self->_gpListMask = static_cast<uint16_t>(
152         IntUtil::maskFromIndex(kX86RegIndexEcx) |
153         IntUtil::maskFromIndex(kX86RegIndexEdx));
154       break;
155 
156     // ------------------------------------------------------------------------
157     // [Borland-FastCall]
158     // ------------------------------------------------------------------------
159 
160     case kX86FuncConvBorlandFastCall:
161       self->_calleePopsStack = true;
162       self->_argumentsDirection = kFuncArgsLTR;
163 
164       self->_gpList[0] = kX86RegIndexEax;
165       self->_gpList[1] = kX86RegIndexEdx;
166       self->_gpList[2] = kX86RegIndexEcx;
167 
168       self->_gpListMask = static_cast<uint16_t>(
169         IntUtil::maskFromIndex(kX86RegIndexEax) |
170         IntUtil::maskFromIndex(kX86RegIndexEdx) |
171         IntUtil::maskFromIndex(kX86RegIndexEcx));
172       break;
173 
174     // ------------------------------------------------------------------------
175     // [Gcc-FastCall]
176     // ------------------------------------------------------------------------
177 
178     case kX86FuncConvGccFastCall:
179       self->_calleePopsStack = true;
180 
181       self->_gpList[0] = kX86RegIndexEcx;
182       self->_gpList[1] = kX86RegIndexEdx;
183 
184       self->_gpListMask = static_cast<uint16_t>(
185         IntUtil::maskFromIndex(kX86RegIndexEcx) |
186         IntUtil::maskFromIndex(kX86RegIndexEdx));
187       break;
188 
189     // ------------------------------------------------------------------------
190     // [Gcc-Regparm(1)]
191     // ------------------------------------------------------------------------
192 
193     case kX86FuncConvGccRegParm1:
194       self->_calleePopsStack = false;
195 
196       self->_gpList[0] = kX86RegIndexEax;
197       self->_gpListMask = static_cast<uint16_t>(
198         IntUtil::maskFromIndex(kX86RegIndexEax));
199       break;
200 
201     // ------------------------------------------------------------------------
202     // [Gcc-Regparm(2)]
203     // ------------------------------------------------------------------------
204 
205     case kX86FuncConvGccRegParm2:
206       self->_calleePopsStack = false;
207 
208       self->_gpList[0] = kX86RegIndexEax;
209       self->_gpList[1] = kX86RegIndexEdx;
210 
211       self->_gpListMask = static_cast<uint16_t>(
212         IntUtil::maskFromIndex(kX86RegIndexEax) |
213         IntUtil::maskFromIndex(kX86RegIndexEdx));
214       break;
215 
216     // ------------------------------------------------------------------------
217     // [Gcc-Regparm(3)]
218     // ------------------------------------------------------------------------
219 
220     case kX86FuncConvGccRegParm3:
221       self->_calleePopsStack = false;
222 
223       self->_gpList[0] = kX86RegIndexEax;
224       self->_gpList[1] = kX86RegIndexEdx;
225       self->_gpList[2] = kX86RegIndexEcx;
226 
227       self->_gpListMask = static_cast<uint16_t>(
228         IntUtil::maskFromIndex(kX86RegIndexEax) |
229         IntUtil::maskFromIndex(kX86RegIndexEdx) |
230         IntUtil::maskFromIndex(kX86RegIndexEcx));
231       break;
232 
233     // ------------------------------------------------------------------------
234     // [Illegal]
235     // ------------------------------------------------------------------------
236 
237     default:
238       // Illegal calling convention.
239       ASMJIT_ASSERT(0);
240   }
241 #endif // ASMJIT_X86
242 
243   // --------------------------------------------------------------------------
244   // [X64 Calling Conventions]
245   // --------------------------------------------------------------------------
246 
247 #if defined(ASMJIT_X64)
248   switch (convention)
249   {
250     // ------------------------------------------------------------------------
251     // [X64-Windows]
252     // ------------------------------------------------------------------------
253 
254     case kX86FuncConvX64W:
255       self->_gpList[0] = kX86RegIndexRcx;
256       self->_gpList[1] = kX86RegIndexRdx;
257       self->_gpList[2] = kX86RegIndexR8;
258       self->_gpList[3] = kX86RegIndexR9;
259 
260       self->_xmmList[0] = kX86RegIndexXmm0;
261       self->_xmmList[1] = kX86RegIndexXmm1;
262       self->_xmmList[2] = kX86RegIndexXmm2;
263       self->_xmmList[3] = kX86RegIndexXmm3;
264 
265       self->_gpListMask = static_cast<uint16_t>(
266         IntUtil::maskFromIndex(kX86RegIndexRcx  ) |
267         IntUtil::maskFromIndex(kX86RegIndexRdx  ) |
268         IntUtil::maskFromIndex(kX86RegIndexR8   ) |
269         IntUtil::maskFromIndex(kX86RegIndexR9   ));
270 
271       self->_xmmListMask = static_cast<uint16_t>(
272         IntUtil::maskFromIndex(kX86RegIndexXmm0 ) |
273         IntUtil::maskFromIndex(kX86RegIndexXmm1 ) |
274         IntUtil::maskFromIndex(kX86RegIndexXmm2 ) |
275         IntUtil::maskFromIndex(kX86RegIndexXmm3 ));
276 
277       self->_gpPreservedMask = static_cast<uint16_t>(
278         IntUtil::maskFromIndex(kX86RegIndexRbx  ) |
279         IntUtil::maskFromIndex(kX86RegIndexRsp  ) |
280         IntUtil::maskFromIndex(kX86RegIndexRbp  ) |
281         IntUtil::maskFromIndex(kX86RegIndexRsi  ) |
282         IntUtil::maskFromIndex(kX86RegIndexRdi  ) |
283         IntUtil::maskFromIndex(kX86RegIndexR12  ) |
284         IntUtil::maskFromIndex(kX86RegIndexR13  ) |
285         IntUtil::maskFromIndex(kX86RegIndexR14  ) |
286         IntUtil::maskFromIndex(kX86RegIndexR15  ));
287 
288       self->_xmmPreservedMask = static_cast<uint16_t>(
289         IntUtil::maskFromIndex(kX86RegIndexXmm6 ) |
290         IntUtil::maskFromIndex(kX86RegIndexXmm7 ) |
291         IntUtil::maskFromIndex(kX86RegIndexXmm8 ) |
292         IntUtil::maskFromIndex(kX86RegIndexXmm9 ) |
293         IntUtil::maskFromIndex(kX86RegIndexXmm10) |
294         IntUtil::maskFromIndex(kX86RegIndexXmm11) |
295         IntUtil::maskFromIndex(kX86RegIndexXmm12) |
296         IntUtil::maskFromIndex(kX86RegIndexXmm13) |
297         IntUtil::maskFromIndex(kX86RegIndexXmm14) |
298         IntUtil::maskFromIndex(kX86RegIndexXmm15));
299       break;
300 
301     // ------------------------------------------------------------------------
302     // [X64-Unix]
303     // ------------------------------------------------------------------------
304 
305     case kX86FuncConvX64U:
306       self->_gpList[0] = kX86RegIndexRdi;
307       self->_gpList[1] = kX86RegIndexRsi;
308       self->_gpList[2] = kX86RegIndexRdx;
309       self->_gpList[3] = kX86RegIndexRcx;
310       self->_gpList[4] = kX86RegIndexR8;
311       self->_gpList[5] = kX86RegIndexR9;
312 
313       self->_xmmList[0] = kX86RegIndexXmm0;
314       self->_xmmList[1] = kX86RegIndexXmm1;
315       self->_xmmList[2] = kX86RegIndexXmm2;
316       self->_xmmList[3] = kX86RegIndexXmm3;
317       self->_xmmList[4] = kX86RegIndexXmm4;
318       self->_xmmList[5] = kX86RegIndexXmm5;
319       self->_xmmList[6] = kX86RegIndexXmm6;
320       self->_xmmList[7] = kX86RegIndexXmm7;
321 
322       self->_gpListMask = static_cast<uint16_t>(
323         IntUtil::maskFromIndex(kX86RegIndexRdi  ) |
324         IntUtil::maskFromIndex(kX86RegIndexRsi  ) |
325         IntUtil::maskFromIndex(kX86RegIndexRdx  ) |
326         IntUtil::maskFromIndex(kX86RegIndexRcx  ) |
327         IntUtil::maskFromIndex(kX86RegIndexR8   ) |
328         IntUtil::maskFromIndex(kX86RegIndexR9   ));
329 
330       self->_xmmListMask = static_cast<uint16_t>(
331         IntUtil::maskFromIndex(kX86RegIndexXmm0 ) |
332         IntUtil::maskFromIndex(kX86RegIndexXmm1 ) |
333         IntUtil::maskFromIndex(kX86RegIndexXmm2 ) |
334         IntUtil::maskFromIndex(kX86RegIndexXmm3 ) |
335         IntUtil::maskFromIndex(kX86RegIndexXmm4 ) |
336         IntUtil::maskFromIndex(kX86RegIndexXmm5 ) |
337         IntUtil::maskFromIndex(kX86RegIndexXmm6 ) |
338         IntUtil::maskFromIndex(kX86RegIndexXmm7 ));
339 
340       self->_gpPreservedMask = static_cast<uint16_t>(
341         IntUtil::maskFromIndex(kX86RegIndexRbx  ) |
342         IntUtil::maskFromIndex(kX86RegIndexRsp  ) |
343         IntUtil::maskFromIndex(kX86RegIndexRbp  ) |
344         IntUtil::maskFromIndex(kX86RegIndexR12  ) |
345         IntUtil::maskFromIndex(kX86RegIndexR13  ) |
346         IntUtil::maskFromIndex(kX86RegIndexR14  ) |
347         IntUtil::maskFromIndex(kX86RegIndexR15  ));
348       break;
349 
350     // ------------------------------------------------------------------------
351     // [Illegal]
352     // ------------------------------------------------------------------------
353 
354     default:
355       // Illegal calling convention.
356       ASMJIT_ASSERT(0);
357   }
358 #endif // ASMJIT_X64
359 }
360 
361 // ============================================================================
362 // [AsmJit::X86FuncDecl - SetPrototype - InitDefinition]
363 // ============================================================================
364 
X86FuncDecl_initDefinition(X86FuncDecl * self,uint32_t returnType,const uint32_t * argumentsData,uint32_t argumentsCount)365 static void X86FuncDecl_initDefinition(X86FuncDecl* self,
366   uint32_t returnType, const uint32_t* argumentsData, uint32_t argumentsCount)
367 {
368   ASMJIT_ASSERT(argumentsCount <= kFuncArgsMax);
369 
370   // --------------------------------------------------------------------------
371   // [Init]
372   // --------------------------------------------------------------------------
373 
374   int32_t i = 0;
375   int32_t gpPos = 0;
376   int32_t xmmPos = 0;
377   int32_t stackOffset = 0;
378 
379   self->_returnType = returnType;
380   self->_argumentsCount = static_cast<uint8_t>(argumentsCount);
381 
382   while (i < static_cast<int32_t>(argumentsCount))
383   {
384     FuncArg& arg = self->_arguments[i];
385 
386     arg._varType = static_cast<uint8_t>(argumentsData[i]);
387     arg._regIndex = kRegIndexInvalid;
388     arg._stackOffset = kFuncStackInvalid;
389 
390     i++;
391   }
392 
393   while (i < kFuncArgsMax)
394   {
395     FuncArg& arg = self->_arguments[i];
396     arg.reset();
397 
398     i++;
399   }
400 
401   self->_argumentsStackSize = 0;
402   self->_gpArgumentsMask = 0x0;
403   self->_mmArgumentsMask = 0x0;
404   self->_xmmArgumentsMask = 0x0;
405 
406   if (self->_argumentsCount == 0)
407     return;
408 
409   // --------------------------------------------------------------------------
410   // [X86 Calling Conventions (32-bit)]
411   // --------------------------------------------------------------------------
412 
413 #if defined(ASMJIT_X86)
414   // Register arguments (Integer), always left-to-right.
415   for (i = 0; i != argumentsCount; i++)
416   {
417     FuncArg& arg = self->_arguments[i];
418     uint32_t varType = arg.getVarType();
419 
420     if (X86Util::isVarTypeInt(varType) && gpPos < 16 && self->_gpList[gpPos] != kRegIndexInvalid)
421     {
422       arg._regIndex = self->_gpList[gpPos++];
423       self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
424     }
425   }
426 
427   // Stack arguments.
428   int32_t iStart = static_cast<int32_t>(argumentsCount - 1);
429   int32_t iEnd   = -1;
430   int32_t iStep  = -1;
431 
432   if (self->_argumentsDirection == kFuncArgsLTR)
433   {
434     iStart = 0;
435     iEnd   = static_cast<int32_t>(argumentsCount);
436     iStep  = 1;
437   }
438 
439   for (i = iStart; i != iEnd; i += iStep)
440   {
441     FuncArg& arg = self->_arguments[i];
442     uint32_t varType = arg.getVarType();
443 
444     if (arg.hasRegIndex())
445       continue;
446 
447     if (X86Util::isVarTypeInt(varType))
448     {
449       stackOffset -= 4;
450       arg._stackOffset = static_cast<int16_t>(stackOffset);
451     }
452     else if (X86Util::isVarTypeFloat(varType))
453     {
454       int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
455       stackOffset -= size;
456       arg._stackOffset = static_cast<int16_t>(stackOffset);
457     }
458   }
459 #endif // ASMJIT_X86
460 
461   // --------------------------------------------------------------------------
462   // [X64 Calling Conventions (64-bit)]
463   // --------------------------------------------------------------------------
464 
465 #if defined(ASMJIT_X64)
466   // Windows 64-bit specific.
467   if (self->_convention == kX86FuncConvX64W)
468   {
469     int32_t max = argumentsCount < 4 ? argumentsCount : 4;
470 
471     // Register arguments (Integer / FP), always left-to-right.
472     for (i = 0; i != max; i++)
473     {
474       FuncArg& arg = self->_arguments[i];
475       uint32_t varType = arg.getVarType();
476 
477       if (X86Util::isVarTypeInt(varType))
478       {
479         arg._regIndex = self->_gpList[i];
480         self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
481       }
482       else if (X86Util::isVarTypeFloat(varType))
483       {
484         arg._regIndex = self->_xmmList[i];
485         self->_xmmArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
486       }
487     }
488 
489     // Stack arguments (always right-to-left).
490     for (i = argumentsCount - 1; i != -1; i--)
491     {
492       FuncArg& arg = self->_arguments[i];
493       uint32_t varType = arg.getVarType();
494 
495       if (arg.isAssigned())
496         continue;
497 
498       if (X86Util::isVarTypeInt(varType))
499       {
500         stackOffset -= 8; // Always 8 bytes.
501         arg._stackOffset = stackOffset;
502       }
503       else if (X86Util::isVarTypeFloat(varType))
504       {
505         int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
506         stackOffset -= size;
507         arg._stackOffset = stackOffset;
508       }
509     }
510 
511     // 32 bytes shadow space (X64W calling convention specific).
512     stackOffset -= 4 * 8;
513   }
514   // Linux/Unix 64-bit (AMD64 calling convention).
515   else
516   {
517     // Register arguments (Integer), always left-to-right.
518     for (i = 0; i != static_cast<int32_t>(argumentsCount); i++)
519     {
520       FuncArg& arg = self->_arguments[i];
521       uint32_t varType = arg.getVarType();
522 
523       if (X86Util::isVarTypeInt(varType) && gpPos < 32 && self->_gpList[gpPos] != kRegIndexInvalid)
524       {
525         arg._regIndex = self->_gpList[gpPos++];
526         self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
527       }
528     }
529 
530     // Register arguments (FP), always left-to-right.
531     for (i = 0; i != static_cast<int32_t>(argumentsCount); i++)
532     {
533       FuncArg& arg = self->_arguments[i];
534       uint32_t varType = arg.getVarType();
535 
536       if (X86Util::isVarTypeFloat(varType))
537       {
538         arg._regIndex = self->_xmmList[xmmPos++];
539         self->_xmmArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
540       }
541     }
542 
543     // Stack arguments.
544     for (i = argumentsCount - 1; i != -1; i--)
545     {
546       FuncArg& arg = self->_arguments[i];
547       uint32_t varType = arg.getVarType();
548 
549       if (arg.isAssigned())
550         continue;
551 
552       if (X86Util::isVarTypeInt(varType))
553       {
554         stackOffset -= 8;
555         arg._stackOffset = static_cast<int16_t>(stackOffset);
556       }
557       else if (X86Util::isVarTypeFloat(varType))
558       {
559         int32_t size = (int32_t)x86VarInfo[varType].getSize();
560 
561         stackOffset -= size;
562         arg._stackOffset = static_cast<int16_t>(stackOffset);
563       }
564     }
565   }
566 #endif // ASMJIT_X64
567 
568   // Modify stack offset (all function parameters will be in positive stack
569   // offset that is never zero).
570   for (i = 0; i < (int32_t)argumentsCount; i++)
571   {
572     FuncArg& arg = self->_arguments[i];
573     if (!arg.hasRegIndex())
574     {
575       arg._stackOffset += static_cast<uint16_t>(static_cast<int32_t>(sizeof(uintptr_t)) - stackOffset);
576     }
577   }
578 
579   self->_argumentsStackSize = (uint32_t)(-stackOffset);
580 }
581 
setPrototype(uint32_t convention,uint32_t returnType,const uint32_t * arguments,uint32_t argumentsCount)582 void X86FuncDecl::setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount)
583 {
584   // Limit maximum function arguments to kFuncArgsMax.
585   if (argumentsCount > kFuncArgsMax)
586     argumentsCount = kFuncArgsMax;
587 
588   X86FuncDecl_initCallingConvention(this, convention);
589   X86FuncDecl_initDefinition(this, returnType, arguments, argumentsCount);
590 }
591 
592 // ============================================================================
593 // [AsmJit::X86FuncDecl - Reset]
594 // ============================================================================
595 
reset()596 void X86FuncDecl::reset()
597 {
598   uint32_t i;
599 
600   // --------------------------------------------------------------------------
601   // [Core]
602   // --------------------------------------------------------------------------
603 
604   _returnType = kVarTypeInvalid;
605   _argumentsCount = 0;
606 
607   _reserved0[0] = 0;
608   _reserved0[1] = 0;
609 
610   for (i = 0; i < ASMJIT_ARRAY_SIZE(_arguments); i++)
611     _arguments[i].reset();
612 
613   _argumentsStackSize = 0;
614   _gpArgumentsMask = 0x0;
615   _mmArgumentsMask = 0x0;
616   _xmmArgumentsMask = 0x0;
617 
618   // --------------------------------------------------------------------------
619   // [Convention]
620   // --------------------------------------------------------------------------
621 
622   _convention = kFuncConvNone;
623   _calleePopsStack = false;
624   _argumentsDirection = kFuncArgsRTL;
625   _reserved1 = 0;
626 
627   for (i = 0; i < ASMJIT_ARRAY_SIZE(_gpList); i++)
628     _gpList[i] = kRegIndexInvalid;
629 
630   for (i = 0; i < ASMJIT_ARRAY_SIZE(_xmmList); i++)
631     _xmmList[i] = kRegIndexInvalid;
632 
633   _gpListMask = 0x0;
634   _mmListMask = 0x0;
635   _xmmListMask = 0x0;
636 
637   _gpPreservedMask = 0x0;
638   _mmPreservedMask = 0x0;
639   _xmmPreservedMask = 0x0;
640 }
641 
642 } // AsmJit namespace
643 
644 // [Api-Begin]
645 #include "../core/apiend.h"
646