VirtualBox

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

Last change on this file since 47399 was 47399, checked in by vboxsync, 12 years ago

IEM: Packed Shuffle Stuff.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 61.3 KB
Line 
1/* $Id: IEMInternal.h 47399 2013-07-25 18:05:08Z 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/** Pointer to the const per-CPU IEM state. */
419typedef IEMCPU const *PCIEMCPU;
420
421/** Converts a IEMCPU pointer to a VMCPU pointer.
422 * @returns VMCPU pointer.
423 * @param a_pIemCpu The IEM per CPU instance data.
424 */
425#define IEMCPU_TO_VMCPU(a_pIemCpu) ((PVMCPU)( (uintptr_t)(a_pIemCpu) + a_pIemCpu->offVMCpu ))
426
427/** Converts a IEMCPU pointer to a VM pointer.
428 * @returns VM pointer.
429 * @param a_pIemCpu The IEM per CPU instance data.
430 */
431#define IEMCPU_TO_VM(a_pIemCpu) ((PVM)( (uintptr_t)(a_pIemCpu) + a_pIemCpu->offVM ))
432
433/** @name IEM_ACCESS_XXX - Access details.
434 * @{ */
435#define IEM_ACCESS_INVALID UINT32_C(0x000000ff)
436#define IEM_ACCESS_TYPE_READ UINT32_C(0x00000001)
437#define IEM_ACCESS_TYPE_WRITE UINT32_C(0x00000002)
438#define IEM_ACCESS_TYPE_EXEC UINT32_C(0x00000004)
439#define IEM_ACCESS_TYPE_MASK UINT32_C(0x00000007)
440#define IEM_ACCESS_WHAT_CODE UINT32_C(0x00000010)
441#define IEM_ACCESS_WHAT_DATA UINT32_C(0x00000020)
442#define IEM_ACCESS_WHAT_STACK UINT32_C(0x00000030)
443#define IEM_ACCESS_WHAT_SYS UINT32_C(0x00000040)
444#define IEM_ACCESS_WHAT_MASK UINT32_C(0x00000070)
445/** The writes are partial, so if initialize the bounce buffer with the
446 * orignal RAM content. */
447#define IEM_ACCESS_PARTIAL_WRITE UINT32_C(0x00000100)
448/** Used in aMemMappings to indicate that the entry is bounce buffered. */
449#define IEM_ACCESS_BOUNCE_BUFFERED UINT32_C(0x00000200)
450/** Read+write data alias. */
451#define IEM_ACCESS_DATA_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
452/** Write data alias. */
453#define IEM_ACCESS_DATA_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
454/** Read data alias. */
455#define IEM_ACCESS_DATA_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_DATA)
456/** Instruction fetch alias. */
457#define IEM_ACCESS_INSTRUCTION (IEM_ACCESS_TYPE_EXEC | IEM_ACCESS_WHAT_CODE)
458/** Stack write alias. */
459#define IEM_ACCESS_STACK_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
460/** Stack read alias. */
461#define IEM_ACCESS_STACK_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_STACK)
462/** Stack read+write alias. */
463#define IEM_ACCESS_STACK_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
464/** Read system table alias. */
465#define IEM_ACCESS_SYS_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_SYS)
466/** Read+write system table alias. */
467#define IEM_ACCESS_SYS_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_SYS)
468/** @} */
469
470/** @name Prefix constants (IEMCPU::fPrefixes)
471 * @{ */
472#define IEM_OP_PRF_SEG_CS RT_BIT_32(0) /**< CS segment prefix (0x2e). */
473#define IEM_OP_PRF_SEG_SS RT_BIT_32(1) /**< SS segment prefix (0x36). */
474#define IEM_OP_PRF_SEG_DS RT_BIT_32(2) /**< DS segment prefix (0x3e). */
475#define IEM_OP_PRF_SEG_ES RT_BIT_32(3) /**< ES segment prefix (0x26). */
476#define IEM_OP_PRF_SEG_FS RT_BIT_32(4) /**< FS segment prefix (0x64). */
477#define IEM_OP_PRF_SEG_GS RT_BIT_32(5) /**< GS segment prefix (0x65). */
478#define IEM_OP_PRF_SEG_MASK UINT32_C(0x3f)
479
480#define IEM_OP_PRF_SIZE_OP RT_BIT_32(8) /**< Operand size prefix (0x66). */
481#define IEM_OP_PRF_SIZE_REX_W RT_BIT_32(9) /**< REX.W prefix (0x48-0x4f). */
482#define IEM_OP_PRF_SIZE_ADDR RT_BIT_32(10) /**< Address size prefix (0x67). */
483
484#define IEM_OP_PRF_LOCK RT_BIT_32(16) /**< Lock prefix (0xf0). */
485#define IEM_OP_PRF_REPNZ RT_BIT_32(17) /**< Repeat-not-zero prefix (0xf2). */
486#define IEM_OP_PRF_REPZ RT_BIT_32(18) /**< Repeat-if-zero prefix (0xf3). */
487
488#define IEM_OP_PRF_REX RT_BIT_32(24) /**< Any REX prefix (0x40-0x4f). */
489#define IEM_OP_PRF_REX_R RT_BIT_32(25) /**< REX.R prefix (0x44,0x45,0x46,0x47,0x4c,0x4d,0x4e,0x4f). */
490#define IEM_OP_PRF_REX_B RT_BIT_32(26) /**< REX.B prefix (0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f). */
491#define IEM_OP_PRF_REX_X RT_BIT_32(27) /**< REX.X prefix (0x42,0x43,0x46,0x47,0x4a,0x4b,0x4e,0x4f). */
492/** Mask with all the REX prefix flags.
493 * This is generally for use when needing to undo the REX prefixes when they
494 * are followed legacy prefixes and therefore does not immediately preceed
495 * the first opcode byte.
496 * For testing whether any REX prefix is present, use IEM_OP_PRF_REX instead. */
497#define IEM_OP_PRF_REX_MASK (IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W )
498/** @} */
499
500/**
501 * Tests if verification mode is enabled.
502 *
503 * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
504 * should therefore cause the compiler to eliminate the verification branch
505 * of an if statement. */
506#ifdef IEM_VERIFICATION_MODE_FULL
507# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem)
508#elif defined(IEM_VERIFICATION_MODE_MINIMAL)
509# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (true)
510#else
511# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (false)
512#endif
513
514/**
515 * Tests if full verification mode is enabled.
516 *
517 * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
518 * should therefore cause the compiler to eliminate the verification branch
519 * of an if statement. */
520#ifdef IEM_VERIFICATION_MODE_FULL
521# define IEM_FULL_VERIFICATION_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem)
522#else
523# define IEM_FULL_VERIFICATION_ENABLED(a_pIemCpu) (false)
524#endif
525
526/** @def IEM_VERIFICATION_MODE
527 * Indicates that one of the verfication modes are enabled.
528 */
529#if (defined(IEM_VERIFICATION_MODE_FULL) || defined(IEM_VERIFICATION_MODE_MINIMAL)) && !defined(IEM_VERIFICATION_MODE)
530# define IEM_VERIFICATION_MODE
531#endif
532
533/**
534 * Indicates to the verifier that the given flag set is undefined.
535 *
536 * Can be invoked again to add more flags.
537 *
538 * This is a NOOP if the verifier isn't compiled in.
539 */
540#ifdef IEM_VERIFICATION_MODE_FULL
541# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { pIemCpu->fUndefinedEFlags |= (a_fEfl); } while (0)
542#else
543# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { } while (0)
544#endif
545
546
547/** @def IEM_DECL_IMPL_TYPE
548 * For typedef'ing 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/** @def IEM_DECL_IMPL_DEF
556 * For defining an instruction implementation function.
557 *
558 * @param a_RetType The return type.
559 * @param a_Name The name of the type.
560 * @param a_ArgList The argument list enclosed in parentheses.
561 */
562
563#if defined(__GNUC__) && defined(RT_ARCH_X86)
564# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
565 __attribute__((__fastcall__)) a_RetType (a_Name) a_ArgList
566# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
567 __attribute__((__fastcall__, __nothrow__)) a_RetType a_Name a_ArgList
568
569#elif defined(_MSC_VER) && defined(RT_ARCH_X86)
570# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
571 a_RetType (__fastcall a_Name) a_ArgList
572# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
573 a_RetType __fastcall a_Name a_ArgList
574
575#else
576# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
577 a_RetType (VBOXCALL a_Name) a_ArgList
578# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
579 a_RetType VBOXCALL a_Name a_ArgList
580
581#endif
582
583/** @name Arithmetic assignment operations on bytes (binary).
584 * @{ */
585typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU8, (uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags));
586typedef FNIEMAIMPLBINU8 *PFNIEMAIMPLBINU8;
587FNIEMAIMPLBINU8 iemAImpl_add_u8, iemAImpl_add_u8_locked;
588FNIEMAIMPLBINU8 iemAImpl_adc_u8, iemAImpl_adc_u8_locked;
589FNIEMAIMPLBINU8 iemAImpl_sub_u8, iemAImpl_sub_u8_locked;
590FNIEMAIMPLBINU8 iemAImpl_sbb_u8, iemAImpl_sbb_u8_locked;
591FNIEMAIMPLBINU8 iemAImpl_or_u8, iemAImpl_or_u8_locked;
592FNIEMAIMPLBINU8 iemAImpl_xor_u8, iemAImpl_xor_u8_locked;
593FNIEMAIMPLBINU8 iemAImpl_and_u8, iemAImpl_and_u8_locked;
594/** @} */
595
596/** @name Arithmetic assignment operations on words (binary).
597 * @{ */
598typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU16, (uint16_t *pu16Dst, uint16_t u16Src, uint32_t *pEFlags));
599typedef FNIEMAIMPLBINU16 *PFNIEMAIMPLBINU16;
600FNIEMAIMPLBINU16 iemAImpl_add_u16, iemAImpl_add_u16_locked;
601FNIEMAIMPLBINU16 iemAImpl_adc_u16, iemAImpl_adc_u16_locked;
602FNIEMAIMPLBINU16 iemAImpl_sub_u16, iemAImpl_sub_u16_locked;
603FNIEMAIMPLBINU16 iemAImpl_sbb_u16, iemAImpl_sbb_u16_locked;
604FNIEMAIMPLBINU16 iemAImpl_or_u16, iemAImpl_or_u16_locked;
605FNIEMAIMPLBINU16 iemAImpl_xor_u16, iemAImpl_xor_u16_locked;
606FNIEMAIMPLBINU16 iemAImpl_and_u16, iemAImpl_and_u16_locked;
607/** @} */
608
609/** @name Arithmetic assignment operations on double words (binary).
610 * @{ */
611typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU32, (uint32_t *pu32Dst, uint32_t u32Src, uint32_t *pEFlags));
612typedef FNIEMAIMPLBINU32 *PFNIEMAIMPLBINU32;
613FNIEMAIMPLBINU32 iemAImpl_add_u32, iemAImpl_add_u32_locked;
614FNIEMAIMPLBINU32 iemAImpl_adc_u32, iemAImpl_adc_u32_locked;
615FNIEMAIMPLBINU32 iemAImpl_sub_u32, iemAImpl_sub_u32_locked;
616FNIEMAIMPLBINU32 iemAImpl_sbb_u32, iemAImpl_sbb_u32_locked;
617FNIEMAIMPLBINU32 iemAImpl_or_u32, iemAImpl_or_u32_locked;
618FNIEMAIMPLBINU32 iemAImpl_xor_u32, iemAImpl_xor_u32_locked;
619FNIEMAIMPLBINU32 iemAImpl_and_u32, iemAImpl_and_u32_locked;
620/** @} */
621
622/** @name Arithmetic assignment operations on quad words (binary).
623 * @{ */
624typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU64, (uint64_t *pu64Dst, uint64_t u64Src, uint32_t *pEFlags));
625typedef FNIEMAIMPLBINU64 *PFNIEMAIMPLBINU64;
626FNIEMAIMPLBINU64 iemAImpl_add_u64, iemAImpl_add_u64_locked;
627FNIEMAIMPLBINU64 iemAImpl_adc_u64, iemAImpl_adc_u64_locked;
628FNIEMAIMPLBINU64 iemAImpl_sub_u64, iemAImpl_sub_u64_locked;
629FNIEMAIMPLBINU64 iemAImpl_sbb_u64, iemAImpl_sbb_u64_locked;
630FNIEMAIMPLBINU64 iemAImpl_or_u64, iemAImpl_or_u64_locked;
631FNIEMAIMPLBINU64 iemAImpl_xor_u64, iemAImpl_xor_u64_locked;
632FNIEMAIMPLBINU64 iemAImpl_and_u64, iemAImpl_and_u64_locked;
633/** @} */
634
635/** @name Compare operations (thrown in with the binary ops).
636 * @{ */
637FNIEMAIMPLBINU8 iemAImpl_cmp_u8;
638FNIEMAIMPLBINU16 iemAImpl_cmp_u16;
639FNIEMAIMPLBINU32 iemAImpl_cmp_u32;
640FNIEMAIMPLBINU64 iemAImpl_cmp_u64;
641/** @} */
642
643/** @name Test operations (thrown in with the binary ops).
644 * @{ */
645FNIEMAIMPLBINU8 iemAImpl_test_u8;
646FNIEMAIMPLBINU16 iemAImpl_test_u16;
647FNIEMAIMPLBINU32 iemAImpl_test_u32;
648FNIEMAIMPLBINU64 iemAImpl_test_u64;
649/** @} */
650
651/** @name Bit operations operations (thrown in with the binary ops).
652 * @{ */
653FNIEMAIMPLBINU16 iemAImpl_bt_u16, iemAImpl_bt_u16_locked;
654FNIEMAIMPLBINU32 iemAImpl_bt_u32, iemAImpl_bt_u32_locked;
655FNIEMAIMPLBINU64 iemAImpl_bt_u64, iemAImpl_bt_u64_locked;
656FNIEMAIMPLBINU16 iemAImpl_btc_u16, iemAImpl_btc_u16_locked;
657FNIEMAIMPLBINU32 iemAImpl_btc_u32, iemAImpl_btc_u32_locked;
658FNIEMAIMPLBINU64 iemAImpl_btc_u64, iemAImpl_btc_u64_locked;
659FNIEMAIMPLBINU16 iemAImpl_btr_u16, iemAImpl_btr_u16_locked;
660FNIEMAIMPLBINU32 iemAImpl_btr_u32, iemAImpl_btr_u32_locked;
661FNIEMAIMPLBINU64 iemAImpl_btr_u64, iemAImpl_btr_u64_locked;
662FNIEMAIMPLBINU16 iemAImpl_bts_u16, iemAImpl_bts_u16_locked;
663FNIEMAIMPLBINU32 iemAImpl_bts_u32, iemAImpl_bts_u32_locked;
664FNIEMAIMPLBINU64 iemAImpl_bts_u64, iemAImpl_bts_u64_locked;
665/** @} */
666
667/** @name Exchange memory with register operations.
668 * @{ */
669IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u8, (uint8_t *pu8Mem, uint8_t *pu8Reg));
670IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u16,(uint16_t *pu16Mem, uint16_t *pu16Reg));
671IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u32,(uint32_t *pu32Mem, uint32_t *pu32Reg));
672IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u64,(uint64_t *pu64Mem, uint64_t *pu64Reg));
673/** @} */
674
675/** @name Exchange and add operations.
676 * @{ */
677IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
678IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
679IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
680IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
681IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8_locked, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
682IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16_locked,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
683IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32_locked,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
684IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
685/** @} */
686
687/** @name Compare and exchange.
688 * @{ */
689IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u8, (uint8_t *pu8Dst, uint8_t *puAl, uint8_t uSrcReg, uint32_t *pEFlags));
690IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u8_locked, (uint8_t *pu8Dst, uint8_t *puAl, uint8_t uSrcReg, uint32_t *pEFlags));
691IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u16, (uint16_t *pu16Dst, uint16_t *puAx, uint16_t uSrcReg, uint32_t *pEFlags));
692IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u16_locked,(uint16_t *pu16Dst, uint16_t *puAx, uint16_t uSrcReg, uint32_t *pEFlags));
693IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u32, (uint32_t *pu32Dst, uint32_t *puEax, uint32_t uSrcReg, uint32_t *pEFlags));
694IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u32_locked,(uint32_t *pu32Dst, uint32_t *puEax, uint32_t uSrcReg, uint32_t *pEFlags));
695#ifdef RT_ARCH_X86
696IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64, (uint64_t *pu64Dst, uint64_t *puRax, uint64_t *puSrcReg, uint32_t *pEFlags));
697IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64_locked,(uint64_t *pu64Dst, uint64_t *puRax, uint64_t *puSrcReg, uint32_t *pEFlags));
698#else
699IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64, (uint64_t *pu64Dst, uint64_t *puRax, uint64_t uSrcReg, uint32_t *pEFlags));
700IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64_locked,(uint64_t *pu64Dst, uint64_t *puRax, uint64_t uSrcReg, uint32_t *pEFlags));
701#endif
702IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg8b,(uint64_t *pu64Dst, PRTUINT64U pu64EaxEdx, PRTUINT64U pu64EbxEcx,
703 uint32_t *pEFlags));
704IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg8b_locked,(uint64_t *pu64Dst, PRTUINT64U pu64EaxEdx, PRTUINT64U pu64EbxEcx,
705 uint32_t *pEFlags));
706IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b,(PRTUINT128U *pu128Dst, PRTUINT128U pu64RaxRdx, PRTUINT128U pu64RbxRcx,
707 uint32_t *pEFlags));
708IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b_locked,(PRTUINT128U *pu128Dst, PRTUINT128U pu64RaxRdx, PRTUINT128U pu64RbxRcx,
709 uint32_t *pEFlags));
710/** @} */
711
712/** @name Memory ordering
713 * @{ */
714typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEMFENCE,(void));
715typedef FNIEMAIMPLMEMFENCE *PFNIEMAIMPLMEMFENCE;
716IEM_DECL_IMPL_DEF(void, iemAImpl_mfence,(void));
717IEM_DECL_IMPL_DEF(void, iemAImpl_sfence,(void));
718IEM_DECL_IMPL_DEF(void, iemAImpl_lfence,(void));
719IEM_DECL_IMPL_DEF(void, iemAImpl_alt_mem_fence,(void));
720/** @} */
721
722/** @name Double precision shifts
723 * @{ */
724typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU16,(uint16_t *pu16Dst, uint16_t u16Src, uint8_t cShift, uint32_t *pEFlags));
725typedef FNIEMAIMPLSHIFTDBLU16 *PFNIEMAIMPLSHIFTDBLU16;
726typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU32,(uint32_t *pu32Dst, uint32_t u32Src, uint8_t cShift, uint32_t *pEFlags));
727typedef FNIEMAIMPLSHIFTDBLU32 *PFNIEMAIMPLSHIFTDBLU32;
728typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU64,(uint64_t *pu64Dst, uint64_t u64Src, uint8_t cShift, uint32_t *pEFlags));
729typedef FNIEMAIMPLSHIFTDBLU64 *PFNIEMAIMPLSHIFTDBLU64;
730FNIEMAIMPLSHIFTDBLU16 iemAImpl_shld_u16;
731FNIEMAIMPLSHIFTDBLU32 iemAImpl_shld_u32;
732FNIEMAIMPLSHIFTDBLU64 iemAImpl_shld_u64;
733FNIEMAIMPLSHIFTDBLU16 iemAImpl_shrd_u16;
734FNIEMAIMPLSHIFTDBLU32 iemAImpl_shrd_u32;
735FNIEMAIMPLSHIFTDBLU64 iemAImpl_shrd_u64;
736/** @} */
737
738
739/** @name Bit search operations (thrown in with the binary ops).
740 * @{ */
741FNIEMAIMPLBINU16 iemAImpl_bsf_u16;
742FNIEMAIMPLBINU32 iemAImpl_bsf_u32;
743FNIEMAIMPLBINU64 iemAImpl_bsf_u64;
744FNIEMAIMPLBINU16 iemAImpl_bsr_u16;
745FNIEMAIMPLBINU32 iemAImpl_bsr_u32;
746FNIEMAIMPLBINU64 iemAImpl_bsr_u64;
747/** @} */
748
749/** @name Signed multiplication operations (thrown in with the binary ops).
750 * @{ */
751FNIEMAIMPLBINU16 iemAImpl_imul_two_u16;
752FNIEMAIMPLBINU32 iemAImpl_imul_two_u32;
753FNIEMAIMPLBINU64 iemAImpl_imul_two_u64;
754/** @} */
755
756/** @name Arithmetic assignment operations on bytes (unary).
757 * @{ */
758typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU8, (uint8_t *pu8Dst, uint32_t *pEFlags));
759typedef FNIEMAIMPLUNARYU8 *PFNIEMAIMPLUNARYU8;
760FNIEMAIMPLUNARYU8 iemAImpl_inc_u8, iemAImpl_inc_u8_locked;
761FNIEMAIMPLUNARYU8 iemAImpl_dec_u8, iemAImpl_dec_u8_locked;
762FNIEMAIMPLUNARYU8 iemAImpl_not_u8, iemAImpl_not_u8_locked;
763FNIEMAIMPLUNARYU8 iemAImpl_neg_u8, iemAImpl_neg_u8_locked;
764/** @} */
765
766/** @name Arithmetic assignment operations on words (unary).
767 * @{ */
768typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU16, (uint16_t *pu16Dst, uint32_t *pEFlags));
769typedef FNIEMAIMPLUNARYU16 *PFNIEMAIMPLUNARYU16;
770FNIEMAIMPLUNARYU16 iemAImpl_inc_u16, iemAImpl_inc_u16_locked;
771FNIEMAIMPLUNARYU16 iemAImpl_dec_u16, iemAImpl_dec_u16_locked;
772FNIEMAIMPLUNARYU16 iemAImpl_not_u16, iemAImpl_not_u16_locked;
773FNIEMAIMPLUNARYU16 iemAImpl_neg_u16, iemAImpl_neg_u16_locked;
774/** @} */
775
776/** @name Arithmetic assignment operations on double words (unary).
777 * @{ */
778typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU32, (uint32_t *pu32Dst, uint32_t *pEFlags));
779typedef FNIEMAIMPLUNARYU32 *PFNIEMAIMPLUNARYU32;
780FNIEMAIMPLUNARYU32 iemAImpl_inc_u32, iemAImpl_inc_u32_locked;
781FNIEMAIMPLUNARYU32 iemAImpl_dec_u32, iemAImpl_dec_u32_locked;
782FNIEMAIMPLUNARYU32 iemAImpl_not_u32, iemAImpl_not_u32_locked;
783FNIEMAIMPLUNARYU32 iemAImpl_neg_u32, iemAImpl_neg_u32_locked;
784/** @} */
785
786/** @name Arithmetic assignment operations on quad words (unary).
787 * @{ */
788typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU64, (uint64_t *pu64Dst, uint32_t *pEFlags));
789typedef FNIEMAIMPLUNARYU64 *PFNIEMAIMPLUNARYU64;
790FNIEMAIMPLUNARYU64 iemAImpl_inc_u64, iemAImpl_inc_u64_locked;
791FNIEMAIMPLUNARYU64 iemAImpl_dec_u64, iemAImpl_dec_u64_locked;
792FNIEMAIMPLUNARYU64 iemAImpl_not_u64, iemAImpl_not_u64_locked;
793FNIEMAIMPLUNARYU64 iemAImpl_neg_u64, iemAImpl_neg_u64_locked;
794/** @} */
795
796
797/** @name Shift operations on bytes (Group 2).
798 * @{ */
799typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU8,(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags));
800typedef FNIEMAIMPLSHIFTU8 *PFNIEMAIMPLSHIFTU8;
801FNIEMAIMPLSHIFTU8 iemAImpl_rol_u8;
802FNIEMAIMPLSHIFTU8 iemAImpl_ror_u8;
803FNIEMAIMPLSHIFTU8 iemAImpl_rcl_u8;
804FNIEMAIMPLSHIFTU8 iemAImpl_rcr_u8;
805FNIEMAIMPLSHIFTU8 iemAImpl_shl_u8;
806FNIEMAIMPLSHIFTU8 iemAImpl_shr_u8;
807FNIEMAIMPLSHIFTU8 iemAImpl_sar_u8;
808/** @} */
809
810/** @name Shift operations on words (Group 2).
811 * @{ */
812typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU16,(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags));
813typedef FNIEMAIMPLSHIFTU16 *PFNIEMAIMPLSHIFTU16;
814FNIEMAIMPLSHIFTU16 iemAImpl_rol_u16;
815FNIEMAIMPLSHIFTU16 iemAImpl_ror_u16;
816FNIEMAIMPLSHIFTU16 iemAImpl_rcl_u16;
817FNIEMAIMPLSHIFTU16 iemAImpl_rcr_u16;
818FNIEMAIMPLSHIFTU16 iemAImpl_shl_u16;
819FNIEMAIMPLSHIFTU16 iemAImpl_shr_u16;
820FNIEMAIMPLSHIFTU16 iemAImpl_sar_u16;
821/** @} */
822
823/** @name Shift operations on double words (Group 2).
824 * @{ */
825typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU32,(uint32_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags));
826typedef FNIEMAIMPLSHIFTU32 *PFNIEMAIMPLSHIFTU32;
827FNIEMAIMPLSHIFTU32 iemAImpl_rol_u32;
828FNIEMAIMPLSHIFTU32 iemAImpl_ror_u32;
829FNIEMAIMPLSHIFTU32 iemAImpl_rcl_u32;
830FNIEMAIMPLSHIFTU32 iemAImpl_rcr_u32;
831FNIEMAIMPLSHIFTU32 iemAImpl_shl_u32;
832FNIEMAIMPLSHIFTU32 iemAImpl_shr_u32;
833FNIEMAIMPLSHIFTU32 iemAImpl_sar_u32;
834/** @} */
835
836/** @name Shift operations on words (Group 2).
837 * @{ */
838typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU64,(uint64_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags));
839typedef FNIEMAIMPLSHIFTU64 *PFNIEMAIMPLSHIFTU64;
840FNIEMAIMPLSHIFTU64 iemAImpl_rol_u64;
841FNIEMAIMPLSHIFTU64 iemAImpl_ror_u64;
842FNIEMAIMPLSHIFTU64 iemAImpl_rcl_u64;
843FNIEMAIMPLSHIFTU64 iemAImpl_rcr_u64;
844FNIEMAIMPLSHIFTU64 iemAImpl_shl_u64;
845FNIEMAIMPLSHIFTU64 iemAImpl_shr_u64;
846FNIEMAIMPLSHIFTU64 iemAImpl_sar_u64;
847/** @} */
848
849/** @name Multiplication and division operations.
850 * @{ */
851typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t *pEFlags));
852typedef FNIEMAIMPLMULDIVU8 *PFNIEMAIMPLMULDIVU8;
853FNIEMAIMPLMULDIVU8 iemAImpl_mul_u8, iemAImpl_imul_u8;
854FNIEMAIMPLMULDIVU8 iemAImpl_div_u8, iemAImpl_idiv_u8;
855
856typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t *pEFlags));
857typedef FNIEMAIMPLMULDIVU16 *PFNIEMAIMPLMULDIVU16;
858FNIEMAIMPLMULDIVU16 iemAImpl_mul_u16, iemAImpl_imul_u16;
859FNIEMAIMPLMULDIVU16 iemAImpl_div_u16, iemAImpl_idiv_u16;
860
861typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t *pEFlags));
862typedef FNIEMAIMPLMULDIVU32 *PFNIEMAIMPLMULDIVU32;
863FNIEMAIMPLMULDIVU32 iemAImpl_mul_u32, iemAImpl_imul_u32;
864FNIEMAIMPLMULDIVU32 iemAImpl_div_u32, iemAImpl_idiv_u32;
865
866typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t *pEFlags));
867typedef FNIEMAIMPLMULDIVU64 *PFNIEMAIMPLMULDIVU64;
868FNIEMAIMPLMULDIVU64 iemAImpl_mul_u64, iemAImpl_imul_u64;
869FNIEMAIMPLMULDIVU64 iemAImpl_div_u64, iemAImpl_idiv_u64;
870/** @} */
871
872/** @name Byte Swap.
873 * @{ */
874IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u16,(uint32_t *pu32Dst)); /* Yes, 32-bit register access. */
875IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u32,(uint32_t *pu32Dst));
876IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u64,(uint64_t *pu64Dst));
877/** @} */
878
879
880/** @name FPU operations taking a 32-bit float argument
881 * @{ */
882typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
883 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
884typedef FNIEMAIMPLFPUR32FSW *PFNIEMAIMPLFPUR32FSW;
885
886typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
887 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
888typedef FNIEMAIMPLFPUR32 *PFNIEMAIMPLFPUR32;
889
890FNIEMAIMPLFPUR32FSW iemAImpl_fcom_r80_by_r32;
891FNIEMAIMPLFPUR32 iemAImpl_fadd_r80_by_r32;
892FNIEMAIMPLFPUR32 iemAImpl_fmul_r80_by_r32;
893FNIEMAIMPLFPUR32 iemAImpl_fsub_r80_by_r32;
894FNIEMAIMPLFPUR32 iemAImpl_fsubr_r80_by_r32;
895FNIEMAIMPLFPUR32 iemAImpl_fdiv_r80_by_r32;
896FNIEMAIMPLFPUR32 iemAImpl_fdivr_r80_by_r32;
897
898IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r32_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT32U pr32Val));
899IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
900 PRTFLOAT32U pr32Val, PCRTFLOAT80U pr80Val));
901/** @} */
902
903/** @name FPU operations taking a 64-bit float argument
904 * @{ */
905typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
906 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
907typedef FNIEMAIMPLFPUR64 *PFNIEMAIMPLFPUR64;
908
909FNIEMAIMPLFPUR64 iemAImpl_fadd_r80_by_r64;
910FNIEMAIMPLFPUR64 iemAImpl_fmul_r80_by_r64;
911FNIEMAIMPLFPUR64 iemAImpl_fsub_r80_by_r64;
912FNIEMAIMPLFPUR64 iemAImpl_fsubr_r80_by_r64;
913FNIEMAIMPLFPUR64 iemAImpl_fdiv_r80_by_r64;
914FNIEMAIMPLFPUR64 iemAImpl_fdivr_r80_by_r64;
915
916IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r64,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
917 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
918IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r64_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val));
919IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
920 PRTFLOAT64U pr32Val, PCRTFLOAT80U pr80Val));
921/** @} */
922
923/** @name FPU operations taking a 80-bit float argument
924 * @{ */
925typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
926 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
927typedef FNIEMAIMPLFPUR80 *PFNIEMAIMPLFPUR80;
928FNIEMAIMPLFPUR80 iemAImpl_fadd_r80_by_r80;
929FNIEMAIMPLFPUR80 iemAImpl_fmul_r80_by_r80;
930FNIEMAIMPLFPUR80 iemAImpl_fsub_r80_by_r80;
931FNIEMAIMPLFPUR80 iemAImpl_fsubr_r80_by_r80;
932FNIEMAIMPLFPUR80 iemAImpl_fdiv_r80_by_r80;
933FNIEMAIMPLFPUR80 iemAImpl_fdivr_r80_by_r80;
934FNIEMAIMPLFPUR80 iemAImpl_fprem_r80_by_r80;
935FNIEMAIMPLFPUR80 iemAImpl_fprem1_r80_by_r80;
936FNIEMAIMPLFPUR80 iemAImpl_fscale_r80_by_r80;
937
938FNIEMAIMPLFPUR80 iemAImpl_fpatan_r80_by_r80;
939FNIEMAIMPLFPUR80 iemAImpl_fyl2xp1_r80_by_r80;
940
941typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
942 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
943typedef FNIEMAIMPLFPUR80FSW *PFNIEMAIMPLFPUR80FSW;
944FNIEMAIMPLFPUR80FSW iemAImpl_fcom_r80_by_r80;
945FNIEMAIMPLFPUR80FSW iemAImpl_fucom_r80_by_r80;
946
947typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLFPUR80EFL,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
948 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
949typedef FNIEMAIMPLFPUR80EFL *PFNIEMAIMPLFPUR80EFL;
950FNIEMAIMPLFPUR80EFL iemAImpl_fcomi_r80_by_r80;
951FNIEMAIMPLFPUR80EFL iemAImpl_fucomi_r80_by_r80;
952
953typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARY,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
954typedef FNIEMAIMPLFPUR80UNARY *PFNIEMAIMPLFPUR80UNARY;
955FNIEMAIMPLFPUR80UNARY iemAImpl_fabs_r80;
956FNIEMAIMPLFPUR80UNARY iemAImpl_fchs_r80;
957FNIEMAIMPLFPUR80UNARY iemAImpl_f2xm1_r80;
958FNIEMAIMPLFPUR80UNARY iemAImpl_fyl2x_r80;
959FNIEMAIMPLFPUR80UNARY iemAImpl_fsqrt_r80;
960FNIEMAIMPLFPUR80UNARY iemAImpl_frndint_r80;
961FNIEMAIMPLFPUR80UNARY iemAImpl_fsin_r80;
962FNIEMAIMPLFPUR80UNARY iemAImpl_fcos_r80;
963
964typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARYFSW,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, PCRTFLOAT80U pr80Val));
965typedef FNIEMAIMPLFPUR80UNARYFSW *PFNIEMAIMPLFPUR80UNARYFSW;
966FNIEMAIMPLFPUR80UNARYFSW iemAImpl_ftst_r80;
967FNIEMAIMPLFPUR80UNARYFSW iemAImpl_fxam_r80;
968
969typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80LDCONST,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes));
970typedef FNIEMAIMPLFPUR80LDCONST *PFNIEMAIMPLFPUR80LDCONST;
971FNIEMAIMPLFPUR80LDCONST iemAImpl_fld1;
972FNIEMAIMPLFPUR80LDCONST iemAImpl_fldl2t;
973FNIEMAIMPLFPUR80LDCONST iemAImpl_fldl2e;
974FNIEMAIMPLFPUR80LDCONST iemAImpl_fldpi;
975FNIEMAIMPLFPUR80LDCONST iemAImpl_fldlg2;
976FNIEMAIMPLFPUR80LDCONST iemAImpl_fldln2;
977FNIEMAIMPLFPUR80LDCONST iemAImpl_fldz;
978
979typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARYTWO,(PCX86FXSTATE pFpuState, PIEMFPURESULTTWO pFpuResTwo,
980 PCRTFLOAT80U pr80Val));
981typedef FNIEMAIMPLFPUR80UNARYTWO *PFNIEMAIMPLFPUR80UNARYTWO;
982FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fptan_r80_r80;
983FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fxtract_r80_r80;
984FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fsincos_r80_r80;
985
986IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r80_from_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
987IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r80,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
988 PRTFLOAT80U pr80Dst, PCRTFLOAT80U pr80Src));
989
990/** @} */
991
992/** @name FPU operations taking a 16-bit signed integer argument
993 * @{ */
994typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI16,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
995 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2));
996typedef FNIEMAIMPLFPUI16 *PFNIEMAIMPLFPUI16;
997
998FNIEMAIMPLFPUI16 iemAImpl_fiadd_r80_by_i16;
999FNIEMAIMPLFPUI16 iemAImpl_fimul_r80_by_i16;
1000FNIEMAIMPLFPUI16 iemAImpl_fisub_r80_by_i16;
1001FNIEMAIMPLFPUI16 iemAImpl_fisubr_r80_by_i16;
1002FNIEMAIMPLFPUI16 iemAImpl_fidiv_r80_by_i16;
1003FNIEMAIMPLFPUI16 iemAImpl_fidivr_r80_by_i16;
1004
1005IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1006 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2));
1007
1008IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i16_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int16_t const *pi16Val));
1009IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1010 int16_t *pi16Val, PCRTFLOAT80U pr80Val));
1011IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1012 int16_t *pi16Val, PCRTFLOAT80U pr80Val));
1013/** @} */
1014
1015/** @name FPU operations taking a 32-bit signed integer argument
1016 * @{ */
1017typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1018 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2));
1019typedef FNIEMAIMPLFPUI32 *PFNIEMAIMPLFPUI32;
1020
1021FNIEMAIMPLFPUI32 iemAImpl_fiadd_r80_by_i32;
1022FNIEMAIMPLFPUI32 iemAImpl_fimul_r80_by_i32;
1023FNIEMAIMPLFPUI32 iemAImpl_fisub_r80_by_i32;
1024FNIEMAIMPLFPUI32 iemAImpl_fisubr_r80_by_i32;
1025FNIEMAIMPLFPUI32 iemAImpl_fidiv_r80_by_i32;
1026FNIEMAIMPLFPUI32 iemAImpl_fidivr_r80_by_i32;
1027
1028IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1029 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2));
1030
1031IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i32_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int32_t const *pi32Val));
1032IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1033 int32_t *pi32Val, PCRTFLOAT80U pr80Val));
1034IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1035 int32_t *pi32Val, PCRTFLOAT80U pr80Val));
1036/** @} */
1037
1038/** @name FPU operations taking a 64-bit signed integer argument
1039 * @{ */
1040typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1041 PCRTFLOAT80U pr80Val1, int64_t const *pi64Val2));
1042typedef FNIEMAIMPLFPUI64 *PFNIEMAIMPLFPUI64;
1043
1044FNIEMAIMPLFPUI64 iemAImpl_fiadd_r80_by_i64;
1045FNIEMAIMPLFPUI64 iemAImpl_fimul_r80_by_i64;
1046FNIEMAIMPLFPUI64 iemAImpl_fisub_r80_by_i64;
1047FNIEMAIMPLFPUI64 iemAImpl_fisubr_r80_by_i64;
1048FNIEMAIMPLFPUI64 iemAImpl_fidiv_r80_by_i64;
1049FNIEMAIMPLFPUI64 iemAImpl_fidivr_r80_by_i64;
1050
1051IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1052 PCRTFLOAT80U pr80Val1, int64_t const *pi64Val2));
1053
1054IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i64_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int64_t const *pi64Val));
1055IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1056 int64_t *pi64Val, PCRTFLOAT80U pr80Val));
1057IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1058 int64_t *pi32Val, PCRTFLOAT80U pr80Val));
1059/** @} */
1060
1061
1062/** Temporary type representing a 256-bit vector register. */
1063typedef struct {uint64_t au64[4]; } IEMVMM256;
1064/** Temporary type pointing to a 256-bit vector register. */
1065typedef IEMVMM256 *PIEMVMM256;
1066/** Temporary type pointing to a const 256-bit vector register. */
1067typedef IEMVMM256 *PCIEMVMM256;
1068
1069
1070/** @name Media (SSE/MMX/AVX) operations: full1 + full2 -> full1.
1071 * @{ */
1072typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF2U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src));
1073typedef FNIEMAIMPLMEDIAF2U64 *PFNIEMAIMPLMEDIAF2U64;
1074typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF2U128,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, uint128_t const *pu128Src));
1075typedef FNIEMAIMPLMEDIAF2U128 *PFNIEMAIMPLMEDIAF2U128;
1076FNIEMAIMPLMEDIAF2U64 iemAImpl_pxor_u64;
1077FNIEMAIMPLMEDIAF2U128 iemAImpl_pxor_u128;
1078/** @} */
1079
1080/** @name Media (SSE/MMX/AVX) operations: lowhalf1 + lowhalf1 -> full1.
1081 * @{ */
1082typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1L1U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint32_t const *pu32Src));
1083typedef FNIEMAIMPLMEDIAF1L1U64 *PFNIEMAIMPLMEDIAF1L1U64;
1084typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1L1U128,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, uint64_t const *pu64Src));
1085typedef FNIEMAIMPLMEDIAF1L1U128 *PFNIEMAIMPLMEDIAF1L1U128;
1086FNIEMAIMPLMEDIAF1L1U64 iemAImpl_punpcklbw_u64, iemAImpl_punpcklwd_u64, iemAImpl_punpckldq_u64;
1087FNIEMAIMPLMEDIAF1L1U128 iemAImpl_punpcklbw_u128, iemAImpl_punpcklwd_u128, iemAImpl_punpckldq_u128, iemAImpl_punpcklqdq_u128;
1088/** @} */
1089
1090/** @name Media (SSE/MMX/AVX) operations: hihalf1 + hihalf2 -> full1.
1091 * @{ */
1092typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1H1U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src));
1093typedef FNIEMAIMPLMEDIAF2U64 *PFNIEMAIMPLMEDIAF1H1U64;
1094typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1H1U128,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, uint128_t const *pu128Src));
1095typedef FNIEMAIMPLMEDIAF2U128 *PFNIEMAIMPLMEDIAF1H1U128;
1096FNIEMAIMPLMEDIAF1H1U64 iemAImpl_punpckhbw_u64, iemAImpl_punpckhwd_u64, iemAImpl_punpckhdq_u64;
1097FNIEMAIMPLMEDIAF1H1U128 iemAImpl_punpckhbw_u128, iemAImpl_punpckhwd_u128, iemAImpl_punpckhdq_u128, iemAImpl_punpckhqdq_u128;
1098/** @} */
1099
1100/** @name Media (SSE/MMX/AVX) operation: Packed Shuffle Stuff (evil)
1101 * @{ */
1102typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAPSHUF,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst,
1103 uint128_t const *pu128Src, uint8_t bEvil));
1104typedef FNIEMAIMPLMEDIAPSHUF *PFNIEMAIMPLMEDIAPSHUF;
1105FNIEMAIMPLMEDIAPSHUF iemAImpl_pshufhw, iemAImpl_pshuflw, iemAImpl_pshufd;
1106IEM_DECL_IMPL_DEF(void, iemAImpl_pshufw,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src, uint8_t bEvil));
1107/** @} */
1108
1109
1110
1111
1112/** @name Function tables.
1113 * @{
1114 */
1115
1116/**
1117 * Function table for a binary operator providing implementation based on
1118 * operand size.
1119 */
1120typedef struct IEMOPBINSIZES
1121{
1122 PFNIEMAIMPLBINU8 pfnNormalU8, pfnLockedU8;
1123 PFNIEMAIMPLBINU16 pfnNormalU16, pfnLockedU16;
1124 PFNIEMAIMPLBINU32 pfnNormalU32, pfnLockedU32;
1125 PFNIEMAIMPLBINU64 pfnNormalU64, pfnLockedU64;
1126} IEMOPBINSIZES;
1127/** Pointer to a binary operator function table. */
1128typedef IEMOPBINSIZES const *PCIEMOPBINSIZES;
1129
1130
1131/**
1132 * Function table for a unary operator providing implementation based on
1133 * operand size.
1134 */
1135typedef struct IEMOPUNARYSIZES
1136{
1137 PFNIEMAIMPLUNARYU8 pfnNormalU8, pfnLockedU8;
1138 PFNIEMAIMPLUNARYU16 pfnNormalU16, pfnLockedU16;
1139 PFNIEMAIMPLUNARYU32 pfnNormalU32, pfnLockedU32;
1140 PFNIEMAIMPLUNARYU64 pfnNormalU64, pfnLockedU64;
1141} IEMOPUNARYSIZES;
1142/** Pointer to a unary operator function table. */
1143typedef IEMOPUNARYSIZES const *PCIEMOPUNARYSIZES;
1144
1145
1146/**
1147 * Function table for a shift operator providing implementation based on
1148 * operand size.
1149 */
1150typedef struct IEMOPSHIFTSIZES
1151{
1152 PFNIEMAIMPLSHIFTU8 pfnNormalU8;
1153 PFNIEMAIMPLSHIFTU16 pfnNormalU16;
1154 PFNIEMAIMPLSHIFTU32 pfnNormalU32;
1155 PFNIEMAIMPLSHIFTU64 pfnNormalU64;
1156} IEMOPSHIFTSIZES;
1157/** Pointer to a shift operator function table. */
1158typedef IEMOPSHIFTSIZES const *PCIEMOPSHIFTSIZES;
1159
1160
1161/**
1162 * Function table for a multiplication or division operation.
1163 */
1164typedef struct IEMOPMULDIVSIZES
1165{
1166 PFNIEMAIMPLMULDIVU8 pfnU8;
1167 PFNIEMAIMPLMULDIVU16 pfnU16;
1168 PFNIEMAIMPLMULDIVU32 pfnU32;
1169 PFNIEMAIMPLMULDIVU64 pfnU64;
1170} IEMOPMULDIVSIZES;
1171/** Pointer to a multiplication or division operation function table. */
1172typedef IEMOPMULDIVSIZES const *PCIEMOPMULDIVSIZES;
1173
1174
1175/**
1176 * Function table for a double precision shift operator providing implementation
1177 * based on operand size.
1178 */
1179typedef struct IEMOPSHIFTDBLSIZES
1180{
1181 PFNIEMAIMPLSHIFTDBLU16 pfnNormalU16;
1182 PFNIEMAIMPLSHIFTDBLU32 pfnNormalU32;
1183 PFNIEMAIMPLSHIFTDBLU64 pfnNormalU64;
1184} IEMOPSHIFTDBLSIZES;
1185/** Pointer to a double precision shift function table. */
1186typedef IEMOPSHIFTDBLSIZES const *PCIEMOPSHIFTDBLSIZES;
1187
1188
1189/**
1190 * Function table for media instruction taking two full sized media registers,
1191 * optionally the 2nd being a memory reference (only modifying the first op.)
1192 */
1193typedef struct IEMOPMEDIAF2
1194{
1195 PFNIEMAIMPLMEDIAF2U64 pfnU64;
1196 PFNIEMAIMPLMEDIAF2U128 pfnU128;
1197} IEMOPMEDIAF2;
1198/** Pointer to a media operation function table for full sized ops. */
1199typedef IEMOPMEDIAF2 const *PCIEMOPMEDIAF2;
1200
1201/**
1202 * Function table for media instruction taking taking one full and one lower
1203 * half media register.
1204 */
1205typedef struct IEMOPMEDIAF1L1
1206{
1207 PFNIEMAIMPLMEDIAF1L1U64 pfnU64;
1208 PFNIEMAIMPLMEDIAF1L1U128 pfnU128;
1209} IEMOPMEDIAF1L1;
1210/** Pointer to a media operation function table for lowhalf+lowhalf -> full. */
1211typedef IEMOPMEDIAF1L1 const *PCIEMOPMEDIAF1L1;
1212
1213/**
1214 * Function table for media instruction taking taking one full and one high half
1215 * media register.
1216 */
1217typedef struct IEMOPMEDIAF1H1
1218{
1219 PFNIEMAIMPLMEDIAF1H1U64 pfnU64;
1220 PFNIEMAIMPLMEDIAF1H1U128 pfnU128;
1221} IEMOPMEDIAF1H1;
1222/** Pointer to a media operation function table for hihalf+hihalf -> full. */
1223typedef IEMOPMEDIAF1H1 const *PCIEMOPMEDIAF1H1;
1224
1225
1226/** @} */
1227
1228
1229/** @name C instruction implementations for anything slightly complicated.
1230 * @{ */
1231
1232/**
1233 * For typedef'ing or declaring a C instruction implementation function taking
1234 * no extra arguments.
1235 *
1236 * @param a_Name The name of the type.
1237 */
1238# define IEM_CIMPL_DECL_TYPE_0(a_Name) \
1239 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr))
1240/**
1241 * For defining a C instruction implementation function taking no extra
1242 * arguments.
1243 *
1244 * @param a_Name The name of the function
1245 */
1246# define IEM_CIMPL_DEF_0(a_Name) \
1247 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr))
1248/**
1249 * For calling a C instruction implementation function taking no extra
1250 * arguments.
1251 *
1252 * This special call macro adds default arguments to the call and allow us to
1253 * change these later.
1254 *
1255 * @param a_fn The name of the function.
1256 */
1257# define IEM_CIMPL_CALL_0(a_fn) a_fn(pIemCpu, cbInstr)
1258
1259/**
1260 * For typedef'ing or declaring a C instruction implementation function taking
1261 * one extra argument.
1262 *
1263 * @param a_Name The name of the type.
1264 * @param a_Type0 The argument type.
1265 * @param a_Arg0 The argument name.
1266 */
1267# define IEM_CIMPL_DECL_TYPE_1(a_Name, a_Type0, a_Arg0) \
1268 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0))
1269/**
1270 * For defining a C instruction implementation function taking one extra
1271 * argument.
1272 *
1273 * @param a_Name The name of the function
1274 * @param a_Type0 The argument type.
1275 * @param a_Arg0 The argument name.
1276 */
1277# define IEM_CIMPL_DEF_1(a_Name, a_Type0, a_Arg0) \
1278 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0))
1279/**
1280 * For calling a C instruction implementation function taking one extra
1281 * argument.
1282 *
1283 * This special call macro adds default arguments to the call and allow us to
1284 * change these later.
1285 *
1286 * @param a_fn The name of the function.
1287 * @param a0 The name of the 1st argument.
1288 */
1289# define IEM_CIMPL_CALL_1(a_fn, a0) a_fn(pIemCpu, cbInstr, (a0))
1290
1291/**
1292 * For typedef'ing or declaring a C instruction implementation function taking
1293 * two extra arguments.
1294 *
1295 * @param a_Name The name of the type.
1296 * @param a_Type0 The type of the 1st argument
1297 * @param a_Arg0 The name of the 1st argument.
1298 * @param a_Type1 The type of the 2nd argument.
1299 * @param a_Arg1 The name of the 2nd argument.
1300 */
1301# define IEM_CIMPL_DECL_TYPE_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
1302 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
1303/**
1304 * For defining a C instruction implementation function taking two extra
1305 * arguments.
1306 *
1307 * @param a_Name The name of the function.
1308 * @param a_Type0 The type of the 1st argument
1309 * @param a_Arg0 The name of the 1st argument.
1310 * @param a_Type1 The type of the 2nd argument.
1311 * @param a_Arg1 The name of the 2nd argument.
1312 */
1313# define IEM_CIMPL_DEF_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
1314 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
1315/**
1316 * For calling a C instruction implementation function taking two extra
1317 * arguments.
1318 *
1319 * This special call macro adds default arguments to the call and allow us to
1320 * change these later.
1321 *
1322 * @param a_fn The name of the function.
1323 * @param a0 The name of the 1st argument.
1324 * @param a1 The name of the 2nd argument.
1325 */
1326# define IEM_CIMPL_CALL_2(a_fn, a0, a1) a_fn(pIemCpu, cbInstr, (a0), (a1))
1327
1328/**
1329 * For typedef'ing or declaring a C instruction implementation function taking
1330 * three extra arguments.
1331 *
1332 * @param a_Name The name of the type.
1333 * @param a_Type0 The type of the 1st argument
1334 * @param a_Arg0 The name of the 1st argument.
1335 * @param a_Type1 The type of the 2nd argument.
1336 * @param a_Arg1 The name of the 2nd argument.
1337 * @param a_Type2 The type of the 3rd argument.
1338 * @param a_Arg2 The name of the 3rd argument.
1339 */
1340# define IEM_CIMPL_DECL_TYPE_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
1341 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
1342/**
1343 * For defining a C instruction implementation function taking three extra
1344 * arguments.
1345 *
1346 * @param a_Name The name of the function.
1347 * @param a_Type0 The type of the 1st argument
1348 * @param a_Arg0 The name of the 1st argument.
1349 * @param a_Type1 The type of the 2nd argument.
1350 * @param a_Arg1 The name of the 2nd argument.
1351 * @param a_Type2 The type of the 3rd argument.
1352 * @param a_Arg2 The name of the 3rd argument.
1353 */
1354# define IEM_CIMPL_DEF_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
1355 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
1356/**
1357 * For calling a C instruction implementation function taking three extra
1358 * arguments.
1359 *
1360 * This special call macro adds default arguments to the call and allow us to
1361 * change these later.
1362 *
1363 * @param a_fn The name of the function.
1364 * @param a0 The name of the 1st argument.
1365 * @param a1 The name of the 2nd argument.
1366 * @param a2 The name of the 3rd argument.
1367 */
1368# define IEM_CIMPL_CALL_3(a_fn, a0, a1, a2) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2))
1369
1370
1371/**
1372 * For typedef'ing or declaring a C instruction implementation function taking
1373 * four extra arguments.
1374 *
1375 * @param a_Name The name of the type.
1376 * @param a_Type0 The type of the 1st argument
1377 * @param a_Arg0 The name of the 1st argument.
1378 * @param a_Type1 The type of the 2nd argument.
1379 * @param a_Arg1 The name of the 2nd argument.
1380 * @param a_Type2 The type of the 3rd argument.
1381 * @param a_Arg2 The name of the 3rd argument.
1382 * @param a_Type3 The type of the 4th argument.
1383 * @param a_Arg3 The name of the 4th argument.
1384 */
1385# define IEM_CIMPL_DECL_TYPE_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
1386 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))
1387/**
1388 * For defining a C instruction implementation function taking four extra
1389 * arguments.
1390 *
1391 * @param a_Name The name of the function.
1392 * @param a_Type0 The type of the 1st argument
1393 * @param a_Arg0 The name of the 1st argument.
1394 * @param a_Type1 The type of the 2nd argument.
1395 * @param a_Arg1 The name of the 2nd argument.
1396 * @param a_Type2 The type of the 3rd argument.
1397 * @param a_Arg2 The name of the 3rd argument.
1398 * @param a_Type3 The type of the 4th argument.
1399 * @param a_Arg3 The name of the 4th argument.
1400 */
1401# define IEM_CIMPL_DEF_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
1402 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, \
1403 a_Type2 a_Arg2, a_Type3 a_Arg3))
1404/**
1405 * For calling a C instruction implementation function taking four extra
1406 * arguments.
1407 *
1408 * This special call macro adds default arguments to the call and allow us to
1409 * change these later.
1410 *
1411 * @param a_fn The name of the function.
1412 * @param a0 The name of the 1st argument.
1413 * @param a1 The name of the 2nd argument.
1414 * @param a2 The name of the 3rd argument.
1415 * @param a3 The name of the 4th argument.
1416 */
1417# define IEM_CIMPL_CALL_4(a_fn, a0, a1, a2, a3) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3))
1418
1419
1420/**
1421 * For typedef'ing or declaring a C instruction implementation function taking
1422 * five extra arguments.
1423 *
1424 * @param a_Name The name of the type.
1425 * @param a_Type0 The type of the 1st argument
1426 * @param a_Arg0 The name of the 1st argument.
1427 * @param a_Type1 The type of the 2nd argument.
1428 * @param a_Arg1 The name of the 2nd argument.
1429 * @param a_Type2 The type of the 3rd argument.
1430 * @param a_Arg2 The name of the 3rd argument.
1431 * @param a_Type3 The type of the 4th argument.
1432 * @param a_Arg3 The name of the 4th argument.
1433 * @param a_Type4 The type of the 5th argument.
1434 * @param a_Arg4 The name of the 5th argument.
1435 */
1436# 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) \
1437 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
1438 a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
1439 a_Type3 a_Arg3, a_Type4 a_Arg4))
1440/**
1441 * For defining a C instruction implementation function taking five extra
1442 * arguments.
1443 *
1444 * @param a_Name The name of the function.
1445 * @param a_Type0 The type of the 1st argument
1446 * @param a_Arg0 The name of the 1st argument.
1447 * @param a_Type1 The type of the 2nd argument.
1448 * @param a_Arg1 The name of the 2nd argument.
1449 * @param a_Type2 The type of the 3rd argument.
1450 * @param a_Arg2 The name of the 3rd argument.
1451 * @param a_Type3 The type of the 4th argument.
1452 * @param a_Arg3 The name of the 4th argument.
1453 * @param a_Type4 The type of the 5th argument.
1454 * @param a_Arg4 The name of the 5th argument.
1455 */
1456# 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) \
1457 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
1458 a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
1459 a_Type3 a_Arg3, a_Type4 a_Arg4))
1460/**
1461 * For calling a C instruction implementation function taking five extra
1462 * arguments.
1463 *
1464 * This special call macro adds default arguments to the call and allow us to
1465 * change these later.
1466 *
1467 * @param a_fn The name of the function.
1468 * @param a0 The name of the 1st argument.
1469 * @param a1 The name of the 2nd argument.
1470 * @param a2 The name of the 3rd argument.
1471 * @param a3 The name of the 4th argument.
1472 * @param a4 The name of the 5th argument.
1473 */
1474# define IEM_CIMPL_CALL_5(a_fn, a0, a1, a2, a3, a4) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3), (a4))
1475
1476/** @} */
1477
1478
1479/** @} */
1480
1481RT_C_DECLS_END
1482
1483#endif
1484
Note: See TracBrowser for help on using the repository browser.

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