VirtualBox

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

Last change on this file since 96860 was 96860, checked in by vboxsync, 20 months ago

IEM: The CMP instruction must not zero out the high half of 64-bit GPRs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.3 KB
Line 
1/* $Id: IEMAllInstructionsInterpretOnly.cpp 96860 2022-09-26 10:44:31Z vboxsync $ */
2/** @file
3 * IEM - Instruction Decoding and Emulation.
4 */
5
6/*
7 * Copyright (C) 2011-2022 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();
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();
985 IEM_MC_END();
986 }
987 return VINF_SUCCESS;
988}
989
990
991/**
992 * Common worker for word/dword/qword instructions like ADD, AND, OR, ++ with
993 * memory/register as the destination.
994 *
995 * @param pImpl Pointer to the instruction implementation (assembly).
996 */
997FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rm_rv, PCIEMOPBINSIZES, pImpl)
998{
999 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1000
1001 /*
1002 * If rm is denoting a register, no more instruction bytes.
1003 */
1004 if (IEM_IS_MODRM_REG_MODE(bRm))
1005 {
1006 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1007
1008 switch (pVCpu->iem.s.enmEffOpSize)
1009 {
1010 case IEMMODE_16BIT:
1011 IEM_MC_BEGIN(3, 0);
1012 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1013 IEM_MC_ARG(uint16_t, u16Src, 1);
1014 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1015
1016 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1017 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
1018 IEM_MC_REF_EFLAGS(pEFlags);
1019 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1020
1021 IEM_MC_ADVANCE_RIP();
1022 IEM_MC_END();
1023 break;
1024
1025 case IEMMODE_32BIT:
1026 IEM_MC_BEGIN(3, 0);
1027 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1028 IEM_MC_ARG(uint32_t, u32Src, 1);
1029 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1030
1031 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1032 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
1033 IEM_MC_REF_EFLAGS(pEFlags);
1034 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1035
1036 if ((pImpl != &g_iemAImpl_test) && (pImpl != &g_iemAImpl_cmp))
1037 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1038 IEM_MC_ADVANCE_RIP();
1039 IEM_MC_END();
1040 break;
1041
1042 case IEMMODE_64BIT:
1043 IEM_MC_BEGIN(3, 0);
1044 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1045 IEM_MC_ARG(uint64_t, u64Src, 1);
1046 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1047
1048 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1049 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
1050 IEM_MC_REF_EFLAGS(pEFlags);
1051 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1052
1053 IEM_MC_ADVANCE_RIP();
1054 IEM_MC_END();
1055 break;
1056 }
1057 }
1058 else
1059 {
1060 /*
1061 * We're accessing memory.
1062 * Note! We're putting the eflags on the stack here so we can commit them
1063 * after the memory.
1064 */
1065 uint32_t const fAccess = pImpl->pfnLockedU8 ? IEM_ACCESS_DATA_RW : IEM_ACCESS_DATA_R /* CMP,TEST */;
1066 switch (pVCpu->iem.s.enmEffOpSize)
1067 {
1068 case IEMMODE_16BIT:
1069 IEM_MC_BEGIN(3, 2);
1070 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1071 IEM_MC_ARG(uint16_t, u16Src, 1);
1072 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
1073 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1074
1075 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1076 if (!pImpl->pfnLockedU16)
1077 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1078 IEM_MC_MEM_MAP(pu16Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
1079 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1080 IEM_MC_FETCH_EFLAGS(EFlags);
1081 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
1082 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1083 else
1084 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
1085
1086 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
1087 IEM_MC_COMMIT_EFLAGS(EFlags);
1088 IEM_MC_ADVANCE_RIP();
1089 IEM_MC_END();
1090 break;
1091
1092 case IEMMODE_32BIT:
1093 IEM_MC_BEGIN(3, 2);
1094 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1095 IEM_MC_ARG(uint32_t, u32Src, 1);
1096 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
1097 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1098
1099 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1100 if (!pImpl->pfnLockedU32)
1101 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1102 IEM_MC_MEM_MAP(pu32Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
1103 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1104 IEM_MC_FETCH_EFLAGS(EFlags);
1105 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
1106 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1107 else
1108 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
1109
1110 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
1111 IEM_MC_COMMIT_EFLAGS(EFlags);
1112 IEM_MC_ADVANCE_RIP();
1113 IEM_MC_END();
1114 break;
1115
1116 case IEMMODE_64BIT:
1117 IEM_MC_BEGIN(3, 2);
1118 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1119 IEM_MC_ARG(uint64_t, u64Src, 1);
1120 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
1121 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1122
1123 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1124 if (!pImpl->pfnLockedU64)
1125 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1126 IEM_MC_MEM_MAP(pu64Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
1127 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm));
1128 IEM_MC_FETCH_EFLAGS(EFlags);
1129 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
1130 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1131 else
1132 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
1133
1134 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
1135 IEM_MC_COMMIT_EFLAGS(EFlags);
1136 IEM_MC_ADVANCE_RIP();
1137 IEM_MC_END();
1138 break;
1139 }
1140 }
1141 return VINF_SUCCESS;
1142}
1143
1144
1145/**
1146 * Common worker for byte instructions like ADD, AND, OR, ++ with a register as
1147 * the destination.
1148 *
1149 * @param pImpl Pointer to the instruction implementation (assembly).
1150 */
1151FNIEMOP_DEF_1(iemOpHlpBinaryOperator_r8_rm, PCIEMOPBINSIZES, pImpl)
1152{
1153 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1154
1155 /*
1156 * If rm is denoting a register, no more instruction bytes.
1157 */
1158 if (IEM_IS_MODRM_REG_MODE(bRm))
1159 {
1160 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1161 IEM_MC_BEGIN(3, 0);
1162 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
1163 IEM_MC_ARG(uint8_t, u8Src, 1);
1164 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1165
1166 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1167 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1168 IEM_MC_REF_EFLAGS(pEFlags);
1169 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
1170
1171 IEM_MC_ADVANCE_RIP();
1172 IEM_MC_END();
1173 }
1174 else
1175 {
1176 /*
1177 * We're accessing memory.
1178 */
1179 IEM_MC_BEGIN(3, 1);
1180 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
1181 IEM_MC_ARG(uint8_t, u8Src, 1);
1182 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1183 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1184
1185 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1186 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1187 IEM_MC_FETCH_MEM_U8(u8Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1188 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1189 IEM_MC_REF_EFLAGS(pEFlags);
1190 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
1191
1192 IEM_MC_ADVANCE_RIP();
1193 IEM_MC_END();
1194 }
1195 return VINF_SUCCESS;
1196}
1197
1198
1199/**
1200 * Common worker for word/dword/qword instructions like ADD, AND, OR, ++ with a
1201 * register as the destination.
1202 *
1203 * @param pImpl Pointer to the instruction implementation (assembly).
1204 */
1205FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rv_rm, PCIEMOPBINSIZES, pImpl)
1206{
1207 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1208
1209 /*
1210 * If rm is denoting a register, no more instruction bytes.
1211 */
1212 if (IEM_IS_MODRM_REG_MODE(bRm))
1213 {
1214 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1215 switch (pVCpu->iem.s.enmEffOpSize)
1216 {
1217 case IEMMODE_16BIT:
1218 IEM_MC_BEGIN(3, 0);
1219 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1220 IEM_MC_ARG(uint16_t, u16Src, 1);
1221 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1222
1223 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1224 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1225 IEM_MC_REF_EFLAGS(pEFlags);
1226 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1227
1228 IEM_MC_ADVANCE_RIP();
1229 IEM_MC_END();
1230 break;
1231
1232 case IEMMODE_32BIT:
1233 IEM_MC_BEGIN(3, 0);
1234 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1235 IEM_MC_ARG(uint32_t, u32Src, 1);
1236 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1237
1238 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1239 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1240 IEM_MC_REF_EFLAGS(pEFlags);
1241 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1242
1243 if (pImpl != &g_iemAImpl_cmp) /* Not used with TEST. */
1244 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1245 IEM_MC_ADVANCE_RIP();
1246 IEM_MC_END();
1247 break;
1248
1249 case IEMMODE_64BIT:
1250 IEM_MC_BEGIN(3, 0);
1251 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1252 IEM_MC_ARG(uint64_t, u64Src, 1);
1253 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1254
1255 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_RM(pVCpu, bRm));
1256 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1257 IEM_MC_REF_EFLAGS(pEFlags);
1258 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1259
1260 IEM_MC_ADVANCE_RIP();
1261 IEM_MC_END();
1262 break;
1263 }
1264 }
1265 else
1266 {
1267 /*
1268 * We're accessing memory.
1269 */
1270 switch (pVCpu->iem.s.enmEffOpSize)
1271 {
1272 case IEMMODE_16BIT:
1273 IEM_MC_BEGIN(3, 1);
1274 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1275 IEM_MC_ARG(uint16_t, u16Src, 1);
1276 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1277 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1278
1279 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1280 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1281 IEM_MC_FETCH_MEM_U16(u16Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1282 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1283 IEM_MC_REF_EFLAGS(pEFlags);
1284 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1285
1286 IEM_MC_ADVANCE_RIP();
1287 IEM_MC_END();
1288 break;
1289
1290 case IEMMODE_32BIT:
1291 IEM_MC_BEGIN(3, 1);
1292 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1293 IEM_MC_ARG(uint32_t, u32Src, 1);
1294 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1295 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1296
1297 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1298 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1299 IEM_MC_FETCH_MEM_U32(u32Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1300 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1301 IEM_MC_REF_EFLAGS(pEFlags);
1302 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1303
1304 if (pImpl != &g_iemAImpl_cmp)
1305 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1306 IEM_MC_ADVANCE_RIP();
1307 IEM_MC_END();
1308 break;
1309
1310 case IEMMODE_64BIT:
1311 IEM_MC_BEGIN(3, 1);
1312 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1313 IEM_MC_ARG(uint64_t, u64Src, 1);
1314 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1315 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
1316
1317 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
1318 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1319 IEM_MC_FETCH_MEM_U64(u64Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
1320 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_REG(pVCpu, bRm));
1321 IEM_MC_REF_EFLAGS(pEFlags);
1322 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1323
1324 IEM_MC_ADVANCE_RIP();
1325 IEM_MC_END();
1326 break;
1327 }
1328 }
1329 return VINF_SUCCESS;
1330}
1331
1332
1333/**
1334 * Common worker for instructions like ADD, AND, OR, ++ with working on AL with
1335 * a byte immediate.
1336 *
1337 * @param pImpl Pointer to the instruction implementation (assembly).
1338 */
1339FNIEMOP_DEF_1(iemOpHlpBinaryOperator_AL_Ib, PCIEMOPBINSIZES, pImpl)
1340{
1341 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
1342 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1343
1344 IEM_MC_BEGIN(3, 0);
1345 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
1346 IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/ u8Imm, 1);
1347 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1348
1349 IEM_MC_REF_GREG_U8(pu8Dst, X86_GREG_xAX);
1350 IEM_MC_REF_EFLAGS(pEFlags);
1351 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
1352
1353 IEM_MC_ADVANCE_RIP();
1354 IEM_MC_END();
1355 return VINF_SUCCESS;
1356}
1357
1358
1359/**
1360 * Common worker for instructions like ADD, AND, OR, ++ with working on
1361 * AX/EAX/RAX with a word/dword immediate.
1362 *
1363 * @param pImpl Pointer to the instruction implementation (assembly).
1364 */
1365FNIEMOP_DEF_1(iemOpHlpBinaryOperator_rAX_Iz, PCIEMOPBINSIZES, pImpl)
1366{
1367 switch (pVCpu->iem.s.enmEffOpSize)
1368 {
1369 case IEMMODE_16BIT:
1370 {
1371 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
1372 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1373
1374 IEM_MC_BEGIN(3, 0);
1375 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1376 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm, 1);
1377 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1378
1379 IEM_MC_REF_GREG_U16(pu16Dst, X86_GREG_xAX);
1380 IEM_MC_REF_EFLAGS(pEFlags);
1381 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
1382
1383 IEM_MC_ADVANCE_RIP();
1384 IEM_MC_END();
1385 return VINF_SUCCESS;
1386 }
1387
1388 case IEMMODE_32BIT:
1389 {
1390 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
1391 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1392
1393 IEM_MC_BEGIN(3, 0);
1394 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1395 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm, 1);
1396 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1397
1398 IEM_MC_REF_GREG_U32(pu32Dst, X86_GREG_xAX);
1399 IEM_MC_REF_EFLAGS(pEFlags);
1400 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
1401
1402 if ((pImpl != &g_iemAImpl_test) && (pImpl != &g_iemAImpl_cmp))
1403 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1404 IEM_MC_ADVANCE_RIP();
1405 IEM_MC_END();
1406 return VINF_SUCCESS;
1407 }
1408
1409 case IEMMODE_64BIT:
1410 {
1411 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
1412 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1413
1414 IEM_MC_BEGIN(3, 0);
1415 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1416 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm, 1);
1417 IEM_MC_ARG(uint32_t *, pEFlags, 2);
1418
1419 IEM_MC_REF_GREG_U64(pu64Dst, X86_GREG_xAX);
1420 IEM_MC_REF_EFLAGS(pEFlags);
1421 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
1422
1423 IEM_MC_ADVANCE_RIP();
1424 IEM_MC_END();
1425 return VINF_SUCCESS;
1426 }
1427
1428 IEM_NOT_REACHED_DEFAULT_CASE_RET();
1429 }
1430}
1431
1432
1433/** Opcodes 0xf1, 0xd6. */
1434FNIEMOP_DEF(iemOp_Invalid)
1435{
1436 IEMOP_MNEMONIC(Invalid, "Invalid");
1437 return IEMOP_RAISE_INVALID_OPCODE();
1438}
1439
1440
1441/** Invalid with RM byte . */
1442FNIEMOPRM_DEF(iemOp_InvalidWithRM)
1443{
1444 RT_NOREF_PV(bRm);
1445 IEMOP_MNEMONIC(InvalidWithRm, "InvalidWithRM");
1446 return IEMOP_RAISE_INVALID_OPCODE();
1447}
1448
1449
1450/** Invalid with RM byte where intel decodes any additional address encoding
1451 * bytes. */
1452FNIEMOPRM_DEF(iemOp_InvalidWithRMNeedDecode)
1453{
1454 IEMOP_MNEMONIC(InvalidWithRMNeedDecode, "InvalidWithRMNeedDecode");
1455 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1456 {
1457#ifndef TST_IEM_CHECK_MC
1458 if (IEM_IS_MODRM_MEM_MODE(bRm))
1459 {
1460 RTGCPTR GCPtrEff;
1461 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1462 if (rcStrict != VINF_SUCCESS)
1463 return rcStrict;
1464 }
1465#endif
1466 }
1467 IEMOP_HLP_DONE_DECODING();
1468 return IEMOP_RAISE_INVALID_OPCODE();
1469}
1470
1471
1472/** Invalid with RM byte where both AMD and Intel decodes any additional
1473 * address encoding bytes. */
1474FNIEMOPRM_DEF(iemOp_InvalidWithRMAllNeeded)
1475{
1476 IEMOP_MNEMONIC(InvalidWithRMAllNeeded, "InvalidWithRMAllNeeded");
1477#ifndef TST_IEM_CHECK_MC
1478 if (IEM_IS_MODRM_MEM_MODE(bRm))
1479 {
1480 RTGCPTR GCPtrEff;
1481 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1482 if (rcStrict != VINF_SUCCESS)
1483 return rcStrict;
1484 }
1485#endif
1486 IEMOP_HLP_DONE_DECODING();
1487 return IEMOP_RAISE_INVALID_OPCODE();
1488}
1489
1490
1491/** Invalid with RM byte where intel requires 8-byte immediate.
1492 * Intel will also need SIB and displacement if bRm indicates memory. */
1493FNIEMOPRM_DEF(iemOp_InvalidWithRMNeedImm8)
1494{
1495 IEMOP_MNEMONIC(InvalidWithRMNeedImm8, "InvalidWithRMNeedImm8");
1496 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1497 {
1498#ifndef TST_IEM_CHECK_MC
1499 if (IEM_IS_MODRM_MEM_MODE(bRm))
1500 {
1501 RTGCPTR GCPtrEff;
1502 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1503 if (rcStrict != VINF_SUCCESS)
1504 return rcStrict;
1505 }
1506#endif
1507 uint8_t bImm8; IEM_OPCODE_GET_NEXT_U8(&bImm8); RT_NOREF(bRm);
1508 }
1509 IEMOP_HLP_DONE_DECODING();
1510 return IEMOP_RAISE_INVALID_OPCODE();
1511}
1512
1513
1514/** Invalid with RM byte where intel requires 8-byte immediate.
1515 * Both AMD and Intel also needs SIB and displacement according to bRm. */
1516FNIEMOPRM_DEF(iemOp_InvalidWithRMAllNeedImm8)
1517{
1518 IEMOP_MNEMONIC(InvalidWithRMAllNeedImm8, "InvalidWithRMAllNeedImm8");
1519#ifndef TST_IEM_CHECK_MC
1520 if (IEM_IS_MODRM_MEM_MODE(bRm))
1521 {
1522 RTGCPTR GCPtrEff;
1523 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1524 if (rcStrict != VINF_SUCCESS)
1525 return rcStrict;
1526 }
1527#endif
1528 uint8_t bImm8; IEM_OPCODE_GET_NEXT_U8(&bImm8); RT_NOREF(bRm);
1529 IEMOP_HLP_DONE_DECODING();
1530 return IEMOP_RAISE_INVALID_OPCODE();
1531}
1532
1533
1534/** Invalid opcode where intel requires Mod R/M sequence. */
1535FNIEMOP_DEF(iemOp_InvalidNeedRM)
1536{
1537 IEMOP_MNEMONIC(InvalidNeedRM, "InvalidNeedRM");
1538 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1539 {
1540 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1541#ifndef TST_IEM_CHECK_MC
1542 if (IEM_IS_MODRM_MEM_MODE(bRm))
1543 {
1544 RTGCPTR GCPtrEff;
1545 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1546 if (rcStrict != VINF_SUCCESS)
1547 return rcStrict;
1548 }
1549#endif
1550 }
1551 IEMOP_HLP_DONE_DECODING();
1552 return IEMOP_RAISE_INVALID_OPCODE();
1553}
1554
1555
1556/** Invalid opcode where both AMD and Intel requires Mod R/M sequence. */
1557FNIEMOP_DEF(iemOp_InvalidAllNeedRM)
1558{
1559 IEMOP_MNEMONIC(InvalidAllNeedRM, "InvalidAllNeedRM");
1560 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1561#ifndef TST_IEM_CHECK_MC
1562 if (IEM_IS_MODRM_MEM_MODE(bRm))
1563 {
1564 RTGCPTR GCPtrEff;
1565 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1566 if (rcStrict != VINF_SUCCESS)
1567 return rcStrict;
1568 }
1569#endif
1570 IEMOP_HLP_DONE_DECODING();
1571 return IEMOP_RAISE_INVALID_OPCODE();
1572}
1573
1574
1575/** Invalid opcode where intel requires Mod R/M sequence and 8-byte
1576 * immediate. */
1577FNIEMOP_DEF(iemOp_InvalidNeedRMImm8)
1578{
1579 IEMOP_MNEMONIC(InvalidNeedRMImm8, "InvalidNeedRMImm8");
1580 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1581 {
1582 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1583#ifndef TST_IEM_CHECK_MC
1584 if (IEM_IS_MODRM_MEM_MODE(bRm))
1585 {
1586 RTGCPTR GCPtrEff;
1587 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1588 if (rcStrict != VINF_SUCCESS)
1589 return rcStrict;
1590 }
1591#endif
1592 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm); RT_NOREF(bImm);
1593 }
1594 IEMOP_HLP_DONE_DECODING();
1595 return IEMOP_RAISE_INVALID_OPCODE();
1596}
1597
1598
1599/** Invalid opcode where intel requires a 3rd escape byte and a Mod R/M
1600 * sequence. */
1601FNIEMOP_DEF(iemOp_InvalidNeed3ByteEscRM)
1602{
1603 IEMOP_MNEMONIC(InvalidNeed3ByteEscRM, "InvalidNeed3ByteEscRM");
1604 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1605 {
1606 uint8_t b3rd; IEM_OPCODE_GET_NEXT_U8(&b3rd); RT_NOREF(b3rd);
1607 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1608#ifndef TST_IEM_CHECK_MC
1609 if (IEM_IS_MODRM_MEM_MODE(bRm))
1610 {
1611 RTGCPTR GCPtrEff;
1612 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
1613 if (rcStrict != VINF_SUCCESS)
1614 return rcStrict;
1615 }
1616#endif
1617 }
1618 IEMOP_HLP_DONE_DECODING();
1619 return IEMOP_RAISE_INVALID_OPCODE();
1620}
1621
1622
1623/** Invalid opcode where intel requires a 3rd escape byte, Mod R/M sequence, and
1624 * a 8-byte immediate. */
1625FNIEMOP_DEF(iemOp_InvalidNeed3ByteEscRMImm8)
1626{
1627 IEMOP_MNEMONIC(InvalidNeed3ByteEscRMImm8, "InvalidNeed3ByteEscRMImm8");
1628 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
1629 {
1630 uint8_t b3rd; IEM_OPCODE_GET_NEXT_U8(&b3rd); RT_NOREF(b3rd);
1631 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
1632#ifndef TST_IEM_CHECK_MC
1633 if (IEM_IS_MODRM_MEM_MODE(bRm))
1634 {
1635 RTGCPTR GCPtrEff;
1636 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 1, &GCPtrEff);
1637 if (rcStrict != VINF_SUCCESS)
1638 return rcStrict;
1639 }
1640#endif
1641 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm); RT_NOREF(bImm);
1642 IEMOP_HLP_DONE_DECODING();
1643 }
1644 return IEMOP_RAISE_INVALID_OPCODE();
1645}
1646
1647
1648/** Repeats a_fn four times. For decoding tables. */
1649#define IEMOP_X4(a_fn) a_fn, a_fn, a_fn, a_fn
1650
1651/*
1652 * Include the tables.
1653 */
1654#ifdef IEM_WITH_3DNOW
1655# include "IEMAllInstructions3DNow.cpp.h"
1656#endif
1657#ifdef IEM_WITH_THREE_0F_38
1658# include "IEMAllInstructionsThree0f38.cpp.h"
1659#endif
1660#ifdef IEM_WITH_THREE_0F_3A
1661# include "IEMAllInstructionsThree0f3a.cpp.h"
1662#endif
1663#include "IEMAllInstructionsTwoByte0f.cpp.h"
1664#ifdef IEM_WITH_VEX
1665# include "IEMAllInstructionsVexMap1.cpp.h"
1666# include "IEMAllInstructionsVexMap2.cpp.h"
1667# include "IEMAllInstructionsVexMap3.cpp.h"
1668#endif
1669#include "IEMAllInstructionsOneByte.cpp.h"
1670
1671
1672#ifdef _MSC_VER
1673# pragma warning(pop)
1674#endif
1675
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use