VirtualBox

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

Last change on this file since 60189 was 60188, checked in by vboxsync, 9 years ago

IEM: Fixed a couple of edge cases and broken verification mode.

  • Update enmCpuMode after loading hidden CS flags (prep for recompiling).
  • Fixed retf in 64-bit mode where we would load CS.BASE with zero when returning to 16-bit or 32-bit code.
  • Fixed ESP/SP handling for protected mode exception injection.
  • Fixed handling of lock prefixed INT xx and INT3.
  • Implemented the two string I/O notification functions that would assert in verification mode.
  • The IEMExec* methods must call iemUninitExec to undo poisoning of decoding data members as it will otherwise interfere with verification mode opcode fetching optimizations and other stuff.

The above makes the current bs3-cpu-basic-2 code work in --execute-all-in-iem mode.

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