VirtualBox

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

Last change on this file since 66469 was 66469, checked in by vboxsync, 8 years ago

IEM: More VEX work. Fixed punpcklbw_Vx_Wx.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 82.3 KB
Line 
1/* $Id: IEMInternal.h 66469 2017-04-07 09:32:59Z vboxsync $ */
2/** @file
3 * IEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2011-2016 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/cpum.h>
22#include <VBox/vmm/iem.h>
23#include <VBox/vmm/stam.h>
24#include <VBox/param.h>
25
26#include <setjmp.h>
27
28
29RT_C_DECLS_BEGIN
30
31
32/** @defgroup grp_iem_int Internals
33 * @ingroup grp_iem
34 * @internal
35 * @{
36 */
37
38/** For expanding symbol in slickedit and other products tagging and
39 * crossreferencing IEM symbols. */
40#ifndef IEM_STATIC
41# define IEM_STATIC static
42#endif
43
44/** @def IEM_WITH_VEX
45 * Enables the VEX decoding. */
46#define IEM_WITH_VEX
47
48/** @def IEM_VERIFICATION_MODE_FULL
49 * Shorthand for:
50 * defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_MINIMAL)
51 */
52#if (defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_MINIMAL) && !defined(IEM_VERIFICATION_MODE_FULL)) \
53 || defined(DOXYGEN_RUNNING)
54# define IEM_VERIFICATION_MODE_FULL
55#endif
56
57
58/** @def IEM_CFG_TARGET_CPU
59 * The minimum target CPU for the IEM emulation (IEMTARGETCPU_XXX value).
60 *
61 * By default we allow this to be configured by the user via the
62 * CPUM/GuestCpuName config string, but this comes at a slight cost during
63 * decoding. So, for applications of this code where there is no need to
64 * be dynamic wrt target CPU, just modify this define.
65 */
66#if !defined(IEM_CFG_TARGET_CPU) || defined(DOXYGEN_RUNNING)
67# define IEM_CFG_TARGET_CPU IEMTARGETCPU_DYNAMIC
68#endif
69
70
71//#define IEM_WITH_CODE_TLB// - work in progress
72
73
74#if !defined(IN_TSTVMSTRUCT) && !defined(DOXYGEN_RUNNING)
75/** Instruction statistics. */
76typedef struct IEMINSTRSTATS
77{
78# define IEM_DO_INSTR_STAT(a_Name, a_szDesc) uint32_t a_Name;
79# include "IEMInstructionStatisticsTmpl.h"
80# undef IEM_DO_INSTR_STAT
81} IEMINSTRSTATS;
82#else
83struct IEMINSTRSTATS;
84typedef struct IEMINSTRSTATS IEMINSTRSTATS;
85#endif
86/** Pointer to IEM instruction statistics. */
87typedef IEMINSTRSTATS *PIEMINSTRSTATS;
88
89/** Finish and move to types.h */
90typedef union
91{
92 uint32_t u32;
93} RTFLOAT32U;
94typedef RTFLOAT32U *PRTFLOAT32U;
95typedef RTFLOAT32U const *PCRTFLOAT32U;
96
97
98/**
99 * Extended operand mode that includes a representation of 8-bit.
100 *
101 * This is used for packing down modes when invoking some C instruction
102 * implementations.
103 */
104typedef enum IEMMODEX
105{
106 IEMMODEX_16BIT = IEMMODE_16BIT,
107 IEMMODEX_32BIT = IEMMODE_32BIT,
108 IEMMODEX_64BIT = IEMMODE_64BIT,
109 IEMMODEX_8BIT
110} IEMMODEX;
111AssertCompileSize(IEMMODEX, 4);
112
113
114/**
115 * Branch types.
116 */
117typedef enum IEMBRANCH
118{
119 IEMBRANCH_JUMP = 1,
120 IEMBRANCH_CALL,
121 IEMBRANCH_TRAP,
122 IEMBRANCH_SOFTWARE_INT,
123 IEMBRANCH_HARDWARE_INT
124} IEMBRANCH;
125AssertCompileSize(IEMBRANCH, 4);
126
127
128/**
129 * A FPU result.
130 */
131typedef struct IEMFPURESULT
132{
133 /** The output value. */
134 RTFLOAT80U r80Result;
135 /** The output status. */
136 uint16_t FSW;
137} IEMFPURESULT;
138AssertCompileMemberOffset(IEMFPURESULT, FSW, 10);
139/** Pointer to a FPU result. */
140typedef IEMFPURESULT *PIEMFPURESULT;
141/** Pointer to a const FPU result. */
142typedef IEMFPURESULT const *PCIEMFPURESULT;
143
144
145/**
146 * A FPU result consisting of two output values and FSW.
147 */
148typedef struct IEMFPURESULTTWO
149{
150 /** The first output value. */
151 RTFLOAT80U r80Result1;
152 /** The output status. */
153 uint16_t FSW;
154 /** The second output value. */
155 RTFLOAT80U r80Result2;
156} IEMFPURESULTTWO;
157AssertCompileMemberOffset(IEMFPURESULTTWO, FSW, 10);
158AssertCompileMemberOffset(IEMFPURESULTTWO, r80Result2, 12);
159/** Pointer to a FPU result consisting of two output values and FSW. */
160typedef IEMFPURESULTTWO *PIEMFPURESULTTWO;
161/** Pointer to a const FPU result consisting of two output values and FSW. */
162typedef IEMFPURESULTTWO const *PCIEMFPURESULTTWO;
163
164
165
166#ifdef IEM_VERIFICATION_MODE_FULL
167
168/**
169 * Verification event type.
170 */
171typedef enum IEMVERIFYEVENT
172{
173 IEMVERIFYEVENT_INVALID = 0,
174 IEMVERIFYEVENT_IOPORT_READ,
175 IEMVERIFYEVENT_IOPORT_WRITE,
176 IEMVERIFYEVENT_IOPORT_STR_READ,
177 IEMVERIFYEVENT_IOPORT_STR_WRITE,
178 IEMVERIFYEVENT_RAM_WRITE,
179 IEMVERIFYEVENT_RAM_READ
180} IEMVERIFYEVENT;
181
182/** Checks if the event type is a RAM read or write. */
183# define IEMVERIFYEVENT_IS_RAM(a_enmType) ((a_enmType) == IEMVERIFYEVENT_RAM_WRITE || (a_enmType) == IEMVERIFYEVENT_RAM_READ)
184
185/**
186 * Verification event record.
187 */
188typedef struct IEMVERIFYEVTREC
189{
190 /** Pointer to the next record in the list. */
191 struct IEMVERIFYEVTREC *pNext;
192 /** The event type. */
193 IEMVERIFYEVENT enmEvent;
194 /** The event data. */
195 union
196 {
197 /** IEMVERIFYEVENT_IOPORT_READ */
198 struct
199 {
200 RTIOPORT Port;
201 uint8_t cbValue;
202 } IOPortRead;
203
204 /** IEMVERIFYEVENT_IOPORT_WRITE */
205 struct
206 {
207 RTIOPORT Port;
208 uint8_t cbValue;
209 uint32_t u32Value;
210 } IOPortWrite;
211
212 /** IEMVERIFYEVENT_IOPORT_STR_READ */
213 struct
214 {
215 RTIOPORT Port;
216 uint8_t cbValue;
217 RTGCUINTREG cTransfers;
218 } IOPortStrRead;
219
220 /** IEMVERIFYEVENT_IOPORT_STR_WRITE */
221 struct
222 {
223 RTIOPORT Port;
224 uint8_t cbValue;
225 RTGCUINTREG cTransfers;
226 } IOPortStrWrite;
227
228 /** IEMVERIFYEVENT_RAM_READ */
229 struct
230 {
231 RTGCPHYS GCPhys;
232 uint32_t cb;
233 } RamRead;
234
235 /** IEMVERIFYEVENT_RAM_WRITE */
236 struct
237 {
238 RTGCPHYS GCPhys;
239 uint32_t cb;
240 uint8_t ab[512];
241 } RamWrite;
242 } u;
243} IEMVERIFYEVTREC;
244/** Pointer to an IEM event verification records. */
245typedef IEMVERIFYEVTREC *PIEMVERIFYEVTREC;
246
247#endif /* IEM_VERIFICATION_MODE_FULL */
248
249
250/**
251 * IEM TLB entry.
252 *
253 * Lookup assembly:
254 * @code{.asm}
255 ; Calculate tag.
256 mov rax, [VA]
257 shl rax, 16
258 shr rax, 16 + X86_PAGE_SHIFT
259 or rax, [uTlbRevision]
260
261 ; Do indexing.
262 movzx ecx, al
263 lea rcx, [pTlbEntries + rcx]
264
265 ; Check tag.
266 cmp [rcx + IEMTLBENTRY.uTag], rax
267 jne .TlbMiss
268
269 ; Check access.
270 movsx rax, ACCESS_FLAGS | MAPPING_R3_NOT_VALID | 0xffffff00
271 and rax, [rcx + IEMTLBENTRY.fFlagsAndPhysRev]
272 cmp rax, [uTlbPhysRev]
273 jne .TlbMiss
274
275 ; Calc address and we're done.
276 mov eax, X86_PAGE_OFFSET_MASK
277 and eax, [VA]
278 or rax, [rcx + IEMTLBENTRY.pMappingR3]
279 %ifdef VBOX_WITH_STATISTICS
280 inc qword [cTlbHits]
281 %endif
282 jmp .Done
283
284 .TlbMiss:
285 mov r8d, ACCESS_FLAGS
286 mov rdx, [VA]
287 mov rcx, [pVCpu]
288 call iemTlbTypeMiss
289 .Done:
290
291 @endcode
292 *
293 */
294typedef struct IEMTLBENTRY
295{
296 /** The TLB entry tag.
297 * Bits 35 thru 0 are made up of the virtual address shifted right 12 bits.
298 * Bits 63 thru 36 are made up of the TLB revision (zero means invalid).
299 *
300 * The TLB lookup code uses the current TLB revision, which won't ever be zero,
301 * enabling an extremely cheap TLB invalidation most of the time. When the TLB
302 * revision wraps around though, the tags needs to be zeroed.
303 *
304 * @note Try use SHRD instruction? After seeing
305 * https://gmplib.org/~tege/x86-timing.pdf, maybe not.
306 */
307 uint64_t uTag;
308 /** Access flags and physical TLB revision.
309 *
310 * - Bit 0 - page tables - not executable (X86_PTE_PAE_NX).
311 * - Bit 1 - page tables - not writable (complemented X86_PTE_RW).
312 * - Bit 2 - page tables - not user (complemented X86_PTE_US).
313 * - Bit 3 - pgm phys/virt - not directly writable.
314 * - Bit 4 - pgm phys page - not directly readable.
315 * - Bit 5 - currently unused.
316 * - Bit 6 - page tables - not dirty (complemented X86_PTE_D).
317 * - Bit 7 - tlb entry - pMappingR3 member not valid.
318 * - Bits 63 thru 8 are used for the physical TLB revision number.
319 *
320 * We're using complemented bit meanings here because it makes it easy to check
321 * whether special action is required. For instance a user mode write access
322 * would do a "TEST fFlags, (X86_PTE_RW | X86_PTE_US | X86_PTE_D)" and a
323 * non-zero result would mean special handling needed because either it wasn't
324 * writable, or it wasn't user, or the page wasn't dirty. A user mode read
325 * access would do "TEST fFlags, X86_PTE_US"; and a kernel mode read wouldn't
326 * need to check any PTE flag.
327 */
328 uint64_t fFlagsAndPhysRev;
329 /** The guest physical page address. */
330 uint64_t GCPhys;
331 /** Pointer to the ring-3 mapping (possibly also valid in ring-0). */
332#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
333 R3PTRTYPE(uint8_t *) pbMappingR3;
334#else
335 R3R0PTRTYPE(uint8_t *) pbMappingR3;
336#endif
337#if HC_ARCH_BITS == 32
338 uint32_t u32Padding1;
339#endif
340} IEMTLBENTRY;
341AssertCompileSize(IEMTLBENTRY, 32);
342/** Pointer to an IEM TLB entry. */
343typedef IEMTLBENTRY *PIEMTLBENTRY;
344
345/** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev)
346 * @{ */
347#define IEMTLBE_F_PT_NO_EXEC RT_BIT_64(0) /**< Page tables: Not executable. */
348#define IEMTLBE_F_PT_NO_WRITE RT_BIT_64(1) /**< Page tables: Not writable. */
349#define IEMTLBE_F_PT_NO_USER RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */
350#define IEMTLBE_F_PG_NO_WRITE RT_BIT_64(3) /**< Phys page: Not writable (access handler, ROM, whatever). */
351#define IEMTLBE_F_PG_NO_READ RT_BIT_64(4) /**< Phys page: Not readable (MMIO / access handler, ROM) */
352#define IEMTLBE_F_PATCH_CODE RT_BIT_64(5) /**< Code TLB: Patch code (PATM). */
353#define IEMTLBE_F_PT_NO_DIRTY RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */
354#define IEMTLBE_F_NO_MAPPINGR3 RT_BIT_64(7) /**< TLB entry: The IEMTLBENTRY::pMappingR3 member is invalid. */
355#define IEMTLBE_F_PHYS_REV UINT64_C(0xffffffffffffff00) /**< Physical revision mask. */
356/** @} */
357
358
359/**
360 * An IEM TLB.
361 *
362 * We've got two of these, one for data and one for instructions.
363 */
364typedef struct IEMTLB
365{
366 /** The TLB entries.
367 * We've choosen 256 because that way we can obtain the result directly from a
368 * 8-bit register without an additional AND instruction. */
369 IEMTLBENTRY aEntries[256];
370 /** The TLB revision.
371 * This is actually only 28 bits wide (see IEMTLBENTRY::uTag) and is incremented
372 * by adding RT_BIT_64(36) to it. When it wraps around and becomes zero, all
373 * the tags in the TLB must be zeroed and the revision set to RT_BIT_64(36).
374 * (The revision zero indicates an invalid TLB entry.)
375 *
376 * The initial value is choosen to cause an early wraparound. */
377 uint64_t uTlbRevision;
378 /** The TLB physical address revision - shadow of PGM variable.
379 *
380 * This is actually only 56 bits wide (see IEMTLBENTRY::fFlagsAndPhysRev) and is
381 * incremented by adding RT_BIT_64(8). When it wraps around and becomes zero,
382 * a rendezvous is called and each CPU wipe the IEMTLBENTRY::pMappingR3 as well
383 * as IEMTLBENTRY::fFlagsAndPhysRev bits 63 thru 8, 4, and 3.
384 *
385 * The initial value is choosen to cause an early wraparound. */
386 uint64_t volatile uTlbPhysRev;
387
388 /* Statistics: */
389
390 /** TLB hits (VBOX_WITH_STATISTICS only). */
391 uint64_t cTlbHits;
392 /** TLB misses. */
393 uint32_t cTlbMisses;
394 /** Slow read path. */
395 uint32_t cTlbSlowReadPath;
396#if 0
397 /** TLB misses because of tag mismatch. */
398 uint32_t cTlbMissesTag;
399 /** TLB misses because of virtual access violation. */
400 uint32_t cTlbMissesVirtAccess;
401 /** TLB misses because of dirty bit. */
402 uint32_t cTlbMissesDirty;
403 /** TLB misses because of MMIO */
404 uint32_t cTlbMissesMmio;
405 /** TLB misses because of write access handlers. */
406 uint32_t cTlbMissesWriteHandler;
407 /** TLB misses because no r3(/r0) mapping. */
408 uint32_t cTlbMissesMapping;
409#endif
410 /** Alignment padding. */
411 uint32_t au32Padding[3+5];
412} IEMTLB;
413AssertCompileSizeAlignment(IEMTLB, 64);
414/** IEMTLB::uTlbRevision increment. */
415#define IEMTLB_REVISION_INCR RT_BIT_64(36)
416/** IEMTLB::uTlbPhysRev increment. */
417#define IEMTLB_PHYS_REV_INCR RT_BIT_64(8)
418
419
420/**
421 * The per-CPU IEM state.
422 */
423typedef struct IEMCPU
424{
425 /** Info status code that needs to be propagated to the IEM caller.
426 * This cannot be passed internally, as it would complicate all success
427 * checks within the interpreter making the code larger and almost impossible
428 * to get right. Instead, we'll store status codes to pass on here. Each
429 * source of these codes will perform appropriate sanity checks. */
430 int32_t rcPassUp; /* 0x00 */
431
432 /** The current CPU execution mode (CS). */
433 IEMMODE enmCpuMode; /* 0x04 */
434 /** The CPL. */
435 uint8_t uCpl; /* 0x05 */
436
437 /** Whether to bypass access handlers or not. */
438 bool fBypassHandlers; /* 0x06 */
439 /** Indicates that we're interpreting patch code - RC only! */
440 bool fInPatchCode; /* 0x07 */
441
442 /** @name Decoder state.
443 * @{ */
444#ifdef IEM_WITH_CODE_TLB
445 /** The offset of the next instruction byte. */
446 uint32_t offInstrNextByte; /* 0x08 */
447 /** The number of bytes available at pbInstrBuf for the current instruction.
448 * This takes the max opcode length into account so that doesn't need to be
449 * checked separately. */
450 uint32_t cbInstrBuf; /* 0x0c */
451 /** Pointer to the page containing RIP, user specified buffer or abOpcode.
452 * This can be NULL if the page isn't mappable for some reason, in which
453 * case we'll do fallback stuff.
454 *
455 * If we're executing an instruction from a user specified buffer,
456 * IEMExecOneWithPrefetchedByPC and friends, this is not necessarily a page
457 * aligned pointer but pointer to the user data.
458 *
459 * For instructions crossing pages, this will start on the first page and be
460 * advanced to the next page by the time we've decoded the instruction. This
461 * therefore precludes stuff like <tt>pbInstrBuf[offInstrNextByte + cbInstrBuf - cbCurInstr]</tt>
462 */
463 uint8_t const *pbInstrBuf; /* 0x10 */
464# if ARCH_BITS == 32
465 uint32_t uInstrBufHigh; /** The high dword of the host context pbInstrBuf member. */
466# endif
467 /** The program counter corresponding to pbInstrBuf.
468 * This is set to a non-canonical address when we need to invalidate it. */
469 uint64_t uInstrBufPc; /* 0x18 */
470 /** The number of bytes available at pbInstrBuf in total (for IEMExecLots).
471 * This takes the CS segment limit into account. */
472 uint16_t cbInstrBufTotal; /* 0x20 */
473 /** Offset into pbInstrBuf of the first byte of the current instruction.
474 * Can be negative to efficiently handle cross page instructions. */
475 int16_t offCurInstrStart; /* 0x22 */
476
477 /** The prefix mask (IEM_OP_PRF_XXX). */
478 uint32_t fPrefixes; /* 0x24 */
479 /** The extra REX ModR/M register field bit (REX.R << 3). */
480 uint8_t uRexReg; /* 0x28 */
481 /** The extra REX ModR/M r/m field, SIB base and opcode reg bit
482 * (REX.B << 3). */
483 uint8_t uRexB; /* 0x29 */
484 /** The extra REX SIB index field bit (REX.X << 3). */
485 uint8_t uRexIndex; /* 0x2a */
486
487 /** The effective segment register (X86_SREG_XXX). */
488 uint8_t iEffSeg; /* 0x2b */
489
490#else
491 /** The size of what has currently been fetched into abOpcodes. */
492 uint8_t cbOpcode; /* 0x08 */
493 /** The current offset into abOpcodes. */
494 uint8_t offOpcode; /* 0x09 */
495
496 /** The effective segment register (X86_SREG_XXX). */
497 uint8_t iEffSeg; /* 0x0a */
498
499 /** The extra REX ModR/M register field bit (REX.R << 3). */
500 uint8_t uRexReg; /* 0x0b */
501 /** The prefix mask (IEM_OP_PRF_XXX). */
502 uint32_t fPrefixes; /* 0x0c */
503 /** The extra REX ModR/M r/m field, SIB base and opcode reg bit
504 * (REX.B << 3). */
505 uint8_t uRexB; /* 0x10 */
506 /** The extra REX SIB index field bit (REX.X << 3). */
507 uint8_t uRexIndex; /* 0x11 */
508
509#endif
510
511 /** The effective operand mode. */
512 IEMMODE enmEffOpSize; /* 0x2c, 0x12 */
513 /** The default addressing mode. */
514 IEMMODE enmDefAddrMode; /* 0x2d, 0x13 */
515 /** The effective addressing mode. */
516 IEMMODE enmEffAddrMode; /* 0x2e, 0x14 */
517 /** The default operand mode. */
518 IEMMODE enmDefOpSize; /* 0x2f, 0x15 */
519
520 /** Prefix index (VEX.pp) for two byte and three byte tables. */
521 uint8_t idxPrefix; /* 0x30, 0x16 */
522 /** 3rd VEX/EVEX/XOP register. */
523 uint8_t uVex3rdReg; /* 0x31, 0x17 */
524 /** The VEX/EVEX/XOP length field. */
525 uint8_t uVexLength; /* 0x32, 0x18 */
526 /** Additional EVEX stuff. */
527 uint8_t fEvexStuff; /* 0x33, 0x19 */
528
529 /** The FPU opcode (FOP). */
530 uint16_t uFpuOpcode; /* 0x34, 0x1a */
531
532 /** Explicit alignment padding. */
533#ifdef IEM_WITH_CODE_TLB
534 uint8_t abAlignment2a[2]; /* 0x36 */
535#endif
536
537 /** The opcode bytes. */
538 uint8_t abOpcode[15]; /* 0x48, 0x1c */
539 /** Explicit alignment padding. */
540#ifdef IEM_WITH_CODE_TLB
541 uint8_t abAlignment2c[0x48 - 0x47]; /* 0x37 */
542#else
543 uint8_t abAlignment2c[0x48 - 0x2b]; /* 0x2b */
544#endif
545 /** @} */
546
547
548 /** The flags of the current exception / interrupt. */
549 uint32_t fCurXcpt; /* 0x48, 0x48 */
550 /** The current exception / interrupt. */
551 uint8_t uCurXcpt;
552 /** Exception / interrupt recursion depth. */
553 int8_t cXcptRecursions;
554
555 /** The number of active guest memory mappings. */
556 uint8_t cActiveMappings;
557 /** The next unused mapping index. */
558 uint8_t iNextMapping;
559 /** Records for tracking guest memory mappings. */
560 struct
561 {
562 /** The address of the mapped bytes. */
563 void *pv;
564#if defined(IN_RC) && HC_ARCH_BITS == 64
565 uint32_t u32Alignment3; /**< Alignment padding. */
566#endif
567 /** The access flags (IEM_ACCESS_XXX).
568 * IEM_ACCESS_INVALID if the entry is unused. */
569 uint32_t fAccess;
570#if HC_ARCH_BITS == 64
571 uint32_t u32Alignment4; /**< Alignment padding. */
572#endif
573 } aMemMappings[3];
574
575 /** Locking records for the mapped memory. */
576 union
577 {
578 PGMPAGEMAPLOCK Lock;
579 uint64_t au64Padding[2];
580 } aMemMappingLocks[3];
581
582 /** Bounce buffer info.
583 * This runs in parallel to aMemMappings. */
584 struct
585 {
586 /** The physical address of the first byte. */
587 RTGCPHYS GCPhysFirst;
588 /** The physical address of the second page. */
589 RTGCPHYS GCPhysSecond;
590 /** The number of bytes in the first page. */
591 uint16_t cbFirst;
592 /** The number of bytes in the second page. */
593 uint16_t cbSecond;
594 /** Whether it's unassigned memory. */
595 bool fUnassigned;
596 /** Explicit alignment padding. */
597 bool afAlignment5[3];
598 } aMemBbMappings[3];
599
600 /** Bounce buffer storage.
601 * This runs in parallel to aMemMappings and aMemBbMappings. */
602 struct
603 {
604 uint8_t ab[512];
605 } aBounceBuffers[3];
606
607
608 /** Pointer set jump buffer - ring-3 context. */
609 R3PTRTYPE(jmp_buf *) pJmpBufR3;
610 /** Pointer set jump buffer - ring-0 context. */
611 R0PTRTYPE(jmp_buf *) pJmpBufR0;
612 /** Pointer set jump buffer - raw-mode context. */
613 RCPTRTYPE(jmp_buf *) pJmpBufRC;
614
615 /** @todo Should move this near @a fCurXcpt later. */
616 /** The error code for the current exception / interrupt. */
617 uint32_t uCurXcptErr;
618 /** The CR2 for the current exception / interrupt. */
619 uint64_t uCurXcptCr2;
620
621 /** @name Statistics
622 * @{ */
623 /** The number of instructions we've executed. */
624 uint32_t cInstructions;
625 /** The number of potential exits. */
626 uint32_t cPotentialExits;
627 /** The number of bytes data or stack written (mostly for IEMExecOneEx).
628 * This may contain uncommitted writes. */
629 uint32_t cbWritten;
630 /** Counts the VERR_IEM_INSTR_NOT_IMPLEMENTED returns. */
631 uint32_t cRetInstrNotImplemented;
632 /** Counts the VERR_IEM_ASPECT_NOT_IMPLEMENTED returns. */
633 uint32_t cRetAspectNotImplemented;
634 /** Counts informational statuses returned (other than VINF_SUCCESS). */
635 uint32_t cRetInfStatuses;
636 /** Counts other error statuses returned. */
637 uint32_t cRetErrStatuses;
638 /** Number of times rcPassUp has been used. */
639 uint32_t cRetPassUpStatus;
640 /** Number of times RZ left with instruction commit pending for ring-3. */
641 uint32_t cPendingCommit;
642 /** Number of long jumps. */
643 uint32_t cLongJumps;
644 uint32_t uAlignment6; /**< Alignment padding. */
645#ifdef IEM_VERIFICATION_MODE_FULL
646 /** The Number of I/O port reads that has been performed. */
647 uint32_t cIOReads;
648 /** The Number of I/O port writes that has been performed. */
649 uint32_t cIOWrites;
650 /** Set if no comparison to REM is currently performed.
651 * This is used to skip past really slow bits. */
652 bool fNoRem;
653 /** Saved fNoRem flag used by #iemInitExec and #iemUninitExec. */
654 bool fNoRemSavedByExec;
655 /** Indicates that RAX and RDX differences should be ignored since RDTSC
656 * and RDTSCP are timing sensitive. */
657 bool fIgnoreRaxRdx;
658 /** Indicates that a MOVS instruction with overlapping source and destination
659 * was executed, causing the memory write records to be incorrrect. */
660 bool fOverlappingMovs;
661 /** Set if there are problematic memory accesses (MMIO, write monitored, ++). */
662 bool fProblematicMemory;
663 /** This is used to communicate a CPL changed caused by IEMInjectTrap that
664 * CPUM doesn't yet reflect. */
665 uint8_t uInjectCpl;
666 /** To prevent EMR3HmSingleInstruction from triggering endless recursion via
667 * emR3ExecuteInstruction and iemExecVerificationModeCheck. */
668 uint8_t cVerifyDepth;
669 bool afAlignment7[2];
670 /** Mask of undefined eflags.
671 * The verifier will any difference in these flags. */
672 uint32_t fUndefinedEFlags;
673 /** The CS of the instruction being interpreted. */
674 RTSEL uOldCs;
675 /** The RIP of the instruction being interpreted. */
676 uint64_t uOldRip;
677 /** The physical address corresponding to abOpcodes[0]. */
678 RTGCPHYS GCPhysOpcodes;
679#endif
680 /** @} */
681
682 /** @name Target CPU information.
683 * @{ */
684#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
685 /** The target CPU. */
686 uint32_t uTargetCpu;
687#else
688 uint32_t u32TargetCpuPadding;
689#endif
690 /** The CPU vendor. */
691 CPUMCPUVENDOR enmCpuVendor;
692 /** @} */
693
694 /** @name Host CPU information.
695 * @{ */
696 /** The CPU vendor. */
697 CPUMCPUVENDOR enmHostCpuVendor;
698 /** @} */
699
700 uint32_t au32Alignment8[HC_ARCH_BITS == 64 ? 4 + 8 : 4]; /**< Alignment padding. */
701
702 /** Data TLB.
703 * @remarks Must be 64-byte aligned. */
704 IEMTLB DataTlb;
705 /** Instruction TLB.
706 * @remarks Must be 64-byte aligned. */
707 IEMTLB CodeTlb;
708
709 /** Pointer to the CPU context - ring-3 context.
710 * @todo put inside IEM_VERIFICATION_MODE_FULL++. */
711 R3PTRTYPE(PCPUMCTX) pCtxR3;
712 /** Pointer to the CPU context - ring-0 context. */
713 R0PTRTYPE(PCPUMCTX) pCtxR0;
714 /** Pointer to the CPU context - raw-mode context. */
715 RCPTRTYPE(PCPUMCTX) pCtxRC;
716
717 /** Pointer to instruction statistics for raw-mode context (same as R0). */
718 RCPTRTYPE(PIEMINSTRSTATS) pStatsRC;
719 /** Pointer to instruction statistics for ring-0 context (same as RC). */
720 R0PTRTYPE(PIEMINSTRSTATS) pStatsR0;
721 /** Pointer to instruction statistics for non-ring-3 code. */
722 R3PTRTYPE(PIEMINSTRSTATS) pStatsCCR3;
723 /** Pointer to instruction statistics for ring-3 context. */
724 R3PTRTYPE(PIEMINSTRSTATS) pStatsR3;
725
726#ifdef IEM_VERIFICATION_MODE_FULL
727 /** The event verification records for what IEM did (LIFO). */
728 R3PTRTYPE(PIEMVERIFYEVTREC) pIemEvtRecHead;
729 /** Insertion point for pIemEvtRecHead. */
730 R3PTRTYPE(PIEMVERIFYEVTREC *) ppIemEvtRecNext;
731 /** The event verification records for what the other party did (FIFO). */
732 R3PTRTYPE(PIEMVERIFYEVTREC) pOtherEvtRecHead;
733 /** Insertion point for pOtherEvtRecHead. */
734 R3PTRTYPE(PIEMVERIFYEVTREC *) ppOtherEvtRecNext;
735 /** List of free event records. */
736 R3PTRTYPE(PIEMVERIFYEVTREC) pFreeEvtRec;
737#endif
738} IEMCPU;
739AssertCompileMemberOffset(IEMCPU, fCurXcpt, 0x48);
740AssertCompileMemberAlignment(IEMCPU, DataTlb, 64);
741AssertCompileMemberAlignment(IEMCPU, CodeTlb, 64);
742/** Pointer to the per-CPU IEM state. */
743typedef IEMCPU *PIEMCPU;
744/** Pointer to the const per-CPU IEM state. */
745typedef IEMCPU const *PCIEMCPU;
746
747
748/** @def IEM_GET_CTX
749 * Gets the guest CPU context for the calling EMT.
750 * @returns PCPUMCTX
751 * @param a_pVCpu The cross context virtual CPU structure of the calling thread.
752 */
753#if !defined(IEM_VERIFICATION_MODE_FULL) && !defined(IEM_VERIFICATION_MODE) \
754 && !defined(IEM_VERIFICATION_MODE_MINIMAL) && defined(VMCPU_INCL_CPUM_GST_CTX)
755# define IEM_GET_CTX(a_pVCpu) (&(a_pVCpu)->cpum.GstCtx)
756#else
757# define IEM_GET_CTX(a_pVCpu) ((a_pVCpu)->iem.s.CTX_SUFF(pCtx))
758#endif
759
760/** Gets the current IEMTARGETCPU value.
761 * @returns IEMTARGETCPU value.
762 * @param a_pVCpu The cross context virtual CPU structure of the calling thread.
763 */
764#if IEM_CFG_TARGET_CPU != IEMTARGETCPU_DYNAMIC
765# define IEM_GET_TARGET_CPU(a_pVCpu) (IEM_CFG_TARGET_CPU)
766#else
767# define IEM_GET_TARGET_CPU(a_pVCpu) ((a_pVCpu)->iem.s.uTargetCpu)
768#endif
769
770/** @def Gets the instruction length. */
771#ifdef IEM_WITH_CODE_TLB
772# define IEM_GET_INSTR_LEN(a_pVCpu) ((a_pVCpu)->iem.s.offInstrNextByte - (uint32_t)(int32_t)(a_pVCpu)->iem.s.offCurInstrStart)
773#else
774# define IEM_GET_INSTR_LEN(a_pVCpu) ((a_pVCpu)->iem.s.offOpcode)
775#endif
776
777
778/** @name IEM_ACCESS_XXX - Access details.
779 * @{ */
780#define IEM_ACCESS_INVALID UINT32_C(0x000000ff)
781#define IEM_ACCESS_TYPE_READ UINT32_C(0x00000001)
782#define IEM_ACCESS_TYPE_WRITE UINT32_C(0x00000002)
783#define IEM_ACCESS_TYPE_EXEC UINT32_C(0x00000004)
784#define IEM_ACCESS_TYPE_MASK UINT32_C(0x00000007)
785#define IEM_ACCESS_WHAT_CODE UINT32_C(0x00000010)
786#define IEM_ACCESS_WHAT_DATA UINT32_C(0x00000020)
787#define IEM_ACCESS_WHAT_STACK UINT32_C(0x00000030)
788#define IEM_ACCESS_WHAT_SYS UINT32_C(0x00000040)
789#define IEM_ACCESS_WHAT_MASK UINT32_C(0x00000070)
790/** The writes are partial, so if initialize the bounce buffer with the
791 * orignal RAM content. */
792#define IEM_ACCESS_PARTIAL_WRITE UINT32_C(0x00000100)
793/** Used in aMemMappings to indicate that the entry is bounce buffered. */
794#define IEM_ACCESS_BOUNCE_BUFFERED UINT32_C(0x00000200)
795/** Bounce buffer with ring-3 write pending, first page. */
796#define IEM_ACCESS_PENDING_R3_WRITE_1ST UINT32_C(0x00000400)
797/** Bounce buffer with ring-3 write pending, second page. */
798#define IEM_ACCESS_PENDING_R3_WRITE_2ND UINT32_C(0x00000800)
799/** Valid bit mask. */
800#define IEM_ACCESS_VALID_MASK UINT32_C(0x00000fff)
801/** Read+write data alias. */
802#define IEM_ACCESS_DATA_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
803/** Write data alias. */
804#define IEM_ACCESS_DATA_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
805/** Read data alias. */
806#define IEM_ACCESS_DATA_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_DATA)
807/** Instruction fetch alias. */
808#define IEM_ACCESS_INSTRUCTION (IEM_ACCESS_TYPE_EXEC | IEM_ACCESS_WHAT_CODE)
809/** Stack write alias. */
810#define IEM_ACCESS_STACK_W (IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
811/** Stack read alias. */
812#define IEM_ACCESS_STACK_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_STACK)
813/** Stack read+write alias. */
814#define IEM_ACCESS_STACK_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_STACK)
815/** Read system table alias. */
816#define IEM_ACCESS_SYS_R (IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_SYS)
817/** Read+write system table alias. */
818#define IEM_ACCESS_SYS_RW (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_SYS)
819/** @} */
820
821/** @name Prefix constants (IEMCPU::fPrefixes)
822 * @{ */
823#define IEM_OP_PRF_SEG_CS RT_BIT_32(0) /**< CS segment prefix (0x2e). */
824#define IEM_OP_PRF_SEG_SS RT_BIT_32(1) /**< SS segment prefix (0x36). */
825#define IEM_OP_PRF_SEG_DS RT_BIT_32(2) /**< DS segment prefix (0x3e). */
826#define IEM_OP_PRF_SEG_ES RT_BIT_32(3) /**< ES segment prefix (0x26). */
827#define IEM_OP_PRF_SEG_FS RT_BIT_32(4) /**< FS segment prefix (0x64). */
828#define IEM_OP_PRF_SEG_GS RT_BIT_32(5) /**< GS segment prefix (0x65). */
829#define IEM_OP_PRF_SEG_MASK UINT32_C(0x3f)
830
831#define IEM_OP_PRF_SIZE_OP RT_BIT_32(8) /**< Operand size prefix (0x66). */
832#define IEM_OP_PRF_SIZE_REX_W RT_BIT_32(9) /**< REX.W prefix (0x48-0x4f). */
833#define IEM_OP_PRF_SIZE_ADDR RT_BIT_32(10) /**< Address size prefix (0x67). */
834
835#define IEM_OP_PRF_LOCK RT_BIT_32(16) /**< Lock prefix (0xf0). */
836#define IEM_OP_PRF_REPNZ RT_BIT_32(17) /**< Repeat-not-zero prefix (0xf2). */
837#define IEM_OP_PRF_REPZ RT_BIT_32(18) /**< Repeat-if-zero prefix (0xf3). */
838
839#define IEM_OP_PRF_REX RT_BIT_32(24) /**< Any REX prefix (0x40-0x4f). */
840#define IEM_OP_PRF_REX_R RT_BIT_32(25) /**< REX.R prefix (0x44,0x45,0x46,0x47,0x4c,0x4d,0x4e,0x4f). */
841#define IEM_OP_PRF_REX_B RT_BIT_32(26) /**< REX.B prefix (0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f). */
842#define IEM_OP_PRF_REX_X RT_BIT_32(27) /**< REX.X prefix (0x42,0x43,0x46,0x47,0x4a,0x4b,0x4e,0x4f). */
843/** Mask with all the REX prefix flags.
844 * This is generally for use when needing to undo the REX prefixes when they
845 * are followed legacy prefixes and therefore does not immediately preceed
846 * the first opcode byte.
847 * For testing whether any REX prefix is present, use IEM_OP_PRF_REX instead. */
848#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 )
849
850#define IEM_OP_PRF_VEX RT_BIT_32(28) /**< Indiciates VEX prefix. */
851#define IEM_OP_PRF_EVEX RT_BIT_32(29) /**< Indiciates EVEX prefix. */
852#define IEM_OP_PRF_XOP RT_BIT_32(30) /**< Indiciates XOP prefix. */
853/** @} */
854
855/** @name IEMOPFORM_XXX - Opcode forms
856 * @note These are ORed together with IEMOPHINT_XXX.
857 * @{ */
858/** ModR/M: reg, r/m */
859#define IEMOPFORM_RM 0
860/** ModR/M: reg, r/m (register) */
861#define IEMOPFORM_RM_REG (IEMOPFORM_RM | IEMOPFORM_MOD3)
862/** ModR/M: reg, r/m (memory) */
863#define IEMOPFORM_RM_MEM (IEMOPFORM_RM | IEMOPFORM_NOT_MOD3)
864/** ModR/M: r/m, reg */
865#define IEMOPFORM_MR 1
866/** ModR/M: r/m (register), reg */
867#define IEMOPFORM_MR_REG (IEMOPFORM_MR | IEMOPFORM_MOD3)
868/** ModR/M: r/m (memory), reg */
869#define IEMOPFORM_MR_MEM (IEMOPFORM_MR | IEMOPFORM_NOT_MOD3)
870/** ModR/M: r/m only */
871#define IEMOPFORM_M 2
872/** ModR/M: r/m only (register). */
873#define IEMOPFORM_M_REG (IEMOPFORM_M | IEMOPFORM_MOD3)
874/** ModR/M: r/m only (memory). */
875#define IEMOPFORM_M_MEM (IEMOPFORM_M | IEMOPFORM_NOT_MOD3)
876/** ModR/M: reg only */
877#define IEMOPFORM_R 3
878
879/** VEX+ModR/M: reg, r/m */
880#define IEMOPFORM_VEX_RM 4
881/** VEX+ModR/M: reg, r/m (register) */
882#define IEMOPFORM_VEX_RM_REG (IEMOPFORM_VEX_RM | IEMOPFORM_MOD3)
883/** VEX+ModR/M: reg, r/m (memory) */
884#define IEMOPFORM_VEX_RM_MEM (IEMOPFORM_VEX_RM | IEMOPFORM_NOT_MOD3)
885/** VEX+ModR/M: r/m, reg */
886#define IEMOPFORM_VEX_MR 5
887/** VEX+ModR/M: r/m (register), reg */
888#define IEMOPFORM_VEX_MR_REG (IEMOPFORM_VEX_MR | IEMOPFORM_MOD3)
889/** VEX+ModR/M: r/m (memory), reg */
890#define IEMOPFORM_VEX_MR_MEM (IEMOPFORM_VEX_MR | IEMOPFORM_NOT_MOD3)
891/** VEX+ModR/M: r/m only */
892#define IEMOPFORM_VEX_M 6
893/** VEX+ModR/M: r/m only (register). */
894#define IEMOPFORM_VEX_M_REG (IEMOPFORM_VEX_M | IEMOPFORM_MOD3)
895/** VEX+ModR/M: r/m only (memory). */
896#define IEMOPFORM_VEX_M_MEM (IEMOPFORM_VEX_M | IEMOPFORM_NOT_MOD3)
897/** VEX+ModR/M: reg only */
898#define IEMOPFORM_VEX_R 7
899/** VEX+ModR/M: reg, vvvv, r/m */
900#define IEMOPFORM_VEX_RVM 8
901/** VEX+ModR/M: r/m, vvvv, reg */
902#define IEMOPFORM_VEX_MVR 9
903
904/** Fixed register instruction, no R/M. */
905#define IEMOPFORM_FIXED 16
906
907/** The r/m is a register. */
908#define IEMOPFORM_MOD3 RT_BIT_32(8)
909/** The r/m is a memory access. */
910#define IEMOPFORM_NOT_MOD3 RT_BIT_32(9)
911/** @} */
912
913/** @name IEMOPHINT_XXX - Additional Opcode Hints
914 * @note These are ORed together with IEMOPFORM_XXX.
915 * @{ */
916/** Both the operand size prefixes are ignored. */
917#define IEMOPHINT_IGNORES_OP_SIZE RT_BIT_32(10)
918/** Allowed with the lock prefix. */
919#define IEMOPHINT_LOCK_ALLOWED RT_BIT_32(11)
920/** Hint to IEMAllInstructionPython.py that this macro should be skipped. */
921#define IEMOPHINT_SKIP_PYTHON RT_BIT_32(31)
922/** @} */
923
924/**
925 * Possible hardware task switch sources.
926 */
927typedef enum IEMTASKSWITCH
928{
929 /** Task switch caused by an interrupt/exception. */
930 IEMTASKSWITCH_INT_XCPT = 1,
931 /** Task switch caused by a far CALL. */
932 IEMTASKSWITCH_CALL,
933 /** Task switch caused by a far JMP. */
934 IEMTASKSWITCH_JUMP,
935 /** Task switch caused by an IRET. */
936 IEMTASKSWITCH_IRET
937} IEMTASKSWITCH;
938AssertCompileSize(IEMTASKSWITCH, 4);
939
940
941/**
942 * Tests if verification mode is enabled.
943 *
944 * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
945 * should therefore cause the compiler to eliminate the verification branch
946 * of an if statement. */
947#ifdef IEM_VERIFICATION_MODE_FULL
948# define IEM_VERIFICATION_ENABLED(a_pVCpu) (!(a_pVCpu)->iem.s.fNoRem)
949#elif defined(IEM_VERIFICATION_MODE_MINIMAL)
950# define IEM_VERIFICATION_ENABLED(a_pVCpu) (true)
951#else
952# define IEM_VERIFICATION_ENABLED(a_pVCpu) (false)
953#endif
954
955/**
956 * Tests if full verification mode is enabled.
957 *
958 * This expands to @c false when IEM_VERIFICATION_MODE_FULL is not defined and
959 * should therefore cause the compiler to eliminate the verification branch
960 * of an if statement. */
961#ifdef IEM_VERIFICATION_MODE_FULL
962# define IEM_FULL_VERIFICATION_ENABLED(a_pVCpu) (!(a_pVCpu)->iem.s.fNoRem)
963#else
964# define IEM_FULL_VERIFICATION_ENABLED(a_pVCpu) (false)
965#endif
966
967/**
968 * Tests if full verification mode is enabled again REM.
969 *
970 * This expands to @c false when IEM_VERIFICATION_MODE_FULL is not defined and
971 * should therefore cause the compiler to eliminate the verification branch
972 * of an if statement. */
973#ifdef IEM_VERIFICATION_MODE_FULL
974# ifdef IEM_VERIFICATION_MODE_FULL_HM
975# define IEM_FULL_VERIFICATION_REM_ENABLED(a_pVCpu) (!(a_pVCpu)->iem.s.fNoRem && !HMIsEnabled((a_pVCpu)->CTX_SUFF(pVM)))
976# else
977# define IEM_FULL_VERIFICATION_REM_ENABLED(a_pVCpu) (!(a_pVCpu)->iem.s.fNoRem)
978# endif
979#else
980# define IEM_FULL_VERIFICATION_REM_ENABLED(a_pVCpu) (false)
981#endif
982
983/** @def IEM_VERIFICATION_MODE
984 * Indicates that one of the verfication modes are enabled.
985 */
986#if (defined(IEM_VERIFICATION_MODE_FULL) || defined(IEM_VERIFICATION_MODE_MINIMAL)) && !defined(IEM_VERIFICATION_MODE) \
987 || defined(DOXYGEN_RUNNING)
988# define IEM_VERIFICATION_MODE
989#endif
990
991/**
992 * Indicates to the verifier that the given flag set is undefined.
993 *
994 * Can be invoked again to add more flags.
995 *
996 * This is a NOOP if the verifier isn't compiled in.
997 */
998#ifdef IEM_VERIFICATION_MODE_FULL
999# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { pVCpu->iem.s.fUndefinedEFlags |= (a_fEfl); } while (0)
1000#else
1001# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { } while (0)
1002#endif
1003
1004
1005/** @def IEM_DECL_IMPL_TYPE
1006 * For typedef'ing an instruction implementation function.
1007 *
1008 * @param a_RetType The return type.
1009 * @param a_Name The name of the type.
1010 * @param a_ArgList The argument list enclosed in parentheses.
1011 */
1012
1013/** @def IEM_DECL_IMPL_DEF
1014 * For defining an instruction implementation function.
1015 *
1016 * @param a_RetType The return type.
1017 * @param a_Name The name of the type.
1018 * @param a_ArgList The argument list enclosed in parentheses.
1019 */
1020
1021#if defined(__GNUC__) && defined(RT_ARCH_X86)
1022# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
1023 __attribute__((__fastcall__)) a_RetType (a_Name) a_ArgList
1024# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
1025 __attribute__((__fastcall__, __nothrow__)) a_RetType a_Name a_ArgList
1026
1027#elif defined(_MSC_VER) && defined(RT_ARCH_X86)
1028# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
1029 a_RetType (__fastcall a_Name) a_ArgList
1030# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
1031 a_RetType __fastcall a_Name a_ArgList
1032
1033#else
1034# define IEM_DECL_IMPL_TYPE(a_RetType, a_Name, a_ArgList) \
1035 a_RetType (VBOXCALL a_Name) a_ArgList
1036# define IEM_DECL_IMPL_DEF(a_RetType, a_Name, a_ArgList) \
1037 a_RetType VBOXCALL a_Name a_ArgList
1038
1039#endif
1040
1041/** @name Arithmetic assignment operations on bytes (binary).
1042 * @{ */
1043typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU8, (uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags));
1044typedef FNIEMAIMPLBINU8 *PFNIEMAIMPLBINU8;
1045FNIEMAIMPLBINU8 iemAImpl_add_u8, iemAImpl_add_u8_locked;
1046FNIEMAIMPLBINU8 iemAImpl_adc_u8, iemAImpl_adc_u8_locked;
1047FNIEMAIMPLBINU8 iemAImpl_sub_u8, iemAImpl_sub_u8_locked;
1048FNIEMAIMPLBINU8 iemAImpl_sbb_u8, iemAImpl_sbb_u8_locked;
1049FNIEMAIMPLBINU8 iemAImpl_or_u8, iemAImpl_or_u8_locked;
1050FNIEMAIMPLBINU8 iemAImpl_xor_u8, iemAImpl_xor_u8_locked;
1051FNIEMAIMPLBINU8 iemAImpl_and_u8, iemAImpl_and_u8_locked;
1052/** @} */
1053
1054/** @name Arithmetic assignment operations on words (binary).
1055 * @{ */
1056typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU16, (uint16_t *pu16Dst, uint16_t u16Src, uint32_t *pEFlags));
1057typedef FNIEMAIMPLBINU16 *PFNIEMAIMPLBINU16;
1058FNIEMAIMPLBINU16 iemAImpl_add_u16, iemAImpl_add_u16_locked;
1059FNIEMAIMPLBINU16 iemAImpl_adc_u16, iemAImpl_adc_u16_locked;
1060FNIEMAIMPLBINU16 iemAImpl_sub_u16, iemAImpl_sub_u16_locked;
1061FNIEMAIMPLBINU16 iemAImpl_sbb_u16, iemAImpl_sbb_u16_locked;
1062FNIEMAIMPLBINU16 iemAImpl_or_u16, iemAImpl_or_u16_locked;
1063FNIEMAIMPLBINU16 iemAImpl_xor_u16, iemAImpl_xor_u16_locked;
1064FNIEMAIMPLBINU16 iemAImpl_and_u16, iemAImpl_and_u16_locked;
1065/** @} */
1066
1067/** @name Arithmetic assignment operations on double words (binary).
1068 * @{ */
1069typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU32, (uint32_t *pu32Dst, uint32_t u32Src, uint32_t *pEFlags));
1070typedef FNIEMAIMPLBINU32 *PFNIEMAIMPLBINU32;
1071FNIEMAIMPLBINU32 iemAImpl_add_u32, iemAImpl_add_u32_locked;
1072FNIEMAIMPLBINU32 iemAImpl_adc_u32, iemAImpl_adc_u32_locked;
1073FNIEMAIMPLBINU32 iemAImpl_sub_u32, iemAImpl_sub_u32_locked;
1074FNIEMAIMPLBINU32 iemAImpl_sbb_u32, iemAImpl_sbb_u32_locked;
1075FNIEMAIMPLBINU32 iemAImpl_or_u32, iemAImpl_or_u32_locked;
1076FNIEMAIMPLBINU32 iemAImpl_xor_u32, iemAImpl_xor_u32_locked;
1077FNIEMAIMPLBINU32 iemAImpl_and_u32, iemAImpl_and_u32_locked;
1078/** @} */
1079
1080/** @name Arithmetic assignment operations on quad words (binary).
1081 * @{ */
1082typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU64, (uint64_t *pu64Dst, uint64_t u64Src, uint32_t *pEFlags));
1083typedef FNIEMAIMPLBINU64 *PFNIEMAIMPLBINU64;
1084FNIEMAIMPLBINU64 iemAImpl_add_u64, iemAImpl_add_u64_locked;
1085FNIEMAIMPLBINU64 iemAImpl_adc_u64, iemAImpl_adc_u64_locked;
1086FNIEMAIMPLBINU64 iemAImpl_sub_u64, iemAImpl_sub_u64_locked;
1087FNIEMAIMPLBINU64 iemAImpl_sbb_u64, iemAImpl_sbb_u64_locked;
1088FNIEMAIMPLBINU64 iemAImpl_or_u64, iemAImpl_or_u64_locked;
1089FNIEMAIMPLBINU64 iemAImpl_xor_u64, iemAImpl_xor_u64_locked;
1090FNIEMAIMPLBINU64 iemAImpl_and_u64, iemAImpl_and_u64_locked;
1091/** @} */
1092
1093/** @name Compare operations (thrown in with the binary ops).
1094 * @{ */
1095FNIEMAIMPLBINU8 iemAImpl_cmp_u8;
1096FNIEMAIMPLBINU16 iemAImpl_cmp_u16;
1097FNIEMAIMPLBINU32 iemAImpl_cmp_u32;
1098FNIEMAIMPLBINU64 iemAImpl_cmp_u64;
1099/** @} */
1100
1101/** @name Test operations (thrown in with the binary ops).
1102 * @{ */
1103FNIEMAIMPLBINU8 iemAImpl_test_u8;
1104FNIEMAIMPLBINU16 iemAImpl_test_u16;
1105FNIEMAIMPLBINU32 iemAImpl_test_u32;
1106FNIEMAIMPLBINU64 iemAImpl_test_u64;
1107/** @} */
1108
1109/** @name Bit operations operations (thrown in with the binary ops).
1110 * @{ */
1111FNIEMAIMPLBINU16 iemAImpl_bt_u16, iemAImpl_bt_u16_locked;
1112FNIEMAIMPLBINU32 iemAImpl_bt_u32, iemAImpl_bt_u32_locked;
1113FNIEMAIMPLBINU64 iemAImpl_bt_u64, iemAImpl_bt_u64_locked;
1114FNIEMAIMPLBINU16 iemAImpl_btc_u16, iemAImpl_btc_u16_locked;
1115FNIEMAIMPLBINU32 iemAImpl_btc_u32, iemAImpl_btc_u32_locked;
1116FNIEMAIMPLBINU64 iemAImpl_btc_u64, iemAImpl_btc_u64_locked;
1117FNIEMAIMPLBINU16 iemAImpl_btr_u16, iemAImpl_btr_u16_locked;
1118FNIEMAIMPLBINU32 iemAImpl_btr_u32, iemAImpl_btr_u32_locked;
1119FNIEMAIMPLBINU64 iemAImpl_btr_u64, iemAImpl_btr_u64_locked;
1120FNIEMAIMPLBINU16 iemAImpl_bts_u16, iemAImpl_bts_u16_locked;
1121FNIEMAIMPLBINU32 iemAImpl_bts_u32, iemAImpl_bts_u32_locked;
1122FNIEMAIMPLBINU64 iemAImpl_bts_u64, iemAImpl_bts_u64_locked;
1123/** @} */
1124
1125/** @name Exchange memory with register operations.
1126 * @{ */
1127IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u8, (uint8_t *pu8Mem, uint8_t *pu8Reg));
1128IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u16,(uint16_t *pu16Mem, uint16_t *pu16Reg));
1129IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u32,(uint32_t *pu32Mem, uint32_t *pu32Reg));
1130IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u64,(uint64_t *pu64Mem, uint64_t *pu64Reg));
1131/** @} */
1132
1133/** @name Exchange and add operations.
1134 * @{ */
1135IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
1136IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
1137IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
1138IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
1139IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8_locked, (uint8_t *pu8Dst, uint8_t *pu8Reg, uint32_t *pEFlags));
1140IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16_locked,(uint16_t *pu16Dst, uint16_t *pu16Reg, uint32_t *pEFlags));
1141IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32_locked,(uint32_t *pu32Dst, uint32_t *pu32Reg, uint32_t *pEFlags));
1142IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *pu64Dst, uint64_t *pu64Reg, uint32_t *pEFlags));
1143/** @} */
1144
1145/** @name Compare and exchange.
1146 * @{ */
1147IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u8, (uint8_t *pu8Dst, uint8_t *puAl, uint8_t uSrcReg, uint32_t *pEFlags));
1148IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u8_locked, (uint8_t *pu8Dst, uint8_t *puAl, uint8_t uSrcReg, uint32_t *pEFlags));
1149IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u16, (uint16_t *pu16Dst, uint16_t *puAx, uint16_t uSrcReg, uint32_t *pEFlags));
1150IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u16_locked,(uint16_t *pu16Dst, uint16_t *puAx, uint16_t uSrcReg, uint32_t *pEFlags));
1151IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u32, (uint32_t *pu32Dst, uint32_t *puEax, uint32_t uSrcReg, uint32_t *pEFlags));
1152IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u32_locked,(uint32_t *pu32Dst, uint32_t *puEax, uint32_t uSrcReg, uint32_t *pEFlags));
1153#ifdef RT_ARCH_X86
1154IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64, (uint64_t *pu64Dst, uint64_t *puRax, uint64_t *puSrcReg, uint32_t *pEFlags));
1155IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64_locked,(uint64_t *pu64Dst, uint64_t *puRax, uint64_t *puSrcReg, uint32_t *pEFlags));
1156#else
1157IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64, (uint64_t *pu64Dst, uint64_t *puRax, uint64_t uSrcReg, uint32_t *pEFlags));
1158IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg_u64_locked,(uint64_t *pu64Dst, uint64_t *puRax, uint64_t uSrcReg, uint32_t *pEFlags));
1159#endif
1160IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg8b,(uint64_t *pu64Dst, PRTUINT64U pu64EaxEdx, PRTUINT64U pu64EbxEcx,
1161 uint32_t *pEFlags));
1162IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg8b_locked,(uint64_t *pu64Dst, PRTUINT64U pu64EaxEdx, PRTUINT64U pu64EbxEcx,
1163 uint32_t *pEFlags));
1164IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b,(PRTUINT128U pu128Dst, PRTUINT128U pu128RaxRdx, PRTUINT128U pu128RbxRcx,
1165 uint32_t *pEFlags));
1166IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b_locked,(PRTUINT128U pu128Dst, PRTUINT128U pu128RaxRdx, PRTUINT128U pu128RbxRcx,
1167 uint32_t *pEFlags));
1168IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b_fallback,(PRTUINT128U pu128Dst, PRTUINT128U pu128RaxRdx,
1169 PRTUINT128U pu128RbxRcx, uint32_t *pEFlags));
1170/** @} */
1171
1172/** @name Memory ordering
1173 * @{ */
1174typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEMFENCE,(void));
1175typedef FNIEMAIMPLMEMFENCE *PFNIEMAIMPLMEMFENCE;
1176IEM_DECL_IMPL_DEF(void, iemAImpl_mfence,(void));
1177IEM_DECL_IMPL_DEF(void, iemAImpl_sfence,(void));
1178IEM_DECL_IMPL_DEF(void, iemAImpl_lfence,(void));
1179IEM_DECL_IMPL_DEF(void, iemAImpl_alt_mem_fence,(void));
1180/** @} */
1181
1182/** @name Double precision shifts
1183 * @{ */
1184typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU16,(uint16_t *pu16Dst, uint16_t u16Src, uint8_t cShift, uint32_t *pEFlags));
1185typedef FNIEMAIMPLSHIFTDBLU16 *PFNIEMAIMPLSHIFTDBLU16;
1186typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU32,(uint32_t *pu32Dst, uint32_t u32Src, uint8_t cShift, uint32_t *pEFlags));
1187typedef FNIEMAIMPLSHIFTDBLU32 *PFNIEMAIMPLSHIFTDBLU32;
1188typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU64,(uint64_t *pu64Dst, uint64_t u64Src, uint8_t cShift, uint32_t *pEFlags));
1189typedef FNIEMAIMPLSHIFTDBLU64 *PFNIEMAIMPLSHIFTDBLU64;
1190FNIEMAIMPLSHIFTDBLU16 iemAImpl_shld_u16;
1191FNIEMAIMPLSHIFTDBLU32 iemAImpl_shld_u32;
1192FNIEMAIMPLSHIFTDBLU64 iemAImpl_shld_u64;
1193FNIEMAIMPLSHIFTDBLU16 iemAImpl_shrd_u16;
1194FNIEMAIMPLSHIFTDBLU32 iemAImpl_shrd_u32;
1195FNIEMAIMPLSHIFTDBLU64 iemAImpl_shrd_u64;
1196/** @} */
1197
1198
1199/** @name Bit search operations (thrown in with the binary ops).
1200 * @{ */
1201FNIEMAIMPLBINU16 iemAImpl_bsf_u16;
1202FNIEMAIMPLBINU32 iemAImpl_bsf_u32;
1203FNIEMAIMPLBINU64 iemAImpl_bsf_u64;
1204FNIEMAIMPLBINU16 iemAImpl_bsr_u16;
1205FNIEMAIMPLBINU32 iemAImpl_bsr_u32;
1206FNIEMAIMPLBINU64 iemAImpl_bsr_u64;
1207/** @} */
1208
1209/** @name Signed multiplication operations (thrown in with the binary ops).
1210 * @{ */
1211FNIEMAIMPLBINU16 iemAImpl_imul_two_u16;
1212FNIEMAIMPLBINU32 iemAImpl_imul_two_u32;
1213FNIEMAIMPLBINU64 iemAImpl_imul_two_u64;
1214/** @} */
1215
1216/** @name Arithmetic assignment operations on bytes (unary).
1217 * @{ */
1218typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU8, (uint8_t *pu8Dst, uint32_t *pEFlags));
1219typedef FNIEMAIMPLUNARYU8 *PFNIEMAIMPLUNARYU8;
1220FNIEMAIMPLUNARYU8 iemAImpl_inc_u8, iemAImpl_inc_u8_locked;
1221FNIEMAIMPLUNARYU8 iemAImpl_dec_u8, iemAImpl_dec_u8_locked;
1222FNIEMAIMPLUNARYU8 iemAImpl_not_u8, iemAImpl_not_u8_locked;
1223FNIEMAIMPLUNARYU8 iemAImpl_neg_u8, iemAImpl_neg_u8_locked;
1224/** @} */
1225
1226/** @name Arithmetic assignment operations on words (unary).
1227 * @{ */
1228typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU16, (uint16_t *pu16Dst, uint32_t *pEFlags));
1229typedef FNIEMAIMPLUNARYU16 *PFNIEMAIMPLUNARYU16;
1230FNIEMAIMPLUNARYU16 iemAImpl_inc_u16, iemAImpl_inc_u16_locked;
1231FNIEMAIMPLUNARYU16 iemAImpl_dec_u16, iemAImpl_dec_u16_locked;
1232FNIEMAIMPLUNARYU16 iemAImpl_not_u16, iemAImpl_not_u16_locked;
1233FNIEMAIMPLUNARYU16 iemAImpl_neg_u16, iemAImpl_neg_u16_locked;
1234/** @} */
1235
1236/** @name Arithmetic assignment operations on double words (unary).
1237 * @{ */
1238typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU32, (uint32_t *pu32Dst, uint32_t *pEFlags));
1239typedef FNIEMAIMPLUNARYU32 *PFNIEMAIMPLUNARYU32;
1240FNIEMAIMPLUNARYU32 iemAImpl_inc_u32, iemAImpl_inc_u32_locked;
1241FNIEMAIMPLUNARYU32 iemAImpl_dec_u32, iemAImpl_dec_u32_locked;
1242FNIEMAIMPLUNARYU32 iemAImpl_not_u32, iemAImpl_not_u32_locked;
1243FNIEMAIMPLUNARYU32 iemAImpl_neg_u32, iemAImpl_neg_u32_locked;
1244/** @} */
1245
1246/** @name Arithmetic assignment operations on quad words (unary).
1247 * @{ */
1248typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLUNARYU64, (uint64_t *pu64Dst, uint32_t *pEFlags));
1249typedef FNIEMAIMPLUNARYU64 *PFNIEMAIMPLUNARYU64;
1250FNIEMAIMPLUNARYU64 iemAImpl_inc_u64, iemAImpl_inc_u64_locked;
1251FNIEMAIMPLUNARYU64 iemAImpl_dec_u64, iemAImpl_dec_u64_locked;
1252FNIEMAIMPLUNARYU64 iemAImpl_not_u64, iemAImpl_not_u64_locked;
1253FNIEMAIMPLUNARYU64 iemAImpl_neg_u64, iemAImpl_neg_u64_locked;
1254/** @} */
1255
1256
1257/** @name Shift operations on bytes (Group 2).
1258 * @{ */
1259typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU8,(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags));
1260typedef FNIEMAIMPLSHIFTU8 *PFNIEMAIMPLSHIFTU8;
1261FNIEMAIMPLSHIFTU8 iemAImpl_rol_u8;
1262FNIEMAIMPLSHIFTU8 iemAImpl_ror_u8;
1263FNIEMAIMPLSHIFTU8 iemAImpl_rcl_u8;
1264FNIEMAIMPLSHIFTU8 iemAImpl_rcr_u8;
1265FNIEMAIMPLSHIFTU8 iemAImpl_shl_u8;
1266FNIEMAIMPLSHIFTU8 iemAImpl_shr_u8;
1267FNIEMAIMPLSHIFTU8 iemAImpl_sar_u8;
1268/** @} */
1269
1270/** @name Shift operations on words (Group 2).
1271 * @{ */
1272typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU16,(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags));
1273typedef FNIEMAIMPLSHIFTU16 *PFNIEMAIMPLSHIFTU16;
1274FNIEMAIMPLSHIFTU16 iemAImpl_rol_u16;
1275FNIEMAIMPLSHIFTU16 iemAImpl_ror_u16;
1276FNIEMAIMPLSHIFTU16 iemAImpl_rcl_u16;
1277FNIEMAIMPLSHIFTU16 iemAImpl_rcr_u16;
1278FNIEMAIMPLSHIFTU16 iemAImpl_shl_u16;
1279FNIEMAIMPLSHIFTU16 iemAImpl_shr_u16;
1280FNIEMAIMPLSHIFTU16 iemAImpl_sar_u16;
1281/** @} */
1282
1283/** @name Shift operations on double words (Group 2).
1284 * @{ */
1285typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU32,(uint32_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags));
1286typedef FNIEMAIMPLSHIFTU32 *PFNIEMAIMPLSHIFTU32;
1287FNIEMAIMPLSHIFTU32 iemAImpl_rol_u32;
1288FNIEMAIMPLSHIFTU32 iemAImpl_ror_u32;
1289FNIEMAIMPLSHIFTU32 iemAImpl_rcl_u32;
1290FNIEMAIMPLSHIFTU32 iemAImpl_rcr_u32;
1291FNIEMAIMPLSHIFTU32 iemAImpl_shl_u32;
1292FNIEMAIMPLSHIFTU32 iemAImpl_shr_u32;
1293FNIEMAIMPLSHIFTU32 iemAImpl_sar_u32;
1294/** @} */
1295
1296/** @name Shift operations on words (Group 2).
1297 * @{ */
1298typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU64,(uint64_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags));
1299typedef FNIEMAIMPLSHIFTU64 *PFNIEMAIMPLSHIFTU64;
1300FNIEMAIMPLSHIFTU64 iemAImpl_rol_u64;
1301FNIEMAIMPLSHIFTU64 iemAImpl_ror_u64;
1302FNIEMAIMPLSHIFTU64 iemAImpl_rcl_u64;
1303FNIEMAIMPLSHIFTU64 iemAImpl_rcr_u64;
1304FNIEMAIMPLSHIFTU64 iemAImpl_shl_u64;
1305FNIEMAIMPLSHIFTU64 iemAImpl_shr_u64;
1306FNIEMAIMPLSHIFTU64 iemAImpl_sar_u64;
1307/** @} */
1308
1309/** @name Multiplication and division operations.
1310 * @{ */
1311typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t *pEFlags));
1312typedef FNIEMAIMPLMULDIVU8 *PFNIEMAIMPLMULDIVU8;
1313FNIEMAIMPLMULDIVU8 iemAImpl_mul_u8, iemAImpl_imul_u8;
1314FNIEMAIMPLMULDIVU8 iemAImpl_div_u8, iemAImpl_idiv_u8;
1315
1316typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t *pEFlags));
1317typedef FNIEMAIMPLMULDIVU16 *PFNIEMAIMPLMULDIVU16;
1318FNIEMAIMPLMULDIVU16 iemAImpl_mul_u16, iemAImpl_imul_u16;
1319FNIEMAIMPLMULDIVU16 iemAImpl_div_u16, iemAImpl_idiv_u16;
1320
1321typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t *pEFlags));
1322typedef FNIEMAIMPLMULDIVU32 *PFNIEMAIMPLMULDIVU32;
1323FNIEMAIMPLMULDIVU32 iemAImpl_mul_u32, iemAImpl_imul_u32;
1324FNIEMAIMPLMULDIVU32 iemAImpl_div_u32, iemAImpl_idiv_u32;
1325
1326typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t *pEFlags));
1327typedef FNIEMAIMPLMULDIVU64 *PFNIEMAIMPLMULDIVU64;
1328FNIEMAIMPLMULDIVU64 iemAImpl_mul_u64, iemAImpl_imul_u64;
1329FNIEMAIMPLMULDIVU64 iemAImpl_div_u64, iemAImpl_idiv_u64;
1330/** @} */
1331
1332/** @name Byte Swap.
1333 * @{ */
1334IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u16,(uint32_t *pu32Dst)); /* Yes, 32-bit register access. */
1335IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u32,(uint32_t *pu32Dst));
1336IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u64,(uint64_t *pu64Dst));
1337/** @} */
1338
1339/** @name Misc.
1340 * @{ */
1341FNIEMAIMPLBINU16 iemAImpl_arpl;
1342/** @} */
1343
1344
1345/** @name FPU operations taking a 32-bit float argument
1346 * @{ */
1347typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
1348 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
1349typedef FNIEMAIMPLFPUR32FSW *PFNIEMAIMPLFPUR32FSW;
1350
1351typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1352 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
1353typedef FNIEMAIMPLFPUR32 *PFNIEMAIMPLFPUR32;
1354
1355FNIEMAIMPLFPUR32FSW iemAImpl_fcom_r80_by_r32;
1356FNIEMAIMPLFPUR32 iemAImpl_fadd_r80_by_r32;
1357FNIEMAIMPLFPUR32 iemAImpl_fmul_r80_by_r32;
1358FNIEMAIMPLFPUR32 iemAImpl_fsub_r80_by_r32;
1359FNIEMAIMPLFPUR32 iemAImpl_fsubr_r80_by_r32;
1360FNIEMAIMPLFPUR32 iemAImpl_fdiv_r80_by_r32;
1361FNIEMAIMPLFPUR32 iemAImpl_fdivr_r80_by_r32;
1362
1363IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r32_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT32U pr32Val));
1364IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1365 PRTFLOAT32U pr32Val, PCRTFLOAT80U pr80Val));
1366/** @} */
1367
1368/** @name FPU operations taking a 64-bit float argument
1369 * @{ */
1370typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1371 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
1372typedef FNIEMAIMPLFPUR64 *PFNIEMAIMPLFPUR64;
1373
1374FNIEMAIMPLFPUR64 iemAImpl_fadd_r80_by_r64;
1375FNIEMAIMPLFPUR64 iemAImpl_fmul_r80_by_r64;
1376FNIEMAIMPLFPUR64 iemAImpl_fsub_r80_by_r64;
1377FNIEMAIMPLFPUR64 iemAImpl_fsubr_r80_by_r64;
1378FNIEMAIMPLFPUR64 iemAImpl_fdiv_r80_by_r64;
1379FNIEMAIMPLFPUR64 iemAImpl_fdivr_r80_by_r64;
1380
1381IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r64,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
1382 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
1383IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r64_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val));
1384IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1385 PRTFLOAT64U pr32Val, PCRTFLOAT80U pr80Val));
1386/** @} */
1387
1388/** @name FPU operations taking a 80-bit float argument
1389 * @{ */
1390typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1391 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
1392typedef FNIEMAIMPLFPUR80 *PFNIEMAIMPLFPUR80;
1393FNIEMAIMPLFPUR80 iemAImpl_fadd_r80_by_r80;
1394FNIEMAIMPLFPUR80 iemAImpl_fmul_r80_by_r80;
1395FNIEMAIMPLFPUR80 iemAImpl_fsub_r80_by_r80;
1396FNIEMAIMPLFPUR80 iemAImpl_fsubr_r80_by_r80;
1397FNIEMAIMPLFPUR80 iemAImpl_fdiv_r80_by_r80;
1398FNIEMAIMPLFPUR80 iemAImpl_fdivr_r80_by_r80;
1399FNIEMAIMPLFPUR80 iemAImpl_fprem_r80_by_r80;
1400FNIEMAIMPLFPUR80 iemAImpl_fprem1_r80_by_r80;
1401FNIEMAIMPLFPUR80 iemAImpl_fscale_r80_by_r80;
1402
1403FNIEMAIMPLFPUR80 iemAImpl_fpatan_r80_by_r80;
1404FNIEMAIMPLFPUR80 iemAImpl_fyl2x_r80_by_r80;
1405FNIEMAIMPLFPUR80 iemAImpl_fyl2xp1_r80_by_r80;
1406
1407typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
1408 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
1409typedef FNIEMAIMPLFPUR80FSW *PFNIEMAIMPLFPUR80FSW;
1410FNIEMAIMPLFPUR80FSW iemAImpl_fcom_r80_by_r80;
1411FNIEMAIMPLFPUR80FSW iemAImpl_fucom_r80_by_r80;
1412
1413typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLFPUR80EFL,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1414 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
1415typedef FNIEMAIMPLFPUR80EFL *PFNIEMAIMPLFPUR80EFL;
1416FNIEMAIMPLFPUR80EFL iemAImpl_fcomi_r80_by_r80;
1417FNIEMAIMPLFPUR80EFL iemAImpl_fucomi_r80_by_r80;
1418
1419typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARY,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
1420typedef FNIEMAIMPLFPUR80UNARY *PFNIEMAIMPLFPUR80UNARY;
1421FNIEMAIMPLFPUR80UNARY iemAImpl_fabs_r80;
1422FNIEMAIMPLFPUR80UNARY iemAImpl_fchs_r80;
1423FNIEMAIMPLFPUR80UNARY iemAImpl_f2xm1_r80;
1424FNIEMAIMPLFPUR80UNARY iemAImpl_fsqrt_r80;
1425FNIEMAIMPLFPUR80UNARY iemAImpl_frndint_r80;
1426FNIEMAIMPLFPUR80UNARY iemAImpl_fsin_r80;
1427FNIEMAIMPLFPUR80UNARY iemAImpl_fcos_r80;
1428
1429typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARYFSW,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, PCRTFLOAT80U pr80Val));
1430typedef FNIEMAIMPLFPUR80UNARYFSW *PFNIEMAIMPLFPUR80UNARYFSW;
1431FNIEMAIMPLFPUR80UNARYFSW iemAImpl_ftst_r80;
1432FNIEMAIMPLFPUR80UNARYFSW iemAImpl_fxam_r80;
1433
1434typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80LDCONST,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes));
1435typedef FNIEMAIMPLFPUR80LDCONST *PFNIEMAIMPLFPUR80LDCONST;
1436FNIEMAIMPLFPUR80LDCONST iemAImpl_fld1;
1437FNIEMAIMPLFPUR80LDCONST iemAImpl_fldl2t;
1438FNIEMAIMPLFPUR80LDCONST iemAImpl_fldl2e;
1439FNIEMAIMPLFPUR80LDCONST iemAImpl_fldpi;
1440FNIEMAIMPLFPUR80LDCONST iemAImpl_fldlg2;
1441FNIEMAIMPLFPUR80LDCONST iemAImpl_fldln2;
1442FNIEMAIMPLFPUR80LDCONST iemAImpl_fldz;
1443
1444typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARYTWO,(PCX86FXSTATE pFpuState, PIEMFPURESULTTWO pFpuResTwo,
1445 PCRTFLOAT80U pr80Val));
1446typedef FNIEMAIMPLFPUR80UNARYTWO *PFNIEMAIMPLFPUR80UNARYTWO;
1447FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fptan_r80_r80;
1448FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fxtract_r80_r80;
1449FNIEMAIMPLFPUR80UNARYTWO iemAImpl_fsincos_r80_r80;
1450
1451IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r80_from_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
1452IEM_DECL_IMPL_DEF(void, iemAImpl_fst_r80_to_r80,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1453 PRTFLOAT80U pr80Dst, PCRTFLOAT80U pr80Src));
1454
1455/** @} */
1456
1457/** @name FPU operations taking a 16-bit signed integer argument
1458 * @{ */
1459typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI16,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1460 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2));
1461typedef FNIEMAIMPLFPUI16 *PFNIEMAIMPLFPUI16;
1462
1463FNIEMAIMPLFPUI16 iemAImpl_fiadd_r80_by_i16;
1464FNIEMAIMPLFPUI16 iemAImpl_fimul_r80_by_i16;
1465FNIEMAIMPLFPUI16 iemAImpl_fisub_r80_by_i16;
1466FNIEMAIMPLFPUI16 iemAImpl_fisubr_r80_by_i16;
1467FNIEMAIMPLFPUI16 iemAImpl_fidiv_r80_by_i16;
1468FNIEMAIMPLFPUI16 iemAImpl_fidivr_r80_by_i16;
1469
1470IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1471 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2));
1472
1473IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i16_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int16_t const *pi16Val));
1474IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1475 int16_t *pi16Val, PCRTFLOAT80U pr80Val));
1476IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1477 int16_t *pi16Val, PCRTFLOAT80U pr80Val));
1478/** @} */
1479
1480/** @name FPU operations taking a 32-bit signed integer argument
1481 * @{ */
1482typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1483 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2));
1484typedef FNIEMAIMPLFPUI32 *PFNIEMAIMPLFPUI32;
1485
1486FNIEMAIMPLFPUI32 iemAImpl_fiadd_r80_by_i32;
1487FNIEMAIMPLFPUI32 iemAImpl_fimul_r80_by_i32;
1488FNIEMAIMPLFPUI32 iemAImpl_fisub_r80_by_i32;
1489FNIEMAIMPLFPUI32 iemAImpl_fisubr_r80_by_i32;
1490FNIEMAIMPLFPUI32 iemAImpl_fidiv_r80_by_i32;
1491FNIEMAIMPLFPUI32 iemAImpl_fidivr_r80_by_i32;
1492
1493IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1494 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2));
1495
1496IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i32_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int32_t const *pi32Val));
1497IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1498 int32_t *pi32Val, PCRTFLOAT80U pr80Val));
1499IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1500 int32_t *pi32Val, PCRTFLOAT80U pr80Val));
1501/** @} */
1502
1503/** @name FPU operations taking a 64-bit signed integer argument
1504 * @{ */
1505typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUI64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
1506 PCRTFLOAT80U pr80Val1, int64_t const *pi64Val2));
1507typedef FNIEMAIMPLFPUI64 *PFNIEMAIMPLFPUI64;
1508
1509FNIEMAIMPLFPUI64 iemAImpl_fiadd_r80_by_i64;
1510FNIEMAIMPLFPUI64 iemAImpl_fimul_r80_by_i64;
1511FNIEMAIMPLFPUI64 iemAImpl_fisub_r80_by_i64;
1512FNIEMAIMPLFPUI64 iemAImpl_fisubr_r80_by_i64;
1513FNIEMAIMPLFPUI64 iemAImpl_fidiv_r80_by_i64;
1514FNIEMAIMPLFPUI64 iemAImpl_fidivr_r80_by_i64;
1515
1516IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
1517 PCRTFLOAT80U pr80Val1, int64_t const *pi64Val2));
1518
1519IEM_DECL_IMPL_DEF(void, iemAImpl_fild_i64_to_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, int64_t const *pi64Val));
1520IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1521 int64_t *pi64Val, PCRTFLOAT80U pr80Val));
1522IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW,
1523 int64_t *pi32Val, PCRTFLOAT80U pr80Val));
1524/** @} */
1525
1526
1527/** Temporary type representing a 256-bit vector register. */
1528typedef struct {uint64_t au64[4]; } IEMVMM256;
1529/** Temporary type pointing to a 256-bit vector register. */
1530typedef IEMVMM256 *PIEMVMM256;
1531/** Temporary type pointing to a const 256-bit vector register. */
1532typedef IEMVMM256 *PCIEMVMM256;
1533
1534
1535/** @name Media (SSE/MMX/AVX) operations: full1 + full2 -> full1.
1536 * @{ */
1537typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF2U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src));
1538typedef FNIEMAIMPLMEDIAF2U64 *PFNIEMAIMPLMEDIAF2U64;
1539typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF2U128,(PCX86FXSTATE pFpuState, PRTUINT128U pu128Dst, PCRTUINT128U pu128Src));
1540typedef FNIEMAIMPLMEDIAF2U128 *PFNIEMAIMPLMEDIAF2U128;
1541FNIEMAIMPLMEDIAF2U64 iemAImpl_pxor_u64, iemAImpl_pcmpeqb_u64, iemAImpl_pcmpeqw_u64, iemAImpl_pcmpeqd_u64;
1542FNIEMAIMPLMEDIAF2U128 iemAImpl_pxor_u128, iemAImpl_pcmpeqb_u128, iemAImpl_pcmpeqw_u128, iemAImpl_pcmpeqd_u128;
1543/** @} */
1544
1545/** @name Media (SSE/MMX/AVX) operations: lowhalf1 + lowhalf1 -> full1.
1546 * @{ */
1547typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1L1U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint32_t const *pu32Src));
1548typedef FNIEMAIMPLMEDIAF1L1U64 *PFNIEMAIMPLMEDIAF1L1U64;
1549typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1L1U128,(PCX86FXSTATE pFpuState, PRTUINT128U pu128Dst, uint64_t const *pu64Src));
1550typedef FNIEMAIMPLMEDIAF1L1U128 *PFNIEMAIMPLMEDIAF1L1U128;
1551FNIEMAIMPLMEDIAF1L1U64 iemAImpl_punpcklbw_u64, iemAImpl_punpcklwd_u64, iemAImpl_punpckldq_u64;
1552FNIEMAIMPLMEDIAF1L1U128 iemAImpl_punpcklbw_u128, iemAImpl_punpcklwd_u128, iemAImpl_punpckldq_u128, iemAImpl_punpcklqdq_u128;
1553/** @} */
1554
1555/** @name Media (SSE/MMX/AVX) operations: hihalf1 + hihalf2 -> full1.
1556 * @{ */
1557typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1H1U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src));
1558typedef FNIEMAIMPLMEDIAF2U64 *PFNIEMAIMPLMEDIAF1H1U64;
1559typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1H1U128,(PCX86FXSTATE pFpuState, PRTUINT128U pu128Dst, PCRTUINT128U pu128Src));
1560typedef FNIEMAIMPLMEDIAF2U128 *PFNIEMAIMPLMEDIAF1H1U128;
1561FNIEMAIMPLMEDIAF1H1U64 iemAImpl_punpckhbw_u64, iemAImpl_punpckhwd_u64, iemAImpl_punpckhdq_u64;
1562FNIEMAIMPLMEDIAF1H1U128 iemAImpl_punpckhbw_u128, iemAImpl_punpckhwd_u128, iemAImpl_punpckhdq_u128, iemAImpl_punpckhqdq_u128;
1563/** @} */
1564
1565/** @name Media (SSE/MMX/AVX) operation: Packed Shuffle Stuff (evil)
1566 * @{ */
1567typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAPSHUF,(PCX86FXSTATE pFpuState, PRTUINT128U pu128Dst,
1568 PCRTUINT128U pu128Src, uint8_t bEvil));
1569typedef FNIEMAIMPLMEDIAPSHUF *PFNIEMAIMPLMEDIAPSHUF;
1570FNIEMAIMPLMEDIAPSHUF iemAImpl_pshufhw, iemAImpl_pshuflw, iemAImpl_pshufd;
1571IEM_DECL_IMPL_DEF(void, iemAImpl_pshufw,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src, uint8_t bEvil));
1572/** @} */
1573
1574/** @name Media (SSE/MMX/AVX) operation: Move Byte Mask
1575 * @{ */
1576IEM_DECL_IMPL_DEF(void, iemAImpl_pmovmskb_u64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src));
1577IEM_DECL_IMPL_DEF(void, iemAImpl_pmovmskb_u128,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, PCRTUINT128U pu128Src));
1578/** @} */
1579
1580/** @name Media (SSE/MMX/AVX) operation: Sort this later
1581 * @{ */
1582IEM_DECL_IMPL_DEF(void, iemAImpl_movsldup,(PCX86FXSTATE pFpuState, PRTUINT128U puDst, PCRTUINT128U puSrc));
1583IEM_DECL_IMPL_DEF(void, iemAImpl_movddup,(PCX86FXSTATE pFpuState, PRTUINT128U puDst, uint64_t uSrc));
1584/** @} */
1585
1586
1587/** @name Function tables.
1588 * @{
1589 */
1590
1591/**
1592 * Function table for a binary operator providing implementation based on
1593 * operand size.
1594 */
1595typedef struct IEMOPBINSIZES
1596{
1597 PFNIEMAIMPLBINU8 pfnNormalU8, pfnLockedU8;
1598 PFNIEMAIMPLBINU16 pfnNormalU16, pfnLockedU16;
1599 PFNIEMAIMPLBINU32 pfnNormalU32, pfnLockedU32;
1600 PFNIEMAIMPLBINU64 pfnNormalU64, pfnLockedU64;
1601} IEMOPBINSIZES;
1602/** Pointer to a binary operator function table. */
1603typedef IEMOPBINSIZES const *PCIEMOPBINSIZES;
1604
1605
1606/**
1607 * Function table for a unary operator providing implementation based on
1608 * operand size.
1609 */
1610typedef struct IEMOPUNARYSIZES
1611{
1612 PFNIEMAIMPLUNARYU8 pfnNormalU8, pfnLockedU8;
1613 PFNIEMAIMPLUNARYU16 pfnNormalU16, pfnLockedU16;
1614 PFNIEMAIMPLUNARYU32 pfnNormalU32, pfnLockedU32;
1615 PFNIEMAIMPLUNARYU64 pfnNormalU64, pfnLockedU64;
1616} IEMOPUNARYSIZES;
1617/** Pointer to a unary operator function table. */
1618typedef IEMOPUNARYSIZES const *PCIEMOPUNARYSIZES;
1619
1620
1621/**
1622 * Function table for a shift operator providing implementation based on
1623 * operand size.
1624 */
1625typedef struct IEMOPSHIFTSIZES
1626{
1627 PFNIEMAIMPLSHIFTU8 pfnNormalU8;
1628 PFNIEMAIMPLSHIFTU16 pfnNormalU16;
1629 PFNIEMAIMPLSHIFTU32 pfnNormalU32;
1630 PFNIEMAIMPLSHIFTU64 pfnNormalU64;
1631} IEMOPSHIFTSIZES;
1632/** Pointer to a shift operator function table. */
1633typedef IEMOPSHIFTSIZES const *PCIEMOPSHIFTSIZES;
1634
1635
1636/**
1637 * Function table for a multiplication or division operation.
1638 */
1639typedef struct IEMOPMULDIVSIZES
1640{
1641 PFNIEMAIMPLMULDIVU8 pfnU8;
1642 PFNIEMAIMPLMULDIVU16 pfnU16;
1643 PFNIEMAIMPLMULDIVU32 pfnU32;
1644 PFNIEMAIMPLMULDIVU64 pfnU64;
1645} IEMOPMULDIVSIZES;
1646/** Pointer to a multiplication or division operation function table. */
1647typedef IEMOPMULDIVSIZES const *PCIEMOPMULDIVSIZES;
1648
1649
1650/**
1651 * Function table for a double precision shift operator providing implementation
1652 * based on operand size.
1653 */
1654typedef struct IEMOPSHIFTDBLSIZES
1655{
1656 PFNIEMAIMPLSHIFTDBLU16 pfnNormalU16;
1657 PFNIEMAIMPLSHIFTDBLU32 pfnNormalU32;
1658 PFNIEMAIMPLSHIFTDBLU64 pfnNormalU64;
1659} IEMOPSHIFTDBLSIZES;
1660/** Pointer to a double precision shift function table. */
1661typedef IEMOPSHIFTDBLSIZES const *PCIEMOPSHIFTDBLSIZES;
1662
1663
1664/**
1665 * Function table for media instruction taking two full sized media registers,
1666 * optionally the 2nd being a memory reference (only modifying the first op.)
1667 */
1668typedef struct IEMOPMEDIAF2
1669{
1670 PFNIEMAIMPLMEDIAF2U64 pfnU64;
1671 PFNIEMAIMPLMEDIAF2U128 pfnU128;
1672} IEMOPMEDIAF2;
1673/** Pointer to a media operation function table for full sized ops. */
1674typedef IEMOPMEDIAF2 const *PCIEMOPMEDIAF2;
1675
1676/**
1677 * Function table for media instruction taking taking one full and one lower
1678 * half media register.
1679 */
1680typedef struct IEMOPMEDIAF1L1
1681{
1682 PFNIEMAIMPLMEDIAF1L1U64 pfnU64;
1683 PFNIEMAIMPLMEDIAF1L1U128 pfnU128;
1684} IEMOPMEDIAF1L1;
1685/** Pointer to a media operation function table for lowhalf+lowhalf -> full. */
1686typedef IEMOPMEDIAF1L1 const *PCIEMOPMEDIAF1L1;
1687
1688/**
1689 * Function table for media instruction taking taking one full and one high half
1690 * media register.
1691 */
1692typedef struct IEMOPMEDIAF1H1
1693{
1694 PFNIEMAIMPLMEDIAF1H1U64 pfnU64;
1695 PFNIEMAIMPLMEDIAF1H1U128 pfnU128;
1696} IEMOPMEDIAF1H1;
1697/** Pointer to a media operation function table for hihalf+hihalf -> full. */
1698typedef IEMOPMEDIAF1H1 const *PCIEMOPMEDIAF1H1;
1699
1700
1701/** @} */
1702
1703
1704/** @name C instruction implementations for anything slightly complicated.
1705 * @{ */
1706
1707/**
1708 * For typedef'ing or declaring a C instruction implementation function taking
1709 * no extra arguments.
1710 *
1711 * @param a_Name The name of the type.
1712 */
1713# define IEM_CIMPL_DECL_TYPE_0(a_Name) \
1714 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr))
1715/**
1716 * For defining a C instruction implementation function taking no extra
1717 * arguments.
1718 *
1719 * @param a_Name The name of the function
1720 */
1721# define IEM_CIMPL_DEF_0(a_Name) \
1722 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr))
1723/**
1724 * For calling a C instruction implementation function taking no extra
1725 * arguments.
1726 *
1727 * This special call macro adds default arguments to the call and allow us to
1728 * change these later.
1729 *
1730 * @param a_fn The name of the function.
1731 */
1732# define IEM_CIMPL_CALL_0(a_fn) a_fn(pVCpu, cbInstr)
1733
1734/**
1735 * For typedef'ing or declaring a C instruction implementation function taking
1736 * one extra argument.
1737 *
1738 * @param a_Name The name of the type.
1739 * @param a_Type0 The argument type.
1740 * @param a_Arg0 The argument name.
1741 */
1742# define IEM_CIMPL_DECL_TYPE_1(a_Name, a_Type0, a_Arg0) \
1743 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0))
1744/**
1745 * For defining a C instruction implementation function taking one extra
1746 * argument.
1747 *
1748 * @param a_Name The name of the function
1749 * @param a_Type0 The argument type.
1750 * @param a_Arg0 The argument name.
1751 */
1752# define IEM_CIMPL_DEF_1(a_Name, a_Type0, a_Arg0) \
1753 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0))
1754/**
1755 * For calling a C instruction implementation function taking one extra
1756 * argument.
1757 *
1758 * This special call macro adds default arguments to the call and allow us to
1759 * change these later.
1760 *
1761 * @param a_fn The name of the function.
1762 * @param a0 The name of the 1st argument.
1763 */
1764# define IEM_CIMPL_CALL_1(a_fn, a0) a_fn(pVCpu, cbInstr, (a0))
1765
1766/**
1767 * For typedef'ing or declaring a C instruction implementation function taking
1768 * two extra arguments.
1769 *
1770 * @param a_Name The name of the type.
1771 * @param a_Type0 The type of the 1st argument
1772 * @param a_Arg0 The name of the 1st argument.
1773 * @param a_Type1 The type of the 2nd argument.
1774 * @param a_Arg1 The name of the 2nd argument.
1775 */
1776# define IEM_CIMPL_DECL_TYPE_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
1777 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
1778/**
1779 * For defining a C instruction implementation function taking two extra
1780 * arguments.
1781 *
1782 * @param a_Name The name of the function.
1783 * @param a_Type0 The type of the 1st argument
1784 * @param a_Arg0 The name of the 1st argument.
1785 * @param a_Type1 The type of the 2nd argument.
1786 * @param a_Arg1 The name of the 2nd argument.
1787 */
1788# define IEM_CIMPL_DEF_2(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1) \
1789 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
1790/**
1791 * For calling a C instruction implementation function taking two extra
1792 * arguments.
1793 *
1794 * This special call macro adds default arguments to the call and allow us to
1795 * change these later.
1796 *
1797 * @param a_fn The name of the function.
1798 * @param a0 The name of the 1st argument.
1799 * @param a1 The name of the 2nd argument.
1800 */
1801# define IEM_CIMPL_CALL_2(a_fn, a0, a1) a_fn(pVCpu, cbInstr, (a0), (a1))
1802
1803/**
1804 * For typedef'ing or declaring a C instruction implementation function taking
1805 * three extra arguments.
1806 *
1807 * @param a_Name The name of the type.
1808 * @param a_Type0 The type of the 1st argument
1809 * @param a_Arg0 The name of the 1st argument.
1810 * @param a_Type1 The type of the 2nd argument.
1811 * @param a_Arg1 The name of the 2nd argument.
1812 * @param a_Type2 The type of the 3rd argument.
1813 * @param a_Arg2 The name of the 3rd argument.
1814 */
1815# define IEM_CIMPL_DECL_TYPE_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
1816 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
1817/**
1818 * For defining a C instruction implementation function taking three extra
1819 * arguments.
1820 *
1821 * @param a_Name The name of the function.
1822 * @param a_Type0 The type of the 1st argument
1823 * @param a_Arg0 The name of the 1st argument.
1824 * @param a_Type1 The type of the 2nd argument.
1825 * @param a_Arg1 The name of the 2nd argument.
1826 * @param a_Type2 The type of the 3rd argument.
1827 * @param a_Arg2 The name of the 3rd argument.
1828 */
1829# define IEM_CIMPL_DEF_3(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2) \
1830 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
1831/**
1832 * For calling a C instruction implementation function taking three extra
1833 * arguments.
1834 *
1835 * This special call macro adds default arguments to the call and allow us to
1836 * change these later.
1837 *
1838 * @param a_fn The name of the function.
1839 * @param a0 The name of the 1st argument.
1840 * @param a1 The name of the 2nd argument.
1841 * @param a2 The name of the 3rd argument.
1842 */
1843# define IEM_CIMPL_CALL_3(a_fn, a0, a1, a2) a_fn(pVCpu, cbInstr, (a0), (a1), (a2))
1844
1845
1846/**
1847 * For typedef'ing or declaring a C instruction implementation function taking
1848 * four extra arguments.
1849 *
1850 * @param a_Name The name of the type.
1851 * @param a_Type0 The type of the 1st argument
1852 * @param a_Arg0 The name of the 1st argument.
1853 * @param a_Type1 The type of the 2nd argument.
1854 * @param a_Arg1 The name of the 2nd argument.
1855 * @param a_Type2 The type of the 3rd argument.
1856 * @param a_Arg2 The name of the 3rd argument.
1857 * @param a_Type3 The type of the 4th argument.
1858 * @param a_Arg3 The name of the 4th argument.
1859 */
1860# define IEM_CIMPL_DECL_TYPE_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
1861 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
1862/**
1863 * For defining a C instruction implementation function taking four extra
1864 * arguments.
1865 *
1866 * @param a_Name The name of the function.
1867 * @param a_Type0 The type of the 1st argument
1868 * @param a_Arg0 The name of the 1st argument.
1869 * @param a_Type1 The type of the 2nd argument.
1870 * @param a_Arg1 The name of the 2nd argument.
1871 * @param a_Type2 The type of the 3rd argument.
1872 * @param a_Arg2 The name of the 3rd argument.
1873 * @param a_Type3 The type of the 4th argument.
1874 * @param a_Arg3 The name of the 4th argument.
1875 */
1876# define IEM_CIMPL_DEF_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
1877 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, \
1878 a_Type2 a_Arg2, a_Type3 a_Arg3))
1879/**
1880 * For calling a C instruction implementation function taking four extra
1881 * arguments.
1882 *
1883 * This special call macro adds default arguments to the call and allow us to
1884 * change these later.
1885 *
1886 * @param a_fn The name of the function.
1887 * @param a0 The name of the 1st argument.
1888 * @param a1 The name of the 2nd argument.
1889 * @param a2 The name of the 3rd argument.
1890 * @param a3 The name of the 4th argument.
1891 */
1892# define IEM_CIMPL_CALL_4(a_fn, a0, a1, a2, a3) a_fn(pVCpu, cbInstr, (a0), (a1), (a2), (a3))
1893
1894
1895/**
1896 * For typedef'ing or declaring a C instruction implementation function taking
1897 * five extra arguments.
1898 *
1899 * @param a_Name The name of the type.
1900 * @param a_Type0 The type of the 1st argument
1901 * @param a_Arg0 The name of the 1st argument.
1902 * @param a_Type1 The type of the 2nd argument.
1903 * @param a_Arg1 The name of the 2nd argument.
1904 * @param a_Type2 The type of the 3rd argument.
1905 * @param a_Arg2 The name of the 3rd argument.
1906 * @param a_Type3 The type of the 4th argument.
1907 * @param a_Arg3 The name of the 4th argument.
1908 * @param a_Type4 The type of the 5th argument.
1909 * @param a_Arg4 The name of the 5th argument.
1910 */
1911# 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) \
1912 IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, \
1913 a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
1914 a_Type3 a_Arg3, a_Type4 a_Arg4))
1915/**
1916 * For defining a C instruction implementation function taking five extra
1917 * arguments.
1918 *
1919 * @param a_Name The name of the function.
1920 * @param a_Type0 The type of the 1st argument
1921 * @param a_Arg0 The name of the 1st argument.
1922 * @param a_Type1 The type of the 2nd argument.
1923 * @param a_Arg1 The name of the 2nd argument.
1924 * @param a_Type2 The type of the 3rd argument.
1925 * @param a_Arg2 The name of the 3rd argument.
1926 * @param a_Type3 The type of the 4th argument.
1927 * @param a_Arg3 The name of the 4th argument.
1928 * @param a_Type4 The type of the 5th argument.
1929 * @param a_Arg4 The name of the 5th argument.
1930 */
1931# 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) \
1932 IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PVMCPU pVCpu, uint8_t cbInstr, \
1933 a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
1934 a_Type3 a_Arg3, a_Type4 a_Arg4))
1935/**
1936 * For calling a C instruction implementation function taking five extra
1937 * arguments.
1938 *
1939 * This special call macro adds default arguments to the call and allow us to
1940 * change these later.
1941 *
1942 * @param a_fn The name of the function.
1943 * @param a0 The name of the 1st argument.
1944 * @param a1 The name of the 2nd argument.
1945 * @param a2 The name of the 3rd argument.
1946 * @param a3 The name of the 4th argument.
1947 * @param a4 The name of the 5th argument.
1948 */
1949# define IEM_CIMPL_CALL_5(a_fn, a0, a1, a2, a3, a4) a_fn(pVCpu, cbInstr, (a0), (a1), (a2), (a3), (a4))
1950
1951/** @} */
1952
1953
1954/** @} */
1955
1956RT_C_DECLS_END
1957
1958#endif
1959
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