VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsInterpretOnly.cpp@ 98103

Last change on this file since 98103 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.6 KB
Line 
1/* $Id: IEMAllInstructionsInterpretOnly.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IEM - Instruction Decoding and Emulation.
4 */
5
6/*
7 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#ifndef LOG_GROUP /* defined when included by tstIEMCheckMc.cpp */
33# define LOG_GROUP LOG_GROUP_IEM
34#endif
35#define VMCPU_INCL_CPUM_GST_CTX
36#include <VBox/vmm/iem.h>
37#include <VBox/vmm/cpum.h>
38#include <VBox/vmm/apic.h>
39#include <VBox/vmm/pdm.h>
40#include <VBox/vmm/pgm.h>
41#include <VBox/vmm/iom.h>
42#include <VBox/vmm/em.h>
43#include <VBox/vmm/hm.h>
44#include <VBox/vmm/nem.h>
45#include <VBox/vmm/gim.h>
46#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
47# include <VBox/vmm/em.h>
48# include <VBox/vmm/hm_svm.h>
49#endif
50#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
51# include <VBox/vmm/hmvmxinline.h>
52#endif
53#include <VBox/vmm/tm.h>
54#include <VBox/vmm/dbgf.h>
55#include <VBox/vmm/dbgftrace.h>
56#ifndef TST_IEM_CHECK_MC
57# include "IEMInternal.h"
58#endif
59#include <VBox/vmm/vmcc.h>
60#include <VBox/log.h>
61#include <VBox/err.h>
62#include <VBox/param.h>
63#include <VBox/dis.h>
64#include <VBox/disopcode.h>
65#include <iprt/asm-math.h>
66#include <iprt/assert.h>
67#include <iprt/string.h>
68#include <iprt/x86.h>
69
70#ifndef TST_IEM_CHECK_MC
71# include "IEMInline.h"
72# include "IEMOpHlp.h"
73# include "IEMMc.h"
74#endif
75
76
77#ifdef _MSC_VER
78# pragma warning(push)
79# pragma warning(disable: 4702) /* Unreachable code like return in iemOp_Grp6_lldt. */
80#endif
81
82
83/*********************************************************************************************************************************
84* Global Variables *
85*********************************************************************************************************************************/
86#ifndef TST_IEM_CHECK_MC
87/** Function table for the ADD instruction. */
88IEM_STATIC const IEMOPBINSIZES g_iemAImpl_add =
89{
90 iemAImpl_add_u8, iemAImpl_add_u8_locked,
91 iemAImpl_add_u16, iemAImpl_add_u16_locked,
92 iemAImpl_add_u32, iemAImpl_add_u32_locked,
93 iemAImpl_add_u64, iemAImpl_add_u64_locked
94};
95
96/** Function table for the ADC instruction. */
97IEM_STATIC const IEMOPBINSIZES g_iemAImpl_adc =
98{
99 iemAImpl_adc_u8, iemAImpl_adc_u8_locked,
100 iemAImpl_adc_u16, iemAImpl_adc_u16_locked,
101 iemAImpl_adc_u32, iemAImpl_adc_u32_locked,
102 iemAImpl_adc_u64, iemAImpl_adc_u64_locked
103};
104
105/** Function table for the SUB instruction. */
106IEM_STATIC const IEMOPBINSIZES g_iemAImpl_sub =
107{
108 iemAImpl_sub_u8, iemAImpl_sub_u8_locked,
109 iemAImpl_sub_u16, iemAImpl_sub_u16_locked,
110 iemAImpl_sub_u32, iemAImpl_sub_u32_locked,
111 iemAImpl_sub_u64, iemAImpl_sub_u64_locked
112};
113
114/** Function table for the SBB instruction. */
115IEM_STATIC const IEMOPBINSIZES g_iemAImpl_sbb =
116{
117 iemAImpl_sbb_u8, iemAImpl_sbb_u8_locked,
118 iemAImpl_sbb_u16, iemAImpl_sbb_u16_locked,
119 iemAImpl_sbb_u32, iemAImpl_sbb_u32_locked,
120 iemAImpl_sbb_u64, iemAImpl_sbb_u64_locked
121};
122
123/** Function table for the OR instruction. */
124IEM_STATIC const IEMOPBINSIZES g_iemAImpl_or =
125{
126 iemAImpl_or_u8, iemAImpl_or_u8_locked,
127 iemAImpl_or_u16, iemAImpl_or_u16_locked,
128 iemAImpl_or_u32, iemAImpl_or_u32_locked,
129 iemAImpl_or_u64, iemAImpl_or_u64_locked
130};
131
132/** Function table for the XOR instruction. */
133IEM_STATIC const IEMOPBINSIZES g_iemAImpl_xor =
134{
135 iemAImpl_xor_u8, iemAImpl_xor_u8_locked,
136 iemAImpl_xor_u16, iemAImpl_xor_u16_locked,
137 iemAImpl_xor_u32, iemAImpl_xor_u32_locked,
138 iemAImpl_xor_u64, iemAImpl_xor_u64_locked
139};
140
141/** Function table for the AND instruction. */
142IEM_STATIC const IEMOPBINSIZES g_iemAImpl_and =
143{
144 iemAImpl_and_u8, iemAImpl_and_u8_locked,
145 iemAImpl_and_u16, iemAImpl_and_u16_locked,
146 iemAImpl_and_u32, iemAImpl_and_u32_locked,
147 iemAImpl_and_u64, iemAImpl_and_u64_locked
148};
149
150/** Function table for the CMP instruction.
151 * @remarks Making operand order ASSUMPTIONS.
152 */
153IEM_STATIC const IEMOPBINSIZES g_iemAImpl_cmp =
154{
155 iemAImpl_cmp_u8, NULL,
156 iemAImpl_cmp_u16, NULL,
157 iemAImpl_cmp_u32, NULL,
158 iemAImpl_cmp_u64, NULL
159};
160
161/** Function table for the TEST instruction.
162 * @remarks Making operand order ASSUMPTIONS.
163 */
164IEM_STATIC const IEMOPBINSIZES g_iemAImpl_test =
165{
166 iemAImpl_test_u8, NULL,
167 iemAImpl_test_u16, NULL,
168 iemAImpl_test_u32, NULL,
169 iemAImpl_test_u64, NULL
170};
171
172
173/** Function table for the BT instruction. */
174IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bt =
175{
176 NULL, NULL,
177 iemAImpl_bt_u16, NULL,
178 iemAImpl_bt_u32, NULL,
179 iemAImpl_bt_u64, NULL
180};
181
182/** Function table for the BTC instruction. */
183IEM_STATIC const IEMOPBINSIZES g_iemAImpl_btc =
184{
185 NULL, NULL,
186 iemAImpl_btc_u16, iemAImpl_btc_u16_locked,
187 iemAImpl_btc_u32, iemAImpl_btc_u32_locked,
188 iemAImpl_btc_u64, iemAImpl_btc_u64_locked
189};
190
191/** Function table for the BTR instruction. */
192IEM_STATIC const IEMOPBINSIZES g_iemAImpl_btr =
193{
194 NULL, NULL,
195 iemAImpl_btr_u16, iemAImpl_btr_u16_locked,
196 iemAImpl_btr_u32, iemAImpl_btr_u32_locked,
197 iemAImpl_btr_u64, iemAImpl_btr_u64_locked
198};
199
200/** Function table for the BTS instruction. */
201IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bts =
202{
203 NULL, NULL,
204 iemAImpl_bts_u16, iemAImpl_bts_u16_locked,
205 iemAImpl_bts_u32, iemAImpl_bts_u32_locked,
206 iemAImpl_bts_u64, iemAImpl_bts_u64_locked
207};
208
209/** Function table for the BSF instruction. */
210IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsf =
211{
212 NULL, NULL,
213 iemAImpl_bsf_u16, NULL,
214 iemAImpl_bsf_u32, NULL,
215 iemAImpl_bsf_u64, NULL
216};
217
218/** Function table for the BSF instruction, AMD EFLAGS variant. */
219IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsf_amd =
220{
221 NULL, NULL,
222 iemAImpl_bsf_u16_amd, NULL,
223 iemAImpl_bsf_u32_amd, NULL,
224 iemAImpl_bsf_u64_amd, NULL
225};
226
227/** Function table for the BSF instruction, Intel EFLAGS variant. */
228IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsf_intel =
229{
230 NULL, NULL,
231 iemAImpl_bsf_u16_intel, NULL,
232 iemAImpl_bsf_u32_intel, NULL,
233 iemAImpl_bsf_u64_intel, NULL
234};
235
236/** EFLAGS variation selection table for the BSF instruction. */
237IEM_STATIC const IEMOPBINSIZES * const g_iemAImpl_bsf_eflags[] =
238{
239 &g_iemAImpl_bsf,
240 &g_iemAImpl_bsf_intel,
241 &g_iemAImpl_bsf_amd,
242 &g_iemAImpl_bsf,
243};
244
245/** Function table for the BSR instruction. */
246IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsr =
247{
248 NULL, NULL,
249 iemAImpl_bsr_u16, NULL,
250 iemAImpl_bsr_u32, NULL,
251 iemAImpl_bsr_u64, NULL
252};
253
254/** Function table for the BSR instruction, AMD EFLAGS variant. */
255IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsr_amd =
256{
257 NULL, NULL,
258 iemAImpl_bsr_u16_amd, NULL,
259 iemAImpl_bsr_u32_amd, NULL,
260 iemAImpl_bsr_u64_amd, NULL
261};
262
263/** Function table for the BSR instruction, Intel EFLAGS variant. */
264IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsr_intel =
265{
266 NULL, NULL,
267 iemAImpl_bsr_u16_intel, NULL,
268 iemAImpl_bsr_u32_intel, NULL,
269 iemAImpl_bsr_u64_intel, NULL
270};
271
272/** EFLAGS variation selection table for the BSR instruction. */
273IEM_STATIC const IEMOPBINSIZES * const g_iemAImpl_bsr_eflags[] =
274{
275 &g_iemAImpl_bsr,
276 &g_iemAImpl_bsr_intel,
277 &g_iemAImpl_bsr_amd,
278 &g_iemAImpl_bsr,
279};
280
281/** Function table for the IMUL instruction. */
282IEM_STATIC const IEMOPBINSIZES g_iemAImpl_imul_two =
283{
284 NULL, NULL,
285 iemAImpl_imul_two_u16, NULL,
286 iemAImpl_imul_two_u32, NULL,
287 iemAImpl_imul_two_u64, NULL
288};
289
290/** Function table for the IMUL instruction, AMD EFLAGS variant. */
291IEM_STATIC const IEMOPBINSIZES g_iemAImpl_imul_two_amd =
292{
293 NULL, NULL,
294 iemAImpl_imul_two_u16_amd, NULL,
295 iemAImpl_imul_two_u32_amd, NULL,
296 iemAImpl_imul_two_u64_amd, NULL
297};
298
299/** Function table for the IMUL instruction, Intel EFLAGS variant. */
300IEM_STATIC const IEMOPBINSIZES g_iemAImpl_imul_two_intel =
301{
302 NULL, NULL,
303 iemAImpl_imul_two_u16_intel, NULL,
304 iemAImpl_imul_two_u32_intel, NULL,
305 iemAImpl_imul_two_u64_intel, NULL
306};
307
308/** EFLAGS variation selection table for the IMUL instruction. */
309IEM_STATIC const IEMOPBINSIZES * const g_iemAImpl_imul_two_eflags[] =
310{
311 &g_iemAImpl_imul_two,
312 &g_iemAImpl_imul_two_intel,
313 &g_iemAImpl_imul_two_amd,
314 &g_iemAImpl_imul_two,
315};
316
317/** EFLAGS variation selection table for the 16-bit IMUL instruction. */
318IEM_STATIC PFNIEMAIMPLBINU16 const g_iemAImpl_imul_two_u16_eflags[] =
319{
320 iemAImpl_imul_two_u16,
321 iemAImpl_imul_two_u16_intel,
322 iemAImpl_imul_two_u16_amd,
323 iemAImpl_imul_two_u16,
324};
325
326/** EFLAGS variation selection table for the 32-bit IMUL instruction. */
327IEM_STATIC PFNIEMAIMPLBINU32 const g_iemAImpl_imul_two_u32_eflags[] =
328{
329 iemAImpl_imul_two_u32,
330 iemAImpl_imul_two_u32_intel,
331 iemAImpl_imul_two_u32_amd,
332 iemAImpl_imul_two_u32,
333};
334
335/** EFLAGS variation selection table for the 64-bit IMUL instruction. */
336IEM_STATIC PFNIEMAIMPLBINU64 const g_iemAImpl_imul_two_u64_eflags[] =
337{
338 iemAImpl_imul_two_u64,
339 iemAImpl_imul_two_u64_intel,
340 iemAImpl_imul_two_u64_amd,
341 iemAImpl_imul_two_u64,
342};
343
344/** Group 1 /r lookup table. */
345IEM_STATIC const PCIEMOPBINSIZES g_apIemImplGrp1[8] =
346{
347 &g_iemAImpl_add,
348 &g_iemAImpl_or,
349 &g_iemAImpl_adc,
350 &g_iemAImpl_sbb,
351 &g_iemAImpl_and,
352 &g_iemAImpl_sub,
353 &g_iemAImpl_xor,
354 &g_iemAImpl_cmp
355};
356
357/** Function table for the INC instruction. */
358IEM_STATIC const IEMOPUNARYSIZES g_iemAImpl_inc =
359{
360 iemAImpl_inc_u8, iemAImpl_inc_u8_locked,
361 iemAImpl_inc_u16, iemAImpl_inc_u16_locked,
362 iemAImpl_inc_u32, iemAImpl_inc_u32_locked,
363 iemAImpl_inc_u64, iemAImpl_inc_u64_locked
364};
365
366/** Function table for the DEC instruction. */
367IEM_STATIC const IEMOPUNARYSIZES g_iemAImpl_dec =
368{
369 iemAImpl_dec_u8, iemAImpl_dec_u8_locked,
370 iemAImpl_dec_u16, iemAImpl_dec_u16_locked,
371 iemAImpl_dec_u32, iemAImpl_dec_u32_locked,
372 iemAImpl_dec_u64, iemAImpl_dec_u64_locked
373};
374
375/** Function table for the NEG instruction. */
376IEM_STATIC const IEMOPUNARYSIZES g_iemAImpl_neg =
377{
378 iemAImpl_neg_u8, iemAImpl_neg_u8_locked,
379 iemAImpl_neg_u16, iemAImpl_neg_u16_locked,
380 iemAImpl_neg_u32, iemAImpl_neg_u32_locked,
381 iemAImpl_neg_u64, iemAImpl_neg_u64_locked
382};
383
384/** Function table for the NOT instruction. */
385IEM_STATIC const IEMOPUNARYSIZES g_iemAImpl_not =
386{
387 iemAImpl_not_u8, iemAImpl_not_u8_locked,
388 iemAImpl_not_u16, iemAImpl_not_u16_locked,
389 iemAImpl_not_u32, iemAImpl_not_u32_locked,
390 iemAImpl_not_u64, iemAImpl_not_u64_locked
391};
392
393
394/** Function table for the ROL instruction. */
395IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rol =
396{
397 iemAImpl_rol_u8,
398 iemAImpl_rol_u16,
399 iemAImpl_rol_u32,
400 iemAImpl_rol_u64
401};
402
403/** Function table for the ROL instruction, AMD EFLAGS variant. */
404IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rol_amd =
405{
406 iemAImpl_rol_u8_amd,
407 iemAImpl_rol_u16_amd,
408 iemAImpl_rol_u32_amd,
409 iemAImpl_rol_u64_amd
410};
411
412/** Function table for the ROL instruction, Intel EFLAGS variant. */
413IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rol_intel =
414{
415 iemAImpl_rol_u8_intel,
416 iemAImpl_rol_u16_intel,
417 iemAImpl_rol_u32_intel,
418 iemAImpl_rol_u64_intel
419};
420
421/** EFLAGS variation selection table for the ROL instruction. */
422IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_rol_eflags[] =
423{
424 &g_iemAImpl_rol,
425 &g_iemAImpl_rol_intel,
426 &g_iemAImpl_rol_amd,
427 &g_iemAImpl_rol,
428};
429
430
431/** Function table for the ROR instruction. */
432IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_ror =
433{
434 iemAImpl_ror_u8,
435 iemAImpl_ror_u16,
436 iemAImpl_ror_u32,
437 iemAImpl_ror_u64
438};
439
440/** Function table for the ROR instruction, AMD EFLAGS variant. */
441IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_ror_amd =
442{
443 iemAImpl_ror_u8_amd,
444 iemAImpl_ror_u16_amd,
445 iemAImpl_ror_u32_amd,
446 iemAImpl_ror_u64_amd
447};
448
449/** Function table for the ROR instruction, Intel EFLAGS variant. */
450IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_ror_intel =
451{
452 iemAImpl_ror_u8_intel,
453 iemAImpl_ror_u16_intel,
454 iemAImpl_ror_u32_intel,
455 iemAImpl_ror_u64_intel
456};
457
458/** EFLAGS variation selection table for the ROR instruction. */
459IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_ror_eflags[] =
460{
461 &g_iemAImpl_ror,
462 &g_iemAImpl_ror_intel,
463 &g_iemAImpl_ror_amd,
464 &g_iemAImpl_ror,
465};
466
467
468/** Function table for the RCL instruction. */
469IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rcl =
470{
471 iemAImpl_rcl_u8,
472 iemAImpl_rcl_u16,
473 iemAImpl_rcl_u32,
474 iemAImpl_rcl_u64
475};
476
477/** Function table for the RCL instruction, AMD EFLAGS variant. */
478IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rcl_amd =
479{
480 iemAImpl_rcl_u8_amd,
481 iemAImpl_rcl_u16_amd,
482 iemAImpl_rcl_u32_amd,
483 iemAImpl_rcl_u64_amd
484};
485
486/** Function table for the RCL instruction, Intel EFLAGS variant. */
487IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rcl_intel =
488{
489 iemAImpl_rcl_u8_intel,
490 iemAImpl_rcl_u16_intel,
491 iemAImpl_rcl_u32_intel,
492 iemAImpl_rcl_u64_intel
493};
494
495/** EFLAGS variation selection table for the RCL instruction. */
496IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_rcl_eflags[] =
497{
498 &g_iemAImpl_rcl,
499 &g_iemAImpl_rcl_intel,
500 &g_iemAImpl_rcl_amd,
501 &g_iemAImpl_rcl,
502};
503
504
505/** Function table for the RCR instruction. */
506IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rcr =
507{
508 iemAImpl_rcr_u8,
509 iemAImpl_rcr_u16,
510 iemAImpl_rcr_u32,
511 iemAImpl_rcr_u64
512};
513
514/** Function table for the RCR instruction, AMD EFLAGS variant. */
515IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rcr_amd =
516{
517 iemAImpl_rcr_u8_amd,
518 iemAImpl_rcr_u16_amd,
519 iemAImpl_rcr_u32_amd,
520 iemAImpl_rcr_u64_amd
521};
522
523/** Function table for the RCR instruction, Intel EFLAGS variant. */
524IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_rcr_intel =
525{
526 iemAImpl_rcr_u8_intel,
527 iemAImpl_rcr_u16_intel,
528 iemAImpl_rcr_u32_intel,
529 iemAImpl_rcr_u64_intel
530};
531
532/** EFLAGS variation selection table for the RCR instruction. */
533IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_rcr_eflags[] =
534{
535 &g_iemAImpl_rcr,
536 &g_iemAImpl_rcr_intel,
537 &g_iemAImpl_rcr_amd,
538 &g_iemAImpl_rcr,
539};
540
541
542/** Function table for the SHL instruction. */
543IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_shl =
544{
545 iemAImpl_shl_u8,
546 iemAImpl_shl_u16,
547 iemAImpl_shl_u32,
548 iemAImpl_shl_u64
549};
550
551/** Function table for the SHL instruction, AMD EFLAGS variant. */
552IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_shl_amd =
553{
554 iemAImpl_shl_u8_amd,
555 iemAImpl_shl_u16_amd,
556 iemAImpl_shl_u32_amd,
557 iemAImpl_shl_u64_amd
558};
559
560/** Function table for the SHL instruction, Intel EFLAGS variant. */
561IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_shl_intel =
562{
563 iemAImpl_shl_u8_intel,
564 iemAImpl_shl_u16_intel,
565 iemAImpl_shl_u32_intel,
566 iemAImpl_shl_u64_intel
567};
568
569/** EFLAGS variation selection table for the SHL instruction. */
570IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_shl_eflags[] =
571{
572 &g_iemAImpl_shl,
573 &g_iemAImpl_shl_intel,
574 &g_iemAImpl_shl_amd,
575 &g_iemAImpl_shl,
576};
577
578
579/** Function table for the SHR instruction. */
580IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_shr =
581{
582 iemAImpl_shr_u8,
583 iemAImpl_shr_u16,
584 iemAImpl_shr_u32,
585 iemAImpl_shr_u64
586};
587
588/** Function table for the SHR instruction, AMD EFLAGS variant. */
589IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_shr_amd =
590{
591 iemAImpl_shr_u8_amd,
592 iemAImpl_shr_u16_amd,
593 iemAImpl_shr_u32_amd,
594 iemAImpl_shr_u64_amd
595};
596
597/** Function table for the SHR instruction, Intel EFLAGS variant. */
598IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_shr_intel =
599{
600 iemAImpl_shr_u8_intel,
601 iemAImpl_shr_u16_intel,
602 iemAImpl_shr_u32_intel,
603 iemAImpl_shr_u64_intel
604};
605
606/** EFLAGS variation selection table for the SHR instruction. */
607IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_shr_eflags[] =
608{
609 &g_iemAImpl_shr,
610 &g_iemAImpl_shr_intel,
611 &g_iemAImpl_shr_amd,
612 &g_iemAImpl_shr,
613};
614
615
616/** Function table for the SAR instruction. */
617IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_sar =
618{
619 iemAImpl_sar_u8,
620 iemAImpl_sar_u16,
621 iemAImpl_sar_u32,
622 iemAImpl_sar_u64
623};
624
625/** Function table for the SAR instruction, AMD EFLAGS variant. */
626IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_sar_amd =
627{
628 iemAImpl_sar_u8_amd,
629 iemAImpl_sar_u16_amd,
630 iemAImpl_sar_u32_amd,
631 iemAImpl_sar_u64_amd
632};
633
634/** Function table for the SAR instruction, Intel EFLAGS variant. */
635IEM_STATIC const IEMOPSHIFTSIZES g_iemAImpl_sar_intel =
636{
637 iemAImpl_sar_u8_intel,
638 iemAImpl_sar_u16_intel,
639 iemAImpl_sar_u32_intel,
640 iemAImpl_sar_u64_intel
641};
642
643/** EFLAGS variation selection table for the SAR instruction. */
644IEM_STATIC const IEMOPSHIFTSIZES * const g_iemAImpl_sar_eflags[] =
645{
646 &g_iemAImpl_sar,
647 &g_iemAImpl_sar_intel,
648 &g_iemAImpl_sar_amd,
649 &g_iemAImpl_sar,
650};
651
652
653/** Function table for the MUL instruction. */
654IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_mul =
655{
656 iemAImpl_mul_u8,
657 iemAImpl_mul_u16,
658 iemAImpl_mul_u32,
659 iemAImpl_mul_u64
660};
661
662/** Function table for the MUL instruction, AMD EFLAGS variation. */
663IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_mul_amd =
664{
665 iemAImpl_mul_u8_amd,
666 iemAImpl_mul_u16_amd,
667 iemAImpl_mul_u32_amd,
668 iemAImpl_mul_u64_amd
669};
670
671/** Function table for the MUL instruction, Intel EFLAGS variation. */
672IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_mul_intel =
673{
674 iemAImpl_mul_u8_intel,
675 iemAImpl_mul_u16_intel,
676 iemAImpl_mul_u32_intel,
677 iemAImpl_mul_u64_intel
678};
679
680/** EFLAGS variation selection table for the MUL instruction. */
681IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_mul_eflags[] =
682{
683 &g_iemAImpl_mul,
684 &g_iemAImpl_mul_intel,
685 &g_iemAImpl_mul_amd,
686 &g_iemAImpl_mul,
687};
688
689/** EFLAGS variation selection table for the 8-bit MUL instruction. */
690IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_mul_u8_eflags[] =
691{
692 iemAImpl_mul_u8,
693 iemAImpl_mul_u8_intel,
694 iemAImpl_mul_u8_amd,
695 iemAImpl_mul_u8
696};
697
698
699/** Function table for the IMUL instruction working implicitly on rAX. */
700IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_imul =
701{
702 iemAImpl_imul_u8,
703 iemAImpl_imul_u16,
704 iemAImpl_imul_u32,
705 iemAImpl_imul_u64
706};
707
708/** Function table for the IMUL instruction working implicitly on rAX, AMD EFLAGS variation. */
709IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_imul_amd =
710{
711 iemAImpl_imul_u8_amd,
712 iemAImpl_imul_u16_amd,
713 iemAImpl_imul_u32_amd,
714 iemAImpl_imul_u64_amd
715};
716
717/** Function table for the IMUL instruction working implicitly on rAX, Intel EFLAGS variation. */
718IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_imul_intel =
719{
720 iemAImpl_imul_u8_intel,
721 iemAImpl_imul_u16_intel,
722 iemAImpl_imul_u32_intel,
723 iemAImpl_imul_u64_intel
724};
725
726/** EFLAGS variation selection table for the IMUL instruction. */
727IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_imul_eflags[] =
728{
729 &g_iemAImpl_imul,
730 &g_iemAImpl_imul_intel,
731 &g_iemAImpl_imul_amd,
732 &g_iemAImpl_imul,
733};
734
735/** EFLAGS variation selection table for the 8-bit IMUL instruction. */
736IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_imul_u8_eflags[] =
737{
738 iemAImpl_imul_u8,
739 iemAImpl_imul_u8_intel,
740 iemAImpl_imul_u8_amd,
741 iemAImpl_imul_u8
742};
743
744
745/** Function table for the DIV instruction. */
746IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_div =
747{
748 iemAImpl_div_u8,
749 iemAImpl_div_u16,
750 iemAImpl_div_u32,
751 iemAImpl_div_u64
752};
753
754/** Function table for the DIV instruction, AMD EFLAGS variation. */
755IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_div_amd =
756{
757 iemAImpl_div_u8_amd,
758 iemAImpl_div_u16_amd,
759 iemAImpl_div_u32_amd,
760 iemAImpl_div_u64_amd
761};
762
763/** Function table for the DIV instruction, Intel EFLAGS variation. */
764IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_div_intel =
765{
766 iemAImpl_div_u8_intel,
767 iemAImpl_div_u16_intel,
768 iemAImpl_div_u32_intel,
769 iemAImpl_div_u64_intel
770};
771
772/** EFLAGS variation selection table for the DIV instruction. */
773IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_div_eflags[] =
774{
775 &g_iemAImpl_div,
776 &g_iemAImpl_div_intel,
777 &g_iemAImpl_div_amd,
778 &g_iemAImpl_div,
779};
780
781/** EFLAGS variation selection table for the 8-bit DIV instruction. */
782IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_div_u8_eflags[] =
783{
784 iemAImpl_div_u8,
785 iemAImpl_div_u8_intel,
786 iemAImpl_div_u8_amd,
787 iemAImpl_div_u8
788};
789
790
791/** Function table for the IDIV instruction. */
792IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_idiv =
793{
794 iemAImpl_idiv_u8,
795 iemAImpl_idiv_u16,
796 iemAImpl_idiv_u32,
797 iemAImpl_idiv_u64
798};
799
800/** Function table for the IDIV instruction, AMD EFLAGS variation. */
801IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_idiv_amd =
802{
803 iemAImpl_idiv_u8_amd,
804 iemAImpl_idiv_u16_amd,
805 iemAImpl_idiv_u32_amd,
806 iemAImpl_idiv_u64_amd
807};
808
809/** Function table for the IDIV instruction, Intel EFLAGS variation. */
810IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_idiv_intel =
811{
812 iemAImpl_idiv_u8_intel,
813 iemAImpl_idiv_u16_intel,
814 iemAImpl_idiv_u32_intel,
815 iemAImpl_idiv_u64_intel
816};
817
818/** EFLAGS variation selection table for the IDIV instruction. */
819IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_idiv_eflags[] =
820{
821 &g_iemAImpl_idiv,
822 &g_iemAImpl_idiv_intel,
823 &g_iemAImpl_idiv_amd,
824 &g_iemAImpl_idiv,
825};
826
827/** EFLAGS variation selection table for the 8-bit IDIV instruction. */
828IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_idiv_u8_eflags[] =
829{
830 iemAImpl_idiv_u8,
831 iemAImpl_idiv_u8_intel,
832 iemAImpl_idiv_u8_amd,
833 iemAImpl_idiv_u8
834};
835
836
837/** Function table for the SHLD instruction. */
838IEM_STATIC const IEMOPSHIFTDBLSIZES g_iemAImpl_shld =
839{
840 iemAImpl_shld_u16,
841 iemAImpl_shld_u32,
842 iemAImpl_shld_u64,
843};
844
845/** Function table for the SHLD instruction, AMD EFLAGS variation. */
846IEM_STATIC const IEMOPSHIFTDBLSIZES g_iemAImpl_shld_amd =
847{
848 iemAImpl_shld_u16_amd,
849 iemAImpl_shld_u32_amd,
850 iemAImpl_shld_u64_amd
851};
852
853/** Function table for the SHLD instruction, Intel EFLAGS variation. */
854IEM_STATIC const IEMOPSHIFTDBLSIZES g_iemAImpl_shld_intel =
855{
856 iemAImpl_shld_u16_intel,
857 iemAImpl_shld_u32_intel,
858 iemAImpl_shld_u64_intel
859};
860
861/** EFLAGS variation selection table for the SHLD instruction. */
862IEM_STATIC const IEMOPSHIFTDBLSIZES * const g_iemAImpl_shld_eflags[] =
863{
864 &g_iemAImpl_shld,
865 &g_iemAImpl_shld_intel,
866 &g_iemAImpl_shld_amd,
867 &g_iemAImpl_shld
868};
869
870/** Function table for the SHRD instruction. */
871IEM_STATIC const IEMOPSHIFTDBLSIZES g_iemAImpl_shrd =
872{
873 iemAImpl_shrd_u16,
874 iemAImpl_shrd_u32,
875 iemAImpl_shrd_u64
876};
877
878/** Function table for the SHRD instruction, AMD EFLAGS variation. */
879IEM_STATIC const IEMOPSHIFTDBLSIZES g_iemAImpl_shrd_amd =
880{
881 iemAImpl_shrd_u16_amd,
882 iemAImpl_shrd_u32_amd,
883 iemAImpl_shrd_u64_amd
884};
885
886/** Function table for the SHRD instruction, Intel EFLAGS variation. */
887IEM_STATIC const IEMOPSHIFTDBLSIZES g_iemAImpl_shrd_intel =
888{
889 iemAImpl_shrd_u16_intel,
890 iemAImpl_shrd_u32_intel,
891 iemAImpl_shrd_u64_intel
892};
893
894/** EFLAGS variation selection table for the SHRD instruction. */
895IEM_STATIC const IEMOPSHIFTDBLSIZES * const g_iemAImpl_shrd_eflags[] =
896{
897 &g_iemAImpl_shrd,
898 &g_iemAImpl_shrd_intel,
899 &g_iemAImpl_shrd_amd,
900 &g_iemAImpl_shrd
901};
902
903
904# ifndef IEM_WITHOUT_ASSEMBLY
905/** Function table for the VPXOR instruction */
906IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpand = { iemAImpl_vpand_u128, iemAImpl_vpand_u256 };
907/** Function table for the VPXORN instruction */
908IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpandn = { iemAImpl_vpandn_u128, iemAImpl_vpandn_u256 };
909/** Function table for the VPOR instruction */
910IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpor = { iemAImpl_vpor_u128, iemAImpl_vpor_u256 };
911/** Function table for the VPXOR instruction */
912IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpxor = { iemAImpl_vpxor_u128, iemAImpl_vpxor_u256 };
913# endif
914
915/** Function table for the VPAND instruction, software fallback. */
916IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpand_fallback = { iemAImpl_vpand_u128_fallback, iemAImpl_vpand_u256_fallback };
917/** Function table for the VPANDN instruction, software fallback. */
918IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpandn_fallback= { iemAImpl_vpandn_u128_fallback, iemAImpl_vpandn_u256_fallback };
919/** Function table for the VPOR instruction, software fallback. */
920IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpor_fallback = { iemAImpl_vpor_u128_fallback, iemAImpl_vpor_u256_fallback };
921/** Function table for the VPXOR instruction, software fallback. */
922IEM_STATIC const IEMOPMEDIAF3 g_iemAImpl_vpxor_fallback = { iemAImpl_vpxor_u128_fallback, iemAImpl_vpxor_u256_fallback };
923
924#endif /* !TST_IEM_CHECK_MC */
925
926
927/**
928 * Common worker for instructions like ADD, AND, OR, ++ with a byte
929 * memory/register as the destination.
930 *
931 * @param pImpl Pointer to the instruction implementation (assembly).
932 */
933FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rm_r8, PCIEMOPBINSIZES, pImpl)
934{
935 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
936
937 /*
938 * If rm is denoting a register, no more instruction bytes.
939 */
940 if (IEM_IS_MODRM_REG_MODE(bRm))
941 {
942 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
943
944 IEM_MC_BEGIN(3, 0);
945 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
946 IEM_MC_ARG(uint8_t, u8Src, 1);
947 IEM_MC_ARG(uint32_t *, pEFlags, 2);
948
949 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm));
950 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
951 IEM_MC_REF_EFLAGS(pEFlags);
952 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
953
954 IEM_MC_ADVANCE_RIP_AND_FINISH();
955 IEM_MC_END();
956 }
957 else
958 {
959 /*
960 * We're accessing memory.
961 * Note! We're putting the eflags on the stack here so we can commit them
962 * after the memory.
963 */
964 uint32_t const fAccess = pImpl->pfnLockedU8 ? IEM_ACCESS_DATA_RW : IEM_ACCESS_DATA_R; /* CMP,TEST */
965 IEM_MC_BEGIN(3, 2);
966 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
967 IEM_MC_ARG(uint8_t, u8Src, 1);
968 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
969 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
970
971 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
972 if (!pImpl->pfnLockedU8)
973 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
974 IEM_MC_MEM_MAP(pu8Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
975 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm));
976 IEM_MC_FETCH_EFLAGS(EFlags);
977 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
978 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
979 else
980 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU8, pu8Dst, u8Src, pEFlags);
981
982 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, fAccess);
983 IEM_MC_COMMIT_EFLAGS(EFlags);
984 IEM_MC_ADVANCE_RIP_AND_FINISH();
985 IEM_MC_END();
986 }
987}
988
989
990/**
991 * Common worker for word/dword/qword instructions like ADD, AND, OR, ++ with
992 * memory/register as the destination.
993 *
994 * @param pImpl Pointer to the instruction implementation (assembly).
995 */
996FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rm_rv, PCIEMOPBINSIZES, pImpl)
997{
998 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
999
1000 /*
1001 * If rm is denoting a register, no more instruction bytes.
1002 */
1003 if (IEM_IS_MODRM_REG_MODE(bRm))
1004 {
1005 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1006
1007 switch (pVCpu->iem.s.enmEffOpSize)
1008 {
1009 case IEMMODE_16BIT:
1010 IEM_MC_BEGIN(3, 0);
1011 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1012 IEM_MC_ARG(uint16_t, u16Src, 1);
1013 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1014
1015 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1016 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
1017 IEM_MC_REF_EFLAGS(pEFlags);
1018 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1019
1020 IEM_MC_ADVANCE_RIP_AND_FINISH();
1021 IEM_MC_END();
1022 break;
1023
1024 case IEMMODE_32BIT:
1025 IEM_MC_BEGIN(3, 0);
1026 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1027 IEM_MC_ARG(uint32_t, u32Src, 1);
1028 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1029
1030 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1031 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
1032 IEM_MC_REF_EFLAGS(pEFlags);
1033 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1034
1035 if ((pImpl != &g_iemAImpl_test) && (pImpl != &g_iemAImpl_cmp))
1036 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1037 IEM_MC_ADVANCE_RIP_AND_FINISH();
1038 IEM_MC_END();
1039 break;
1040
1041 case IEMMODE_64BIT:
1042 IEM_MC_BEGIN(3, 0);
1043 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1044 IEM_MC_ARG(uint64_t, u64Src, 1);
1045 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1046
1047 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1048 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
1049 IEM_MC_REF_EFLAGS(pEFlags);
1050 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1051
1052 IEM_MC_ADVANCE_RIP_AND_FINISH();
1053 IEM_MC_END();
1054 break;
1055
1056 IEM_NOT_REACHED_DEFAULT_CASE_RET();
1057 }
1058 }
1059 else
1060 {
1061 /*
1062 * We're accessing memory.
1063 * Note! We're putting the eflags on the stack here so we can commit them
1064 * after the memory.
1065 */
1066 uint32_t const fAccess = pImpl->pfnLockedU8 ? IEM_ACCESS_DATA_RW : IEM_ACCESS_DATA_R /* CMP,TEST */;
1067 switch (pVCpu->iem.s.enmEffOpSize)
1068 {
1069 case IEMMODE_16BIT:
1070 IEM_MC_BEGIN(3, 2);
1071 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1072 IEM_MC_ARG(uint16_t, u16Src, 1);
1073 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
1074 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1075
1076 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1077 if (!pImpl->pfnLockedU16)
1078 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1079 IEM_MC_MEM_MAP(pu16Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
1080 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1081 IEM_MC_FETCH_EFLAGS(EFlags);
1082 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
1083 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1084 else
1085 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
1086
1087 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
1088 IEM_MC_COMMIT_EFLAGS(EFlags);
1089 IEM_MC_ADVANCE_RIP_AND_FINISH();
1090 IEM_MC_END();
1091 break;
1092
1093 case IEMMODE_32BIT:
1094 IEM_MC_BEGIN(3, 2);
1095 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1096 IEM_MC_ARG(uint32_t, u32Src, 1);
1097 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
1098 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1099
1100 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1101 if (!pImpl->pfnLockedU32)
1102 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1103 IEM_MC_MEM_MAP(pu32Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
1104 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1105 IEM_MC_FETCH_EFLAGS(EFlags);
1106 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
1107 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1108 else
1109 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
1110
1111 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
1112 IEM_MC_COMMIT_EFLAGS(EFlags);
1113 IEM_MC_ADVANCE_RIP_AND_FINISH();
1114 IEM_MC_END();
1115 break;
1116
1117 case IEMMODE_64BIT:
1118 IEM_MC_BEGIN(3, 2);
1119 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1120 IEM_MC_ARG(uint64_t, u64Src, 1);
1121 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
1122 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1123
1124 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1125 if (!pImpl->pfnLockedU64)
1126 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1127 IEM_MC_MEM_MAP(pu64Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
1128 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1129 IEM_MC_FETCH_EFLAGS(EFlags);
1130 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
1131 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1132 else
1133 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
1134
1135 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
1136 IEM_MC_COMMIT_EFLAGS(EFlags);
1137 IEM_MC_ADVANCE_RIP_AND_FINISH();
1138 IEM_MC_END();
1139 break;
1140
1141 IEM_NOT_REACHED_DEFAULT_CASE_RET();
1142 }
1143 }
1144}
1145
1146
1147/**
1148 * Common worker for byte instructions like ADD, AND, OR, ++ with a register as
1149 * the destination.
1150 *
1151 * @param pImpl Pointer to the instruction implementation (assembly).
1152 */
1153FNIEMOP_DEF_1(iemOpHlpBinaryOperator_r8_rm, PCIEMOPBINSIZES, pImpl)
1154{
1155 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1156
1157 /*
1158 * If rm is denoting a register, no more instruction bytes.
1159 */
1160 if (IEM_IS_MODRM_REG_MODE(bRm))
1161 {
1162 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1163 IEM_MC_BEGIN(3, 0);
1164 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
1165 IEM_MC_ARG(uint8_t, u8Src, 1);
1166 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1167
1168 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1169 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1170 IEM_MC_REF_EFLAGS(pEFlags);
1171 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
1172
1173 IEM_MC_ADVANCE_RIP_AND_FINISH();
1174 IEM_MC_END();
1175 }
1176 else
1177 {
1178 /*
1179 * We're accessing memory.
1180 */
1181 IEM_MC_BEGIN(3, 1);
1182 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
1183 IEM_MC_ARG(uint8_t, u8Src, 1);
1184 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1185 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1186
1187 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1188 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1189 IEM_MC_FETCH_MEM_U8(u8Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1190 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1191 IEM_MC_REF_EFLAGS(pEFlags);
1192 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
1193
1194 IEM_MC_ADVANCE_RIP_AND_FINISH();
1195 IEM_MC_END();
1196 }
1197}
1198
1199
1200/**
1201 * Common worker for word/dword/qword instructions like ADD, AND, OR, ++ with a
1202 * register as the destination.
1203 *
1204 * @param pImpl Pointer to the instruction implementation (assembly).
1205 */
1206FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rv_rm, PCIEMOPBINSIZES, pImpl)
1207{
1208 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1209
1210 /*
1211 * If rm is denoting a register, no more instruction bytes.
1212 */
1213 if (IEM_IS_MODRM_REG_MODE(bRm))
1214 {
1215 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1216 switch (pVCpu->iem.s.enmEffOpSize)
1217 {
1218 case IEMMODE_16BIT:
1219 IEM_MC_BEGIN(3, 0);
1220 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1221 IEM_MC_ARG(uint16_t, u16Src, 1);
1222 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1223
1224 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1225 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1226 IEM_MC_REF_EFLAGS(pEFlags);
1227 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1228
1229 IEM_MC_ADVANCE_RIP_AND_FINISH();
1230 IEM_MC_END();
1231 break;
1232
1233 case IEMMODE_32BIT:
1234 IEM_MC_BEGIN(3, 0);
1235 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1236 IEM_MC_ARG(uint32_t, u32Src, 1);
1237 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1238
1239 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1240 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1241 IEM_MC_REF_EFLAGS(pEFlags);
1242 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1243
1244 if (pImpl != &g_iemAImpl_cmp) /* Not used with TEST. */
1245 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1246 IEM_MC_ADVANCE_RIP_AND_FINISH();
1247 IEM_MC_END();
1248 break;
1249
1250 case IEMMODE_64BIT:
1251 IEM_MC_BEGIN(3, 0);
1252 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1253 IEM_MC_ARG(uint64_t, u64Src, 1);
1254 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1255
1256 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1257 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1258 IEM_MC_REF_EFLAGS(pEFlags);
1259 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1260
1261 IEM_MC_ADVANCE_RIP_AND_FINISH();
1262 IEM_MC_END();
1263 break;
1264
1265 IEM_NOT_REACHED_DEFAULT_CASE_RET();
1266 }
1267 }
1268 else
1269 {
1270 /*
1271 * We're accessing memory.
1272 */
1273 switch (pVCpu->iem.s.enmEffOpSize)
1274 {
1275 case IEMMODE_16BIT:
1276 IEM_MC_BEGIN(3, 1);
1277 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1278 IEM_MC_ARG(uint16_t, u16Src, 1);
1279 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1280 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1281
1282 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1283 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1284 IEM_MC_FETCH_MEM_U16(u16Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1285 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1286 IEM_MC_REF_EFLAGS(pEFlags);
1287 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1288
1289 IEM_MC_ADVANCE_RIP_AND_FINISH();
1290 IEM_MC_END();
1291 break;
1292
1293 case IEMMODE_32BIT:
1294 IEM_MC_BEGIN(3, 1);
1295 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1296 IEM_MC_ARG(uint32_t, u32Src, 1);
1297 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1298 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1299
1300 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1301 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1302 IEM_MC_FETCH_MEM_U32(u32Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1303 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1304 IEM_MC_REF_EFLAGS(pEFlags);
1305 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1306
1307 if (pImpl != &g_iemAImpl_cmp)
1308 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1309 IEM_MC_ADVANCE_RIP_AND_FINISH();
1310 IEM_MC_END();
1311 break;
1312
1313 case IEMMODE_64BIT:
1314 IEM_MC_BEGIN(3, 1);
1315 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1316 IEM_MC_ARG(uint64_t, u64Src, 1);
1317 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1318 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1319
1320 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1321 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1322 IEM_MC_FETCH_MEM_U64(u64Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1323 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1324 IEM_MC_REF_EFLAGS(pEFlags);
1325 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1326
1327 IEM_MC_ADVANCE_RIP_AND_FINISH();
1328 IEM_MC_END();
1329 break;
1330
1331 IEM_NOT_REACHED_DEFAULT_CASE_RET();
1332 }
1333 }
1334}
1335
1336
1337/**
1338 * Common worker for instructions like ADD, AND, OR, ++ with working on AL with
1339 * a byte immediate.
1340 *
1341 * @param pImpl Pointer to the instruction implementation (assembly).
1342 */
1343FNIEMOP_DEF_1(iemOpHlpBinaryOperator_AL_Ib, PCIEMOPBINSIZES, pImpl)
1344{
1345 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
1346 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1347
1348 IEM_MC_BEGIN(3, 0);
1349 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
1350 IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/ u8Imm, 1);
1351 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1352
1353 IEM_MC_REF_GREG_U8(pu8Dst, X86_GREG_xAX);
1354 IEM_MC_REF_EFLAGS(pEFlags);
1355 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
1356
1357 IEM_MC_ADVANCE_RIP_AND_FINISH();
1358 IEM_MC_END();
1359}
1360
1361
1362/**
1363 * Common worker for instructions like ADD, AND, OR, ++ with working on
1364 * AX/EAX/RAX with a word/dword immediate.
1365 *
1366 * @param pImpl Pointer to the instruction implementation (assembly).
1367 */
1368FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rAX_Iz, PCIEMOPBINSIZES, pImpl)
1369{
1370 switch (pVCpu->iem.s.enmEffOpSize)
1371 {
1372 case IEMMODE_16BIT:
1373 {
1374 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
1375 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1376
1377 IEM_MC_BEGIN(3, 0);
1378 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1379 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm, 1);
1380 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1381
1382 IEM_MC_REF_GREG_U16(pu16Dst, X86_GREG_xAX);
1383 IEM_MC_REF_EFLAGS(pEFlags);
1384 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1385
1386 IEM_MC_ADVANCE_RIP_AND_FINISH();
1387 IEM_MC_END();
1388 return VINF_SUCCESS;
1389 }
1390
1391 case IEMMODE_32BIT:
1392 {
1393 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
1394 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1395
1396 IEM_MC_BEGIN(3, 0);
1397 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1398 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm, 1);
1399 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1400
1401 IEM_MC_REF_GREG_U32(pu32Dst, X86_GREG_xAX);
1402 IEM_MC_REF_EFLAGS(pEFlags);
1403 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1404
1405 if ((pImpl != &g_iemAImpl_test) && (pImpl != &g_iemAImpl_cmp))
1406 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1407 IEM_MC_ADVANCE_RIP_AND_FINISH();
1408 IEM_MC_END();
1409 return VINF_SUCCESS;
1410 }
1411
1412 case IEMMODE_64BIT:
1413 {
1414 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
1415 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1416
1417 IEM_MC_BEGIN(3, 0);
1418 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1419 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm, 1);
1420 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1421
1422 IEM_MC_REF_GREG_U64(pu64Dst, X86_GREG_xAX);
1423 IEM_MC_REF_EFLAGS(pEFlags);
1424 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1425
1426 IEM_MC_ADVANCE_RIP_AND_FINISH();
1427 IEM_MC_END();
1428 return VINF_SUCCESS;
1429 }
1430
1431 IEM_NOT_REACHED_DEFAULT_CASE_RET();
1432 }
1433}
1434
1435
1436/** Opcodes 0xf1, 0xd6. */
1437FNIEMOP_DEF(iemOp_Invalid)
1438{
1439 IEMOP_MNEMONIC(Invalid, "Invalid");
1440 return IEMOP_RAISE_INVALID_OPCODE();
1441}
1442
1443
1444/** Invalid with RM byte . */
1445FNIEMOPRM_DEF(iemOp_InvalidWithRM)
1446{
1447 RT_NOREF_PV(bRm);
1448 IEMOP_MNEMONIC(InvalidWithRm, "InvalidWithRM");
1449 return IEMOP_RAISE_INVALID_OPCODE();
1450}
1451
1452
1453/** Invalid with RM byte where intel decodes any additional address encoding
1454 * bytes. */
1455FNIEMOPRM_DEF(iemOp_InvalidWithRMNeedDecode)
1456{
1457 IEMOP_MNEMONIC(InvalidWithRMNeedDecode, "InvalidWithRMNeedDecode");
1458 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1459 {
1460#ifndef TST_IEM_CHECK_MC
1461 if (IEM_IS_MODRM_MEM_MODE(bRm))
1462 {
1463 RTGCPTR GCPtrEff;
1464 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1465 if (rcStrict != VINF_SUCCESS)
1466 return rcStrict;
1467 }
1468#endif
1469 }
1470 IEMOP_HLP_DONE_DECODING();
1471 return IEMOP_RAISE_INVALID_OPCODE();
1472}
1473
1474
1475/** Invalid with RM byte where both AMD and Intel decodes any additional
1476 * address encoding bytes. */
1477FNIEMOPRM_DEF(iemOp_InvalidWithRMAllNeeded)
1478{
1479 IEMOP_MNEMONIC(InvalidWithRMAllNeeded, "InvalidWithRMAllNeeded");
1480#ifndef TST_IEM_CHECK_MC
1481 if (IEM_IS_MODRM_MEM_MODE(bRm))
1482 {
1483 RTGCPTR GCPtrEff;
1484 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1485 if (rcStrict != VINF_SUCCESS)
1486 return rcStrict;
1487 }
1488#endif
1489 IEMOP_HLP_DONE_DECODING();
1490 return IEMOP_RAISE_INVALID_OPCODE();
1491}
1492
1493
1494/** Invalid with RM byte where intel requires 8-byte immediate.
1495 * Intel will also need SIB and displacement if bRm indicates memory. */
1496FNIEMOPRM_DEF(iemOp_InvalidWithRMNeedImm8)
1497{
1498 IEMOP_MNEMONIC(InvalidWithRMNeedImm8, "InvalidWithRMNeedImm8");
1499 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1500 {
1501#ifndef TST_IEM_CHECK_MC
1502 if (IEM_IS_MODRM_MEM_MODE(bRm))
1503 {
1504 RTGCPTR GCPtrEff;
1505 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1506 if (rcStrict != VINF_SUCCESS)
1507 return rcStrict;
1508 }
1509#endif
1510 uint8_t bImm8; IEM_OPCODE_GET_NEXT_U8(&bImm8); RT_NOREF(bRm);
1511 }
1512 IEMOP_HLP_DONE_DECODING();
1513 return IEMOP_RAISE_INVALID_OPCODE();
1514}
1515
1516
1517/** Invalid with RM byte where intel requires 8-byte immediate.
1518 * Both AMD and Intel also needs SIB and displacement according to bRm. */
1519FNIEMOPRM_DEF(iemOp_InvalidWithRMAllNeedImm8)
1520{
1521 IEMOP_MNEMONIC(InvalidWithRMAllNeedImm8, "InvalidWithRMAllNeedImm8");
1522#ifndef TST_IEM_CHECK_MC
1523 if (IEM_IS_MODRM_MEM_MODE(bRm))
1524 {
1525 RTGCPTR GCPtrEff;
1526 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1527 if (rcStrict != VINF_SUCCESS)
1528 return rcStrict;
1529 }
1530#endif
1531 uint8_t bImm8; IEM_OPCODE_GET_NEXT_U8(&bImm8); RT_NOREF(bRm);
1532 IEMOP_HLP_DONE_DECODING();
1533 return IEMOP_RAISE_INVALID_OPCODE();
1534}
1535
1536
1537/** Invalid opcode where intel requires Mod R/M sequence. */
1538FNIEMOP_DEF(iemOp_InvalidNeedRM)
1539{
1540 IEMOP_MNEMONIC(InvalidNeedRM, "InvalidNeedRM");
1541 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1542 {
1543 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1544#ifndef TST_IEM_CHECK_MC
1545 if (IEM_IS_MODRM_MEM_MODE(bRm))
1546 {
1547 RTGCPTR GCPtrEff;
1548 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1549 if (rcStrict != VINF_SUCCESS)
1550 return rcStrict;
1551 }
1552#endif
1553 }
1554 IEMOP_HLP_DONE_DECODING();
1555 return IEMOP_RAISE_INVALID_OPCODE();
1556}
1557
1558
1559/** Invalid opcode where both AMD and Intel requires Mod R/M sequence. */
1560FNIEMOP_DEF(iemOp_InvalidAllNeedRM)
1561{
1562 IEMOP_MNEMONIC(InvalidAllNeedRM, "InvalidAllNeedRM");
1563 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1564#ifndef TST_IEM_CHECK_MC
1565 if (IEM_IS_MODRM_MEM_MODE(bRm))
1566 {
1567 RTGCPTR GCPtrEff;
1568 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1569 if (rcStrict != VINF_SUCCESS)
1570 return rcStrict;
1571 }
1572#endif
1573 IEMOP_HLP_DONE_DECODING();
1574 return IEMOP_RAISE_INVALID_OPCODE();
1575}
1576
1577
1578/** Invalid opcode where intel requires Mod R/M sequence and 8-byte
1579 * immediate. */
1580FNIEMOP_DEF(iemOp_InvalidNeedRMImm8)
1581{
1582 IEMOP_MNEMONIC(InvalidNeedRMImm8, "InvalidNeedRMImm8");
1583 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1584 {
1585 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1586#ifndef TST_IEM_CHECK_MC
1587 if (IEM_IS_MODRM_MEM_MODE(bRm))
1588 {
1589 RTGCPTR GCPtrEff;
1590 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1591 if (rcStrict != VINF_SUCCESS)
1592 return rcStrict;
1593 }
1594#endif
1595 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm); RT_NOREF(bImm);
1596 }
1597 IEMOP_HLP_DONE_DECODING();
1598 return IEMOP_RAISE_INVALID_OPCODE();
1599}
1600
1601
1602/** Invalid opcode where intel requires a 3rd escape byte and a Mod R/M
1603 * sequence. */
1604FNIEMOP_DEF(iemOp_InvalidNeed3ByteEscRM)
1605{
1606 IEMOP_MNEMONIC(InvalidNeed3ByteEscRM, "InvalidNeed3ByteEscRM");
1607 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1608 {
1609 uint8_t b3rd; IEM_OPCODE_GET_NEXT_U8(&b3rd); RT_NOREF(b3rd);
1610 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1611#ifndef TST_IEM_CHECK_MC
1612 if (IEM_IS_MODRM_MEM_MODE(bRm))
1613 {
1614 RTGCPTR GCPtrEff;
1615 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1616 if (rcStrict != VINF_SUCCESS)
1617 return rcStrict;
1618 }
1619#endif
1620 }
1621 IEMOP_HLP_DONE_DECODING();
1622 return IEMOP_RAISE_INVALID_OPCODE();
1623}
1624
1625
1626/** Invalid opcode where intel requires a 3rd escape byte, Mod R/M sequence, and
1627 * a 8-byte immediate. */
1628FNIEMOP_DEF(iemOp_InvalidNeed3ByteEscRMImm8)
1629{
1630 IEMOP_MNEMONIC(InvalidNeed3ByteEscRMImm8, "InvalidNeed3ByteEscRMImm8");
1631 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1632 {
1633 uint8_t b3rd; IEM_OPCODE_GET_NEXT_U8(&b3rd); RT_NOREF(b3rd);
1634 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1635#ifndef TST_IEM_CHECK_MC
1636 if (IEM_IS_MODRM_MEM_MODE(bRm))
1637 {
1638 RTGCPTR GCPtrEff;
1639 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 1, &GCPtrEff);
1640 if (rcStrict != VINF_SUCCESS)
1641 return rcStrict;
1642 }
1643#endif
1644 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm); RT_NOREF(bImm);
1645 IEMOP_HLP_DONE_DECODING();
1646 }
1647 return IEMOP_RAISE_INVALID_OPCODE();
1648}
1649
1650
1651/** Repeats a_fn four times. For decoding tables. */
1652#define IEMOP_X4(a_fn) a_fn, a_fn, a_fn, a_fn
1653
1654/*
1655 * Include the tables.
1656 */
1657#ifdef IEM_WITH_3DNOW
1658# include "IEMAllInstructions3DNow.cpp.h"
1659#endif
1660#ifdef IEM_WITH_THREE_0F_38
1661# include "IEMAllInstructionsThree0f38.cpp.h"
1662#endif
1663#ifdef IEM_WITH_THREE_0F_3A
1664# include "IEMAllInstructionsThree0f3a.cpp.h"
1665#endif
1666#include "IEMAllInstructionsTwoByte0f.cpp.h"
1667#ifdef IEM_WITH_VEX
1668# include "IEMAllInstructionsVexMap1.cpp.h"
1669# include "IEMAllInstructionsVexMap2.cpp.h"
1670# include "IEMAllInstructionsVexMap3.cpp.h"
1671#endif
1672#include "IEMAllInstructionsOneByte.cpp.h"
1673
1674
1675#ifdef _MSC_VER
1676# pragma warning(pop)
1677#endif
1678
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