VirtualBox

source: vbox/trunk/src/VBox/VMM/include/IEMInternal.h@ 47314

Last change on this file since 47314 was 47314, checked in by vboxsync, 11 years ago

Use IEM_DECL_IMPL_TYPE with typedef. Should fix the build.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 57.0 KB
Line 
1/* $Id: IEMInternal.h 47314 2013-07-22 15:39:12Z vboxsync $ */
2/** @file
3 * IEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2011-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___IEMInternal_h
19#define ___IEMInternal_h
20
21#include <VBox/vmm/stam.h>
22#include <VBox/vmm/cpum.h>
23#include <VBox/param.h>
24
25
26RT_C_DECLS_BEGIN
27
28
29/** @defgroup grp_iem_int Internals
30 * @ingroup grp_iem
31 * @internal
32 * @{
33 */
34
35/** @def IEM_VERIFICATION_MODE_FULL
36 * Shorthand for:
37 * defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_MINIMAL)
38 */
39#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_MINIMAL) && !defined(IEM_VERIFICATION_MODE_FULL)
40# define IEM_VERIFICATION_MODE_FULL
41#endif
42
43
44/** Finish and move to types.h */
45typedef union
46{
47 uint32_t u32;
48} RTFLOAT32U;
49typedef RTFLOAT32U *PRTFLOAT32U;
50typedef RTFLOAT32U const *PCRTFLOAT32U;
51
52
53/**
54 * Operand or addressing mode.
55 */
56typedef enum IEMMODE
57{
58 IEMMODE_16BIT = 0,
59 IEMMODE_32BIT,
60 IEMMODE_64BIT
61} IEMMODE;
62AssertCompileSize(IEMMODE, 4);
63
64/**
65 * Extended operand mode that includes a representation of 8-bit.
66 *
67 * This is used for packing down modes when invoking some C instruction
68 * implementations.
69 */
70typedef enum IEMMODEX
71{
72 IEMMODEX_16BIT = IEMMODE_16BIT,
73 IEMMODEX_32BIT = IEMMODE_32BIT,
74 IEMMODEX_64BIT = IEMMODE_64BIT,
75 IEMMODEX_8BIT
76} IEMMODEX;
77AssertCompileSize(IEMMODEX, 4);
78
79
80/**
81 * Branch types.
82 */
83typedef enum IEMBRANCH
84{
85 IEMBRANCH_JUMP = 1,
86 IEMBRANCH_CALL,
87 IEMBRANCH_TRAP,
88 IEMBRANCH_SOFTWARE_INT,
89 IEMBRANCH_HARDWARE_INT
90} IEMBRANCH;
91AssertCompileSize(IEMBRANCH, 4);
92
93
94/**
95 * A FPU result.
96 */
97typedef struct IEMFPURESULT
98{
99 /** The output value. */
100 RTFLOAT80U r80Result;
101 /** The output status. */
102 uint16_t FSW;
103} IEMFPURESULT;
104AssertCompileMemberOffset(IEMFPURESULT, FSW, 10);
105/** Pointer to a FPU result. */
106typedef IEMFPURESULT *PIEMFPURESULT;
107/** Pointer to a const FPU result. */
108typedef IEMFPURESULT const *PCIEMFPURESULT;
109
110
111/**
112 * A FPU result consisting of two output values and FSW.
113 */
114typedef struct IEMFPURESULTTWO
115{
116 /** The first output value. */
117 RTFLOAT80U r80Result1;
118 /** The output status. */
119 uint16_t FSW;
120 /** The second output value. */
121 RTFLOAT80U r80Result2;
122} IEMFPURESULTTWO;
123AssertCompileMemberOffset(IEMFPURESULTTWO, FSW, 10);
124AssertCompileMemberOffset(IEMFPURESULTTWO, r80Result2, 12);
125/** Pointer to a FPU result consisting of two output values and FSW. */
126typedef IEMFPURESULTTWO *PIEMFPURESULTTWO;
127/** Pointer to a const FPU result consisting of two output values and FSW. */
128typedef IEMFPURESULTTWO const *PCIEMFPURESULTTWO;
129
130
131#ifdef IEM_VERIFICATION_MODE_FULL
132
133/**
134 * Verification event type.
135 */
136typedef enum IEMVERIFYEVENT
137{
138 IEMVERIFYEVENT_INVALID = 0,
139 IEMVERIFYEVENT_IOPORT_READ,
140 IEMVERIFYEVENT_IOPORT_WRITE,
141 IEMVERIFYEVENT_RAM_WRITE,
142 IEMVERIFYEVENT_RAM_READ
143} IEMVERIFYEVENT;
144
145/** Checks if the event type is a RAM read or write. */
146# define IEMVERIFYEVENT_IS_RAM(a_enmType) ((a_enmType) == IEMVERIFYEVENT_RAM_WRITE || (a_enmType) == IEMVERIFYEVENT_RAM_READ)
147
148/**
149 * Verification event record.
150 */
151typedef struct IEMVERIFYEVTREC
152{
153 /** Pointer to the next record in the list. */
154 struct IEMVERIFYEVTREC *pNext;
155 /** The event type. */
156 IEMVERIFYEVENT enmEvent;
157 /** The event data. */
158 union
159 {
160 /** IEMVERIFYEVENT_IOPORT_READ */
161 struct
162 {
163 RTIOPORT Port;
164 uint32_t cbValue;
165 } IOPortRead;
166
167 /** IEMVERIFYEVENT_IOPORT_WRITE */
168 struct
169 {
170 RTIOPORT Port;
171 uint32_t cbValue;
172 uint32_t u32Value;
173 } IOPortWrite;
174
175 /** IEMVERIFYEVENT_RAM_READ */
176 struct
177 {
178 RTGCPHYS GCPhys;
179 uint32_t cb;
180 } RamRead;
181
182 /** IEMVERIFYEVENT_RAM_WRITE */
183 struct
184 {
185 RTGCPHYS GCPhys;
186 uint32_t cb;
187 uint8_t ab[512];
188 } RamWrite;
189 } u;
190} IEMVERIFYEVTREC;
191/** Pointer to an IEM event verification records. */
192typedef IEMVERIFYEVTREC *PIEMVERIFYEVTREC;
193
194#endif /* IEM_VERIFICATION_MODE_FULL */
195
196
197/**
198 * The per-CPU IEM state.
199 */
200typedef struct IEMCPU
201{
202 /** Pointer to the CPU context - ring-3 contex. */
203 R3PTRTYPE(PCPUMCTX) pCtxR3;
204 /** Pointer to the CPU context - ring-0 contex. */
205 R0PTRTYPE(PCPUMCTX) pCtxR0;
206 /** Pointer to the CPU context - raw-mode contex. */
207 RCPTRTYPE(PCPUMCTX) pCtxRC;
208
209 /** Offset of the VMCPU structure relative to this structure (negative). */
210 int32_t offVMCpu;
211 /** Offset of the VM structure relative to this structure (negative). */
212 int32_t offVM;
213
214 /** Whether to bypass access handlers or not. */
215 bool fBypassHandlers;
216 /** Indicates that we're interpreting patch code - RC only! */
217 bool fInPatchCode;
218 /** Explicit alignment padding. */
219 bool afAlignment0[2];
220
221 /** The flags of the current exception / interrupt. */
222 uint32_t fCurXcpt;
223 /** The current exception / interrupt. */
224 uint8_t uCurXcpt;
225 /** Exception / interrupt recursion depth. */
226 int8_t cXcptRecursions;
227 /** Explicit alignment padding. */
228 bool afAlignment1[1];
229 /** The CPL. */
230 uint8_t uCpl;
231 /** The current CPU execution mode (CS). */
232 IEMMODE enmCpuMode;
233 /** Info status code that needs to be propagated to the IEM caller.
234 * This cannot be passed internally, as it would complicate all success
235 * checks within the interpreter making the code larger and almost impossible
236 * to get right. Instead, we'll store status codes to pass on here. Each
237 * source of these codes will perform appropriate sanity checks. */
238 int32_t rcPassUp;
239
240 /** @name Statistics
241 * @{ */
242 /** The number of instructions we've executed. */
243 uint32_t cInstructions;
244 /** The number of potential exits. */
245 uint32_t cPotentialExits;
246 /** The number of bytes data or stack written (mostly for IEMExecOneEx).
247 * This may contain uncommitted writes. */
248 uint32_t cbWritten;
249 /** Counts the VERR_IEM_INSTR_NOT_IMPLEMENTED returns. */
250 uint32_t cRetInstrNotImplemented;
251 /** Counts the VERR_IEM_ASPECT_NOT_IMPLEMENTED returns. */
252 uint32_t cRetAspectNotImplemented;
253 /** Counts informational statuses returned (other than VINF_SUCCESS). */
254 uint32_t cRetInfStatuses;
255 /** Counts other error statuses returned. */
256 uint32_t cRetErrStatuses;
257 /** Number of times rcPassUp has been used. */
258 uint32_t cRetPassUpStatus;
259#ifdef IEM_VERIFICATION_MODE_FULL
260 /** The Number of I/O port reads that has been performed. */
261 uint32_t cIOReads;
262 /** The Number of I/O port writes that has been performed. */
263 uint32_t cIOWrites;
264 /** Set if no comparison to REM is currently performed.
265 * This is used to skip past really slow bits. */
266 bool fNoRem;
267 /** Indicates that RAX and RDX differences should be ignored since RDTSC
268 * and RDTSCP are timing sensitive. */
269 bool fIgnoreRaxRdx;
270 /** Indicates that a MOVS instruction with overlapping source and destination
271 * was executed, causing the memory write records to be incorrrect. */
272 bool fOverlappingMovs;
273 /** This is used to communicate a CPL changed caused by IEMInjectTrap that
274 * CPUM doesn't yet reflect. */
275 uint8_t uInjectCpl;
276 bool afAlignment2[4];
277 /** Mask of undefined eflags.
278 * The verifier will any difference in these flags. */
279 uint32_t fUndefinedEFlags;
280 /** The CS of the instruction being interpreted. */
281 RTSEL uOldCs;
282 /** The RIP of the instruction being interpreted. */
283 uint64_t uOldRip;
284 /** The physical address corresponding to abOpcodes[0]. */
285 RTGCPHYS GCPhysOpcodes;
286#endif
287 /** @} */
288
289 /** @name Decoder state.
290 * @{ */
291
292 /** The default addressing mode . */
293 IEMMODE enmDefAddrMode;
294 /** The effective addressing mode . */
295 IEMMODE enmEffAddrMode;
296 /** The default operand mode . */
297 IEMMODE enmDefOpSize;
298 /** The effective operand mode . */
299 IEMMODE enmEffOpSize;
300
301 /** The prefix mask (IEM_OP_PRF_XXX). */
302 uint32_t fPrefixes;
303 /** The extra REX ModR/M register field bit (REX.R << 3). */
304 uint8_t uRexReg;
305 /** The extra REX ModR/M r/m field, SIB base and opcode reg bit
306 * (REX.B << 3). */
307 uint8_t uRexB;
308 /** The extra REX SIB index field bit (REX.X << 3). */
309 uint8_t uRexIndex;
310 /** The effective segment register (X86_SREG_XXX). */
311 uint8_t iEffSeg;
312
313 /** The current offset into abOpcodes. */
314 uint8_t offOpcode;
315 /** The size of what has currently been fetched into abOpcodes. */
316 uint8_t cbOpcode;
317 /** The opcode bytes. */
318 uint8_t abOpcode[15];
319 /** Offset into abOpcodes where the FPU instruction starts.
320 * Only set by the FPU escape opcodes (0xd8-0xdf) and used later on when the
321 * instruction result is committed. */
322 uint8_t offFpuOpcode;
323
324 /** @}*/
325
326 /** Alignment padding for aMemMappings. */
327 uint8_t abAlignment2[4];
328
329 /** The number of active guest memory mappings. */
330 uint8_t cActiveMappings;
331 /** The next unused mapping index. */
332 uint8_t iNextMapping;
333 /** Records for tracking guest memory mappings. */
334 struct
335 {
336 /** The address of the mapped bytes. */
337 void *pv;
338#if defined(IN_RC) && HC_ARCH_BITS == 64
339 uint32_t u32Alignment3; /**< Alignment padding. */
340#endif
341 /** The access flags (IEM_ACCESS_XXX).
342 * IEM_ACCESS_INVALID if the entry is unused. */
343 uint32_t fAccess;
344#if HC_ARCH_BITS == 64
345 uint32_t u32Alignment4; /**< Alignment padding. */
346#endif
347 } aMemMappings[3];
348
349 /** Locking records for the mapped memory. */
350 union
351 {
352 PGMPAGEMAPLOCK Lock;
353 uint64_t au64Padding[2];
354 } aMemMappingLocks[3];
355
356 /** Bounce buffer info.
357 * This runs in parallel to aMemMappings. */
358 struct
359 {
360 /** The physical address of the first byte. */
361 RTGCPHYS GCPhysFirst;
362 /** The physical address of the second page. */
363 RTGCPHYS GCPhysSecond;
364 /** The number of bytes in the first page. */
365 uint16_t cbFirst;
366 /** The number of bytes in the second page. */
367 uint16_t cbSecond;
368 /** Whether it's unassigned memory. */
369 bool fUnassigned;
370 /** Explicit alignment padding. */
371 bool afAlignment5[3];
372 } aMemBbMappings[3];
373
374 /** Bounce buffer storage.
375 * This runs in parallel to aMemMappings and aMemBbMappings. */
376 struct
377 {
378 uint8_t ab[512];
379 } aBounceBuffers[3];
380
381 /** @name Target CPU information.
382 * @{ */
383 /** EDX value of CPUID(1).
384 * @remarks Some bits are subject to change and must be queried dynamically. */
385 uint32_t fCpuIdStdFeaturesEdx;
386 /** ECX value of CPUID(1).
387 * @remarks Some bits are subject to change and must be queried dynamically. */
388 uint32_t fCpuIdStdFeaturesEcx;
389 /** The CPU vendor. */
390 CPUMCPUVENDOR enmCpuVendor;
391 /** @} */
392
393 /** @name Host CPU information.
394 * @{ */
395 /** EDX value of CPUID(1). */
396 uint32_t fHostCpuIdStdFeaturesEdx;
397 /** ECX value of CPUID(1). */
398 uint32_t fHostCpuIdStdFeaturesEcx;
399 /** The CPU vendor. */
400 CPUMCPUVENDOR enmHostCpuVendor;
401 /** @} */
402
403#ifdef IEM_VERIFICATION_MODE_FULL
404 /** The event verification records for what IEM did (LIFO). */
405 R3PTRTYPE(PIEMVERIFYEVTREC) pIemEvtRecHead;
406 /** Insertion point for pIemEvtRecHead. */
407 R3PTRTYPE(PIEMVERIFYEVTREC *) ppIemEvtRecNext;
408 /** The event verification records for what the other party did (FIFO). */
409 R3PTRTYPE(PIEMVERIFYEVTREC) pOtherEvtRecHead;
410 /** Insertion point for pOtherEvtRecHead. */
411 R3PTRTYPE(PIEMVERIFYEVTREC *) ppOtherEvtRecNext;
412 /** List of free event records. */
413 R3PTRTYPE(PIEMVERIFYEVTREC) pFreeEvtRec;
414#endif
415} IEMCPU;
416/** Pointer to the per-CPU IEM state. */
417typedef IEMCPU *PIEMCPU;
418
419/** Converts a IEMCPU pointer to a VMCPU pointer.
420 * @returns VMCPU pointer.
421 * @param a_pIemCpu The IEM per CPU instance data.
422 */
423#define IEMCPU_TO_VMCPU(a_pIemCpu) ((PVMCPU)( (uintptr_t)(a_pIemCpu) + a_pIemCpu->offVMCpu ))
424
425/** Converts a IEMCPU pointer to a VM pointer.
426 * @returns VM pointer.
427 * @param a_pIemCpu The IEM per CPU instance data.
428 */
429#define IEMCPU_TO_VM(a_pIemCpu) ((PVM)( (uintptr_t)(a_pIemCpu) + a_pIemCpu->offVM ))
430
431/** @name IEM_ACCESS_XXX - Access details.
432 * @{ */
433#define IEM_ACCESS_INVALID UINT32_C(0x000000ff)
434#define IEM_ACCESS_TYPE_READ UINT32_C(0x00000001)
435#define IEM_ACCESS_TYPE_WRITE UINT32_C(0x00000002)
436#define IEM_ACCESS_TYPE_EXEC UINT32_C(0x00000004)
437#define IEM_ACCESS_TYPE_MASK UINT32_C(0x00000007)
438#define IEM_ACCESS_WHAT_CODE UINT32_C(0x00000010)
439#define IEM_ACCESS_WHAT_DATA UINT32_C(0x00000020)
440#define IEM_ACCESS_WHAT_STACK UINT32_C(0x00000030)
441#define IEM_ACCESS_WHAT_SYS UINT32_C(0x00000040)
442#define IEM_ACCESS_WHAT_MASK UINT32_C(0x00000070)
443/** The writes are partial, so if initialize the bounce buffer with the
444 * orignal RAM content. */
445#define IEM_ACCESS_PARTIAL_WRITE UINT32_C(0x00000100)
446/** Used in aMemMappings to indicate that the entry is bounce buffered. */
447#define IEM_ACCESS_BOUNCE_BUFFERED UINT32_C(0x00000200)
448/** Read+write data alias. */
449#define IEM_ACCESS_DATA_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
450/** Write data alias. */
451#define IEM_ACCESS_DATA_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
452/** Read data alias. */
453#define IEM_ACCESS_DATA_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_DATA)
454/** Instruction fetch alias. */
455#define IEM_ACCESS_INSTRUCTION (IEM_ACCESS_TYPE_EXEC | IEM_ACCESS_WHAT_CODE)
456/** Stack write alias. */
457#define IEM_ACCESS_STACK_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
458/** Stack read alias. */
459#define IEM_ACCESS_STACK_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_STACK)
460/** Stack read+write alias. */
461#define IEM_ACCESS_STACK_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
462/** Read system table alias. */
463#define IEM_ACCESS_SYS_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_SYS)
464/** Read+write system table alias. */
465#define IEM_ACCESS_SYS_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_SYS)
466/** @} */
467
468/** @name Prefix constants (IEMCPU::fPrefixes)
469 * @{ */
470#define IEM_OP_PRF_SEG_CS RT_BIT_32(0) /**< CS segment prefix (0x2e). */
471#define IEM_OP_PRF_SEG_SS RT_BIT_32(1) /**< SS segment prefix (0x36). */
472#define IEM_OP_PRF_SEG_DS RT_BIT_32(2) /**< DS segment prefix (0x3e). */
473#define IEM_OP_PRF_SEG_ES RT_BIT_32(3) /**< ES segment prefix (0x26). */
474#define IEM_OP_PRF_SEG_FS RT_BIT_32(4) /**< FS segment prefix (0x64). */
475#define IEM_OP_PRF_SEG_GS RT_BIT_32(5) /**< GS segment prefix (0x65). */
476#define IEM_OP_PRF_SEG_MASK UINT32_C(0x3f)
477
478#define IEM_OP_PRF_SIZE_OP RT_BIT_32(8) /**< Operand size prefix (0x66). */
479#define IEM_OP_PRF_SIZE_REX_W RT_BIT_32(9) /**< REX.W prefix (0x48-0x4f). */
480#define IEM_OP_PRF_SIZE_ADDR RT_BIT_32(10) /**< Address size prefix (0x67). */
481
482#define IEM_OP_PRF_LOCK RT_BIT_32(16) /**< Lock prefix (0xf0). */
483#define IEM_OP_PRF_REPNZ RT_BIT_32(17) /**< Repeat-not-zero prefix (0xf2). */
484#define IEM_OP_PRF_REPZ RT_BIT_32(18) /**< Repeat-if-zero prefix (0xf3). */
485
486#define IEM_OP_PRF_REX RT_BIT_32(24) /**< Any REX prefix (0x40-0x4f). */
487#define IEM_OP_PRF_REX_R RT_BIT_32(25) /**< REX.R prefix (0x44,0x45,0x46,0x47,0x4c,0x4d,0x4e,0x4f). */
488#define IEM_OP_PRF_REX_B RT_BIT_32(26) /**< REX.B prefix (0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f). */
489#define IEM_OP_PRF_REX_X RT_BIT_32(27) /**< REX.X prefix (0x42,0x43,0x46,0x47,0x4a,0x4b,0x4e,0x4f). */
490/** @} */
491
492/**
493 * Tests if verification mode is enabled.
494 *
495 * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
496 * should therefore cause the compiler to eliminate the verification branch
497 * of an if statement. */
498#ifdef IEM_VERIFICATION_MODE_FULL
499# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem)
500#elif defined(IEM_VERIFICATION_MODE_MINIMAL)
501# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (true)
502#else
503# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (false)
504#endif
505
506/**
507 * Tests if full verification mode is enabled.
508 *
509 * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
510 * should therefore cause the compiler to eliminate the verification branch
511 * of an if statement. */
512#ifdef IEM_VERIFICATION_MODE_FULL
513# define IEM_FULL_VERIFICATION_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem)
514#else
515# define IEM_FULL_VERIFICATION_ENABLED(a_pIemCpu) (false)
516#endif
517
518/** @def IEM_VERIFICATION_MODE
519 * Indicates that one of the verfication modes are enabled.
520 */
521#if (defined(IEM_VERIFICATION_MODE_FULL) || defined(IEM_VERIFICATION_MODE_MINIMAL)) && !defined(IEM_VERIFICATION_MODE)
522# define IEM_VERIFICATION_MODE
523#endif
524
525/**
526 * Indicates to the verifier that the given flag set is undefined.
527 *
528 * Can be invoked again to add more flags.
529 *
530 * This is a NOOP if the verifier isn't compiled in.
531 */
532#ifdef IEM_VERIFICATION_MODE_FULL
533# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { pIemCpu->fUndefinedEFlags |= (a_fEfl); } while (0)
534#else
535# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { } while (0)
536#endif
537
538
539/** @def IEM_DECL_IMPL_TYPE
540 * For typedef'ing an instruction implementation function.
541 *
542 * @param a_RetType The return type.
543 * @param a_Name The name of the type.
544 * @param a_ArgList The argument list enclosed in parentheses.
545 */
546
547/** @def IEM_DECL_IMPL_DEF
548 * For defining an instruction implementation function.
549 *
550 * @param a_RetType The return type.
551 * @param a_Name The name of the type.
552 * @param a_ArgList The argument list enclosed in parentheses.
553 */
554
555#if defined(__GNUC__) && defined(RT_ARCH_X86)
556# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
557 __attribute__((__fastcall__)) a_RetType (a_Name) a_ArgList
558# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
559 __attribute__((__fastcall__, __nothrow__)) a_RetType a_Name a_ArgList
560
561#elif defined(_MSC_VER) && defined(RT_ARCH_X86)
562# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
563 a_RetType (__fastcall a_Name) a_ArgList
564# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
565 a_RetType __fastcall a_Name a_ArgList
566
567#else
568# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
569 a_RetType (VBOXCALL a_Name) a_ArgList
570# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
571 a_RetType VBOXCALL a_Name a_ArgList
572
573#endif
574
575/** @name Arithmetic assignment operations on bytes (binary).
576 * @{ */
577typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU8, (uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags));
578typedef FNIEMAIMPLBINU8 *PFNIEMAIMPLBINU8;
579FNIEMAIMPLBINU8 iemAImpl_add_u8, iemAImpl_add_u8_locked;
580FNIEMAIMPLBINU8 iemAImpl_adc_u8, iemAImpl_adc_u8_locked;
581FNIEMAIMPLBINU8 iemAImpl_sub_u8, iemAImpl_sub_u8_locked;
582FNIEMAIMPLBINU8 iemAImpl_sbb_u8, iemAImpl_sbb_u8_locked;
583FNIEMAIMPLBINU8 iemAImpl_or_u8, iemAImpl_or_u8_locked;
584FNIEMAIMPLBINU8 iemAImpl_xor_u8, iemAImpl_xor_u8_locked;
585FNIEMAIMPLBINU8 iemAImpl_and_u8, iemAImpl_and_u8_locked;
586/** @} */
587
588/** @name Arithmetic assignment operations on words (binary).
589 * @{ */
590typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU16, (uint16_t *pu16Dst, uint16_t u16Src, uint32_t *pEFlags));
591typedef FNIEMAIMPLBINU16 *PFNIEMAIMPLBINU16;
592FNIEMAIMPLBINU16 iemAImpl_add_u16, iemAImpl_add_u16_locked;
593FNIEMAIMPLBINU16 iemAImpl_adc_u16, iemAImpl_adc_u16_locked;
594FNIEMAIMPLBINU16 iemAImpl_sub_u16, iemAImpl_sub_u16_locked;
595FNIEMAIMPLBINU16 iemAImpl_sbb_u16, iemAImpl_sbb_u16_locked;
596FNIEMAIMPLBINU16 iemAImpl_or_u16, iemAImpl_or_u16_locked;
597FNIEMAIMPLBINU16 iemAImpl_xor_u16, iemAImpl_xor_u16_locked;
598FNIEMAIMPLBINU16 iemAImpl_and_u16, iemAImpl_and_u16_locked;
599/** @} */
600
601/** @name Arithmetic assignment operations on double words (binary).
602 * @{ */
603typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU32, (uint32_t *pu32Dst, uint32_t u32Src, uint32_t *pEFlags));
604typedef FNIEMAIMPLBINU32 *PFNIEMAIMPLBINU32;
605FNIEMAIMPLBINU32 iemAImpl_add_u32, iemAImpl_add_u32_locked;
606FNIEMAIMPLBINU32 iemAImpl_adc_u32, iemAImpl_adc_u32_locked;
607FNIEMAIMPLBINU32 iemAImpl_sub_u32, iemAImpl_sub_u32_locked;
608FNIEMAIMPLBINU32 iemAImpl_sbb_u32, iemAImpl_sbb_u32_locked;
609FNIEMAIMPLBINU32 iemAImpl_or_u32, iemAImpl_or_u32_locked;
610FNIEMAIMPLBINU32 iemAImpl_xor_u32, iemAImpl_xor_u32_locked;
611FNIEMAIMPLBINU32 iemAImpl_and_u32, iemAImpl_and_u32_locked;
612/** @} */
613
614/** @name Arithmetic assignment operations on quad words (binary).
615 * @{ */
616typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU64, (uint64_t *pu64Dst, uint64_t u64Src, uint32_t *pEFlags));
617typedef FNIEMAIMPLBINU64 *PFNIEMAIMPLBINU64;
618FNIEMAIMPLBINU64 iemAImpl_add_u64, iemAImpl_add_u64_locked;
619FNIEMAIMPLBINU64 iemAImpl_adc_u64, iemAImpl_adc_u64_locked;
620FNIEMAIMPLBINU64 iemAImpl_sub_u64, iemAImpl_sub_u64_locked;
621FNIEMAIMPLBINU64 iemAImpl_sbb_u64, iemAImpl_sbb_u64_locked;
622FNIEMAIMPLBINU64 iemAImpl_or_u64, iemAImpl_or_u64_locked;
623FNIEMAIMPLBINU64 iemAImpl_xor_u64, iemAImpl_xor_u64_locked;
624FNIEMAIMPLBINU64 iemAImpl_and_u64, iemAImpl_and_u64_locked;
625/** @} */
626
627/** @name Compare operations (thrown in with the binary ops).
628 * @{ */
629FNIEMAIMPLBINU8 iemAImpl_cmp_u8;
630FNIEMAIMPLBINU16 iemAImpl_cmp_u16;
631FNIEMAIMPLBINU32 iemAImpl_cmp_u32;
632FNIEMAIMPLBINU64 iemAImpl_cmp_u64;
633/** @} */
634
635/** @name Test operations (thrown in with the binary ops).
636 * @{ */
637FNIEMAIMPLBINU8 iemAImpl_test_u8;
638FNIEMAIMPLBINU16 iemAImpl_test_u16;
639FNIEMAIMPLBINU32 iemAImpl_test_u32;
640FNIEMAIMPLBINU64 iemAImpl_test_u64;
641/** @} */
642
643/** @name Bit operations operations (thrown in with the binary ops).
644 * @{ */
645FNIEMAIMPLBINU16 iemAImpl_bt_u16, iemAImpl_bt_u16_locked;
646FNIEMAIMPLBINU32 iemAImpl_bt_u32, iemAImpl_bt_u32_locked;
647FNIEMAIMPLBINU64 iemAImpl_bt_u64, iemAImpl_bt_u64_locked;
648FNIEMAIMPLBINU16 iemAImpl_btc_u16, iemAImpl_btc_u16_locked;
649FNIEMAIMPLBINU32 iemAImpl_btc_u32, iemAImpl_btc_u32_locked;
650FNIEMAIMPLBINU64 iemAImpl_btc_u64, iemAImpl_btc_u64_locked;
651FNIEMAIMPLBINU16 iemAImpl_btr_u16, iemAImpl_btr_u16_locked;
652FNIEMAIMPLBINU32 iemAImpl_btr_u32, iemAImpl_btr_u32_locked;
653FNIEMAIMPLBINU64 iemAImpl_btr_u64, iemAImpl_btr_u64_locked;
654FNIEMAIMPLBINU16 iemAImpl_bts_u16, iemAImpl_bts_u16_locked;
655FNIEMAIMPLBINU32 iemAImpl_bts_u32, iemAImpl_bts_u32_locked;
656FNIEMAIMPLBINU64 iemAImpl_bts_u64, iemAImpl_bts_u64_locked;
657/** @} */
658
659/** @name Exchange memory with register operations.
660 * @{ */
661IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u8, (uint8_t *pu8Mem, uint8_t *pu8Reg));
662IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u16,(uint16_t *pu16Mem, uint16_t *pu16Reg));
663IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u32,(uint32_t *pu32Mem, uint32_t *pu32Reg));
664IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u64,(uint64_t *pu64Mem, uint64_t *pu64Reg));
665/** @} */
666
667/** @name Exchange and add operations.
668 * @{ */
669IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
670IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
671IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
672IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
673IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8_locked, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
674IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16_locked,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
675IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32_locked,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
676IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
677/** @} */
678
679/** @name Compare and exchange.
680 * @{ */
681IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u8, (uint8_t *pu8Dst, uint8_t *puAl, uint8_t uSrcReg, uint32_t *pEFlags));
682IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u8_locked, (uint8_t *pu8Dst, uint8_t *puAl, uint8_t uSrcReg, uint32_t *pEFlags));
683IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u16, (uint16_t *pu16Dst, uint16_t *puAx, uint16_t uSrcReg, uint32_t *pEFlags));
684IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u16_locked,(uint16_t *pu16Dst, uint16_t *puAx, uint16_t uSrcReg, uint32_t *pEFlags));
685IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u32, (uint32_t *pu32Dst, uint32_t *puEax, uint32_t uSrcReg, uint32_t *pEFlags));
686IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u32_locked,(uint32_t *pu32Dst, uint32_t *puEax, uint32_t uSrcReg, uint32_t *pEFlags));
687#ifdef RT_ARCH_X86
688IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64, (uint64_t *pu64Dst, uint64_t *puRax, uint64_t *puSrcReg, uint32_t *pEFlags));
689IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64_locked,(uint64_t *pu64Dst, uint64_t *puRax, uint64_t *puSrcReg, uint32_t *pEFlags));
690#else
691IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64, (uint64_t *pu64Dst, uint64_t *puRax, uint64_t uSrcReg, uint32_t *pEFlags));
692IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64_locked,(uint64_t *pu64Dst, uint64_t *puRax, uint64_t uSrcReg, uint32_t *pEFlags));
693#endif
694IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg8b,(uint64_t *pu64Dst, PRTUINT64U pu64EaxEdx, PRTUINT64U pu64EbxEcx,
695 uint32_t *pEFlags));
696IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg8b_locked,(uint64_t *pu64Dst, PRTUINT64U pu64EaxEdx, PRTUINT64U pu64EbxEcx,
697 uint32_t *pEFlags));
698IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b,(PRTUINT128U *pu128Dst, PRTUINT128U pu64RaxRdx, PRTUINT128U pu64RbxRcx,
699 uint32_t *pEFlags));
700IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b_locked,(PRTUINT128U *pu128Dst, PRTUINT128U pu64RaxRdx, PRTUINT128U pu64RbxRcx,
701 uint32_t *pEFlags));
702/** @} */
703
704/** @name Memory ordering
705 * @{ */
706typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEMFENCE,(void));
707typedef FNIEMAIMPLMEMFENCE *PFNIEMAIMPLMEMFENCE;
708IEM_DECL_IMPL_DEF(void, iemAImpl_mfence,(void));
709IEM_DECL_IMPL_DEF(void, iemAImpl_sfence,(void));
710IEM_DECL_IMPL_DEF(void, iemAImpl_lfence,(void));
711IEM_DECL_IMPL_DEF(void, iemAImpl_alt_mem_fence,(void));
712/** @} */
713
714/** @name Double precision shifts
715 * @{ */
716typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU16,(uint16_t *pu16Dst, uint16_t u16Src, uint8_t cShift, uint32_t *pEFlags));
717typedef FNIEMAIMPLSHIFTDBLU16 *PFNIEMAIMPLSHIFTDBLU16;
718typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU32,(uint32_t *pu32Dst, uint32_t u32Src, uint8_t cShift, uint32_t *pEFlags));
719typedef FNIEMAIMPLSHIFTDBLU32 *PFNIEMAIMPLSHIFTDBLU32;
720typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU64,(uint64_t *pu64Dst, uint64_t u64Src, uint8_t cShift, uint32_t *pEFlags));
721typedef FNIEMAIMPLSHIFTDBLU64 *PFNIEMAIMPLSHIFTDBLU64;
722FNIEMAIMPLSHIFTDBLU16 iemAImpl_shld_u16;
723FNIEMAIMPLSHIFTDBLU32 iemAImpl_shld_u32;
724FNIEMAIMPLSHIFTDBLU64 iemAImpl_shld_u64;
725FNIEMAIMPLSHIFTDBLU16 iemAImpl_shrd_u16;
726FNIEMAIMPLSHIFTDBLU32 iemAImpl_shrd_u32;
727FNIEMAIMPLSHIFTDBLU64 iemAImpl_shrd_u64;
728/** @} */
729
730
731/** @name Bit search operations (thrown in with the binary ops).
732 * @{ */
733FNIEMAIMPLBINU16 iemAImpl_bsf_u16;
734FNIEMAIMPLBINU32 iemAImpl_bsf_u32;
735FNIEMAIMPLBINU64 iemAImpl_bsf_u64;
736FNIEMAIMPLBINU16 iemAImpl_bsr_u16;
737FNIEMAIMPLBINU32 iemAImpl_bsr_u32;
738FNIEMAIMPLBINU64 iemAImpl_bsr_u64;
739/** @} */
740
741/** @name Signed multiplication operations (thrown in with the binary ops).
742 * @{ */
743FNIEMAIMPLBINU16 iemAImpl_imul_two_u16;
744FNIEMAIMPLBINU32 iemAImpl_imul_two_u32;
745FNIEMAIMPLBINU64 iemAImpl_imul_two_u64;
746/** @} */
747
748/** @name Arithmetic assignment operations on bytes (unary).
749 * @{ */
750typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU8, (uint8_t *pu8Dst, uint32_t *pEFlags));
751typedef FNIEMAIMPLUNARYU8 *PFNIEMAIMPLUNARYU8;
752FNIEMAIMPLUNARYU8 iemAImpl_inc_u8, iemAImpl_inc_u8_locked;
753FNIEMAIMPLUNARYU8 iemAImpl_dec_u8, iemAImpl_dec_u8_locked;
754FNIEMAIMPLUNARYU8 iemAImpl_not_u8, iemAImpl_not_u8_locked;
755FNIEMAIMPLUNARYU8 iemAImpl_neg_u8, iemAImpl_neg_u8_locked;
756/** @} */
757
758/** @name Arithmetic assignment operations on words (unary).
759 * @{ */
760typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU16, (uint16_t *pu16Dst, uint32_t *pEFlags));
761typedef FNIEMAIMPLUNARYU16 *PFNIEMAIMPLUNARYU16;
762FNIEMAIMPLUNARYU16 iemAImpl_inc_u16, iemAImpl_inc_u16_locked;
763FNIEMAIMPLUNARYU16 iemAImpl_dec_u16, iemAImpl_dec_u16_locked;
764FNIEMAIMPLUNARYU16 iemAImpl_not_u16, iemAImpl_not_u16_locked;
765FNIEMAIMPLUNARYU16 iemAImpl_neg_u16, iemAImpl_neg_u16_locked;
766/** @} */
767
768/** @name Arithmetic assignment operations on double words (unary).
769 * @{ */
770typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU32, (uint32_t *pu32Dst, uint32_t *pEFlags));
771typedef FNIEMAIMPLUNARYU32 *PFNIEMAIMPLUNARYU32;
772FNIEMAIMPLUNARYU32 iemAImpl_inc_u32, iemAImpl_inc_u32_locked;
773FNIEMAIMPLUNARYU32 iemAImpl_dec_u32, iemAImpl_dec_u32_locked;
774FNIEMAIMPLUNARYU32 iemAImpl_not_u32, iemAImpl_not_u32_locked;
775FNIEMAIMPLUNARYU32 iemAImpl_neg_u32, iemAImpl_neg_u32_locked;
776/** @} */
777
778/** @name Arithmetic assignment operations on quad words (unary).
779 * @{ */
780typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU64, (uint64_t *pu64Dst, uint32_t *pEFlags));
781typedef FNIEMAIMPLUNARYU64 *PFNIEMAIMPLUNARYU64;
782FNIEMAIMPLUNARYU64 iemAImpl_inc_u64, iemAImpl_inc_u64_locked;
783FNIEMAIMPLUNARYU64 iemAImpl_dec_u64, iemAImpl_dec_u64_locked;
784FNIEMAIMPLUNARYU64 iemAImpl_not_u64, iemAImpl_not_u64_locked;
785FNIEMAIMPLUNARYU64 iemAImpl_neg_u64, iemAImpl_neg_u64_locked;
786/** @} */
787
788
789/** @name Shift operations on bytes (Group 2).
790 * @{ */
791typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU8,(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags));
792typedef FNIEMAIMPLSHIFTU8 *PFNIEMAIMPLSHIFTU8;
793FNIEMAIMPLSHIFTU8 iemAImpl_rol_u8;
794FNIEMAIMPLSHIFTU8 iemAImpl_ror_u8;
795FNIEMAIMPLSHIFTU8 iemAImpl_rcl_u8;
796FNIEMAIMPLSHIFTU8 iemAImpl_rcr_u8;
797FNIEMAIMPLSHIFTU8 iemAImpl_shl_u8;
798FNIEMAIMPLSHIFTU8 iemAImpl_shr_u8;
799FNIEMAIMPLSHIFTU8 iemAImpl_sar_u8;
800/** @} */
801
802/** @name Shift operations on words (Group 2).
803 * @{ */
804typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU16,(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags));
805typedef FNIEMAIMPLSHIFTU16 *PFNIEMAIMPLSHIFTU16;
806FNIEMAIMPLSHIFTU16 iemAImpl_rol_u16;
807FNIEMAIMPLSHIFTU16 iemAImpl_ror_u16;
808FNIEMAIMPLSHIFTU16 iemAImpl_rcl_u16;
809FNIEMAIMPLSHIFTU16 iemAImpl_rcr_u16;
810FNIEMAIMPLSHIFTU16 iemAImpl_shl_u16;
811FNIEMAIMPLSHIFTU16 iemAImpl_shr_u16;
812FNIEMAIMPLSHIFTU16 iemAImpl_sar_u16;
813/** @} */
814
815/** @name Shift operations on double words (Group 2).
816 * @{ */
817typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU32,(uint32_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags));
818typedef FNIEMAIMPLSHIFTU32 *PFNIEMAIMPLSHIFTU32;
819FNIEMAIMPLSHIFTU32 iemAImpl_rol_u32;
820FNIEMAIMPLSHIFTU32 iemAImpl_ror_u32;
821FNIEMAIMPLSHIFTU32 iemAImpl_rcl_u32;
822FNIEMAIMPLSHIFTU32 iemAImpl_rcr_u32;
823FNIEMAIMPLSHIFTU32 iemAImpl_shl_u32;
824FNIEMAIMPLSHIFTU32 iemAImpl_shr_u32;
825FNIEMAIMPLSHIFTU32 iemAImpl_sar_u32;
826/** @} */
827
828/** @name Shift operations on words (Group 2).
829 * @{ */
830typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU64,(uint64_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags));
831typedef FNIEMAIMPLSHIFTU64 *PFNIEMAIMPLSHIFTU64;
832FNIEMAIMPLSHIFTU64 iemAImpl_rol_u64;
833FNIEMAIMPLSHIFTU64 iemAImpl_ror_u64;
834FNIEMAIMPLSHIFTU64 iemAImpl_rcl_u64;
835FNIEMAIMPLSHIFTU64 iemAImpl_rcr_u64;
836FNIEMAIMPLSHIFTU64 iemAImpl_shl_u64;
837FNIEMAIMPLSHIFTU64 iemAImpl_shr_u64;
838FNIEMAIMPLSHIFTU64 iemAImpl_sar_u64;
839/** @} */
840
841/** @name Multiplication and division operations.
842 * @{ */
843typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t *pEFlags));
844typedef FNIEMAIMPLMULDIVU8 *PFNIEMAIMPLMULDIVU8;
845FNIEMAIMPLMULDIVU8 iemAImpl_mul_u8, iemAImpl_imul_u8;
846FNIEMAIMPLMULDIVU8 iemAImpl_div_u8, iemAImpl_idiv_u8;
847
848typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t *pEFlags));
849typedef FNIEMAIMPLMULDIVU16 *PFNIEMAIMPLMULDIVU16;
850FNIEMAIMPLMULDIVU16 iemAImpl_mul_u16, iemAImpl_imul_u16;
851FNIEMAIMPLMULDIVU16 iemAImpl_div_u16, iemAImpl_idiv_u16;
852
853typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t *pEFlags));
854typedef FNIEMAIMPLMULDIVU32 *PFNIEMAIMPLMULDIVU32;
855FNIEMAIMPLMULDIVU32 iemAImpl_mul_u32, iemAImpl_imul_u32;
856FNIEMAIMPLMULDIVU32 iemAImpl_div_u32, iemAImpl_idiv_u32;
857
858typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t *pEFlags));
859typedef FNIEMAIMPLMULDIVU64 *PFNIEMAIMPLMULDIVU64;
860FNIEMAIMPLMULDIVU64 iemAImpl_mul_u64, iemAImpl_imul_u64;
861FNIEMAIMPLMULDIVU64 iemAImpl_div_u64, iemAImpl_idiv_u64;
862/** @} */
863
864/** @name Byte Swap.
865 * @{ */
866IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u16,(uint32_t *pu32Dst)); /* Yes, 32-bit register access. */
867IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u32,(uint32_t *pu32Dst));
868IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u64,(uint64_t *pu64Dst));
869/** @} */
870
871
872/** @name FPU operations taking a 32-bit float argument
873 * @{ */
874typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
875 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
876typedef FNIEMAIMPLFPUR32FSW *PFNIEMAIMPLFPUR32FSW;
877
878typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
879 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
880typedef FNIEMAIMPLFPUR32 *PFNIEMAIMPLFPUR32;
881
882FNIEMAIMPLFPUR32FSW iemAImpl_fcom_r80_by_r32;
883FNIEMAIMPLFPUR32 iemAImpl_fadd_r80_by_r32;
884FNIEMAIMPLFPUR32 iemAImpl_fmul_r80_by_r32;
885FNIEMAIMPLFPUR32 iemAImpl_fsub_r80_by_r32;
886FNIEMAIMPLFPUR32 iemAImpl_fsubr_r80_by_r32;
887FNIEMAIMPLFPUR32 iemAImpl_fdiv_r80_by_r32;
888FNIEMAIMPLFPUR32 iemAImpl_fdivr_r80_by_r32;
889
890IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r32_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT32U pr32Val));
891IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
892 PRTFLOAT32U pr32Val, PCRTFLOAT80U pr80Val));
893/** @} */
894
895/** @name FPU operations taking a 64-bit float argument
896 * @{ */
897typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
898 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
899typedef FNIEMAIMPLFPUR64 *PFNIEMAIMPLFPUR64;
900
901FNIEMAIMPLFPUR64 iemAImpl_fadd_r80_by_r64;
902FNIEMAIMPLFPUR64 iemAImpl_fmul_r80_by_r64;
903FNIEMAIMPLFPUR64 iemAImpl_fsub_r80_by_r64;
904FNIEMAIMPLFPUR64 iemAImpl_fsubr_r80_by_r64;
905FNIEMAIMPLFPUR64 iemAImpl_fdiv_r80_by_r64;
906FNIEMAIMPLFPUR64 iemAImpl_fdivr_r80_by_r64;
907
908IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r64,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
909 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
910IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r64_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val));
911IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
912 PRTFLOAT64U pr32Val, PCRTFLOAT80U pr80Val));
913/** @} */
914
915/** @name FPU operations taking a 80-bit float argument
916 * @{ */
917typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
918 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
919typedef FNIEMAIMPLFPUR80 *PFNIEMAIMPLFPUR80;
920FNIEMAIMPLFPUR80 iemAImpl_fadd_r80_by_r80;
921FNIEMAIMPLFPUR80 iemAImpl_fmul_r80_by_r80;
922FNIEMAIMPLFPUR80 iemAImpl_fsub_r80_by_r80;
923FNIEMAIMPLFPUR80 iemAImpl_fsubr_r80_by_r80;
924FNIEMAIMPLFPUR80 iemAImpl_fdiv_r80_by_r80;
925FNIEMAIMPLFPUR80 iemAImpl_fdivr_r80_by_r80;
926FNIEMAIMPLFPUR80 iemAImpl_fprem_r80_by_r80;
927FNIEMAIMPLFPUR80 iemAImpl_fprem1_r80_by_r80;
928FNIEMAIMPLFPUR80 iemAImpl_fscale_r80_by_r80;
929
930FNIEMAIMPLFPUR80 iemAImpl_fpatan_r80_by_r80;
931FNIEMAIMPLFPUR80 iemAImpl_fyl2xp1_r80_by_r80;
932
933typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
934 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
935typedef FNIEMAIMPLFPUR80FSW *PFNIEMAIMPLFPUR80FSW;
936FNIEMAIMPLFPUR80FSW iemAImpl_fcom_r80_by_r80;
937FNIEMAIMPLFPUR80FSW iemAImpl_fucom_r80_by_r80;
938
939typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLFPUR80EFL,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
940 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
941typedef FNIEMAIMPLFPUR80EFL *PFNIEMAIMPLFPUR80EFL;
942FNIEMAIMPLFPUR80EFL iemAImpl_fcomi_r80_by_r80;
943FNIEMAIMPLFPUR80EFL iemAImpl_fucomi_r80_by_r80;
944
945typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARY,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
946typedef FNIEMAIMPLFPUR80UNARY *PFNIEMAIMPLFPUR80UNARY;
947FNIEMAIMPLFPUR80UNARY iemAImpl_fabs_r80;
948FNIEMAIMPLFPUR80UNARY iemAImpl_fchs_r80;
949FNIEMAIMPLFPUR80UNARY iemAImpl_f2xm1_r80;
950FNIEMAIMPLFPUR80UNARY iemAImpl_fyl2x_r80;
951FNIEMAIMPLFPUR80UNARY iemAImpl_fsqrt_r80;
952FNIEMAIMPLFPUR80UNARY iemAImpl_frndint_r80;
953FNIEMAIMPLFPUR80UNARY iemAImpl_fsin_r80;
954FNIEMAIMPLFPUR80UNARY iemAImpl_fcos_r80;
955
956typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARYFSW,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, PCRTFLOAT80U pr80Val));
957typedef FNIEMAIMPLFPUR80UNARYFSW *PFNIEMAIMPLFPUR80UNARYFSW;
958FNIEMAIMPLFPUR80UNARYFSW iemAImpl_ftst_r80;
959FNIEMAIMPLFPUR80UNARYFSW iemAImpl_fxam_r80;
960
961typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80LDCONST,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes));
962typedef FNIEMAIMPLFPUR80LDCONST *PFNIEMAIMPLFPUR80LDCONST;
963FNIEMAIMPLFPUR80LDCONST iemAImpl_fld1;
964FNIEMAIMPLFPUR80LDCONST iemAImpl_fldl2t;
965FNIEMAIMPLFPUR80LDCONST iemAImpl_fldl2e;
966FNIEMAIMPLFPUR80LDCONST iemAImpl_fldpi;
967FNIEMAIMPLFPUR80LDCONST iemAImpl_fldlg2;
968FNIEMAIMPLFPUR80LDCONST iemAImpl_fldln2;
969FNIEMAIMPLFPUR80LDCONST iemAImpl_fldz;
970
971typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARYTWO,(PCX86FXSTATE pFpuState, PIEMFPURESULTTWO pFpuResTwo,
972 PCRTFLOAT80U pr80Val));
973typedef FNIEMAIMPLFPUR80UNARYTWO *PFNIEMAIMPLFPUR80UNARYTWO;
974FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fptan_r80_r80;
975FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fxtract_r80_r80;
976FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fsincos_r80_r80;
977
978IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r80_from_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
979IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r80,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
980 PRTFLOAT80U pr80Dst, PCRTFLOAT80U pr80Src));
981
982/** @} */
983
984/** @name FPU operations taking a 16-bit signed integer argument
985 * @{ */
986typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI16,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
987 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2));
988typedef FNIEMAIMPLFPUI16 *PFNIEMAIMPLFPUI16;
989
990FNIEMAIMPLFPUI16 iemAImpl_fiadd_r80_by_i16;
991FNIEMAIMPLFPUI16 iemAImpl_fimul_r80_by_i16;
992FNIEMAIMPLFPUI16 iemAImpl_fisub_r80_by_i16;
993FNIEMAIMPLFPUI16 iemAImpl_fisubr_r80_by_i16;
994FNIEMAIMPLFPUI16 iemAImpl_fidiv_r80_by_i16;
995FNIEMAIMPLFPUI16 iemAImpl_fidivr_r80_by_i16;
996
997IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
998 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2));
999
1000IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i16_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int16_t const *pi16Val));
1001IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1002 int16_t *pi16Val, PCRTFLOAT80U pr80Val));
1003IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1004 int16_t *pi16Val, PCRTFLOAT80U pr80Val));
1005/** @} */
1006
1007/** @name FPU operations taking a 32-bit signed integer argument
1008 * @{ */
1009typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1010 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2));
1011typedef FNIEMAIMPLFPUI32 *PFNIEMAIMPLFPUI32;
1012
1013FNIEMAIMPLFPUI32 iemAImpl_fiadd_r80_by_i32;
1014FNIEMAIMPLFPUI32 iemAImpl_fimul_r80_by_i32;
1015FNIEMAIMPLFPUI32 iemAImpl_fisub_r80_by_i32;
1016FNIEMAIMPLFPUI32 iemAImpl_fisubr_r80_by_i32;
1017FNIEMAIMPLFPUI32 iemAImpl_fidiv_r80_by_i32;
1018FNIEMAIMPLFPUI32 iemAImpl_fidivr_r80_by_i32;
1019
1020IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1021 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2));
1022
1023IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i32_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int32_t const *pi32Val));
1024IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1025 int32_t *pi32Val, PCRTFLOAT80U pr80Val));
1026IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1027 int32_t *pi32Val, PCRTFLOAT80U pr80Val));
1028/** @} */
1029
1030/** @name FPU operations taking a 64-bit signed integer argument
1031 * @{ */
1032typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1033 PCRTFLOAT80U pr80Val1, int64_t const *pi64Val2));
1034typedef FNIEMAIMPLFPUI64 *PFNIEMAIMPLFPUI64;
1035
1036FNIEMAIMPLFPUI64 iemAImpl_fiadd_r80_by_i64;
1037FNIEMAIMPLFPUI64 iemAImpl_fimul_r80_by_i64;
1038FNIEMAIMPLFPUI64 iemAImpl_fisub_r80_by_i64;
1039FNIEMAIMPLFPUI64 iemAImpl_fisubr_r80_by_i64;
1040FNIEMAIMPLFPUI64 iemAImpl_fidiv_r80_by_i64;
1041FNIEMAIMPLFPUI64 iemAImpl_fidivr_r80_by_i64;
1042
1043IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1044 PCRTFLOAT80U pr80Val1, int64_t const *pi64Val2));
1045
1046IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i64_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int64_t const *pi64Val));
1047IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1048 int64_t *pi64Val, PCRTFLOAT80U pr80Val));
1049IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1050 int64_t *pi32Val, PCRTFLOAT80U pr80Val));
1051/** @} */
1052
1053
1054/** @name Function tables.
1055 * @{
1056 */
1057
1058/**
1059 * Function table for a binary operator providing implementation based on
1060 * operand size.
1061 */
1062typedef struct IEMOPBINSIZES
1063{
1064 PFNIEMAIMPLBINU8 pfnNormalU8, pfnLockedU8;
1065 PFNIEMAIMPLBINU16 pfnNormalU16, pfnLockedU16;
1066 PFNIEMAIMPLBINU32 pfnNormalU32, pfnLockedU32;
1067 PFNIEMAIMPLBINU64 pfnNormalU64, pfnLockedU64;
1068} IEMOPBINSIZES;
1069/** Pointer to a binary operator function table. */
1070typedef IEMOPBINSIZES const *PCIEMOPBINSIZES;
1071
1072
1073/**
1074 * Function table for a unary operator providing implementation based on
1075 * operand size.
1076 */
1077typedef struct IEMOPUNARYSIZES
1078{
1079 PFNIEMAIMPLUNARYU8 pfnNormalU8, pfnLockedU8;
1080 PFNIEMAIMPLUNARYU16 pfnNormalU16, pfnLockedU16;
1081 PFNIEMAIMPLUNARYU32 pfnNormalU32, pfnLockedU32;
1082 PFNIEMAIMPLUNARYU64 pfnNormalU64, pfnLockedU64;
1083} IEMOPUNARYSIZES;
1084/** Pointer to a unary operator function table. */
1085typedef IEMOPUNARYSIZES const *PCIEMOPUNARYSIZES;
1086
1087
1088/**
1089 * Function table for a shift operator providing implementation based on
1090 * operand size.
1091 */
1092typedef struct IEMOPSHIFTSIZES
1093{
1094 PFNIEMAIMPLSHIFTU8 pfnNormalU8;
1095 PFNIEMAIMPLSHIFTU16 pfnNormalU16;
1096 PFNIEMAIMPLSHIFTU32 pfnNormalU32;
1097 PFNIEMAIMPLSHIFTU64 pfnNormalU64;
1098} IEMOPSHIFTSIZES;
1099/** Pointer to a shift operator function table. */
1100typedef IEMOPSHIFTSIZES const *PCIEMOPSHIFTSIZES;
1101
1102
1103/**
1104 * Function table for a multiplication or division operation.
1105 */
1106typedef struct IEMOPMULDIVSIZES
1107{
1108 PFNIEMAIMPLMULDIVU8 pfnU8;
1109 PFNIEMAIMPLMULDIVU16 pfnU16;
1110 PFNIEMAIMPLMULDIVU32 pfnU32;
1111 PFNIEMAIMPLMULDIVU64 pfnU64;
1112} IEMOPMULDIVSIZES;
1113/** Pointer to a multiplication or division operation function table. */
1114typedef IEMOPMULDIVSIZES const *PCIEMOPMULDIVSIZES;
1115
1116
1117/**
1118 * Function table for a double precision shift operator providing implementation
1119 * based on operand size.
1120 */
1121typedef struct IEMOPSHIFTDBLSIZES
1122{
1123 PFNIEMAIMPLSHIFTDBLU16 pfnNormalU16;
1124 PFNIEMAIMPLSHIFTDBLU32 pfnNormalU32;
1125 PFNIEMAIMPLSHIFTDBLU64 pfnNormalU64;
1126} IEMOPSHIFTDBLSIZES;
1127/** Pointer to a double precision shift function table. */
1128typedef IEMOPSHIFTDBLSIZES const *PCIEMOPSHIFTDBLSIZES;
1129
1130
1131/** @} */
1132
1133
1134/** @name C instruction implementations for anything slightly complicated.
1135 * @{ */
1136
1137/**
1138 * For typedef'ing or declaring a C instruction implementation function taking
1139 * no extra arguments.
1140 *
1141 * @param a_Name The name of the type.
1142 */
1143# define IEM_CIMPL_DECL_TYPE_0(a_Name) \
1144 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr))
1145/**
1146 * For defining a C instruction implementation function taking no extra
1147 * arguments.
1148 *
1149 * @param a_Name The name of the function
1150 */
1151# define IEM_CIMPL_DEF_0(a_Name) \
1152 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr))
1153/**
1154 * For calling a C instruction implementation function taking no extra
1155 * arguments.
1156 *
1157 * This special call macro adds default arguments to the call and allow us to
1158 * change these later.
1159 *
1160 * @param a_fn The name of the function.
1161 */
1162# define IEM_CIMPL_CALL_0(a_fn) a_fn(pIemCpu, cbInstr)
1163
1164/**
1165 * For typedef'ing or declaring a C instruction implementation function taking
1166 * one extra argument.
1167 *
1168 * @param a_Name The name of the type.
1169 * @param a_Type0 The argument type.
1170 * @param a_Arg0 The argument name.
1171 */
1172# define IEM_CIMPL_DECL_TYPE_1(a_Name, a_Type0, a_Arg0) \
1173 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0))
1174/**
1175 * For defining a C instruction implementation function taking one extra
1176 * argument.
1177 *
1178 * @param a_Name The name of the function
1179 * @param a_Type0 The argument type.
1180 * @param a_Arg0 The argument name.
1181 */
1182# define IEM_CIMPL_DEF_1(a_Name, a_Type0, a_Arg0) \
1183 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0))
1184/**
1185 * For calling a C instruction implementation function taking one extra
1186 * argument.
1187 *
1188 * This special call macro adds default arguments to the call and allow us to
1189 * change these later.
1190 *
1191 * @param a_fn The name of the function.
1192 * @param a0 The name of the 1st argument.
1193 */
1194# define IEM_CIMPL_CALL_1(a_fn, a0) a_fn(pIemCpu, cbInstr, (a0))
1195
1196/**
1197 * For typedef'ing or declaring a C instruction implementation function taking
1198 * two extra arguments.
1199 *
1200 * @param a_Name The name of the type.
1201 * @param a_Type0 The type of the 1st argument
1202 * @param a_Arg0 The name of the 1st argument.
1203 * @param a_Type1 The type of the 2nd argument.
1204 * @param a_Arg1 The name of the 2nd argument.
1205 */
1206# define IEM_CIMPL_DECL_TYPE_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
1207 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
1208/**
1209 * For defining a C instruction implementation function taking two extra
1210 * arguments.
1211 *
1212 * @param a_Name The name of the function.
1213 * @param a_Type0 The type of the 1st argument
1214 * @param a_Arg0 The name of the 1st argument.
1215 * @param a_Type1 The type of the 2nd argument.
1216 * @param a_Arg1 The name of the 2nd argument.
1217 */
1218# define IEM_CIMPL_DEF_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
1219 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
1220/**
1221 * For calling a C instruction implementation function taking two extra
1222 * arguments.
1223 *
1224 * This special call macro adds default arguments to the call and allow us to
1225 * change these later.
1226 *
1227 * @param a_fn The name of the function.
1228 * @param a0 The name of the 1st argument.
1229 * @param a1 The name of the 2nd argument.
1230 */
1231# define IEM_CIMPL_CALL_2(a_fn, a0, a1) a_fn(pIemCpu, cbInstr, (a0), (a1))
1232
1233/**
1234 * For typedef'ing or declaring a C instruction implementation function taking
1235 * three extra arguments.
1236 *
1237 * @param a_Name The name of the type.
1238 * @param a_Type0 The type of the 1st argument
1239 * @param a_Arg0 The name of the 1st argument.
1240 * @param a_Type1 The type of the 2nd argument.
1241 * @param a_Arg1 The name of the 2nd argument.
1242 * @param a_Type2 The type of the 3rd argument.
1243 * @param a_Arg2 The name of the 3rd argument.
1244 */
1245# define IEM_CIMPL_DECL_TYPE_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
1246 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
1247/**
1248 * For defining a C instruction implementation function taking three extra
1249 * arguments.
1250 *
1251 * @param a_Name The name of the function.
1252 * @param a_Type0 The type of the 1st argument
1253 * @param a_Arg0 The name of the 1st argument.
1254 * @param a_Type1 The type of the 2nd argument.
1255 * @param a_Arg1 The name of the 2nd argument.
1256 * @param a_Type2 The type of the 3rd argument.
1257 * @param a_Arg2 The name of the 3rd argument.
1258 */
1259# define IEM_CIMPL_DEF_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
1260 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
1261/**
1262 * For calling a C instruction implementation function taking three extra
1263 * arguments.
1264 *
1265 * This special call macro adds default arguments to the call and allow us to
1266 * change these later.
1267 *
1268 * @param a_fn The name of the function.
1269 * @param a0 The name of the 1st argument.
1270 * @param a1 The name of the 2nd argument.
1271 * @param a2 The name of the 3rd argument.
1272 */
1273# define IEM_CIMPL_CALL_3(a_fn, a0, a1, a2) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2))
1274
1275
1276/**
1277 * For typedef'ing or declaring a C instruction implementation function taking
1278 * four extra arguments.
1279 *
1280 * @param a_Name The name of the type.
1281 * @param a_Type0 The type of the 1st argument
1282 * @param a_Arg0 The name of the 1st argument.
1283 * @param a_Type1 The type of the 2nd argument.
1284 * @param a_Arg1 The name of the 2nd argument.
1285 * @param a_Type2 The type of the 3rd argument.
1286 * @param a_Arg2 The name of the 3rd argument.
1287 * @param a_Type3 The type of the 4th argument.
1288 * @param a_Arg3 The name of the 4th argument.
1289 */
1290# define IEM_CIMPL_DECL_TYPE_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
1291 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
1292/**
1293 * For defining a C instruction implementation function taking four extra
1294 * arguments.
1295 *
1296 * @param a_Name The name of the function.
1297 * @param a_Type0 The type of the 1st argument
1298 * @param a_Arg0 The name of the 1st argument.
1299 * @param a_Type1 The type of the 2nd argument.
1300 * @param a_Arg1 The name of the 2nd argument.
1301 * @param a_Type2 The type of the 3rd argument.
1302 * @param a_Arg2 The name of the 3rd argument.
1303 * @param a_Type3 The type of the 4th argument.
1304 * @param a_Arg3 The name of the 4th argument.
1305 */
1306# define IEM_CIMPL_DEF_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
1307 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, \
1308 a_Type2 a_Arg2, a_Type3 a_Arg3))
1309/**
1310 * For calling a C instruction implementation function taking four extra
1311 * arguments.
1312 *
1313 * This special call macro adds default arguments to the call and allow us to
1314 * change these later.
1315 *
1316 * @param a_fn The name of the function.
1317 * @param a0 The name of the 1st argument.
1318 * @param a1 The name of the 2nd argument.
1319 * @param a2 The name of the 3rd argument.
1320 * @param a3 The name of the 4th argument.
1321 */
1322# define IEM_CIMPL_CALL_4(a_fn, a0, a1, a2, a3) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3))
1323
1324
1325/**
1326 * For typedef'ing or declaring a C instruction implementation function taking
1327 * five extra arguments.
1328 *
1329 * @param a_Name The name of the type.
1330 * @param a_Type0 The type of the 1st argument
1331 * @param a_Arg0 The name of the 1st argument.
1332 * @param a_Type1 The type of the 2nd argument.
1333 * @param a_Arg1 The name of the 2nd argument.
1334 * @param a_Type2 The type of the 3rd argument.
1335 * @param a_Arg2 The name of the 3rd argument.
1336 * @param a_Type3 The type of the 4th argument.
1337 * @param a_Arg3 The name of the 4th argument.
1338 * @param a_Type4 The type of the 5th argument.
1339 * @param a_Arg4 The name of the 5th argument.
1340 */
1341# define IEM_CIMPL_DECL_TYPE_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
1342 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
1343 a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
1344 a_Type3 a_Arg3, a_Type4 a_Arg4))
1345/**
1346 * For defining a C instruction implementation function taking five extra
1347 * arguments.
1348 *
1349 * @param a_Name The name of the function.
1350 * @param a_Type0 The type of the 1st argument
1351 * @param a_Arg0 The name of the 1st argument.
1352 * @param a_Type1 The type of the 2nd argument.
1353 * @param a_Arg1 The name of the 2nd argument.
1354 * @param a_Type2 The type of the 3rd argument.
1355 * @param a_Arg2 The name of the 3rd argument.
1356 * @param a_Type3 The type of the 4th argument.
1357 * @param a_Arg3 The name of the 4th argument.
1358 * @param a_Type4 The type of the 5th argument.
1359 * @param a_Arg4 The name of the 5th argument.
1360 */
1361# define IEM_CIMPL_DEF_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
1362 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
1363 a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
1364 a_Type3 a_Arg3, a_Type4 a_Arg4))
1365/**
1366 * For calling a C instruction implementation function taking five extra
1367 * arguments.
1368 *
1369 * This special call macro adds default arguments to the call and allow us to
1370 * change these later.
1371 *
1372 * @param a_fn The name of the function.
1373 * @param a0 The name of the 1st argument.
1374 * @param a1 The name of the 2nd argument.
1375 * @param a2 The name of the 3rd argument.
1376 * @param a3 The name of the 4th argument.
1377 * @param a4 The name of the 5th argument.
1378 */
1379# define IEM_CIMPL_CALL_5(a_fn, a0, a1, a2, a3, a4) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3), (a4))
1380
1381/** @} */
1382
1383
1384/** @} */
1385
1386RT_C_DECLS_END
1387
1388#endif
1389
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette