VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h@ 102473

Last change on this file since 102473 was 102473, checked in by vboxsync, 12 months ago

VMM/IEM: optimize todo. bugref:10371

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 534.6 KB
Line 
1/* $Id: IEMAllInstOneByte.cpp.h 102473 2023-12-05 12:54:55Z 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* Global Variables *
31*******************************************************************************/
32extern const PFNIEMOP g_apfnOneByteMap[256]; /* not static since we need to forward declare it. */
33
34/* Instruction group definitions: */
35
36/** @defgroup og_gen General
37 * @{ */
38 /** @defgroup og_gen_arith Arithmetic
39 * @{ */
40 /** @defgroup og_gen_arith_bin Binary numbers */
41 /** @defgroup og_gen_arith_dec Decimal numbers */
42 /** @} */
43/** @} */
44
45/** @defgroup og_stack Stack
46 * @{ */
47 /** @defgroup og_stack_sreg Segment registers */
48/** @} */
49
50/** @defgroup og_prefix Prefixes */
51/** @defgroup og_escapes Escape bytes */
52
53
54
55/** @name One byte opcodes.
56 * @{
57 */
58
59/**
60 * Body for instructions like ADD, AND, OR, TEST, CMP, ++ with a byte
61 * memory/register as the destination.
62 *
63 * Used with IEMOP_BODY_BINARY_rm_r8_NO_LOCK or IEMOP_BODY_BINARY_rm_r8_LOCKED.
64 */
65#define IEMOP_BODY_BINARY_rm_r8_RW(a_fnNormalU8) \
66 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
67 \
68 /* \
69 * If rm is denoting a register, no more instruction bytes. \
70 */ \
71 if (IEM_IS_MODRM_REG_MODE(bRm)) \
72 { \
73 IEM_MC_BEGIN(3, 0, 0, 0); \
74 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
75 IEM_MC_ARG(uint8_t, u8Src, 1); \
76 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
77 \
78 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
79 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
80 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
81 IEM_MC_REF_EFLAGS(pEFlags); \
82 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
83 \
84 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
85 IEM_MC_END(); \
86 } \
87 else \
88 { \
89 /* \
90 * We're accessing memory. \
91 * Note! We're putting the eflags on the stack here so we can commit them \
92 * after the memory. \
93 */ \
94 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
95 { \
96 IEM_MC_BEGIN(3, 3, 0, 0); \
97 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
98 IEM_MC_ARG(uint8_t, u8Src, 1); \
99 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
100 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
101 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
102 \
103 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
104 IEMOP_HLP_DONE_DECODING(); \
105 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
106 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
107 IEM_MC_FETCH_EFLAGS(EFlags); \
108 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
109 \
110 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
111 IEM_MC_COMMIT_EFLAGS(EFlags); \
112 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
113 IEM_MC_END(); \
114 } \
115 else \
116 { \
117 (void)0
118
119/**
120 * Body for instructions like TEST & CMP, ++ with a byte memory/registers as
121 * operands.
122 *
123 * Used with IEMOP_BODY_BINARY_rm_r8_NO_LOCK or IEMOP_BODY_BINARY_rm_r8_LOCKED.
124 */
125#define IEMOP_BODY_BINARY_rm_r8_RO(a_fnNormalU8) \
126 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
127 \
128 /* \
129 * If rm is denoting a register, no more instruction bytes. \
130 */ \
131 if (IEM_IS_MODRM_REG_MODE(bRm)) \
132 { \
133 IEM_MC_BEGIN(3, 0, 0, 0); \
134 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
135 IEM_MC_ARG(uint8_t, u8Src, 1); \
136 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
137 \
138 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
139 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
140 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
141 IEM_MC_REF_EFLAGS(pEFlags); \
142 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
143 \
144 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
145 IEM_MC_END(); \
146 } \
147 else \
148 { \
149 /* \
150 * We're accessing memory. \
151 * Note! We're putting the eflags on the stack here so we can commit them \
152 * after the memory. \
153 */ \
154 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
155 { \
156 IEM_MC_BEGIN(3, 3, 0, 0); \
157 IEM_MC_ARG(uint8_t const *, pu8Dst, 0); \
158 IEM_MC_ARG(uint8_t, u8Src, 1); \
159 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
160 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
161 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
162 \
163 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
164 IEMOP_HLP_DONE_DECODING(); \
165 IEM_MC_MEM_MAP_U8_RO(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
166 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
167 IEM_MC_FETCH_EFLAGS(EFlags); \
168 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
169 \
170 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
171 IEM_MC_COMMIT_EFLAGS(EFlags); \
172 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
173 IEM_MC_END(); \
174 } \
175 else \
176 { \
177 (void)0
178
179#define IEMOP_BODY_BINARY_rm_r8_NO_LOCK() \
180 IEMOP_HLP_DONE_DECODING(); \
181 IEMOP_RAISE_INVALID_LOCK_PREFIX_RET(); \
182 } \
183 } \
184 (void)0
185
186#define IEMOP_BODY_BINARY_rm_r8_LOCKED(a_fnLockedU8) \
187 IEM_MC_BEGIN(3, 3, 0, 0); \
188 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
189 IEM_MC_ARG(uint8_t, u8Src, 1); \
190 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
191 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
192 IEM_MC_LOCAL(uint8_t, bMapInfoDst); \
193 \
194 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
195 IEMOP_HLP_DONE_DECODING(); \
196 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bMapInfoDst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
197 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
198 IEM_MC_FETCH_EFLAGS(EFlags); \
199 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU8, pu8Dst, u8Src, pEFlags); \
200 \
201 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bMapInfoDst); \
202 IEM_MC_COMMIT_EFLAGS(EFlags); \
203 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
204 IEM_MC_END(); \
205 } \
206 } \
207 (void)0
208
209/**
210 * Body for byte instructions like ADD, AND, OR, ++ with a register as the
211 * destination.
212 */
213#define IEMOP_BODY_BINARY_r8_rm(a_fnNormalU8) \
214 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
215 \
216 /* \
217 * If rm is denoting a register, no more instruction bytes. \
218 */ \
219 if (IEM_IS_MODRM_REG_MODE(bRm)) \
220 { \
221 IEM_MC_BEGIN(3, 0, 0, 0); \
222 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
223 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
224 IEM_MC_ARG(uint8_t, u8Src, 1); \
225 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
226 \
227 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_RM(pVCpu, bRm)); \
228 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_REG(pVCpu, bRm)); \
229 IEM_MC_REF_EFLAGS(pEFlags); \
230 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
231 \
232 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
233 IEM_MC_END(); \
234 } \
235 else \
236 { \
237 /* \
238 * We're accessing memory. \
239 */ \
240 IEM_MC_BEGIN(3, 1, 0, 0); \
241 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
242 IEM_MC_ARG(uint8_t, u8Src, 1); \
243 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
244 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
245 \
246 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
247 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
248 IEM_MC_FETCH_MEM_U8(u8Src, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
249 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_REG(pVCpu, bRm)); \
250 IEM_MC_REF_EFLAGS(pEFlags); \
251 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
252 \
253 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
254 IEM_MC_END(); \
255 } \
256 (void)0
257
258
259/**
260 * Body for word/dword/qword instructions like ADD, AND, OR, ++ with
261 * memory/register as the destination.
262 */
263#define IEMOP_BODY_BINARY_rm_rv_RW(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
264 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
265 \
266 /* \
267 * If rm is denoting a register, no more instruction bytes. \
268 */ \
269 if (IEM_IS_MODRM_REG_MODE(bRm)) \
270 { \
271 switch (pVCpu->iem.s.enmEffOpSize) \
272 { \
273 case IEMMODE_16BIT: \
274 IEM_MC_BEGIN(3, 0, 0, 0); \
275 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
276 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
277 IEM_MC_ARG(uint16_t, u16Src, 1); \
278 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
279 \
280 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
281 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
282 IEM_MC_REF_EFLAGS(pEFlags); \
283 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
284 \
285 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
286 IEM_MC_END(); \
287 break; \
288 \
289 case IEMMODE_32BIT: \
290 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
291 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
292 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
293 IEM_MC_ARG(uint32_t, u32Src, 1); \
294 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
295 \
296 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
297 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
298 IEM_MC_REF_EFLAGS(pEFlags); \
299 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
300 \
301 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm)); \
302 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
303 IEM_MC_END(); \
304 break; \
305 \
306 case IEMMODE_64BIT: \
307 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
308 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
309 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
310 IEM_MC_ARG(uint64_t, u64Src, 1); \
311 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
312 \
313 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
314 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
315 IEM_MC_REF_EFLAGS(pEFlags); \
316 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
317 \
318 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
319 IEM_MC_END(); \
320 break; \
321 \
322 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
323 } \
324 } \
325 else \
326 { \
327 /* \
328 * We're accessing memory. \
329 * Note! We're putting the eflags on the stack here so we can commit them \
330 * after the memory. \
331 */ \
332 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
333 { \
334 switch (pVCpu->iem.s.enmEffOpSize) \
335 { \
336 case IEMMODE_16BIT: \
337 IEM_MC_BEGIN(3, 3, 0, 0); \
338 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
339 IEM_MC_ARG(uint16_t, u16Src, 1); \
340 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
341 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
342 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
343 \
344 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
345 IEMOP_HLP_DONE_DECODING(); \
346 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
347 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
348 IEM_MC_FETCH_EFLAGS(EFlags); \
349 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
350 \
351 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
352 IEM_MC_COMMIT_EFLAGS(EFlags); \
353 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
354 IEM_MC_END(); \
355 break; \
356 \
357 case IEMMODE_32BIT: \
358 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
359 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
360 IEM_MC_ARG(uint32_t, u32Src, 1); \
361 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
362 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
363 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
364 \
365 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
366 IEMOP_HLP_DONE_DECODING(); \
367 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
368 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
369 IEM_MC_FETCH_EFLAGS(EFlags); \
370 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
371 \
372 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
373 IEM_MC_COMMIT_EFLAGS(EFlags); \
374 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
375 IEM_MC_END(); \
376 break; \
377 \
378 case IEMMODE_64BIT: \
379 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
380 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
381 IEM_MC_ARG(uint64_t, u64Src, 1); \
382 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
383 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
384 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
385 \
386 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
387 IEMOP_HLP_DONE_DECODING(); \
388 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
389 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
390 IEM_MC_FETCH_EFLAGS(EFlags); \
391 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
392 \
393 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
394 IEM_MC_COMMIT_EFLAGS(EFlags); \
395 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
396 IEM_MC_END(); \
397 break; \
398 \
399 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
400 } \
401 } \
402 else \
403 { \
404 (void)0
405/* Separate macro to work around parsing issue in IEMAllInstPython.py */
406#define IEMOP_BODY_BINARY_rm_rv_LOCKED(a_fnLockedU16, a_fnLockedU32, a_fnLockedU64) \
407 switch (pVCpu->iem.s.enmEffOpSize) \
408 { \
409 case IEMMODE_16BIT: \
410 IEM_MC_BEGIN(3, 3, 0, 0); \
411 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
412 IEM_MC_ARG(uint16_t, u16Src, 1); \
413 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
414 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
415 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
416 \
417 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
418 IEMOP_HLP_DONE_DECODING(); \
419 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
420 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
421 IEM_MC_FETCH_EFLAGS(EFlags); \
422 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU16, pu16Dst, u16Src, pEFlags); \
423 \
424 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
425 IEM_MC_COMMIT_EFLAGS(EFlags); \
426 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
427 IEM_MC_END(); \
428 break; \
429 \
430 case IEMMODE_32BIT: \
431 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
432 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
433 IEM_MC_ARG(uint32_t, u32Src, 1); \
434 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
435 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
436 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
437 \
438 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
439 IEMOP_HLP_DONE_DECODING(); \
440 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
441 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
442 IEM_MC_FETCH_EFLAGS(EFlags); \
443 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU32, pu32Dst, u32Src, pEFlags); \
444 \
445 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo /* CMP,TEST */); \
446 IEM_MC_COMMIT_EFLAGS(EFlags); \
447 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
448 IEM_MC_END(); \
449 break; \
450 \
451 case IEMMODE_64BIT: \
452 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
453 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
454 IEM_MC_ARG(uint64_t, u64Src, 1); \
455 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2); \
456 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
457 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
458 \
459 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
460 IEMOP_HLP_DONE_DECODING(); \
461 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
462 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
463 IEM_MC_FETCH_EFLAGS(EFlags); \
464 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU64, pu64Dst, u64Src, pEFlags); \
465 \
466 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
467 IEM_MC_COMMIT_EFLAGS(EFlags); \
468 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
469 IEM_MC_END(); \
470 break; \
471 \
472 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
473 } \
474 } \
475 } \
476 (void)0
477
478/**
479 * Body for read-only word/dword/qword instructions like TEST and CMP with
480 * memory/register as the destination.
481 */
482#define IEMOP_BODY_BINARY_rm_rv_RO(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
483 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
484 \
485 /* \
486 * If rm is denoting a register, no more instruction bytes. \
487 */ \
488 if (IEM_IS_MODRM_REG_MODE(bRm)) \
489 { \
490 switch (pVCpu->iem.s.enmEffOpSize) \
491 { \
492 case IEMMODE_16BIT: \
493 IEM_MC_BEGIN(3, 0, 0, 0); \
494 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
495 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
496 IEM_MC_ARG(uint16_t, u16Src, 1); \
497 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
498 \
499 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
500 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
501 IEM_MC_REF_EFLAGS(pEFlags); \
502 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
503 \
504 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
505 IEM_MC_END(); \
506 break; \
507 \
508 case IEMMODE_32BIT: \
509 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
510 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
511 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
512 IEM_MC_ARG(uint32_t, u32Src, 1); \
513 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
514 \
515 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
516 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
517 IEM_MC_REF_EFLAGS(pEFlags); \
518 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
519 \
520 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
521 IEM_MC_END(); \
522 break; \
523 \
524 case IEMMODE_64BIT: \
525 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
526 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
527 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
528 IEM_MC_ARG(uint64_t, u64Src, 1); \
529 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
530 \
531 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
532 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
533 IEM_MC_REF_EFLAGS(pEFlags); \
534 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
535 \
536 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
537 IEM_MC_END(); \
538 break; \
539 \
540 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
541 } \
542 } \
543 else \
544 { \
545 /* \
546 * We're accessing memory. \
547 * Note! We're putting the eflags on the stack here so we can commit them \
548 * after the memory. \
549 */ \
550 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
551 { \
552 switch (pVCpu->iem.s.enmEffOpSize) \
553 { \
554 case IEMMODE_16BIT: \
555 IEM_MC_BEGIN(3, 3, 0, 0); \
556 IEM_MC_ARG(uint16_t const *, pu16Dst, 0); \
557 IEM_MC_ARG(uint16_t, u16Src, 1); \
558 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
559 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
560 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
561 \
562 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
563 IEMOP_HLP_DONE_DECODING(); \
564 IEM_MC_MEM_MAP_U16_RO(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
565 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
566 IEM_MC_FETCH_EFLAGS(EFlags); \
567 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
568 \
569 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
570 IEM_MC_COMMIT_EFLAGS(EFlags); \
571 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
572 IEM_MC_END(); \
573 break; \
574 \
575 case IEMMODE_32BIT: \
576 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
577 IEM_MC_ARG(uint32_t const *, pu32Dst, 0); \
578 IEM_MC_ARG(uint32_t, u32Src, 1); \
579 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
580 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
581 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
582 \
583 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
584 IEMOP_HLP_DONE_DECODING(); \
585 IEM_MC_MEM_MAP_U32_RO(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
586 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
587 IEM_MC_FETCH_EFLAGS(EFlags); \
588 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
589 \
590 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
591 IEM_MC_COMMIT_EFLAGS(EFlags); \
592 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
593 IEM_MC_END(); \
594 break; \
595 \
596 case IEMMODE_64BIT: \
597 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
598 IEM_MC_ARG(uint64_t const *, pu64Dst, 0); \
599 IEM_MC_ARG(uint64_t, u64Src, 1); \
600 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
601 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
602 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
603 \
604 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
605 IEMOP_HLP_DONE_DECODING(); \
606 IEM_MC_MEM_MAP_U64_RO(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
607 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
608 IEM_MC_FETCH_EFLAGS(EFlags); \
609 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
610 \
611 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
612 IEM_MC_COMMIT_EFLAGS(EFlags); \
613 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
614 IEM_MC_END(); \
615 break; \
616 \
617 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
618 } \
619 } \
620 else \
621 { \
622 IEMOP_HLP_DONE_DECODING(); \
623 IEMOP_RAISE_INVALID_LOCK_PREFIX_RET(); \
624 } \
625 } \
626 (void)0
627
628
629/**
630 * Body for instructions like ADD, AND, OR, ++ with working on AL with
631 * a byte immediate.
632 */
633#define IEMOP_BODY_BINARY_AL_Ib(a_fnNormalU8) \
634 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
635 \
636 IEM_MC_BEGIN(3, 0, 0, 0); \
637 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
638 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
639 IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/ u8Imm, 1); \
640 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
641 \
642 IEM_MC_REF_GREG_U8(pu8Dst, X86_GREG_xAX); \
643 IEM_MC_REF_EFLAGS(pEFlags); \
644 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
645 \
646 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
647 IEM_MC_END()
648
649/**
650 * Body for instructions like ADD, AND, OR, ++ with working on
651 * AX/EAX/RAX with a word/dword immediate.
652 */
653#define IEMOP_BODY_BINARY_rAX_Iz(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64, a_fModifiesDstReg) \
654 switch (pVCpu->iem.s.enmEffOpSize) \
655 { \
656 case IEMMODE_16BIT: \
657 { \
658 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); \
659 \
660 IEM_MC_BEGIN(3, 0, 0, 0); \
661 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
662 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
663 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm, 1); \
664 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
665 \
666 IEM_MC_REF_GREG_U16(pu16Dst, X86_GREG_xAX); \
667 IEM_MC_REF_EFLAGS(pEFlags); \
668 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
669 \
670 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
671 IEM_MC_END(); \
672 } \
673 \
674 case IEMMODE_32BIT: \
675 { \
676 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); \
677 \
678 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
679 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
680 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
681 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm, 1); \
682 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
683 \
684 IEM_MC_REF_GREG_U32(pu32Dst, X86_GREG_xAX); \
685 IEM_MC_REF_EFLAGS(pEFlags); \
686 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
687 \
688 if (a_fModifiesDstReg) \
689 IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX); \
690 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
691 IEM_MC_END(); \
692 } \
693 \
694 case IEMMODE_64BIT: \
695 { \
696 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm); \
697 \
698 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
699 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
700 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
701 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm, 1); \
702 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
703 \
704 IEM_MC_REF_GREG_U64(pu64Dst, X86_GREG_xAX); \
705 IEM_MC_REF_EFLAGS(pEFlags); \
706 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
707 \
708 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
709 IEM_MC_END(); \
710 } \
711 \
712 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
713 } \
714 (void)0
715
716
717
718/* Instruction specification format - work in progress: */
719
720/**
721 * @opcode 0x00
722 * @opmnemonic add
723 * @op1 rm:Eb
724 * @op2 reg:Gb
725 * @opmaps one
726 * @openc ModR/M
727 * @opflmodify cf,pf,af,zf,sf,of
728 * @ophints harmless ignores_op_sizes
729 * @opstats add_Eb_Gb
730 * @opgroup og_gen_arith_bin
731 * @optest op1=1 op2=1 -> op1=2 efl&|=nc,pe,na,nz,pl,nv
732 * @optest efl|=cf op1=1 op2=2 -> op1=3 efl&|=nc,po,na,nz,pl,nv
733 * @optest op1=254 op2=1 -> op1=255 efl&|=nc,po,na,nz,ng,nv
734 * @optest op1=128 op2=128 -> op1=0 efl&|=ov,pl,zf,na,po,cf
735 */
736FNIEMOP_DEF(iemOp_add_Eb_Gb)
737{
738 IEMOP_MNEMONIC2(MR, ADD, add, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
739 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_add_u8);
740 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_add_u8_locked);
741}
742
743
744/**
745 * @opcode 0x01
746 * @opgroup og_gen_arith_bin
747 * @opflmodify cf,pf,af,zf,sf,of
748 * @optest op1=1 op2=1 -> op1=2 efl&|=nc,pe,na,nz,pl,nv
749 * @optest efl|=cf op1=2 op2=2 -> op1=4 efl&|=nc,pe,na,nz,pl,nv
750 * @optest efl&~=cf op1=-1 op2=1 -> op1=0 efl&|=cf,po,af,zf,pl,nv
751 * @optest op1=-1 op2=-1 -> op1=-2 efl&|=cf,pe,af,nz,ng,nv
752 */
753FNIEMOP_DEF(iemOp_add_Ev_Gv)
754{
755 IEMOP_MNEMONIC2(MR, ADD, add, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
756 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_add_u16, iemAImpl_add_u32, iemAImpl_add_u64);
757 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_add_u16_locked, iemAImpl_add_u32_locked, iemAImpl_add_u64_locked);
758}
759
760
761/**
762 * @opcode 0x02
763 * @opgroup og_gen_arith_bin
764 * @opflmodify cf,pf,af,zf,sf,of
765 * @opcopytests iemOp_add_Eb_Gb
766 */
767FNIEMOP_DEF(iemOp_add_Gb_Eb)
768{
769 IEMOP_MNEMONIC2(RM, ADD, add, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
770 IEMOP_BODY_BINARY_r8_rm(iemAImpl_add_u8);
771}
772
773
774/**
775 * @opcode 0x03
776 * @opgroup og_gen_arith_bin
777 * @opflmodify cf,pf,af,zf,sf,of
778 * @opcopytests iemOp_add_Ev_Gv
779 */
780FNIEMOP_DEF(iemOp_add_Gv_Ev)
781{
782 IEMOP_MNEMONIC2(RM, ADD, add, Gv, Ev, DISOPTYPE_HARMLESS, 0);
783 IEMOP_BODY_BINARY_rv_rm(iemAImpl_add_u16, iemAImpl_add_u32, iemAImpl_add_u64, 1, 0);
784}
785
786
787/**
788 * @opcode 0x04
789 * @opgroup og_gen_arith_bin
790 * @opflmodify cf,pf,af,zf,sf,of
791 * @opcopytests iemOp_add_Eb_Gb
792 */
793FNIEMOP_DEF(iemOp_add_Al_Ib)
794{
795 IEMOP_MNEMONIC2(FIXED, ADD, add, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
796 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_add_u8);
797}
798
799
800/**
801 * @opcode 0x05
802 * @opgroup og_gen_arith_bin
803 * @opflmodify cf,pf,af,zf,sf,of
804 * @optest op1=1 op2=1 -> op1=2 efl&|=nv,pl,nz,na,pe
805 * @optest efl|=cf op1=2 op2=2 -> op1=4 efl&|=nc,pe,na,nz,pl,nv
806 * @optest efl&~=cf op1=-1 op2=1 -> op1=0 efl&|=cf,po,af,zf,pl,nv
807 * @optest op1=-1 op2=-1 -> op1=-2 efl&|=cf,pe,af,nz,ng,nv
808 */
809FNIEMOP_DEF(iemOp_add_eAX_Iz)
810{
811 IEMOP_MNEMONIC2(FIXED, ADD, add, rAX, Iz, DISOPTYPE_HARMLESS, 0);
812 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_add_u16, iemAImpl_add_u32, iemAImpl_add_u64, 1);
813}
814
815
816/**
817 * @opcode 0x06
818 * @opgroup og_stack_sreg
819 */
820FNIEMOP_DEF(iemOp_push_ES)
821{
822 IEMOP_MNEMONIC1(FIXED, PUSH, push, ES, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0);
823 IEMOP_HLP_NO_64BIT();
824 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_ES);
825}
826
827
828/**
829 * @opcode 0x07
830 * @opgroup og_stack_sreg
831 */
832FNIEMOP_DEF(iemOp_pop_ES)
833{
834 IEMOP_MNEMONIC1(FIXED, POP, pop, ES, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0);
835 IEMOP_HLP_NO_64BIT();
836 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
837 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_MODE,
838 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
839 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_ES)
840 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_ES)
841 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_ES),
842 iemCImpl_pop_Sreg, X86_SREG_ES, pVCpu->iem.s.enmEffOpSize);
843}
844
845
846/**
847 * @opcode 0x08
848 * @opgroup og_gen_arith_bin
849 * @opflmodify cf,pf,af,zf,sf,of
850 * @opflundef af
851 * @opflclear of,cf
852 * @optest op1=7 op2=12 -> op1=15 efl&|=nc,po,na,nz,pl,nv
853 * @optest efl|=of,cf op1=0 op2=0 -> op1=0 efl&|=nc,po,na,zf,pl,nv
854 * @optest op1=0xee op2=0x11 -> op1=0xff efl&|=nc,po,na,nz,ng,nv
855 * @optest op1=0xff op2=0xff -> op1=0xff efl&|=nc,po,na,nz,ng,nv
856 */
857FNIEMOP_DEF(iemOp_or_Eb_Gb)
858{
859 IEMOP_MNEMONIC2(MR, OR, or, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
860 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
861 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_or_u8);
862 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_or_u8_locked);
863}
864
865
866/*
867 * @opcode 0x09
868 * @opgroup og_gen_arith_bin
869 * @opflmodify cf,pf,af,zf,sf,of
870 * @opflundef af
871 * @opflclear of,cf
872 * @optest efl|=of,cf op1=12 op2=7 -> op1=15 efl&|=nc,po,na,nz,pl,nv
873 * @optest efl|=of,cf op1=0 op2=0 -> op1=0 efl&|=nc,po,na,zf,pl,nv
874 * @optest op1=-2 op2=1 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
875 * @optest o16 / op1=0x5a5a op2=0xa5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
876 * @optest o32 / op1=0x5a5a5a5a op2=0xa5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
877 * @optest o64 / op1=0x5a5a5a5a5a5a5a5a op2=0xa5a5a5a5a5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
878 */
879FNIEMOP_DEF(iemOp_or_Ev_Gv)
880{
881 IEMOP_MNEMONIC2(MR, OR, or, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
882 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
883 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_or_u16, iemAImpl_or_u32, iemAImpl_or_u64);
884 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_or_u16_locked, iemAImpl_or_u32_locked, iemAImpl_or_u64_locked);
885}
886
887
888/**
889 * @opcode 0x0a
890 * @opgroup og_gen_arith_bin
891 * @opflmodify cf,pf,af,zf,sf,of
892 * @opflundef af
893 * @opflclear of,cf
894 * @opcopytests iemOp_or_Eb_Gb
895 */
896FNIEMOP_DEF(iemOp_or_Gb_Eb)
897{
898 IEMOP_MNEMONIC2(RM, OR, or, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
899 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
900 IEMOP_BODY_BINARY_r8_rm(iemAImpl_or_u8);
901}
902
903
904/**
905 * @opcode 0x0b
906 * @opgroup og_gen_arith_bin
907 * @opflmodify cf,pf,af,zf,sf,of
908 * @opflundef af
909 * @opflclear of,cf
910 * @opcopytests iemOp_or_Ev_Gv
911 */
912FNIEMOP_DEF(iemOp_or_Gv_Ev)
913{
914 IEMOP_MNEMONIC2(RM, OR, or, Gv, Ev, DISOPTYPE_HARMLESS, 0);
915 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
916 IEMOP_BODY_BINARY_rv_rm(iemAImpl_or_u16, iemAImpl_or_u32, iemAImpl_or_u64, 1, 0);
917}
918
919
920/**
921 * @opcode 0x0c
922 * @opgroup og_gen_arith_bin
923 * @opflmodify cf,pf,af,zf,sf,of
924 * @opflundef af
925 * @opflclear of,cf
926 * @opcopytests iemOp_or_Eb_Gb
927 */
928FNIEMOP_DEF(iemOp_or_Al_Ib)
929{
930 IEMOP_MNEMONIC2(FIXED, OR, or, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
931 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
932 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_or_u8);
933}
934
935
936/**
937 * @opcode 0x0d
938 * @opgroup og_gen_arith_bin
939 * @opflmodify cf,pf,af,zf,sf,of
940 * @opflundef af
941 * @opflclear of,cf
942 * @optest efl|=of,cf op1=12 op2=7 -> op1=15 efl&|=nc,po,na,nz,pl,nv
943 * @optest efl|=of,cf op1=0 op2=0 -> op1=0 efl&|=nc,po,na,zf,pl,nv
944 * @optest op1=-2 op2=1 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
945 * @optest o16 / op1=0x5a5a op2=0xa5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
946 * @optest o32 / op1=0x5a5a5a5a op2=0xa5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
947 * @optest o64 / op1=0x5a5a5a5a5a5a5a5a op2=0xa5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
948 * @optest o64 / op1=0x5a5a5a5aa5a5a5a5 op2=0x5a5a5a5a -> op1=0x5a5a5a5affffffff efl&|=nc,po,na,nz,pl,nv
949 */
950FNIEMOP_DEF(iemOp_or_eAX_Iz)
951{
952 IEMOP_MNEMONIC2(FIXED, OR, or, rAX, Iz, DISOPTYPE_HARMLESS, 0);
953 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
954 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_or_u16, iemAImpl_or_u32, iemAImpl_or_u64, 1);
955}
956
957
958/**
959 * @opcode 0x0e
960 * @opgroup og_stack_sreg
961 */
962FNIEMOP_DEF(iemOp_push_CS)
963{
964 IEMOP_MNEMONIC1(FIXED, PUSH, push, CS, DISOPTYPE_HARMLESS | DISOPTYPE_POTENTIALLY_DANGEROUS | DISOPTYPE_X86_INVALID_64, 0);
965 IEMOP_HLP_NO_64BIT();
966 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_CS);
967}
968
969
970/**
971 * @opcode 0x0f
972 * @opmnemonic EscTwo0f
973 * @openc two0f
974 * @opdisenum OP_2B_ESC
975 * @ophints harmless
976 * @opgroup og_escapes
977 */
978FNIEMOP_DEF(iemOp_2byteEscape)
979{
980#if 0 /// @todo def VBOX_STRICT
981 /* Sanity check the table the first time around. */
982 static bool s_fTested = false;
983 if (RT_LIKELY(s_fTested)) { /* likely */ }
984 else
985 {
986 s_fTested = true;
987 Assert(g_apfnTwoByteMap[0xbc * 4 + 0] == iemOp_bsf_Gv_Ev);
988 Assert(g_apfnTwoByteMap[0xbc * 4 + 1] == iemOp_bsf_Gv_Ev);
989 Assert(g_apfnTwoByteMap[0xbc * 4 + 2] == iemOp_tzcnt_Gv_Ev);
990 Assert(g_apfnTwoByteMap[0xbc * 4 + 3] == iemOp_bsf_Gv_Ev);
991 }
992#endif
993
994 if (RT_LIKELY(IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_286))
995 {
996 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
997 IEMOP_HLP_MIN_286();
998 return FNIEMOP_CALL(g_apfnTwoByteMap[(uintptr_t)b * 4 + pVCpu->iem.s.idxPrefix]);
999 }
1000 /* @opdone */
1001
1002 /*
1003 * On the 8086 this is a POP CS instruction.
1004 * For the time being we don't specify this this.
1005 */
1006 IEMOP_MNEMONIC1(FIXED, POP, pop, CS, DISOPTYPE_HARMLESS | DISOPTYPE_POTENTIALLY_DANGEROUS | DISOPTYPE_X86_INVALID_64, IEMOPHINT_SKIP_PYTHON);
1007 IEMOP_HLP_NO_64BIT();
1008 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1009 /** @todo eliminate END_TB here */
1010 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_END_TB,
1011 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
1012 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_CS),
1013 iemCImpl_pop_Sreg, X86_SREG_CS, pVCpu->iem.s.enmEffOpSize);
1014}
1015
1016/**
1017 * @opcode 0x10
1018 * @opgroup og_gen_arith_bin
1019 * @opfltest cf
1020 * @opflmodify cf,pf,af,zf,sf,of
1021 * @optest op1=1 op2=1 efl&~=cf -> op1=2 efl&|=nc,pe,na,nz,pl,nv
1022 * @optest op1=1 op2=1 efl|=cf -> op1=3 efl&|=nc,po,na,nz,pl,nv
1023 * @optest op1=0xff op2=0 efl|=cf -> op1=0 efl&|=cf,po,af,zf,pl,nv
1024 * @optest op1=0 op2=0 efl|=cf -> op1=1 efl&|=nc,pe,na,nz,pl,nv
1025 * @optest op1=0 op2=0 efl&~=cf -> op1=0 efl&|=nc,po,na,zf,pl,nv
1026 */
1027FNIEMOP_DEF(iemOp_adc_Eb_Gb)
1028{
1029 IEMOP_MNEMONIC2(MR, ADC, adc, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
1030 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_adc_u8);
1031 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_adc_u8_locked);
1032}
1033
1034
1035/**
1036 * @opcode 0x11
1037 * @opgroup og_gen_arith_bin
1038 * @opfltest cf
1039 * @opflmodify cf,pf,af,zf,sf,of
1040 * @optest op1=1 op2=1 efl&~=cf -> op1=2 efl&|=nc,pe,na,nz,pl,nv
1041 * @optest op1=1 op2=1 efl|=cf -> op1=3 efl&|=nc,po,na,nz,pl,nv
1042 * @optest op1=-1 op2=0 efl|=cf -> op1=0 efl&|=cf,po,af,zf,pl,nv
1043 * @optest op1=0 op2=0 efl|=cf -> op1=1 efl&|=nc,pe,na,nz,pl,nv
1044 * @optest op1=0 op2=0 efl&~=cf -> op1=0 efl&|=nc,po,na,zf,pl,nv
1045 */
1046FNIEMOP_DEF(iemOp_adc_Ev_Gv)
1047{
1048 IEMOP_MNEMONIC2(MR, ADC, adc, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
1049 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_adc_u16, iemAImpl_adc_u32, iemAImpl_adc_u64);
1050 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_adc_u16_locked, iemAImpl_adc_u32_locked, iemAImpl_adc_u64_locked);
1051}
1052
1053
1054/**
1055 * @opcode 0x12
1056 * @opgroup og_gen_arith_bin
1057 * @opfltest cf
1058 * @opflmodify cf,pf,af,zf,sf,of
1059 * @opcopytests iemOp_adc_Eb_Gb
1060 */
1061FNIEMOP_DEF(iemOp_adc_Gb_Eb)
1062{
1063 IEMOP_MNEMONIC2(RM, ADC, adc, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1064 IEMOP_BODY_BINARY_r8_rm(iemAImpl_adc_u8);
1065}
1066
1067
1068/**
1069 * @opcode 0x13
1070 * @opgroup og_gen_arith_bin
1071 * @opfltest cf
1072 * @opflmodify cf,pf,af,zf,sf,of
1073 * @opcopytests iemOp_adc_Ev_Gv
1074 */
1075FNIEMOP_DEF(iemOp_adc_Gv_Ev)
1076{
1077 IEMOP_MNEMONIC2(RM, ADC, adc, Gv, Ev, DISOPTYPE_HARMLESS, 0);
1078 IEMOP_BODY_BINARY_rv_rm(iemAImpl_adc_u16, iemAImpl_adc_u32, iemAImpl_adc_u64, 1, 0);
1079}
1080
1081
1082/**
1083 * @opcode 0x14
1084 * @opgroup og_gen_arith_bin
1085 * @opfltest cf
1086 * @opflmodify cf,pf,af,zf,sf,of
1087 * @opcopytests iemOp_adc_Eb_Gb
1088 */
1089FNIEMOP_DEF(iemOp_adc_Al_Ib)
1090{
1091 IEMOP_MNEMONIC2(FIXED, ADC, adc, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1092 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_adc_u8);
1093}
1094
1095
1096/**
1097 * @opcode 0x15
1098 * @opgroup og_gen_arith_bin
1099 * @opfltest cf
1100 * @opflmodify cf,pf,af,zf,sf,of
1101 * @opcopytests iemOp_adc_Ev_Gv
1102 */
1103FNIEMOP_DEF(iemOp_adc_eAX_Iz)
1104{
1105 IEMOP_MNEMONIC2(FIXED, ADC, adc, rAX, Iz, DISOPTYPE_HARMLESS, 0);
1106 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_adc_u16, iemAImpl_adc_u32, iemAImpl_adc_u64, 1);
1107}
1108
1109
1110/**
1111 * @opcode 0x16
1112 */
1113FNIEMOP_DEF(iemOp_push_SS)
1114{
1115 IEMOP_MNEMONIC1(FIXED, PUSH, push, SS, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64 | DISOPTYPE_RRM_DANGEROUS, 0);
1116 IEMOP_HLP_NO_64BIT();
1117 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_SS);
1118}
1119
1120
1121/**
1122 * @opcode 0x17
1123 * @opgroup og_gen_arith_bin
1124 * @opfltest cf
1125 * @opflmodify cf,pf,af,zf,sf,of
1126 */
1127FNIEMOP_DEF(iemOp_pop_SS)
1128{
1129 IEMOP_MNEMONIC1(FIXED, POP, pop, SS, DISOPTYPE_HARMLESS | DISOPTYPE_INHIBIT_IRQS | DISOPTYPE_X86_INVALID_64 | DISOPTYPE_RRM_DANGEROUS , 0);
1130 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1131 IEMOP_HLP_NO_64BIT();
1132 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_MODE | IEM_CIMPL_F_INHIBIT_SHADOW,
1133 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
1134 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_SS)
1135 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_SS)
1136 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_SS),
1137 iemCImpl_pop_Sreg, X86_SREG_SS, pVCpu->iem.s.enmEffOpSize);
1138}
1139
1140
1141/**
1142 * @opcode 0x18
1143 * @opgroup og_gen_arith_bin
1144 * @opfltest cf
1145 * @opflmodify cf,pf,af,zf,sf,of
1146 */
1147FNIEMOP_DEF(iemOp_sbb_Eb_Gb)
1148{
1149 IEMOP_MNEMONIC2(MR, SBB, sbb, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
1150 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_sbb_u8);
1151 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_sbb_u8_locked);
1152}
1153
1154
1155/**
1156 * @opcode 0x19
1157 * @opgroup og_gen_arith_bin
1158 * @opfltest cf
1159 * @opflmodify cf,pf,af,zf,sf,of
1160 */
1161FNIEMOP_DEF(iemOp_sbb_Ev_Gv)
1162{
1163 IEMOP_MNEMONIC2(MR, SBB, sbb, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
1164 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_sbb_u16, iemAImpl_sbb_u32, iemAImpl_sbb_u64);
1165 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_sbb_u16_locked, iemAImpl_sbb_u32_locked, iemAImpl_sbb_u64_locked);
1166}
1167
1168
1169/**
1170 * @opcode 0x1a
1171 * @opgroup og_gen_arith_bin
1172 * @opfltest cf
1173 * @opflmodify cf,pf,af,zf,sf,of
1174 */
1175FNIEMOP_DEF(iemOp_sbb_Gb_Eb)
1176{
1177 IEMOP_MNEMONIC2(RM, SBB, sbb, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1178 IEMOP_BODY_BINARY_r8_rm(iemAImpl_sbb_u8);
1179}
1180
1181
1182/**
1183 * @opcode 0x1b
1184 * @opgroup og_gen_arith_bin
1185 * @opfltest cf
1186 * @opflmodify cf,pf,af,zf,sf,of
1187 */
1188FNIEMOP_DEF(iemOp_sbb_Gv_Ev)
1189{
1190 IEMOP_MNEMONIC2(RM, SBB, sbb, Gv, Ev, DISOPTYPE_HARMLESS, 0);
1191 IEMOP_BODY_BINARY_rv_rm(iemAImpl_sbb_u16, iemAImpl_sbb_u32, iemAImpl_sbb_u64, 1, 0);
1192}
1193
1194
1195/**
1196 * @opcode 0x1c
1197 * @opgroup og_gen_arith_bin
1198 * @opfltest cf
1199 * @opflmodify cf,pf,af,zf,sf,of
1200 */
1201FNIEMOP_DEF(iemOp_sbb_Al_Ib)
1202{
1203 IEMOP_MNEMONIC2(FIXED, SBB, sbb, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1204 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_sbb_u8);
1205}
1206
1207
1208/**
1209 * @opcode 0x1d
1210 * @opgroup og_gen_arith_bin
1211 * @opfltest cf
1212 * @opflmodify cf,pf,af,zf,sf,of
1213 */
1214FNIEMOP_DEF(iemOp_sbb_eAX_Iz)
1215{
1216 IEMOP_MNEMONIC2(FIXED, SBB, sbb, rAX, Iz, DISOPTYPE_HARMLESS, 0);
1217 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_sbb_u16, iemAImpl_sbb_u32, iemAImpl_sbb_u64, 1);
1218}
1219
1220
1221/**
1222 * @opcode 0x1e
1223 * @opgroup og_stack_sreg
1224 */
1225FNIEMOP_DEF(iemOp_push_DS)
1226{
1227 IEMOP_MNEMONIC1(FIXED, PUSH, push, DS, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0);
1228 IEMOP_HLP_NO_64BIT();
1229 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_DS);
1230}
1231
1232
1233/**
1234 * @opcode 0x1f
1235 * @opgroup og_stack_sreg
1236 */
1237FNIEMOP_DEF(iemOp_pop_DS)
1238{
1239 IEMOP_MNEMONIC1(FIXED, POP, pop, DS, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64 | DISOPTYPE_RRM_DANGEROUS, 0);
1240 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1241 IEMOP_HLP_NO_64BIT();
1242 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_MODE,
1243 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
1244 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_DS)
1245 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_DS)
1246 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_DS),
1247 iemCImpl_pop_Sreg, X86_SREG_DS, pVCpu->iem.s.enmEffOpSize);
1248}
1249
1250
1251/**
1252 * @opcode 0x20
1253 * @opgroup og_gen_arith_bin
1254 * @opflmodify cf,pf,af,zf,sf,of
1255 * @opflundef af
1256 * @opflclear of,cf
1257 */
1258FNIEMOP_DEF(iemOp_and_Eb_Gb)
1259{
1260 IEMOP_MNEMONIC2(MR, AND, and, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
1261 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1262 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_and_u8);
1263 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_and_u8_locked);
1264}
1265
1266
1267/**
1268 * @opcode 0x21
1269 * @opgroup og_gen_arith_bin
1270 * @opflmodify cf,pf,af,zf,sf,of
1271 * @opflundef af
1272 * @opflclear of,cf
1273 */
1274FNIEMOP_DEF(iemOp_and_Ev_Gv)
1275{
1276 IEMOP_MNEMONIC2(MR, AND, and, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
1277 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1278 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64);
1279 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_and_u16_locked, iemAImpl_and_u32_locked, iemAImpl_and_u64_locked);
1280}
1281
1282
1283/**
1284 * @opcode 0x22
1285 * @opgroup og_gen_arith_bin
1286 * @opflmodify cf,pf,af,zf,sf,of
1287 * @opflundef af
1288 * @opflclear of,cf
1289 */
1290FNIEMOP_DEF(iemOp_and_Gb_Eb)
1291{
1292 IEMOP_MNEMONIC2(RM, AND, and, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1293 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1294 IEMOP_BODY_BINARY_r8_rm(iemAImpl_and_u8);
1295}
1296
1297
1298/**
1299 * @opcode 0x23
1300 * @opgroup og_gen_arith_bin
1301 * @opflmodify cf,pf,af,zf,sf,of
1302 * @opflundef af
1303 * @opflclear of,cf
1304 */
1305FNIEMOP_DEF(iemOp_and_Gv_Ev)
1306{
1307 IEMOP_MNEMONIC2(RM, AND, and, Gv, Ev, DISOPTYPE_HARMLESS, 0);
1308 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1309 IEMOP_BODY_BINARY_rv_rm(iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64, 1, 0);
1310}
1311
1312
1313/**
1314 * @opcode 0x24
1315 * @opgroup og_gen_arith_bin
1316 * @opflmodify cf,pf,af,zf,sf,of
1317 * @opflundef af
1318 * @opflclear of,cf
1319 */
1320FNIEMOP_DEF(iemOp_and_Al_Ib)
1321{
1322 IEMOP_MNEMONIC2(FIXED, AND, and, AL, Ib, DISOPTYPE_HARMLESS, 0);
1323 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1324 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_and_u8);
1325}
1326
1327
1328/**
1329 * @opcode 0x25
1330 * @opgroup og_gen_arith_bin
1331 * @opflmodify cf,pf,af,zf,sf,of
1332 * @opflundef af
1333 * @opflclear of,cf
1334 */
1335FNIEMOP_DEF(iemOp_and_eAX_Iz)
1336{
1337 IEMOP_MNEMONIC2(FIXED, AND, and, rAX, Iz, DISOPTYPE_HARMLESS, 0);
1338 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1339 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64, 1);
1340}
1341
1342
1343/**
1344 * @opcode 0x26
1345 * @opmnemonic SEG
1346 * @op1 ES
1347 * @opgroup og_prefix
1348 * @openc prefix
1349 * @opdisenum OP_SEG
1350 * @ophints harmless
1351 */
1352FNIEMOP_DEF(iemOp_seg_ES)
1353{
1354 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg es");
1355 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_ES;
1356 pVCpu->iem.s.iEffSeg = X86_SREG_ES;
1357
1358 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1359 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1360}
1361
1362
1363/**
1364 * @opcode 0x27
1365 * @opfltest af,cf
1366 * @opflmodify cf,pf,af,zf,sf,of
1367 * @opflundef of
1368 */
1369FNIEMOP_DEF(iemOp_daa)
1370{
1371 IEMOP_MNEMONIC0(FIXED, DAA, daa, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0); /* express implicit AL register use */
1372 IEMOP_HLP_NO_64BIT();
1373 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1374 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
1375 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_STATUS_FLAGS, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX), iemCImpl_daa);
1376}
1377
1378
1379/**
1380 * @opcode 0x28
1381 * @opgroup og_gen_arith_bin
1382 * @opflmodify cf,pf,af,zf,sf,of
1383 */
1384FNIEMOP_DEF(iemOp_sub_Eb_Gb)
1385{
1386 IEMOP_MNEMONIC2(MR, SUB, sub, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
1387 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_sub_u8);
1388 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_sub_u8_locked);
1389}
1390
1391
1392/**
1393 * @opcode 0x29
1394 * @opgroup og_gen_arith_bin
1395 * @opflmodify cf,pf,af,zf,sf,of
1396 */
1397FNIEMOP_DEF(iemOp_sub_Ev_Gv)
1398{
1399 IEMOP_MNEMONIC2(MR, SUB, sub, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
1400 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64);
1401 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_sub_u16_locked, iemAImpl_sub_u32_locked, iemAImpl_sub_u64_locked);
1402}
1403
1404
1405/**
1406 * @opcode 0x2a
1407 * @opgroup og_gen_arith_bin
1408 * @opflmodify cf,pf,af,zf,sf,of
1409 */
1410FNIEMOP_DEF(iemOp_sub_Gb_Eb)
1411{
1412 IEMOP_MNEMONIC2(RM, SUB, sub, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1413 IEMOP_BODY_BINARY_r8_rm(iemAImpl_sub_u8);
1414}
1415
1416
1417/**
1418 * @opcode 0x2b
1419 * @opgroup og_gen_arith_bin
1420 * @opflmodify cf,pf,af,zf,sf,of
1421 */
1422FNIEMOP_DEF(iemOp_sub_Gv_Ev)
1423{
1424 IEMOP_MNEMONIC2(RM, SUB, sub, Gv, Ev, DISOPTYPE_HARMLESS, 0);
1425 IEMOP_BODY_BINARY_rv_rm(iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64, 1, 0);
1426}
1427
1428
1429/**
1430 * @opcode 0x2c
1431 * @opgroup og_gen_arith_bin
1432 * @opflmodify cf,pf,af,zf,sf,of
1433 */
1434FNIEMOP_DEF(iemOp_sub_Al_Ib)
1435{
1436 IEMOP_MNEMONIC2(FIXED, SUB, sub, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1437 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_sub_u8);
1438}
1439
1440
1441/**
1442 * @opcode 0x2d
1443 * @opgroup og_gen_arith_bin
1444 * @opflmodify cf,pf,af,zf,sf,of
1445 */
1446FNIEMOP_DEF(iemOp_sub_eAX_Iz)
1447{
1448 IEMOP_MNEMONIC2(FIXED, SUB, sub, rAX, Iz, DISOPTYPE_HARMLESS, 0);
1449 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64, 1);
1450}
1451
1452
1453/**
1454 * @opcode 0x2e
1455 * @opmnemonic SEG
1456 * @op1 CS
1457 * @opgroup og_prefix
1458 * @openc prefix
1459 * @opdisenum OP_SEG
1460 * @ophints harmless
1461 */
1462FNIEMOP_DEF(iemOp_seg_CS)
1463{
1464 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg cs");
1465 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_CS;
1466 pVCpu->iem.s.iEffSeg = X86_SREG_CS;
1467
1468 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1469 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1470}
1471
1472
1473/**
1474 * @opcode 0x2f
1475 * @opfltest af,cf
1476 * @opflmodify cf,pf,af,zf,sf,of
1477 * @opflundef of
1478 */
1479FNIEMOP_DEF(iemOp_das)
1480{
1481 IEMOP_MNEMONIC0(FIXED, DAS, das, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0); /* express implicit AL register use */
1482 IEMOP_HLP_NO_64BIT();
1483 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1484 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
1485 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_STATUS_FLAGS, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX), iemCImpl_das);
1486}
1487
1488
1489/**
1490 * @opcode 0x30
1491 * @opgroup og_gen_arith_bin
1492 * @opflmodify cf,pf,af,zf,sf,of
1493 * @opflundef af
1494 * @opflclear of,cf
1495 */
1496FNIEMOP_DEF(iemOp_xor_Eb_Gb)
1497{
1498 IEMOP_MNEMONIC2(MR, XOR, xor, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
1499 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1500 IEMOP_BODY_BINARY_rm_r8_RW( iemAImpl_xor_u8);
1501 IEMOP_BODY_BINARY_rm_r8_LOCKED(iemAImpl_xor_u8_locked);
1502}
1503
1504
1505/**
1506 * @opcode 0x31
1507 * @opgroup og_gen_arith_bin
1508 * @opflmodify cf,pf,af,zf,sf,of
1509 * @opflundef af
1510 * @opflclear of,cf
1511 */
1512FNIEMOP_DEF(iemOp_xor_Ev_Gv)
1513{
1514 IEMOP_MNEMONIC2(MR, XOR, xor, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
1515 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1516 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_xor_u16, iemAImpl_xor_u32, iemAImpl_xor_u64);
1517 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_xor_u16_locked, iemAImpl_xor_u32_locked, iemAImpl_xor_u64_locked);
1518}
1519
1520
1521/**
1522 * @opcode 0x32
1523 * @opgroup og_gen_arith_bin
1524 * @opflmodify cf,pf,af,zf,sf,of
1525 * @opflundef af
1526 * @opflclear of,cf
1527 */
1528FNIEMOP_DEF(iemOp_xor_Gb_Eb)
1529{
1530 IEMOP_MNEMONIC2(RM, XOR, xor, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1531 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1532 IEMOP_BODY_BINARY_r8_rm(iemAImpl_xor_u8);
1533}
1534
1535
1536/**
1537 * @opcode 0x33
1538 * @opgroup og_gen_arith_bin
1539 * @opflmodify cf,pf,af,zf,sf,of
1540 * @opflundef af
1541 * @opflclear of,cf
1542 */
1543FNIEMOP_DEF(iemOp_xor_Gv_Ev)
1544{
1545 IEMOP_MNEMONIC2(RM, XOR, xor, Gv, Ev, DISOPTYPE_HARMLESS, 0);
1546 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1547 IEMOP_BODY_BINARY_rv_rm(iemAImpl_xor_u16, iemAImpl_xor_u32, iemAImpl_xor_u64, 1, 0);
1548}
1549
1550
1551/**
1552 * @opcode 0x34
1553 * @opgroup og_gen_arith_bin
1554 * @opflmodify cf,pf,af,zf,sf,of
1555 * @opflundef af
1556 * @opflclear of,cf
1557 */
1558FNIEMOP_DEF(iemOp_xor_Al_Ib)
1559{
1560 IEMOP_MNEMONIC2(FIXED, XOR, xor, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1561 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1562 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_xor_u8);
1563}
1564
1565
1566/**
1567 * @opcode 0x35
1568 * @opgroup og_gen_arith_bin
1569 * @opflmodify cf,pf,af,zf,sf,of
1570 * @opflundef af
1571 * @opflclear of,cf
1572 */
1573FNIEMOP_DEF(iemOp_xor_eAX_Iz)
1574{
1575 IEMOP_MNEMONIC2(FIXED, XOR, xor, rAX, Iz, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1576 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
1577 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_xor_u16, iemAImpl_xor_u32, iemAImpl_xor_u64, 1);
1578}
1579
1580
1581/**
1582 * @opcode 0x36
1583 * @opmnemonic SEG
1584 * @op1 SS
1585 * @opgroup og_prefix
1586 * @openc prefix
1587 * @opdisenum OP_SEG
1588 * @ophints harmless
1589 */
1590FNIEMOP_DEF(iemOp_seg_SS)
1591{
1592 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg ss");
1593 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_SS;
1594 pVCpu->iem.s.iEffSeg = X86_SREG_SS;
1595
1596 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1597 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1598}
1599
1600
1601/**
1602 * @opcode 0x37
1603 * @opfltest af,cf
1604 * @opflmodify cf,pf,af,zf,sf,of
1605 * @opflundef pf,zf,sf,of
1606 * @opgroup og_gen_arith_dec
1607 * @optest efl&~=af ax=9 -> efl&|=nc,po,na,nz,pl,nv
1608 * @optest efl&~=af ax=0 -> efl&|=nc,po,na,zf,pl,nv
1609 * @optest intel / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,zf,pl,nv
1610 * @optest amd / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,nz,pl,nv
1611 * @optest efl&~=af ax=0x00f9 -> ax=0x0009 efl&|=nc,po,na,nz,pl,nv
1612 * @optest efl|=af ax=0 -> ax=0x0106 efl&|=cf,po,af,nz,pl,nv
1613 * @optest efl|=af ax=0x0100 -> ax=0x0206 efl&|=cf,po,af,nz,pl,nv
1614 * @optest intel / efl|=af ax=0x000a -> ax=0x0100 efl&|=cf,po,af,zf,pl,nv
1615 * @optest amd / efl|=af ax=0x000a -> ax=0x0100 efl&|=cf,pe,af,nz,pl,nv
1616 * @optest intel / efl|=af ax=0x010a -> ax=0x0200 efl&|=cf,po,af,zf,pl,nv
1617 * @optest amd / efl|=af ax=0x010a -> ax=0x0200 efl&|=cf,pe,af,nz,pl,nv
1618 * @optest intel / efl|=af ax=0x0f0a -> ax=0x1000 efl&|=cf,po,af,zf,pl,nv
1619 * @optest amd / efl|=af ax=0x0f0a -> ax=0x1000 efl&|=cf,pe,af,nz,pl,nv
1620 * @optest intel / efl|=af ax=0x7f0a -> ax=0x8000 efl&|=cf,po,af,zf,pl,nv
1621 * @optest amd / efl|=af ax=0x7f0a -> ax=0x8000 efl&|=cf,pe,af,nz,ng,ov
1622 * @optest intel / efl|=af ax=0xff0a -> ax=0x0000 efl&|=cf,po,af,zf,pl,nv
1623 * @optest amd / efl|=af ax=0xff0a -> ax=0x0000 efl&|=cf,pe,af,nz,pl,nv
1624 * @optest intel / efl&~=af ax=0xff0a -> ax=0x0000 efl&|=cf,po,af,zf,pl,nv
1625 * @optest amd / efl&~=af ax=0xff0a -> ax=0x0000 efl&|=cf,pe,af,nz,pl,nv
1626 * @optest intel / efl&~=af ax=0x000b -> ax=0x0101 efl&|=cf,pe,af,nz,pl,nv
1627 * @optest amd / efl&~=af ax=0x000b -> ax=0x0101 efl&|=cf,po,af,nz,pl,nv
1628 * @optest intel / efl&~=af ax=0x000c -> ax=0x0102 efl&|=cf,pe,af,nz,pl,nv
1629 * @optest amd / efl&~=af ax=0x000c -> ax=0x0102 efl&|=cf,po,af,nz,pl,nv
1630 * @optest intel / efl&~=af ax=0x000d -> ax=0x0103 efl&|=cf,po,af,nz,pl,nv
1631 * @optest amd / efl&~=af ax=0x000d -> ax=0x0103 efl&|=cf,pe,af,nz,pl,nv
1632 * @optest intel / efl&~=af ax=0x000e -> ax=0x0104 efl&|=cf,pe,af,nz,pl,nv
1633 * @optest amd / efl&~=af ax=0x000e -> ax=0x0104 efl&|=cf,po,af,nz,pl,nv
1634 * @optest intel / efl&~=af ax=0x000f -> ax=0x0105 efl&|=cf,po,af,nz,pl,nv
1635 * @optest amd / efl&~=af ax=0x000f -> ax=0x0105 efl&|=cf,pe,af,nz,pl,nv
1636 * @optest intel / efl&~=af ax=0x020f -> ax=0x0305 efl&|=cf,po,af,nz,pl,nv
1637 * @optest amd / efl&~=af ax=0x020f -> ax=0x0305 efl&|=cf,pe,af,nz,pl,nv
1638 */
1639FNIEMOP_DEF(iemOp_aaa)
1640{
1641 IEMOP_MNEMONIC0(FIXED, AAA, aaa, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0); /* express implicit AL/AX register use */
1642 IEMOP_HLP_NO_64BIT();
1643 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1644 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
1645
1646 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_STATUS_FLAGS, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX), iemCImpl_aaa);
1647}
1648
1649
1650/**
1651 * @opcode 0x38
1652 */
1653FNIEMOP_DEF(iemOp_cmp_Eb_Gb)
1654{
1655 IEMOP_MNEMONIC(cmp_Eb_Gb, "cmp Eb,Gb");
1656 IEMOP_BODY_BINARY_rm_r8_RO(iemAImpl_cmp_u8);
1657 IEMOP_BODY_BINARY_rm_r8_NO_LOCK();
1658}
1659
1660
1661/**
1662 * @opcode 0x39
1663 */
1664FNIEMOP_DEF(iemOp_cmp_Ev_Gv)
1665{
1666 IEMOP_MNEMONIC(cmp_Ev_Gv, "cmp Ev,Gv");
1667 IEMOP_BODY_BINARY_rm_rv_RO(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64);
1668}
1669
1670
1671/**
1672 * @opcode 0x3a
1673 */
1674FNIEMOP_DEF(iemOp_cmp_Gb_Eb)
1675{
1676 IEMOP_MNEMONIC(cmp_Gb_Eb, "cmp Gb,Eb");
1677 IEMOP_BODY_BINARY_r8_rm(iemAImpl_cmp_u8);
1678}
1679
1680
1681/**
1682 * @opcode 0x3b
1683 */
1684FNIEMOP_DEF(iemOp_cmp_Gv_Ev)
1685{
1686 IEMOP_MNEMONIC(cmp_Gv_Ev, "cmp Gv,Ev");
1687 IEMOP_BODY_BINARY_rv_rm(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64, 0, 0);
1688}
1689
1690
1691/**
1692 * @opcode 0x3c
1693 */
1694FNIEMOP_DEF(iemOp_cmp_Al_Ib)
1695{
1696 IEMOP_MNEMONIC(cmp_al_Ib, "cmp al,Ib");
1697 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_cmp_u8);
1698}
1699
1700
1701/**
1702 * @opcode 0x3d
1703 */
1704FNIEMOP_DEF(iemOp_cmp_eAX_Iz)
1705{
1706 IEMOP_MNEMONIC(cmp_rAX_Iz, "cmp rAX,Iz");
1707 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64, 0);
1708}
1709
1710
1711/**
1712 * @opcode 0x3e
1713 */
1714FNIEMOP_DEF(iemOp_seg_DS)
1715{
1716 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg ds");
1717 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_DS;
1718 pVCpu->iem.s.iEffSeg = X86_SREG_DS;
1719
1720 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1721 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1722}
1723
1724
1725/**
1726 * @opcode 0x3f
1727 * @opfltest af,cf
1728 * @opflmodify cf,pf,af,zf,sf,of
1729 * @opflundef pf,zf,sf,of
1730 * @opgroup og_gen_arith_dec
1731 * @optest / efl&~=af ax=0x0009 -> efl&|=nc,po,na,nz,pl,nv
1732 * @optest / efl&~=af ax=0x0000 -> efl&|=nc,po,na,zf,pl,nv
1733 * @optest intel / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,zf,pl,nv
1734 * @optest amd / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,nz,pl,nv
1735 * @optest / efl&~=af ax=0x00f9 -> ax=0x0009 efl&|=nc,po,na,nz,pl,nv
1736 * @optest intel / efl|=af ax=0x0000 -> ax=0xfe0a efl&|=cf,po,af,nz,pl,nv
1737 * @optest amd / efl|=af ax=0x0000 -> ax=0xfe0a efl&|=cf,po,af,nz,ng,nv
1738 * @optest intel / efl|=af ax=0x0100 -> ax=0xff0a efl&|=cf,po,af,nz,pl,nv
1739 * @optest amd / efl|=af ax=0x0100 -> ax=0xff0a efl&|=cf,po,af,nz,ng,nv
1740 * @optest intel / efl|=af ax=0x000a -> ax=0xff04 efl&|=cf,pe,af,nz,pl,nv
1741 * @optest amd / efl|=af ax=0x000a -> ax=0xff04 efl&|=cf,pe,af,nz,ng,nv
1742 * @optest / efl|=af ax=0x010a -> ax=0x0004 efl&|=cf,pe,af,nz,pl,nv
1743 * @optest / efl|=af ax=0x020a -> ax=0x0104 efl&|=cf,pe,af,nz,pl,nv
1744 * @optest / efl|=af ax=0x0f0a -> ax=0x0e04 efl&|=cf,pe,af,nz,pl,nv
1745 * @optest / efl|=af ax=0x7f0a -> ax=0x7e04 efl&|=cf,pe,af,nz,pl,nv
1746 * @optest intel / efl|=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,pl,nv
1747 * @optest amd / efl|=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,ng,nv
1748 * @optest intel / efl&~=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,pl,nv
1749 * @optest amd / efl&~=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,ng,nv
1750 * @optest intel / efl&~=af ax=0xff09 -> ax=0xff09 efl&|=nc,po,na,nz,pl,nv
1751 * @optest amd / efl&~=af ax=0xff09 -> ax=0xff09 efl&|=nc,po,na,nz,ng,nv
1752 * @optest intel / efl&~=af ax=0x000b -> ax=0xff05 efl&|=cf,po,af,nz,pl,nv
1753 * @optest amd / efl&~=af ax=0x000b -> ax=0xff05 efl&|=cf,po,af,nz,ng,nv
1754 * @optest intel / efl&~=af ax=0x000c -> ax=0xff06 efl&|=cf,po,af,nz,pl,nv
1755 * @optest amd / efl&~=af ax=0x000c -> ax=0xff06 efl&|=cf,po,af,nz,ng,nv
1756 * @optest intel / efl&~=af ax=0x000d -> ax=0xff07 efl&|=cf,pe,af,nz,pl,nv
1757 * @optest amd / efl&~=af ax=0x000d -> ax=0xff07 efl&|=cf,pe,af,nz,ng,nv
1758 * @optest intel / efl&~=af ax=0x000e -> ax=0xff08 efl&|=cf,pe,af,nz,pl,nv
1759 * @optest amd / efl&~=af ax=0x000e -> ax=0xff08 efl&|=cf,pe,af,nz,ng,nv
1760 * @optest intel / efl&~=af ax=0x000f -> ax=0xff09 efl&|=cf,po,af,nz,pl,nv
1761 * @optest amd / efl&~=af ax=0x000f -> ax=0xff09 efl&|=cf,po,af,nz,ng,nv
1762 * @optest intel / efl&~=af ax=0x00fa -> ax=0xff04 efl&|=cf,pe,af,nz,pl,nv
1763 * @optest amd / efl&~=af ax=0x00fa -> ax=0xff04 efl&|=cf,pe,af,nz,ng,nv
1764 * @optest intel / efl&~=af ax=0xfffa -> ax=0xfe04 efl&|=cf,pe,af,nz,pl,nv
1765 * @optest amd / efl&~=af ax=0xfffa -> ax=0xfe04 efl&|=cf,pe,af,nz,ng,nv
1766 */
1767FNIEMOP_DEF(iemOp_aas)
1768{
1769 IEMOP_MNEMONIC0(FIXED, AAS, aas, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64, 0); /* express implicit AL/AX register use */
1770 IEMOP_HLP_NO_64BIT();
1771 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1772 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_OF);
1773
1774 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_STATUS_FLAGS, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX), iemCImpl_aas);
1775}
1776
1777
1778/**
1779 * Common 'inc/dec register' helper.
1780 *
1781 * Not for 64-bit code, only for what became the rex prefixes.
1782 */
1783#define IEMOP_BODY_UNARY_GReg(a_fnNormalU16, a_fnNormalU32, a_iReg) \
1784 switch (pVCpu->iem.s.enmEffOpSize) \
1785 { \
1786 case IEMMODE_16BIT: \
1787 IEM_MC_BEGIN(2, 0, IEM_MC_F_NOT_64BIT, 0); \
1788 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
1789 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
1790 IEM_MC_ARG(uint32_t *, pEFlags, 1); \
1791 IEM_MC_REF_GREG_U16(pu16Dst, a_iReg); \
1792 IEM_MC_REF_EFLAGS(pEFlags); \
1793 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU16, pu16Dst, pEFlags); \
1794 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
1795 IEM_MC_END(); \
1796 break; \
1797 \
1798 case IEMMODE_32BIT: \
1799 IEM_MC_BEGIN(2, 0, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0); \
1800 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
1801 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
1802 IEM_MC_ARG(uint32_t *, pEFlags, 1); \
1803 IEM_MC_REF_GREG_U32(pu32Dst, a_iReg); \
1804 IEM_MC_REF_EFLAGS(pEFlags); \
1805 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU32, pu32Dst, pEFlags); \
1806 IEM_MC_CLEAR_HIGH_GREG_U64(a_iReg); \
1807 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
1808 IEM_MC_END(); \
1809 break; \
1810 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
1811 } \
1812 (void)0
1813
1814/**
1815 * @opcode 0x40
1816 */
1817FNIEMOP_DEF(iemOp_inc_eAX)
1818{
1819 /*
1820 * This is a REX prefix in 64-bit mode.
1821 */
1822 if (IEM_IS_64BIT_CODE(pVCpu))
1823 {
1824 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex");
1825 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX;
1826
1827 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1828 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1829 }
1830
1831 IEMOP_MNEMONIC(inc_eAX, "inc eAX");
1832 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xAX);
1833}
1834
1835
1836/**
1837 * @opcode 0x41
1838 */
1839FNIEMOP_DEF(iemOp_inc_eCX)
1840{
1841 /*
1842 * This is a REX prefix in 64-bit mode.
1843 */
1844 if (IEM_IS_64BIT_CODE(pVCpu))
1845 {
1846 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.b");
1847 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B;
1848 pVCpu->iem.s.uRexB = 1 << 3;
1849
1850 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1851 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1852 }
1853
1854 IEMOP_MNEMONIC(inc_eCX, "inc eCX");
1855 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xCX);
1856}
1857
1858
1859/**
1860 * @opcode 0x42
1861 */
1862FNIEMOP_DEF(iemOp_inc_eDX)
1863{
1864 /*
1865 * This is a REX prefix in 64-bit mode.
1866 */
1867 if (IEM_IS_64BIT_CODE(pVCpu))
1868 {
1869 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.x");
1870 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_X;
1871 pVCpu->iem.s.uRexIndex = 1 << 3;
1872
1873 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1874 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1875 }
1876
1877 IEMOP_MNEMONIC(inc_eDX, "inc eDX");
1878 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xDX);
1879}
1880
1881
1882
1883/**
1884 * @opcode 0x43
1885 */
1886FNIEMOP_DEF(iemOp_inc_eBX)
1887{
1888 /*
1889 * This is a REX prefix in 64-bit mode.
1890 */
1891 if (IEM_IS_64BIT_CODE(pVCpu))
1892 {
1893 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.bx");
1894 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X;
1895 pVCpu->iem.s.uRexB = 1 << 3;
1896 pVCpu->iem.s.uRexIndex = 1 << 3;
1897
1898 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1899 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1900 }
1901
1902 IEMOP_MNEMONIC(inc_eBX, "inc eBX");
1903 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xBX);
1904}
1905
1906
1907/**
1908 * @opcode 0x44
1909 */
1910FNIEMOP_DEF(iemOp_inc_eSP)
1911{
1912 /*
1913 * This is a REX prefix in 64-bit mode.
1914 */
1915 if (IEM_IS_64BIT_CODE(pVCpu))
1916 {
1917 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.r");
1918 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R;
1919 pVCpu->iem.s.uRexReg = 1 << 3;
1920
1921 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1922 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1923 }
1924
1925 IEMOP_MNEMONIC(inc_eSP, "inc eSP");
1926 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xSP);
1927}
1928
1929
1930/**
1931 * @opcode 0x45
1932 */
1933FNIEMOP_DEF(iemOp_inc_eBP)
1934{
1935 /*
1936 * This is a REX prefix in 64-bit mode.
1937 */
1938 if (IEM_IS_64BIT_CODE(pVCpu))
1939 {
1940 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rb");
1941 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B;
1942 pVCpu->iem.s.uRexReg = 1 << 3;
1943 pVCpu->iem.s.uRexB = 1 << 3;
1944
1945 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1946 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1947 }
1948
1949 IEMOP_MNEMONIC(inc_eBP, "inc eBP");
1950 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xBP);
1951}
1952
1953
1954/**
1955 * @opcode 0x46
1956 */
1957FNIEMOP_DEF(iemOp_inc_eSI)
1958{
1959 /*
1960 * This is a REX prefix in 64-bit mode.
1961 */
1962 if (IEM_IS_64BIT_CODE(pVCpu))
1963 {
1964 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rx");
1965 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_X;
1966 pVCpu->iem.s.uRexReg = 1 << 3;
1967 pVCpu->iem.s.uRexIndex = 1 << 3;
1968
1969 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1970 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1971 }
1972
1973 IEMOP_MNEMONIC(inc_eSI, "inc eSI");
1974 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xSI);
1975}
1976
1977
1978/**
1979 * @opcode 0x47
1980 */
1981FNIEMOP_DEF(iemOp_inc_eDI)
1982{
1983 /*
1984 * This is a REX prefix in 64-bit mode.
1985 */
1986 if (IEM_IS_64BIT_CODE(pVCpu))
1987 {
1988 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rbx");
1989 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X;
1990 pVCpu->iem.s.uRexReg = 1 << 3;
1991 pVCpu->iem.s.uRexB = 1 << 3;
1992 pVCpu->iem.s.uRexIndex = 1 << 3;
1993
1994 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1995 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1996 }
1997
1998 IEMOP_MNEMONIC(inc_eDI, "inc eDI");
1999 IEMOP_BODY_UNARY_GReg(iemAImpl_inc_u16, iemAImpl_inc_u32, X86_GREG_xDI);
2000}
2001
2002
2003/**
2004 * @opcode 0x48
2005 */
2006FNIEMOP_DEF(iemOp_dec_eAX)
2007{
2008 /*
2009 * This is a REX prefix in 64-bit mode.
2010 */
2011 if (IEM_IS_64BIT_CODE(pVCpu))
2012 {
2013 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.w");
2014 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_SIZE_REX_W;
2015 iemRecalEffOpSize(pVCpu);
2016
2017 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2018 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2019 }
2020
2021 IEMOP_MNEMONIC(dec_eAX, "dec eAX");
2022 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xAX);
2023}
2024
2025
2026/**
2027 * @opcode 0x49
2028 */
2029FNIEMOP_DEF(iemOp_dec_eCX)
2030{
2031 /*
2032 * This is a REX prefix in 64-bit mode.
2033 */
2034 if (IEM_IS_64BIT_CODE(pVCpu))
2035 {
2036 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.bw");
2037 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_SIZE_REX_W;
2038 pVCpu->iem.s.uRexB = 1 << 3;
2039 iemRecalEffOpSize(pVCpu);
2040
2041 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2042 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2043 }
2044
2045 IEMOP_MNEMONIC(dec_eCX, "dec eCX");
2046 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xCX);
2047}
2048
2049
2050/**
2051 * @opcode 0x4a
2052 */
2053FNIEMOP_DEF(iemOp_dec_eDX)
2054{
2055 /*
2056 * This is a REX prefix in 64-bit mode.
2057 */
2058 if (IEM_IS_64BIT_CODE(pVCpu))
2059 {
2060 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.xw");
2061 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
2062 pVCpu->iem.s.uRexIndex = 1 << 3;
2063 iemRecalEffOpSize(pVCpu);
2064
2065 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2066 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2067 }
2068
2069 IEMOP_MNEMONIC(dec_eDX, "dec eDX");
2070 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xDX);
2071}
2072
2073
2074/**
2075 * @opcode 0x4b
2076 */
2077FNIEMOP_DEF(iemOp_dec_eBX)
2078{
2079 /*
2080 * This is a REX prefix in 64-bit mode.
2081 */
2082 if (IEM_IS_64BIT_CODE(pVCpu))
2083 {
2084 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.bxw");
2085 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
2086 pVCpu->iem.s.uRexB = 1 << 3;
2087 pVCpu->iem.s.uRexIndex = 1 << 3;
2088 iemRecalEffOpSize(pVCpu);
2089
2090 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2091 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2092 }
2093
2094 IEMOP_MNEMONIC(dec_eBX, "dec eBX");
2095 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xBX);
2096}
2097
2098
2099/**
2100 * @opcode 0x4c
2101 */
2102FNIEMOP_DEF(iemOp_dec_eSP)
2103{
2104 /*
2105 * This is a REX prefix in 64-bit mode.
2106 */
2107 if (IEM_IS_64BIT_CODE(pVCpu))
2108 {
2109 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rw");
2110 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_SIZE_REX_W;
2111 pVCpu->iem.s.uRexReg = 1 << 3;
2112 iemRecalEffOpSize(pVCpu);
2113
2114 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2115 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2116 }
2117
2118 IEMOP_MNEMONIC(dec_eSP, "dec eSP");
2119 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xSP);
2120}
2121
2122
2123/**
2124 * @opcode 0x4d
2125 */
2126FNIEMOP_DEF(iemOp_dec_eBP)
2127{
2128 /*
2129 * This is a REX prefix in 64-bit mode.
2130 */
2131 if (IEM_IS_64BIT_CODE(pVCpu))
2132 {
2133 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rbw");
2134 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_SIZE_REX_W;
2135 pVCpu->iem.s.uRexReg = 1 << 3;
2136 pVCpu->iem.s.uRexB = 1 << 3;
2137 iemRecalEffOpSize(pVCpu);
2138
2139 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2140 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2141 }
2142
2143 IEMOP_MNEMONIC(dec_eBP, "dec eBP");
2144 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xBP);
2145}
2146
2147
2148/**
2149 * @opcode 0x4e
2150 */
2151FNIEMOP_DEF(iemOp_dec_eSI)
2152{
2153 /*
2154 * This is a REX prefix in 64-bit mode.
2155 */
2156 if (IEM_IS_64BIT_CODE(pVCpu))
2157 {
2158 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rxw");
2159 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
2160 pVCpu->iem.s.uRexReg = 1 << 3;
2161 pVCpu->iem.s.uRexIndex = 1 << 3;
2162 iemRecalEffOpSize(pVCpu);
2163
2164 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2165 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2166 }
2167
2168 IEMOP_MNEMONIC(dec_eSI, "dec eSI");
2169 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xSI);
2170}
2171
2172
2173/**
2174 * @opcode 0x4f
2175 */
2176FNIEMOP_DEF(iemOp_dec_eDI)
2177{
2178 /*
2179 * This is a REX prefix in 64-bit mode.
2180 */
2181 if (IEM_IS_64BIT_CODE(pVCpu))
2182 {
2183 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rbxw");
2184 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
2185 pVCpu->iem.s.uRexReg = 1 << 3;
2186 pVCpu->iem.s.uRexB = 1 << 3;
2187 pVCpu->iem.s.uRexIndex = 1 << 3;
2188 iemRecalEffOpSize(pVCpu);
2189
2190 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2191 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2192 }
2193
2194 IEMOP_MNEMONIC(dec_eDI, "dec eDI");
2195 IEMOP_BODY_UNARY_GReg(iemAImpl_dec_u16, iemAImpl_dec_u32, X86_GREG_xDI);
2196}
2197
2198
2199/**
2200 * Common 'push register' helper.
2201 */
2202FNIEMOP_DEF_1(iemOpCommonPushGReg, uint8_t, iReg)
2203{
2204 if (IEM_IS_64BIT_CODE(pVCpu))
2205 {
2206 iReg |= pVCpu->iem.s.uRexB;
2207 pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
2208 pVCpu->iem.s.enmEffOpSize = !(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
2209 }
2210
2211 switch (pVCpu->iem.s.enmEffOpSize)
2212 {
2213 case IEMMODE_16BIT:
2214 IEM_MC_BEGIN(0, 1, 0, 0);
2215 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2216 IEM_MC_LOCAL(uint16_t, u16Value);
2217 IEM_MC_FETCH_GREG_U16(u16Value, iReg);
2218 IEM_MC_PUSH_U16(u16Value);
2219 IEM_MC_ADVANCE_RIP_AND_FINISH();
2220 IEM_MC_END();
2221 break;
2222
2223 case IEMMODE_32BIT:
2224 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0);
2225 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2226 IEM_MC_LOCAL(uint32_t, u32Value);
2227 IEM_MC_FETCH_GREG_U32(u32Value, iReg);
2228 IEM_MC_PUSH_U32(u32Value);
2229 IEM_MC_ADVANCE_RIP_AND_FINISH();
2230 IEM_MC_END();
2231 break;
2232
2233 case IEMMODE_64BIT:
2234 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
2235 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2236 IEM_MC_LOCAL(uint64_t, u64Value);
2237 IEM_MC_FETCH_GREG_U64(u64Value, iReg);
2238 IEM_MC_PUSH_U64(u64Value);
2239 IEM_MC_ADVANCE_RIP_AND_FINISH();
2240 IEM_MC_END();
2241 break;
2242
2243 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2244 }
2245}
2246
2247
2248/**
2249 * @opcode 0x50
2250 */
2251FNIEMOP_DEF(iemOp_push_eAX)
2252{
2253 IEMOP_MNEMONIC(push_rAX, "push rAX");
2254 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xAX);
2255}
2256
2257
2258/**
2259 * @opcode 0x51
2260 */
2261FNIEMOP_DEF(iemOp_push_eCX)
2262{
2263 IEMOP_MNEMONIC(push_rCX, "push rCX");
2264 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xCX);
2265}
2266
2267
2268/**
2269 * @opcode 0x52
2270 */
2271FNIEMOP_DEF(iemOp_push_eDX)
2272{
2273 IEMOP_MNEMONIC(push_rDX, "push rDX");
2274 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xDX);
2275}
2276
2277
2278/**
2279 * @opcode 0x53
2280 */
2281FNIEMOP_DEF(iemOp_push_eBX)
2282{
2283 IEMOP_MNEMONIC(push_rBX, "push rBX");
2284 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xBX);
2285}
2286
2287
2288/**
2289 * @opcode 0x54
2290 */
2291FNIEMOP_DEF(iemOp_push_eSP)
2292{
2293 IEMOP_MNEMONIC(push_rSP, "push rSP");
2294 if (IEM_GET_TARGET_CPU(pVCpu) == IEMTARGETCPU_8086)
2295 {
2296 IEM_MC_BEGIN(0, 1, IEM_MC_F_ONLY_8086, 0);
2297 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2298 IEM_MC_LOCAL(uint16_t, u16Value);
2299 IEM_MC_FETCH_GREG_U16(u16Value, X86_GREG_xSP);
2300 IEM_MC_SUB_LOCAL_U16(u16Value, 2);
2301 IEM_MC_PUSH_U16(u16Value);
2302 IEM_MC_ADVANCE_RIP_AND_FINISH();
2303 IEM_MC_END();
2304 }
2305 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSP);
2306}
2307
2308
2309/**
2310 * @opcode 0x55
2311 */
2312FNIEMOP_DEF(iemOp_push_eBP)
2313{
2314 IEMOP_MNEMONIC(push_rBP, "push rBP");
2315 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xBP);
2316}
2317
2318
2319/**
2320 * @opcode 0x56
2321 */
2322FNIEMOP_DEF(iemOp_push_eSI)
2323{
2324 IEMOP_MNEMONIC(push_rSI, "push rSI");
2325 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSI);
2326}
2327
2328
2329/**
2330 * @opcode 0x57
2331 */
2332FNIEMOP_DEF(iemOp_push_eDI)
2333{
2334 IEMOP_MNEMONIC(push_rDI, "push rDI");
2335 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xDI);
2336}
2337
2338
2339/**
2340 * Common 'pop register' helper.
2341 */
2342FNIEMOP_DEF_1(iemOpCommonPopGReg, uint8_t, iReg)
2343{
2344 if (IEM_IS_64BIT_CODE(pVCpu))
2345 {
2346 iReg |= pVCpu->iem.s.uRexB;
2347 pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
2348 pVCpu->iem.s.enmEffOpSize = !(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
2349 }
2350
2351 switch (pVCpu->iem.s.enmEffOpSize)
2352 {
2353 case IEMMODE_16BIT:
2354 IEM_MC_BEGIN(0, 1, 0, 0);
2355 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2356 IEM_MC_LOCAL(uint16_t *, pu16Dst);
2357 IEM_MC_REF_GREG_U16(pu16Dst, iReg);
2358 IEM_MC_POP_U16(pu16Dst);
2359 IEM_MC_ADVANCE_RIP_AND_FINISH();
2360 IEM_MC_END();
2361 break;
2362
2363 case IEMMODE_32BIT:
2364 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0);
2365 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2366 IEM_MC_LOCAL(uint32_t *, pu32Dst);
2367 IEM_MC_REF_GREG_U32(pu32Dst, iReg);
2368 IEM_MC_POP_U32(pu32Dst);
2369 IEM_MC_CLEAR_HIGH_GREG_U64(iReg); /** @todo testcase*/
2370 IEM_MC_ADVANCE_RIP_AND_FINISH();
2371 IEM_MC_END();
2372 break;
2373
2374 case IEMMODE_64BIT:
2375 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
2376 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2377 IEM_MC_LOCAL(uint64_t *, pu64Dst);
2378 IEM_MC_REF_GREG_U64(pu64Dst, iReg);
2379 IEM_MC_POP_U64(pu64Dst);
2380 IEM_MC_ADVANCE_RIP_AND_FINISH();
2381 IEM_MC_END();
2382 break;
2383
2384 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2385 }
2386}
2387
2388
2389/**
2390 * @opcode 0x58
2391 */
2392FNIEMOP_DEF(iemOp_pop_eAX)
2393{
2394 IEMOP_MNEMONIC(pop_rAX, "pop rAX");
2395 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xAX);
2396}
2397
2398
2399/**
2400 * @opcode 0x59
2401 */
2402FNIEMOP_DEF(iemOp_pop_eCX)
2403{
2404 IEMOP_MNEMONIC(pop_rCX, "pop rCX");
2405 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xCX);
2406}
2407
2408
2409/**
2410 * @opcode 0x5a
2411 */
2412FNIEMOP_DEF(iemOp_pop_eDX)
2413{
2414 IEMOP_MNEMONIC(pop_rDX, "pop rDX");
2415 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xDX);
2416}
2417
2418
2419/**
2420 * @opcode 0x5b
2421 */
2422FNIEMOP_DEF(iemOp_pop_eBX)
2423{
2424 IEMOP_MNEMONIC(pop_rBX, "pop rBX");
2425 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xBX);
2426}
2427
2428
2429/**
2430 * @opcode 0x5c
2431 */
2432FNIEMOP_DEF(iemOp_pop_eSP)
2433{
2434 IEMOP_MNEMONIC(pop_rSP, "pop rSP");
2435 if (IEM_IS_64BIT_CODE(pVCpu))
2436 {
2437 if (pVCpu->iem.s.uRexB)
2438 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xSP);
2439 pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
2440 pVCpu->iem.s.enmEffOpSize = !(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
2441 }
2442
2443 /** @todo add testcase for this instruction. */
2444 switch (pVCpu->iem.s.enmEffOpSize)
2445 {
2446 case IEMMODE_16BIT:
2447 IEM_MC_BEGIN(0, 2, 0, 0);
2448 IEMOP_HLP_DECODED_NL_1(OP_POP, IEMOPFORM_FIXED, OP_PARM_REG_ESP,
2449 DISOPTYPE_HARMLESS | DISOPTYPE_X86_DEFAULT_64_OP_SIZE | DISOPTYPE_X86_REXB_EXTENDS_OPREG);
2450 IEM_MC_LOCAL(uint16_t, u16Dst);
2451 IEM_MC_LOCAL(uint16_t *, pu16Dst);
2452 IEM_MC_REF_LOCAL(pu16Dst, u16Dst);
2453 IEM_MC_POP_U16(pu16Dst); /** @todo not correct MC, fix later. */
2454 IEM_MC_STORE_GREG_U16(X86_GREG_xSP, u16Dst);
2455 IEM_MC_ADVANCE_RIP_AND_FINISH();
2456 IEM_MC_END();
2457 break;
2458
2459 case IEMMODE_32BIT:
2460 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
2461 IEMOP_HLP_DECODED_NL_1(OP_POP, IEMOPFORM_FIXED, OP_PARM_REG_ESP,
2462 DISOPTYPE_HARMLESS | DISOPTYPE_X86_DEFAULT_64_OP_SIZE | DISOPTYPE_X86_REXB_EXTENDS_OPREG);
2463 IEM_MC_LOCAL(uint32_t, u32Dst);
2464 IEM_MC_LOCAL(uint32_t *, pu32Dst);
2465 IEM_MC_REF_LOCAL(pu32Dst, u32Dst);
2466 IEM_MC_POP_U32(pu32Dst);
2467 IEM_MC_STORE_GREG_U32(X86_GREG_xSP, u32Dst);
2468 IEM_MC_ADVANCE_RIP_AND_FINISH();
2469 IEM_MC_END();
2470 break;
2471
2472 case IEMMODE_64BIT:
2473 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
2474 IEMOP_HLP_DECODED_NL_1(OP_POP, IEMOPFORM_FIXED, OP_PARM_REG_ESP,
2475 DISOPTYPE_HARMLESS | DISOPTYPE_X86_DEFAULT_64_OP_SIZE | DISOPTYPE_X86_REXB_EXTENDS_OPREG);
2476 IEM_MC_LOCAL(uint64_t, u64Dst);
2477 IEM_MC_LOCAL(uint64_t *, pu64Dst);
2478 IEM_MC_REF_LOCAL(pu64Dst, u64Dst);
2479 IEM_MC_POP_U64(pu64Dst);
2480 IEM_MC_STORE_GREG_U64(X86_GREG_xSP, u64Dst);
2481 IEM_MC_ADVANCE_RIP_AND_FINISH();
2482 IEM_MC_END();
2483 break;
2484
2485 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2486 }
2487}
2488
2489
2490/**
2491 * @opcode 0x5d
2492 */
2493FNIEMOP_DEF(iemOp_pop_eBP)
2494{
2495 IEMOP_MNEMONIC(pop_rBP, "pop rBP");
2496 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xBP);
2497}
2498
2499
2500/**
2501 * @opcode 0x5e
2502 */
2503FNIEMOP_DEF(iemOp_pop_eSI)
2504{
2505 IEMOP_MNEMONIC(pop_rSI, "pop rSI");
2506 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xSI);
2507}
2508
2509
2510/**
2511 * @opcode 0x5f
2512 */
2513FNIEMOP_DEF(iemOp_pop_eDI)
2514{
2515 IEMOP_MNEMONIC(pop_rDI, "pop rDI");
2516 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xDI);
2517}
2518
2519
2520/**
2521 * @opcode 0x60
2522 */
2523FNIEMOP_DEF(iemOp_pusha)
2524{
2525 IEMOP_MNEMONIC(pusha, "pusha");
2526 IEMOP_HLP_MIN_186();
2527 IEMOP_HLP_NO_64BIT();
2528 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
2529 IEM_MC_DEFER_TO_CIMPL_0_RET(0, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP), iemCImpl_pusha_16);
2530 Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_32BIT);
2531 IEM_MC_DEFER_TO_CIMPL_0_RET(0, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP), iemCImpl_pusha_32);
2532}
2533
2534
2535/**
2536 * @opcode 0x61
2537 */
2538FNIEMOP_DEF(iemOp_popa__mvex)
2539{
2540 if (!IEM_IS_64BIT_CODE(pVCpu))
2541 {
2542 IEMOP_MNEMONIC(popa, "popa");
2543 IEMOP_HLP_MIN_186();
2544 IEMOP_HLP_NO_64BIT();
2545 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
2546 IEM_MC_DEFER_TO_CIMPL_0_RET(0,
2547 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
2548 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX)
2549 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDX)
2550 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xBX)
2551 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
2552 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xBP)
2553 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
2554 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
2555 iemCImpl_popa_16);
2556 Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_32BIT);
2557 IEM_MC_DEFER_TO_CIMPL_0_RET(0,
2558 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
2559 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX)
2560 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDX)
2561 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xBX)
2562 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
2563 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xBP)
2564 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
2565 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
2566 iemCImpl_popa_32);
2567 }
2568 IEMOP_MNEMONIC(mvex, "mvex");
2569 Log(("mvex prefix is not supported!\n"));
2570 IEMOP_RAISE_INVALID_OPCODE_RET();
2571}
2572
2573
2574/**
2575 * @opcode 0x62
2576 * @opmnemonic bound
2577 * @op1 Gv_RO
2578 * @op2 Ma
2579 * @opmincpu 80186
2580 * @ophints harmless x86_invalid_64
2581 * @optest op1=0 op2=0 ->
2582 * @optest op1=1 op2=0 -> value.xcpt=5
2583 * @optest o16 / op1=0xffff op2=0x0000fffe ->
2584 * @optest o16 / op1=0xfffe op2=0x0000fffe ->
2585 * @optest o16 / op1=0x7fff op2=0x0000fffe -> value.xcpt=5
2586 * @optest o16 / op1=0x7fff op2=0x7ffffffe ->
2587 * @optest o16 / op1=0x7fff op2=0xfffe8000 -> value.xcpt=5
2588 * @optest o16 / op1=0x8000 op2=0xfffe8000 ->
2589 * @optest o16 / op1=0xffff op2=0xfffe8000 -> value.xcpt=5
2590 * @optest o16 / op1=0xfffe op2=0xfffe8000 ->
2591 * @optest o16 / op1=0xfffe op2=0x8000fffe -> value.xcpt=5
2592 * @optest o16 / op1=0x8000 op2=0x8000fffe -> value.xcpt=5
2593 * @optest o16 / op1=0x0000 op2=0x8000fffe -> value.xcpt=5
2594 * @optest o16 / op1=0x0001 op2=0x8000fffe -> value.xcpt=5
2595 * @optest o16 / op1=0xffff op2=0x0001000f -> value.xcpt=5
2596 * @optest o16 / op1=0x0000 op2=0x0001000f -> value.xcpt=5
2597 * @optest o16 / op1=0x0001 op2=0x0001000f -> value.xcpt=5
2598 * @optest o16 / op1=0x0002 op2=0x0001000f -> value.xcpt=5
2599 * @optest o16 / op1=0x0003 op2=0x0001000f -> value.xcpt=5
2600 * @optest o16 / op1=0x0004 op2=0x0001000f -> value.xcpt=5
2601 * @optest o16 / op1=0x000e op2=0x0001000f -> value.xcpt=5
2602 * @optest o16 / op1=0x000f op2=0x0001000f -> value.xcpt=5
2603 * @optest o16 / op1=0x0010 op2=0x0001000f -> value.xcpt=5
2604 * @optest o16 / op1=0x0011 op2=0x0001000f -> value.xcpt=5
2605 * @optest o32 / op1=0xffffffff op2=0x00000000fffffffe ->
2606 * @optest o32 / op1=0xfffffffe op2=0x00000000fffffffe ->
2607 * @optest o32 / op1=0x7fffffff op2=0x00000000fffffffe -> value.xcpt=5
2608 * @optest o32 / op1=0x7fffffff op2=0x7ffffffffffffffe ->
2609 * @optest o32 / op1=0x7fffffff op2=0xfffffffe80000000 -> value.xcpt=5
2610 * @optest o32 / op1=0x80000000 op2=0xfffffffe80000000 ->
2611 * @optest o32 / op1=0xffffffff op2=0xfffffffe80000000 -> value.xcpt=5
2612 * @optest o32 / op1=0xfffffffe op2=0xfffffffe80000000 ->
2613 * @optest o32 / op1=0xfffffffe op2=0x80000000fffffffe -> value.xcpt=5
2614 * @optest o32 / op1=0x80000000 op2=0x80000000fffffffe -> value.xcpt=5
2615 * @optest o32 / op1=0x00000000 op2=0x80000000fffffffe -> value.xcpt=5
2616 * @optest o32 / op1=0x00000002 op2=0x80000000fffffffe -> value.xcpt=5
2617 * @optest o32 / op1=0x00000001 op2=0x0000000100000003 -> value.xcpt=5
2618 * @optest o32 / op1=0x00000002 op2=0x0000000100000003 -> value.xcpt=5
2619 * @optest o32 / op1=0x00000003 op2=0x0000000100000003 -> value.xcpt=5
2620 * @optest o32 / op1=0x00000004 op2=0x0000000100000003 -> value.xcpt=5
2621 * @optest o32 / op1=0x00000005 op2=0x0000000100000003 -> value.xcpt=5
2622 * @optest o32 / op1=0x0000000e op2=0x0000000100000003 -> value.xcpt=5
2623 * @optest o32 / op1=0x0000000f op2=0x0000000100000003 -> value.xcpt=5
2624 * @optest o32 / op1=0x00000010 op2=0x0000000100000003 -> value.xcpt=5
2625 */
2626FNIEMOP_DEF(iemOp_bound_Gv_Ma__evex)
2627{
2628 /* The BOUND instruction is invalid 64-bit mode. In legacy and
2629 compatability mode it is invalid with MOD=3.
2630
2631 In 32-bit mode, the EVEX prefix works by having the top two bits (MOD)
2632 both be set. In the Intel EVEX documentation (sdm vol 2) these are simply
2633 given as R and X without an exact description, so we assume it builds on
2634 the VEX one and means they are inverted wrt REX.R and REX.X. Thus, just
2635 like with the 3-byte VEX, 32-bit code is restrict wrt addressable registers. */
2636 uint8_t bRm;
2637 if (!IEM_IS_64BIT_CODE(pVCpu))
2638 {
2639 IEMOP_MNEMONIC2(RM_MEM, BOUND, bound, Gv_RO, Ma, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2640 IEMOP_HLP_MIN_186();
2641 IEM_OPCODE_GET_NEXT_U8(&bRm);
2642 if (IEM_IS_MODRM_MEM_MODE(bRm))
2643 {
2644 /** @todo testcase: check that there are two memory accesses involved. Check
2645 * whether they're both read before the \#BR triggers. */
2646 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
2647 {
2648 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_186 | IEM_MC_F_NOT_64BIT, 0);
2649 IEM_MC_ARG(uint16_t, u16Index, 0); /* Note! All operands are actually signed. Lazy unsigned bird. */
2650 IEM_MC_ARG(uint16_t, u16LowerBounds, 1);
2651 IEM_MC_ARG(uint16_t, u16UpperBounds, 2);
2652 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2653
2654 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2655 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2656
2657 IEM_MC_FETCH_GREG_U16(u16Index, IEM_GET_MODRM_REG_8(bRm));
2658 IEM_MC_FETCH_MEM_U16(u16LowerBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
2659 IEM_MC_FETCH_MEM_U16_DISP(u16UpperBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 2);
2660
2661 IEM_MC_CALL_CIMPL_3(0, 0, iemCImpl_bound_16, u16Index, u16LowerBounds, u16UpperBounds); /* returns */
2662 IEM_MC_END();
2663 }
2664 else /* 32-bit operands */
2665 {
2666 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0);
2667 IEM_MC_ARG(uint32_t, u32Index, 0); /* Note! All operands are actually signed. Lazy unsigned bird. */
2668 IEM_MC_ARG(uint32_t, u32LowerBounds, 1);
2669 IEM_MC_ARG(uint32_t, u32UpperBounds, 2);
2670 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2671
2672 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2673 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2674
2675 IEM_MC_FETCH_GREG_U32(u32Index, IEM_GET_MODRM_REG_8(bRm));
2676 IEM_MC_FETCH_MEM_U32(u32LowerBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
2677 IEM_MC_FETCH_MEM_U32_DISP(u32UpperBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 4);
2678
2679 IEM_MC_CALL_CIMPL_3(0, 0, iemCImpl_bound_32, u32Index, u32LowerBounds, u32UpperBounds); /* returns */
2680 IEM_MC_END();
2681 }
2682 }
2683
2684 /*
2685 * @opdone
2686 */
2687 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx512Foundation)
2688 {
2689 /* Note that there is no need for the CPU to fetch further bytes
2690 here because MODRM.MOD == 3. */
2691 Log(("evex not supported by the guest CPU!\n"));
2692 IEMOP_RAISE_INVALID_OPCODE_RET();
2693 }
2694 }
2695 else
2696 {
2697 /** @todo check how this is decoded in 64-bit mode w/o EVEX. Intel probably
2698 * does modr/m read, whereas AMD probably doesn't... */
2699 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx512Foundation)
2700 {
2701 Log(("evex not supported by the guest CPU!\n"));
2702 return FNIEMOP_CALL(iemOp_InvalidAllNeedRM);
2703 }
2704 IEM_OPCODE_GET_NEXT_U8(&bRm);
2705 }
2706
2707 IEMOP_MNEMONIC(evex, "evex");
2708 uint8_t bP2; IEM_OPCODE_GET_NEXT_U8(&bP2);
2709 uint8_t bP3; IEM_OPCODE_GET_NEXT_U8(&bP3);
2710 Log(("evex prefix is not implemented!\n"));
2711 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
2712}
2713
2714
2715/** Opcode 0x63 - non-64-bit modes. */
2716FNIEMOP_DEF(iemOp_arpl_Ew_Gw)
2717{
2718 IEMOP_MNEMONIC(arpl_Ew_Gw, "arpl Ew,Gw");
2719 IEMOP_HLP_MIN_286();
2720 IEMOP_HLP_NO_REAL_OR_V86_MODE();
2721 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2722
2723 if (IEM_IS_MODRM_REG_MODE(bRm))
2724 {
2725 /* Register */
2726 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_286 | IEM_MC_F_NOT_64BIT, 0);
2727 IEMOP_HLP_DECODED_NL_2(OP_ARPL, IEMOPFORM_MR_REG, OP_PARM_Ew, OP_PARM_Gw, DISOPTYPE_HARMLESS);
2728 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2729 IEM_MC_ARG(uint16_t, u16Src, 1);
2730 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2731
2732 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG_8(bRm));
2733 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM_8(bRm));
2734 IEM_MC_REF_EFLAGS(pEFlags);
2735 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_arpl, pu16Dst, u16Src, pEFlags);
2736
2737 IEM_MC_ADVANCE_RIP_AND_FINISH();
2738 IEM_MC_END();
2739 }
2740 else
2741 {
2742 /* Memory */
2743 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_286 | IEM_MC_F_NOT_64BIT, 0);
2744 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2745 IEM_MC_ARG(uint16_t, u16Src, 1);
2746 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
2747 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2748 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
2749
2750 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
2751 IEMOP_HLP_DECODED_NL_2(OP_ARPL, IEMOPFORM_MR_REG, OP_PARM_Ew, OP_PARM_Gw, DISOPTYPE_HARMLESS);
2752 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2753 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG_8(bRm));
2754 IEM_MC_FETCH_EFLAGS(EFlags);
2755 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_arpl, pu16Dst, u16Src, pEFlags);
2756
2757 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
2758 IEM_MC_COMMIT_EFLAGS(EFlags);
2759 IEM_MC_ADVANCE_RIP_AND_FINISH();
2760 IEM_MC_END();
2761 }
2762}
2763
2764
2765/**
2766 * @opcode 0x63
2767 *
2768 * @note This is a weird one. It works like a regular move instruction if
2769 * REX.W isn't set, at least according to AMD docs (rev 3.15, 2009-11).
2770 * @todo This definitely needs a testcase to verify the odd cases. */
2771FNIEMOP_DEF(iemOp_movsxd_Gv_Ev)
2772{
2773 Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_64BIT); /* Caller branched already . */
2774
2775 IEMOP_MNEMONIC(movsxd_Gv_Ev, "movsxd Gv,Ev");
2776 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2777
2778 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
2779 {
2780 if (IEM_IS_MODRM_REG_MODE(bRm))
2781 {
2782 /*
2783 * Register to register.
2784 */
2785 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
2786 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2787 IEM_MC_LOCAL(uint64_t, u64Value);
2788 IEM_MC_FETCH_GREG_U32_SX_U64(u64Value, IEM_GET_MODRM_RM(pVCpu, bRm));
2789 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Value);
2790 IEM_MC_ADVANCE_RIP_AND_FINISH();
2791 IEM_MC_END();
2792 }
2793 else
2794 {
2795 /*
2796 * We're loading a register from memory.
2797 */
2798 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
2799 IEM_MC_LOCAL(uint64_t, u64Value);
2800 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2801 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
2802 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2803 IEM_MC_FETCH_MEM_U32_SX_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2804 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Value);
2805 IEM_MC_ADVANCE_RIP_AND_FINISH();
2806 IEM_MC_END();
2807 }
2808 }
2809 else
2810 AssertFailedReturn(VERR_IEM_INSTR_NOT_IMPLEMENTED);
2811}
2812
2813
2814/**
2815 * @opcode 0x64
2816 * @opmnemonic segfs
2817 * @opmincpu 80386
2818 * @opgroup og_prefixes
2819 */
2820FNIEMOP_DEF(iemOp_seg_FS)
2821{
2822 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg fs");
2823 IEMOP_HLP_MIN_386();
2824
2825 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_FS;
2826 pVCpu->iem.s.iEffSeg = X86_SREG_FS;
2827
2828 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2829 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2830}
2831
2832
2833/**
2834 * @opcode 0x65
2835 * @opmnemonic seggs
2836 * @opmincpu 80386
2837 * @opgroup og_prefixes
2838 */
2839FNIEMOP_DEF(iemOp_seg_GS)
2840{
2841 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg gs");
2842 IEMOP_HLP_MIN_386();
2843
2844 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_GS;
2845 pVCpu->iem.s.iEffSeg = X86_SREG_GS;
2846
2847 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2848 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2849}
2850
2851
2852/**
2853 * @opcode 0x66
2854 * @opmnemonic opsize
2855 * @openc prefix
2856 * @opmincpu 80386
2857 * @ophints harmless
2858 * @opgroup og_prefixes
2859 */
2860FNIEMOP_DEF(iemOp_op_size)
2861{
2862 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("op size");
2863 IEMOP_HLP_MIN_386();
2864
2865 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_OP;
2866 iemRecalEffOpSize(pVCpu);
2867
2868 /* For the 4 entry opcode tables, the operand prefix doesn't not count
2869 when REPZ or REPNZ are present. */
2870 if (pVCpu->iem.s.idxPrefix == 0)
2871 pVCpu->iem.s.idxPrefix = 1;
2872
2873 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2874 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2875}
2876
2877
2878/**
2879 * @opcode 0x67
2880 * @opmnemonic addrsize
2881 * @openc prefix
2882 * @opmincpu 80386
2883 * @ophints harmless
2884 * @opgroup og_prefixes
2885 */
2886FNIEMOP_DEF(iemOp_addr_size)
2887{
2888 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("addr size");
2889 IEMOP_HLP_MIN_386();
2890
2891 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_ADDR;
2892 switch (pVCpu->iem.s.enmDefAddrMode)
2893 {
2894 case IEMMODE_16BIT: pVCpu->iem.s.enmEffAddrMode = IEMMODE_32BIT; break;
2895 case IEMMODE_32BIT: pVCpu->iem.s.enmEffAddrMode = IEMMODE_16BIT; break;
2896 case IEMMODE_64BIT: pVCpu->iem.s.enmEffAddrMode = IEMMODE_32BIT; break;
2897 default: AssertFailed();
2898 }
2899
2900 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2901 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2902}
2903
2904
2905/**
2906 * @opcode 0x68
2907 */
2908FNIEMOP_DEF(iemOp_push_Iz)
2909{
2910 IEMOP_MNEMONIC(push_Iz, "push Iz");
2911 IEMOP_HLP_MIN_186();
2912 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2913 switch (pVCpu->iem.s.enmEffOpSize)
2914 {
2915 case IEMMODE_16BIT:
2916 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_186, 0);
2917 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
2918 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2919 IEM_MC_LOCAL_CONST(uint16_t, u16Value, u16Imm);
2920 IEM_MC_PUSH_U16(u16Value);
2921 IEM_MC_ADVANCE_RIP_AND_FINISH();
2922 IEM_MC_END();
2923 break;
2924
2925 case IEMMODE_32BIT:
2926 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0);
2927 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
2928 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2929 IEM_MC_LOCAL_CONST(uint32_t, u32Value, u32Imm);
2930 IEM_MC_PUSH_U32(u32Value);
2931 IEM_MC_ADVANCE_RIP_AND_FINISH();
2932 IEM_MC_END();
2933 break;
2934
2935 case IEMMODE_64BIT:
2936 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
2937 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
2938 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2939 IEM_MC_LOCAL_CONST(uint64_t, u64Value, u64Imm);
2940 IEM_MC_PUSH_U64(u64Value);
2941 IEM_MC_ADVANCE_RIP_AND_FINISH();
2942 IEM_MC_END();
2943 break;
2944
2945 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2946 }
2947}
2948
2949
2950/**
2951 * @opcode 0x69
2952 */
2953FNIEMOP_DEF(iemOp_imul_Gv_Ev_Iz)
2954{
2955 IEMOP_MNEMONIC(imul_Gv_Ev_Iz, "imul Gv,Ev,Iz"); /* Gv = Ev * Iz; */
2956 IEMOP_HLP_MIN_186();
2957 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2958 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
2959
2960 switch (pVCpu->iem.s.enmEffOpSize)
2961 {
2962 case IEMMODE_16BIT:
2963 {
2964 PFNIEMAIMPLBINU16 const pfnAImplU16 = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u16_eflags);
2965 if (IEM_IS_MODRM_REG_MODE(bRm))
2966 {
2967 /* register operand */
2968 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
2969 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_186, 0);
2970 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2971 IEM_MC_LOCAL(uint16_t, u16Tmp);
2972 IEM_MC_FETCH_GREG_U16(u16Tmp, IEM_GET_MODRM_RM(pVCpu, bRm));
2973 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Dst, u16Tmp, 0);
2974 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm, 1);
2975 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2976 IEM_MC_REF_EFLAGS(pEFlags);
2977 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU16, pu16Dst, u16Src, pEFlags);
2978 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Tmp);
2979
2980 IEM_MC_ADVANCE_RIP_AND_FINISH();
2981 IEM_MC_END();
2982 }
2983 else
2984 {
2985 /* memory operand */
2986 IEM_MC_BEGIN(3, 2, IEM_MC_F_MIN_186, 0);
2987 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2988 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
2989
2990 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
2991 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2992
2993 IEM_MC_LOCAL(uint16_t, u16Tmp);
2994 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2995
2996 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Dst, u16Tmp, 0);
2997 IEM_MC_ARG_CONST(uint16_t, u16Src, u16Imm, 1);
2998 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2999 IEM_MC_REF_EFLAGS(pEFlags);
3000 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU16, pu16Dst, u16Src, pEFlags);
3001 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Tmp);
3002
3003 IEM_MC_ADVANCE_RIP_AND_FINISH();
3004 IEM_MC_END();
3005 }
3006 break;
3007 }
3008
3009 case IEMMODE_32BIT:
3010 {
3011 PFNIEMAIMPLBINU32 const pfnAImplU32 = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u32_eflags);
3012 if (IEM_IS_MODRM_REG_MODE(bRm))
3013 {
3014 /* register operand */
3015 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
3016 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_386, 0);
3017 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3018 IEM_MC_LOCAL(uint32_t, u32Tmp);
3019 IEM_MC_FETCH_GREG_U32(u32Tmp, IEM_GET_MODRM_RM(pVCpu, bRm));
3020
3021 IEM_MC_ARG_LOCAL_REF(uint32_t *, pu32Dst, u32Tmp, 0);
3022 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm, 1);
3023 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3024 IEM_MC_REF_EFLAGS(pEFlags);
3025 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU32, pu32Dst, u32Src, pEFlags);
3026 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Tmp);
3027
3028 IEM_MC_ADVANCE_RIP_AND_FINISH();
3029 IEM_MC_END();
3030 }
3031 else
3032 {
3033 /* memory operand */
3034 IEM_MC_BEGIN(3, 2, IEM_MC_F_MIN_386, 0);
3035 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3036 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
3037
3038 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
3039 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3040
3041 IEM_MC_LOCAL(uint32_t, u32Tmp);
3042 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
3043
3044 IEM_MC_ARG_LOCAL_REF(uint32_t *, pu32Dst, u32Tmp, 0);
3045 IEM_MC_ARG_CONST(uint32_t, u32Src, u32Imm, 1);
3046 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3047 IEM_MC_REF_EFLAGS(pEFlags);
3048 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU32, pu32Dst, u32Src, pEFlags);
3049 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Tmp);
3050
3051 IEM_MC_ADVANCE_RIP_AND_FINISH();
3052 IEM_MC_END();
3053 }
3054 break;
3055 }
3056
3057 case IEMMODE_64BIT:
3058 {
3059 PFNIEMAIMPLBINU64 const pfnAImplU64 = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u64_eflags);
3060 if (IEM_IS_MODRM_REG_MODE(bRm))
3061 {
3062 /* register operand */
3063 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
3064 IEM_MC_BEGIN(3, 1, IEM_MC_F_64BIT, 0);
3065 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3066 IEM_MC_LOCAL(uint64_t, u64Tmp);
3067 IEM_MC_FETCH_GREG_U64(u64Tmp, IEM_GET_MODRM_RM(pVCpu, bRm));
3068
3069 IEM_MC_ARG_LOCAL_REF(uint64_t *, pu64Dst, u64Tmp, 0);
3070 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm, 1);
3071 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3072 IEM_MC_REF_EFLAGS(pEFlags);
3073 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU64, pu64Dst, u64Src, pEFlags);
3074 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Tmp);
3075
3076 IEM_MC_ADVANCE_RIP_AND_FINISH();
3077 IEM_MC_END();
3078 }
3079 else
3080 {
3081 /* memory operand */
3082 IEM_MC_BEGIN(3, 2, IEM_MC_F_64BIT, 0);
3083 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3084 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
3085
3086 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); /* Not using IEM_OPCODE_GET_NEXT_S32_SX_U64 to reduce the */
3087 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /* parameter count for the threaded function for this block. */
3088
3089 IEM_MC_LOCAL(uint64_t, u64Tmp);
3090 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
3091
3092 IEM_MC_ARG_LOCAL_REF(uint64_t *, pu64Dst, u64Tmp, 0);
3093 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int64_t)(int32_t)u32Imm, 1);
3094 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3095 IEM_MC_REF_EFLAGS(pEFlags);
3096 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU64, pu64Dst, u64Src, pEFlags);
3097 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Tmp);
3098
3099 IEM_MC_ADVANCE_RIP_AND_FINISH();
3100 IEM_MC_END();
3101 }
3102 break;
3103 }
3104
3105 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3106 }
3107}
3108
3109
3110/**
3111 * @opcode 0x6a
3112 */
3113FNIEMOP_DEF(iemOp_push_Ib)
3114{
3115 IEMOP_MNEMONIC(push_Ib, "push Ib");
3116 IEMOP_HLP_MIN_186();
3117 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3118 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
3119
3120 switch (pVCpu->iem.s.enmEffOpSize)
3121 {
3122 case IEMMODE_16BIT:
3123 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_186, 0);
3124 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3125 IEM_MC_LOCAL_CONST(uint16_t, uValue, (int16_t)i8Imm);
3126 IEM_MC_PUSH_U16(uValue);
3127 IEM_MC_ADVANCE_RIP_AND_FINISH();
3128 IEM_MC_END();
3129 break;
3130 case IEMMODE_32BIT:
3131 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0);
3132 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3133 IEM_MC_LOCAL_CONST(uint32_t, uValue, (int32_t)i8Imm);
3134 IEM_MC_PUSH_U32(uValue);
3135 IEM_MC_ADVANCE_RIP_AND_FINISH();
3136 IEM_MC_END();
3137 break;
3138 case IEMMODE_64BIT:
3139 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
3140 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3141 IEM_MC_LOCAL_CONST(uint64_t, uValue, (int64_t)i8Imm);
3142 IEM_MC_PUSH_U64(uValue);
3143 IEM_MC_ADVANCE_RIP_AND_FINISH();
3144 IEM_MC_END();
3145 break;
3146 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3147 }
3148}
3149
3150
3151/**
3152 * @opcode 0x6b
3153 */
3154FNIEMOP_DEF(iemOp_imul_Gv_Ev_Ib)
3155{
3156 IEMOP_MNEMONIC(imul_Gv_Ev_Ib, "imul Gv,Ev,Ib"); /* Gv = Ev * Iz; */
3157 IEMOP_HLP_MIN_186();
3158 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3159 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
3160
3161 switch (pVCpu->iem.s.enmEffOpSize)
3162 {
3163 case IEMMODE_16BIT:
3164 {
3165 PFNIEMAIMPLBINU16 const pfnAImplU16 = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u16_eflags);
3166 if (IEM_IS_MODRM_REG_MODE(bRm))
3167 {
3168 /* register operand */
3169 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_186, 0);
3170 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3171 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3172
3173 IEM_MC_LOCAL(uint16_t, u16Tmp);
3174 IEM_MC_FETCH_GREG_U16(u16Tmp, IEM_GET_MODRM_RM(pVCpu, bRm));
3175
3176 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Dst, u16Tmp, 0);
3177 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ (int8_t)u8Imm, 1);
3178 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3179 IEM_MC_REF_EFLAGS(pEFlags);
3180 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU16, pu16Dst, u16Src, pEFlags);
3181 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Tmp);
3182
3183 IEM_MC_ADVANCE_RIP_AND_FINISH();
3184 IEM_MC_END();
3185 }
3186 else
3187 {
3188 /* memory operand */
3189 IEM_MC_BEGIN(3, 2, IEM_MC_F_MIN_186, 0);
3190
3191 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3192 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3193
3194 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_S8_SX_U16(&u16Imm);
3195 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3196
3197 IEM_MC_LOCAL(uint16_t, u16Tmp);
3198 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
3199
3200 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Dst, u16Tmp, 0);
3201 IEM_MC_ARG_CONST(uint16_t, u16Src, u16Imm, 1);
3202 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3203 IEM_MC_REF_EFLAGS(pEFlags);
3204 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU16, pu16Dst, u16Src, pEFlags);
3205 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Tmp);
3206
3207 IEM_MC_ADVANCE_RIP_AND_FINISH();
3208 IEM_MC_END();
3209 }
3210 break;
3211 }
3212
3213 case IEMMODE_32BIT:
3214 {
3215 PFNIEMAIMPLBINU32 const pfnAImplU32 = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u32_eflags);
3216 if (IEM_IS_MODRM_REG_MODE(bRm))
3217 {
3218 /* register operand */
3219 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3220 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_386, 0);
3221 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3222 IEM_MC_LOCAL(uint32_t, u32Tmp);
3223 IEM_MC_FETCH_GREG_U32(u32Tmp, IEM_GET_MODRM_RM(pVCpu, bRm));
3224
3225 IEM_MC_ARG_LOCAL_REF(uint32_t *, pu32Dst, u32Tmp, 0);
3226 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ (int8_t)u8Imm, 1);
3227 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3228 IEM_MC_REF_EFLAGS(pEFlags);
3229 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU32, pu32Dst, u32Src, pEFlags);
3230 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Tmp);
3231
3232 IEM_MC_ADVANCE_RIP_AND_FINISH();
3233 IEM_MC_END();
3234 }
3235 else
3236 {
3237 /* memory operand */
3238 IEM_MC_BEGIN(3, 2, IEM_MC_F_MIN_386, 0);
3239 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3240 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3241
3242 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_S8_SX_U32(&u32Imm);
3243 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3244
3245 IEM_MC_LOCAL(uint32_t, u32Tmp);
3246 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
3247
3248 IEM_MC_ARG_LOCAL_REF(uint32_t *, pu32Dst, u32Tmp, 0);
3249 IEM_MC_ARG_CONST(uint32_t, u32Src, u32Imm, 1);
3250 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3251 IEM_MC_REF_EFLAGS(pEFlags);
3252 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU32, pu32Dst, u32Src, pEFlags);
3253 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Tmp);
3254
3255 IEM_MC_ADVANCE_RIP_AND_FINISH();
3256 IEM_MC_END();
3257 }
3258 break;
3259 }
3260
3261 case IEMMODE_64BIT:
3262 {
3263 PFNIEMAIMPLBINU64 const pfnAImplU64 = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u64_eflags);
3264 if (IEM_IS_MODRM_REG_MODE(bRm))
3265 {
3266 /* register operand */
3267 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3268 IEM_MC_BEGIN(3, 1, IEM_MC_F_64BIT, 0);
3269 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3270 IEM_MC_LOCAL(uint64_t, u64Tmp);
3271 IEM_MC_FETCH_GREG_U64(u64Tmp, IEM_GET_MODRM_RM(pVCpu, bRm));
3272
3273 IEM_MC_ARG_LOCAL_REF(uint64_t *, pu64Dst, u64Tmp, 0);
3274 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int64_t)(int8_t)u8Imm, 1);
3275 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3276 IEM_MC_REF_EFLAGS(pEFlags);
3277 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU64, pu64Dst, u64Src, pEFlags);
3278 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Tmp);
3279
3280 IEM_MC_ADVANCE_RIP_AND_FINISH();
3281 IEM_MC_END();
3282 }
3283 else
3284 {
3285 /* memory operand */
3286 IEM_MC_BEGIN(3, 2, IEM_MC_F_64BIT, 0);
3287 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3288 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3289
3290 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); /* Not using IEM_OPCODE_GET_NEXT_S8_SX_U64 to reduce the threaded parameter count. */
3291 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3292
3293 IEM_MC_LOCAL(uint64_t, u64Tmp);
3294 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
3295
3296 IEM_MC_ARG_LOCAL_REF(uint64_t *, pu64Dst, u64Tmp, 0);
3297 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int64_t)(int8_t)u8Imm, 1);
3298 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3299 IEM_MC_REF_EFLAGS(pEFlags);
3300 IEM_MC_CALL_VOID_AIMPL_3(pfnAImplU64, pu64Dst, u64Src, pEFlags);
3301 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Tmp);
3302
3303 IEM_MC_ADVANCE_RIP_AND_FINISH();
3304 IEM_MC_END();
3305 }
3306 break;
3307 }
3308
3309 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3310 }
3311}
3312
3313
3314/**
3315 * @opcode 0x6c
3316 */
3317FNIEMOP_DEF(iemOp_insb_Yb_DX)
3318{
3319 IEMOP_HLP_MIN_186();
3320 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3321 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
3322 {
3323 IEMOP_MNEMONIC(rep_insb_Yb_DX, "rep ins Yb,DX");
3324 switch (pVCpu->iem.s.enmEffAddrMode)
3325 {
3326 case IEMMODE_16BIT:
3327 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3328 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3329 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3330 iemCImpl_rep_ins_op8_addr16, false);
3331 case IEMMODE_32BIT:
3332 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3333 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3334 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3335 iemCImpl_rep_ins_op8_addr32, false);
3336 case IEMMODE_64BIT:
3337 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3338 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3339 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3340 iemCImpl_rep_ins_op8_addr64, false);
3341 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3342 }
3343 }
3344 else
3345 {
3346 IEMOP_MNEMONIC(ins_Yb_DX, "ins Yb,DX");
3347 switch (pVCpu->iem.s.enmEffAddrMode)
3348 {
3349 case IEMMODE_16BIT:
3350 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3351 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3352 iemCImpl_ins_op8_addr16, false);
3353 case IEMMODE_32BIT:
3354 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3355 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3356 iemCImpl_ins_op8_addr32, false);
3357 case IEMMODE_64BIT:
3358 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3359 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3360 iemCImpl_ins_op8_addr64, false);
3361 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3362 }
3363 }
3364}
3365
3366
3367/**
3368 * @opcode 0x6d
3369 */
3370FNIEMOP_DEF(iemOp_inswd_Yv_DX)
3371{
3372 IEMOP_HLP_MIN_186();
3373 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3374 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ))
3375 {
3376 IEMOP_MNEMONIC(rep_ins_Yv_DX, "rep ins Yv,DX");
3377 switch (pVCpu->iem.s.enmEffOpSize)
3378 {
3379 case IEMMODE_16BIT:
3380 switch (pVCpu->iem.s.enmEffAddrMode)
3381 {
3382 case IEMMODE_16BIT:
3383 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3384 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3385 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3386 iemCImpl_rep_ins_op16_addr16, false);
3387 case IEMMODE_32BIT:
3388 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3389 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3390 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3391 iemCImpl_rep_ins_op16_addr32, false);
3392 case IEMMODE_64BIT:
3393 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3394 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3395 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3396 iemCImpl_rep_ins_op16_addr64, false);
3397 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3398 }
3399 break;
3400 case IEMMODE_64BIT:
3401 case IEMMODE_32BIT:
3402 switch (pVCpu->iem.s.enmEffAddrMode)
3403 {
3404 case IEMMODE_16BIT:
3405 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3406 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3407 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3408 iemCImpl_rep_ins_op32_addr16, false);
3409 case IEMMODE_32BIT:
3410 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3411 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3412 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3413 iemCImpl_rep_ins_op32_addr32, false);
3414 case IEMMODE_64BIT:
3415 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3416 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
3417 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3418 iemCImpl_rep_ins_op32_addr64, false);
3419 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3420 }
3421 break;
3422 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3423 }
3424 }
3425 else
3426 {
3427 IEMOP_MNEMONIC(ins_Yv_DX, "ins Yv,DX");
3428 switch (pVCpu->iem.s.enmEffOpSize)
3429 {
3430 case IEMMODE_16BIT:
3431 switch (pVCpu->iem.s.enmEffAddrMode)
3432 {
3433 case IEMMODE_16BIT:
3434 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3435 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3436 iemCImpl_ins_op16_addr16, false);
3437 case IEMMODE_32BIT:
3438 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3439 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3440 iemCImpl_ins_op16_addr32, false);
3441 case IEMMODE_64BIT:
3442 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3443 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3444 iemCImpl_ins_op16_addr64, false);
3445 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3446 }
3447 break;
3448 case IEMMODE_64BIT:
3449 case IEMMODE_32BIT:
3450 switch (pVCpu->iem.s.enmEffAddrMode)
3451 {
3452 case IEMMODE_16BIT:
3453 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3454 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3455 iemCImpl_ins_op32_addr16, false);
3456 case IEMMODE_32BIT:
3457 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3458 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3459 iemCImpl_ins_op32_addr32, false);
3460 case IEMMODE_64BIT:
3461 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3462 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI),
3463 iemCImpl_ins_op32_addr64, false);
3464 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3465 }
3466 break;
3467 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3468 }
3469 }
3470}
3471
3472
3473/**
3474 * @opcode 0x6e
3475 */
3476FNIEMOP_DEF(iemOp_outsb_Yb_DX)
3477{
3478 IEMOP_HLP_MIN_186();
3479 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3480 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
3481 {
3482 IEMOP_MNEMONIC(rep_outsb_DX_Yb, "rep outs DX,Yb");
3483 switch (pVCpu->iem.s.enmEffAddrMode)
3484 {
3485 case IEMMODE_16BIT:
3486 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3487 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3488 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3489 iemCImpl_rep_outs_op8_addr16, pVCpu->iem.s.iEffSeg, false);
3490 case IEMMODE_32BIT:
3491 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3492 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3493 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3494 iemCImpl_rep_outs_op8_addr32, pVCpu->iem.s.iEffSeg, false);
3495 case IEMMODE_64BIT:
3496 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3497 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3498 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3499 iemCImpl_rep_outs_op8_addr64, pVCpu->iem.s.iEffSeg, false);
3500 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3501 }
3502 }
3503 else
3504 {
3505 IEMOP_MNEMONIC(outs_DX_Yb, "outs DX,Yb");
3506 switch (pVCpu->iem.s.enmEffAddrMode)
3507 {
3508 case IEMMODE_16BIT:
3509 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3510 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3511 iemCImpl_outs_op8_addr16, pVCpu->iem.s.iEffSeg, false);
3512 case IEMMODE_32BIT:
3513 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3514 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3515 iemCImpl_outs_op8_addr32, pVCpu->iem.s.iEffSeg, false);
3516 case IEMMODE_64BIT:
3517 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3518 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3519 iemCImpl_outs_op8_addr64, pVCpu->iem.s.iEffSeg, false);
3520 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3521 }
3522 }
3523}
3524
3525
3526/**
3527 * @opcode 0x6f
3528 */
3529FNIEMOP_DEF(iemOp_outswd_Yv_DX)
3530{
3531 IEMOP_HLP_MIN_186();
3532 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3533 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ))
3534 {
3535 IEMOP_MNEMONIC(rep_outs_DX_Yv, "rep outs DX,Yv");
3536 switch (pVCpu->iem.s.enmEffOpSize)
3537 {
3538 case IEMMODE_16BIT:
3539 switch (pVCpu->iem.s.enmEffAddrMode)
3540 {
3541 case IEMMODE_16BIT:
3542 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3543 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3544 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3545 iemCImpl_rep_outs_op16_addr16, pVCpu->iem.s.iEffSeg, false);
3546 case IEMMODE_32BIT:
3547 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3548 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3549 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3550 iemCImpl_rep_outs_op16_addr32, pVCpu->iem.s.iEffSeg, false);
3551 case IEMMODE_64BIT:
3552 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3553 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3554 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3555 iemCImpl_rep_outs_op16_addr64, pVCpu->iem.s.iEffSeg, false);
3556 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3557 }
3558 break;
3559 case IEMMODE_64BIT:
3560 case IEMMODE_32BIT:
3561 switch (pVCpu->iem.s.enmEffAddrMode)
3562 {
3563 case IEMMODE_16BIT:
3564 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3565 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3566 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3567 iemCImpl_rep_outs_op32_addr16, pVCpu->iem.s.iEffSeg, false);
3568 case IEMMODE_32BIT:
3569 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3570 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3571 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3572 iemCImpl_rep_outs_op32_addr32, pVCpu->iem.s.iEffSeg, false);
3573 case IEMMODE_64BIT:
3574 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3575 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
3576 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
3577 iemCImpl_rep_outs_op32_addr64, pVCpu->iem.s.iEffSeg, false);
3578 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3579 }
3580 break;
3581 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3582 }
3583 }
3584 else
3585 {
3586 IEMOP_MNEMONIC(outs_DX_Yv, "outs DX,Yv");
3587 switch (pVCpu->iem.s.enmEffOpSize)
3588 {
3589 case IEMMODE_16BIT:
3590 switch (pVCpu->iem.s.enmEffAddrMode)
3591 {
3592 case IEMMODE_16BIT:
3593 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3594 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3595 iemCImpl_outs_op16_addr16, pVCpu->iem.s.iEffSeg, false);
3596 case IEMMODE_32BIT:
3597 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3598 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3599 iemCImpl_outs_op16_addr32, pVCpu->iem.s.iEffSeg, false);
3600 case IEMMODE_64BIT:
3601 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3602 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3603 iemCImpl_outs_op16_addr64, pVCpu->iem.s.iEffSeg, false);
3604 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3605 }
3606 break;
3607 case IEMMODE_64BIT:
3608 case IEMMODE_32BIT:
3609 switch (pVCpu->iem.s.enmEffAddrMode)
3610 {
3611 case IEMMODE_16BIT:
3612 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3613 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3614 iemCImpl_outs_op32_addr16, pVCpu->iem.s.iEffSeg, false);
3615 case IEMMODE_32BIT:
3616 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3617 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3618 iemCImpl_outs_op32_addr32, pVCpu->iem.s.iEffSeg, false);
3619 case IEMMODE_64BIT:
3620 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
3621 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI),
3622 iemCImpl_outs_op32_addr64, pVCpu->iem.s.iEffSeg, false);
3623 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3624 }
3625 break;
3626 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3627 }
3628 }
3629}
3630
3631
3632/**
3633 * @opcode 0x70
3634 */
3635FNIEMOP_DEF(iemOp_jo_Jb)
3636{
3637 IEMOP_MNEMONIC(jo_Jb, "jo Jb");
3638 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3639 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3640
3641 IEM_MC_BEGIN(0, 0, 0, 0);
3642 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3643 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
3644 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3645 } IEM_MC_ELSE() {
3646 IEM_MC_ADVANCE_RIP_AND_FINISH();
3647 } IEM_MC_ENDIF();
3648 IEM_MC_END();
3649}
3650
3651
3652/**
3653 * @opcode 0x71
3654 */
3655FNIEMOP_DEF(iemOp_jno_Jb)
3656{
3657 IEMOP_MNEMONIC(jno_Jb, "jno Jb");
3658 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3659 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3660
3661 IEM_MC_BEGIN(0, 0, 0, 0);
3662 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3663 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
3664 IEM_MC_ADVANCE_RIP_AND_FINISH();
3665 } IEM_MC_ELSE() {
3666 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3667 } IEM_MC_ENDIF();
3668 IEM_MC_END();
3669}
3670
3671/**
3672 * @opcode 0x72
3673 */
3674FNIEMOP_DEF(iemOp_jc_Jb)
3675{
3676 IEMOP_MNEMONIC(jc_Jb, "jc/jnae Jb");
3677 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3678 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3679
3680 IEM_MC_BEGIN(0, 0, 0, 0);
3681 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3682 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
3683 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3684 } IEM_MC_ELSE() {
3685 IEM_MC_ADVANCE_RIP_AND_FINISH();
3686 } IEM_MC_ENDIF();
3687 IEM_MC_END();
3688}
3689
3690
3691/**
3692 * @opcode 0x73
3693 */
3694FNIEMOP_DEF(iemOp_jnc_Jb)
3695{
3696 IEMOP_MNEMONIC(jnc_Jb, "jnc/jnb Jb");
3697 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3698 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3699
3700 IEM_MC_BEGIN(0, 0, 0, 0);
3701 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3702 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
3703 IEM_MC_ADVANCE_RIP_AND_FINISH();
3704 } IEM_MC_ELSE() {
3705 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3706 } IEM_MC_ENDIF();
3707 IEM_MC_END();
3708}
3709
3710
3711/**
3712 * @opcode 0x74
3713 */
3714FNIEMOP_DEF(iemOp_je_Jb)
3715{
3716 IEMOP_MNEMONIC(je_Jb, "je/jz Jb");
3717 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3718 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3719
3720 IEM_MC_BEGIN(0, 0, 0, 0);
3721 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3722 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
3723 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3724 } IEM_MC_ELSE() {
3725 IEM_MC_ADVANCE_RIP_AND_FINISH();
3726 } IEM_MC_ENDIF();
3727 IEM_MC_END();
3728}
3729
3730
3731/**
3732 * @opcode 0x75
3733 */
3734FNIEMOP_DEF(iemOp_jne_Jb)
3735{
3736 IEMOP_MNEMONIC(jne_Jb, "jne/jnz Jb");
3737 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3738 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3739
3740 IEM_MC_BEGIN(0, 0, 0, 0);
3741 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3742 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
3743 IEM_MC_ADVANCE_RIP_AND_FINISH();
3744 } IEM_MC_ELSE() {
3745 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3746 } IEM_MC_ENDIF();
3747 IEM_MC_END();
3748}
3749
3750
3751/**
3752 * @opcode 0x76
3753 */
3754FNIEMOP_DEF(iemOp_jbe_Jb)
3755{
3756 IEMOP_MNEMONIC(jbe_Jb, "jbe/jna Jb");
3757 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3758 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3759
3760 IEM_MC_BEGIN(0, 0, 0, 0);
3761 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3762 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
3763 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3764 } IEM_MC_ELSE() {
3765 IEM_MC_ADVANCE_RIP_AND_FINISH();
3766 } IEM_MC_ENDIF();
3767 IEM_MC_END();
3768}
3769
3770
3771/**
3772 * @opcode 0x77
3773 */
3774FNIEMOP_DEF(iemOp_jnbe_Jb)
3775{
3776 IEMOP_MNEMONIC(ja_Jb, "ja/jnbe Jb");
3777 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3778 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3779
3780 IEM_MC_BEGIN(0, 0, 0, 0);
3781 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3782 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
3783 IEM_MC_ADVANCE_RIP_AND_FINISH();
3784 } IEM_MC_ELSE() {
3785 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3786 } IEM_MC_ENDIF();
3787 IEM_MC_END();
3788}
3789
3790
3791/**
3792 * @opcode 0x78
3793 */
3794FNIEMOP_DEF(iemOp_js_Jb)
3795{
3796 IEMOP_MNEMONIC(js_Jb, "js Jb");
3797 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3798 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3799
3800 IEM_MC_BEGIN(0, 0, 0, 0);
3801 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3802 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
3803 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3804 } IEM_MC_ELSE() {
3805 IEM_MC_ADVANCE_RIP_AND_FINISH();
3806 } IEM_MC_ENDIF();
3807 IEM_MC_END();
3808}
3809
3810
3811/**
3812 * @opcode 0x79
3813 */
3814FNIEMOP_DEF(iemOp_jns_Jb)
3815{
3816 IEMOP_MNEMONIC(jns_Jb, "jns Jb");
3817 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3818 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3819
3820 IEM_MC_BEGIN(0, 0, 0, 0);
3821 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3822 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
3823 IEM_MC_ADVANCE_RIP_AND_FINISH();
3824 } IEM_MC_ELSE() {
3825 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3826 } IEM_MC_ENDIF();
3827 IEM_MC_END();
3828}
3829
3830
3831/**
3832 * @opcode 0x7a
3833 */
3834FNIEMOP_DEF(iemOp_jp_Jb)
3835{
3836 IEMOP_MNEMONIC(jp_Jb, "jp Jb");
3837 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3838 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3839
3840 IEM_MC_BEGIN(0, 0, 0, 0);
3841 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3842 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
3843 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3844 } IEM_MC_ELSE() {
3845 IEM_MC_ADVANCE_RIP_AND_FINISH();
3846 } IEM_MC_ENDIF();
3847 IEM_MC_END();
3848}
3849
3850
3851/**
3852 * @opcode 0x7b
3853 */
3854FNIEMOP_DEF(iemOp_jnp_Jb)
3855{
3856 IEMOP_MNEMONIC(jnp_Jb, "jnp Jb");
3857 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3858 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3859
3860 IEM_MC_BEGIN(0, 0, 0, 0);
3861 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3862 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
3863 IEM_MC_ADVANCE_RIP_AND_FINISH();
3864 } IEM_MC_ELSE() {
3865 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3866 } IEM_MC_ENDIF();
3867 IEM_MC_END();
3868}
3869
3870
3871/**
3872 * @opcode 0x7c
3873 */
3874FNIEMOP_DEF(iemOp_jl_Jb)
3875{
3876 IEMOP_MNEMONIC(jl_Jb, "jl/jnge Jb");
3877 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3878 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3879
3880 IEM_MC_BEGIN(0, 0, 0, 0);
3881 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3882 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
3883 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3884 } IEM_MC_ELSE() {
3885 IEM_MC_ADVANCE_RIP_AND_FINISH();
3886 } IEM_MC_ENDIF();
3887 IEM_MC_END();
3888}
3889
3890
3891/**
3892 * @opcode 0x7d
3893 */
3894FNIEMOP_DEF(iemOp_jnl_Jb)
3895{
3896 IEMOP_MNEMONIC(jge_Jb, "jnl/jge Jb");
3897 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3898 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3899
3900 IEM_MC_BEGIN(0, 0, 0, 0);
3901 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3902 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
3903 IEM_MC_ADVANCE_RIP_AND_FINISH();
3904 } IEM_MC_ELSE() {
3905 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3906 } IEM_MC_ENDIF();
3907 IEM_MC_END();
3908}
3909
3910
3911/**
3912 * @opcode 0x7e
3913 */
3914FNIEMOP_DEF(iemOp_jle_Jb)
3915{
3916 IEMOP_MNEMONIC(jle_Jb, "jle/jng Jb");
3917 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3918 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3919
3920 IEM_MC_BEGIN(0, 0, 0, 0);
3921 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3922 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
3923 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3924 } IEM_MC_ELSE() {
3925 IEM_MC_ADVANCE_RIP_AND_FINISH();
3926 } IEM_MC_ENDIF();
3927 IEM_MC_END();
3928}
3929
3930
3931/**
3932 * @opcode 0x7f
3933 */
3934FNIEMOP_DEF(iemOp_jnle_Jb)
3935{
3936 IEMOP_MNEMONIC(jg_Jb, "jnle/jg Jb");
3937 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3938 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
3939
3940 IEM_MC_BEGIN(0, 0, 0, 0);
3941 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3942 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
3943 IEM_MC_ADVANCE_RIP_AND_FINISH();
3944 } IEM_MC_ELSE() {
3945 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
3946 } IEM_MC_ENDIF();
3947 IEM_MC_END();
3948}
3949
3950
3951/**
3952 * Body for group 1 instruction (binary) w/ byte imm operand, dispatched via
3953 * iemOp_Grp1_Eb_Ib_80.
3954 */
3955#define IEMOP_BODY_BINARY_Eb_Ib_RW(a_fnNormalU8) \
3956 if (IEM_IS_MODRM_REG_MODE(bRm)) \
3957 { \
3958 /* register target */ \
3959 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
3960 IEM_MC_BEGIN(3, 0, 0, 0); \
3961 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
3962 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
3963 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1); \
3964 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
3965 \
3966 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
3967 IEM_MC_REF_EFLAGS(pEFlags); \
3968 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
3969 \
3970 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
3971 IEM_MC_END(); \
3972 } \
3973 else \
3974 { \
3975 /* memory target */ \
3976 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
3977 { \
3978 IEM_MC_BEGIN(3, 3, 0, 0); \
3979 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
3980 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
3981 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
3982 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
3983 \
3984 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
3985 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
3986 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1); \
3987 IEMOP_HLP_DONE_DECODING(); \
3988 \
3989 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
3990 IEM_MC_FETCH_EFLAGS(EFlags); \
3991 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
3992 \
3993 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
3994 IEM_MC_COMMIT_EFLAGS(EFlags); \
3995 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
3996 IEM_MC_END(); \
3997 } \
3998 else \
3999 { \
4000 (void)0
4001
4002#define IEMOP_BODY_BINARY_Eb_Ib_LOCKED(a_fnLockedU8) \
4003 IEM_MC_BEGIN(3, 3, 0, 0); \
4004 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
4005 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4006 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4007 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4008 \
4009 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4010 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4011 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1); \
4012 IEMOP_HLP_DONE_DECODING(); \
4013 \
4014 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4015 IEM_MC_FETCH_EFLAGS(EFlags); \
4016 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU8, pu8Dst, u8Src, pEFlags); \
4017 \
4018 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4019 IEM_MC_COMMIT_EFLAGS(EFlags); \
4020 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4021 IEM_MC_END(); \
4022 } \
4023 } \
4024 (void)0
4025
4026#define IEMOP_BODY_BINARY_Eb_Ib_RO(a_fnNormalU8) \
4027 if (IEM_IS_MODRM_REG_MODE(bRm)) \
4028 { \
4029 /* register target */ \
4030 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4031 IEM_MC_BEGIN(3, 0, 0, 0); \
4032 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4033 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
4034 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1); \
4035 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4036 \
4037 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4038 IEM_MC_REF_EFLAGS(pEFlags); \
4039 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
4040 \
4041 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4042 IEM_MC_END(); \
4043 } \
4044 else \
4045 { \
4046 /* memory target */ \
4047 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
4048 { \
4049 IEM_MC_BEGIN(3, 3, 0, 0); \
4050 IEM_MC_ARG(uint8_t const *, pu8Dst, 0); \
4051 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4052 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4053 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4054 \
4055 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4056 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4057 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1); \
4058 IEMOP_HLP_DONE_DECODING(); \
4059 \
4060 IEM_MC_MEM_MAP_U8_RO(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4061 IEM_MC_FETCH_EFLAGS(EFlags); \
4062 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU8, pu8Dst, u8Src, pEFlags); \
4063 \
4064 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
4065 IEM_MC_COMMIT_EFLAGS(EFlags); \
4066 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4067 IEM_MC_END(); \
4068 } \
4069 else \
4070 { \
4071 (void)0
4072
4073#define IEMOP_BODY_BINARY_Eb_Ib_NO_LOCK() \
4074 IEMOP_HLP_DONE_DECODING(); \
4075 IEMOP_RAISE_INVALID_LOCK_PREFIX_RET(); \
4076 } \
4077 } \
4078 (void)0
4079
4080
4081
4082/**
4083 * @opmaps grp1_80,grp1_83
4084 * @opcode /0
4085 */
4086FNIEMOP_DEF_1(iemOp_Grp1_add_Eb_Ib, uint8_t, bRm)
4087{
4088 IEMOP_MNEMONIC(add_Eb_Ib, "add Eb,Ib");
4089 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_add_u8);
4090 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_add_u8_locked);
4091}
4092
4093
4094/**
4095 * @opmaps grp1_80,grp1_83
4096 * @opcode /1
4097 */
4098FNIEMOP_DEF_1(iemOp_Grp1_or_Eb_Ib, uint8_t, bRm)
4099{
4100 IEMOP_MNEMONIC(or_Eb_Ib, "or Eb,Ib");
4101 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_or_u8);
4102 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_or_u8_locked);
4103}
4104
4105
4106/**
4107 * @opmaps grp1_80,grp1_83
4108 * @opcode /2
4109 */
4110FNIEMOP_DEF_1(iemOp_Grp1_adc_Eb_Ib, uint8_t, bRm)
4111{
4112 IEMOP_MNEMONIC(adc_Eb_Ib, "adc Eb,Ib");
4113 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_adc_u8);
4114 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_adc_u8_locked);
4115}
4116
4117
4118/**
4119 * @opmaps grp1_80,grp1_83
4120 * @opcode /3
4121 */
4122FNIEMOP_DEF_1(iemOp_Grp1_sbb_Eb_Ib, uint8_t, bRm)
4123{
4124 IEMOP_MNEMONIC(sbb_Eb_Ib, "sbb Eb,Ib");
4125 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_sbb_u8);
4126 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_sbb_u8_locked);
4127}
4128
4129
4130/**
4131 * @opmaps grp1_80,grp1_83
4132 * @opcode /4
4133 */
4134FNIEMOP_DEF_1(iemOp_Grp1_and_Eb_Ib, uint8_t, bRm)
4135{
4136 IEMOP_MNEMONIC(and_Eb_Ib, "and Eb,Ib");
4137 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_and_u8);
4138 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_and_u8_locked);
4139}
4140
4141
4142/**
4143 * @opmaps grp1_80,grp1_83
4144 * @opcode /5
4145 */
4146FNIEMOP_DEF_1(iemOp_Grp1_sub_Eb_Ib, uint8_t, bRm)
4147{
4148 IEMOP_MNEMONIC(sub_Eb_Ib, "sub Eb,Ib");
4149 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_sub_u8);
4150 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_sub_u8_locked);
4151}
4152
4153
4154/**
4155 * @opmaps grp1_80,grp1_83
4156 * @opcode /6
4157 */
4158FNIEMOP_DEF_1(iemOp_Grp1_xor_Eb_Ib, uint8_t, bRm)
4159{
4160 IEMOP_MNEMONIC(xor_Eb_Ib, "xor Eb,Ib");
4161 IEMOP_BODY_BINARY_Eb_Ib_RW( iemAImpl_xor_u8);
4162 IEMOP_BODY_BINARY_Eb_Ib_LOCKED(iemAImpl_xor_u8_locked);
4163}
4164
4165
4166/**
4167 * @opmaps grp1_80,grp1_83
4168 * @opcode /7
4169 */
4170FNIEMOP_DEF_1(iemOp_Grp1_cmp_Eb_Ib, uint8_t, bRm)
4171{
4172 IEMOP_MNEMONIC(cmp_Eb_Ib, "cmp Eb,Ib");
4173 IEMOP_BODY_BINARY_Eb_Ib_RO(iemAImpl_cmp_u8);
4174 IEMOP_BODY_BINARY_Eb_Ib_NO_LOCK();
4175}
4176
4177
4178/**
4179 * @opcode 0x80
4180 */
4181FNIEMOP_DEF(iemOp_Grp1_Eb_Ib_80)
4182{
4183 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4184 switch (IEM_GET_MODRM_REG_8(bRm))
4185 {
4186 case 0: return FNIEMOP_CALL_1(iemOp_Grp1_add_Eb_Ib, bRm);
4187 case 1: return FNIEMOP_CALL_1(iemOp_Grp1_or_Eb_Ib, bRm);
4188 case 2: return FNIEMOP_CALL_1(iemOp_Grp1_adc_Eb_Ib, bRm);
4189 case 3: return FNIEMOP_CALL_1(iemOp_Grp1_sbb_Eb_Ib, bRm);
4190 case 4: return FNIEMOP_CALL_1(iemOp_Grp1_and_Eb_Ib, bRm);
4191 case 5: return FNIEMOP_CALL_1(iemOp_Grp1_sub_Eb_Ib, bRm);
4192 case 6: return FNIEMOP_CALL_1(iemOp_Grp1_xor_Eb_Ib, bRm);
4193 case 7: return FNIEMOP_CALL_1(iemOp_Grp1_cmp_Eb_Ib, bRm);
4194 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4195 }
4196}
4197
4198
4199/**
4200 * Body for a group 1 binary operator.
4201 */
4202#define IEMOP_BODY_BINARY_Ev_Iz_RW(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
4203 if (IEM_IS_MODRM_REG_MODE(bRm)) \
4204 { \
4205 /* register target */ \
4206 switch (pVCpu->iem.s.enmEffOpSize) \
4207 { \
4208 case IEMMODE_16BIT: \
4209 { \
4210 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); \
4211 IEM_MC_BEGIN(3, 0, 0, 0); \
4212 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4213 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4214 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ u16Imm, 1); \
4215 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4216 \
4217 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4218 IEM_MC_REF_EFLAGS(pEFlags); \
4219 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4220 \
4221 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4222 IEM_MC_END(); \
4223 break; \
4224 } \
4225 \
4226 case IEMMODE_32BIT: \
4227 { \
4228 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); \
4229 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
4230 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4231 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4232 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ u32Imm, 1); \
4233 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4234 \
4235 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4236 IEM_MC_REF_EFLAGS(pEFlags); \
4237 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4238 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm)); \
4239 \
4240 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4241 IEM_MC_END(); \
4242 break; \
4243 } \
4244 \
4245 case IEMMODE_64BIT: \
4246 { \
4247 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm); \
4248 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
4249 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4250 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4251 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ u64Imm, 1); \
4252 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4253 \
4254 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4255 IEM_MC_REF_EFLAGS(pEFlags); \
4256 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
4257 \
4258 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4259 IEM_MC_END(); \
4260 break; \
4261 } \
4262 \
4263 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4264 } \
4265 } \
4266 else \
4267 { \
4268 /* memory target */ \
4269 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
4270 { \
4271 switch (pVCpu->iem.s.enmEffOpSize) \
4272 { \
4273 case IEMMODE_16BIT: \
4274 { \
4275 IEM_MC_BEGIN(3, 3, 0, 0); \
4276 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4277 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2); \
4278 \
4279 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); \
4280 IEMOP_HLP_DONE_DECODING(); \
4281 \
4282 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4283 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4284 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4285 \
4286 IEM_MC_ARG_CONST(uint16_t, u16Src, u16Imm, 1); \
4287 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4288 IEM_MC_FETCH_EFLAGS(EFlags); \
4289 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4290 \
4291 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4292 IEM_MC_COMMIT_EFLAGS(EFlags); \
4293 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4294 IEM_MC_END(); \
4295 break; \
4296 } \
4297 \
4298 case IEMMODE_32BIT: \
4299 { \
4300 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
4301 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4302 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4); \
4303 \
4304 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); \
4305 IEMOP_HLP_DONE_DECODING(); \
4306 \
4307 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4308 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4309 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4310 \
4311 IEM_MC_ARG_CONST(uint32_t, u32Src, u32Imm, 1); \
4312 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4313 IEM_MC_FETCH_EFLAGS(EFlags); \
4314 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4315 \
4316 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4317 IEM_MC_COMMIT_EFLAGS(EFlags); \
4318 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4319 IEM_MC_END(); \
4320 break; \
4321 } \
4322 \
4323 case IEMMODE_64BIT: \
4324 { \
4325 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
4326 \
4327 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4328 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4); \
4329 \
4330 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm); \
4331 IEMOP_HLP_DONE_DECODING(); \
4332 \
4333 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4334 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4335 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4336 \
4337 IEM_MC_ARG_CONST(uint64_t, u64Src, u64Imm, 1); \
4338 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4339 IEM_MC_FETCH_EFLAGS(EFlags); \
4340 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
4341 \
4342 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4343 IEM_MC_COMMIT_EFLAGS(EFlags); \
4344 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4345 IEM_MC_END(); \
4346 break; \
4347 } \
4348 \
4349 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4350 } \
4351 } \
4352 else \
4353 { \
4354 (void)0
4355/* This must be a separate macro due to parsing restrictions in IEMAllInstPython.py. */
4356#define IEMOP_BODY_BINARY_Ev_Iz_LOCKED(a_fnLockedU16, a_fnLockedU32, a_fnLockedU64) \
4357 switch (pVCpu->iem.s.enmEffOpSize) \
4358 { \
4359 case IEMMODE_16BIT: \
4360 { \
4361 IEM_MC_BEGIN(3, 3, 0, 0); \
4362 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4363 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2); \
4364 \
4365 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); \
4366 IEMOP_HLP_DONE_DECODING(); \
4367 \
4368 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4369 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4370 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4371 \
4372 IEM_MC_ARG_CONST(uint16_t, u16Src, u16Imm, 1); \
4373 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4374 IEM_MC_FETCH_EFLAGS(EFlags); \
4375 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU16, pu16Dst, u16Src, pEFlags); \
4376 \
4377 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4378 IEM_MC_COMMIT_EFLAGS(EFlags); \
4379 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4380 IEM_MC_END(); \
4381 break; \
4382 } \
4383 \
4384 case IEMMODE_32BIT: \
4385 { \
4386 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
4387 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4388 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4); \
4389 \
4390 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); \
4391 IEMOP_HLP_DONE_DECODING(); \
4392 \
4393 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4394 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4395 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4396 \
4397 IEM_MC_ARG_CONST(uint32_t, u32Src, u32Imm, 1); \
4398 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4399 IEM_MC_FETCH_EFLAGS(EFlags); \
4400 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU32, pu32Dst, u32Src, pEFlags); \
4401 \
4402 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4403 IEM_MC_COMMIT_EFLAGS(EFlags); \
4404 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4405 IEM_MC_END(); \
4406 break; \
4407 } \
4408 \
4409 case IEMMODE_64BIT: \
4410 { \
4411 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
4412 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4413 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4); \
4414 \
4415 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm); \
4416 IEMOP_HLP_DONE_DECODING(); \
4417 \
4418 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4419 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4420 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4421 \
4422 IEM_MC_ARG_CONST(uint64_t, u64Src, u64Imm, 1); \
4423 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4424 IEM_MC_FETCH_EFLAGS(EFlags); \
4425 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU64, pu64Dst, u64Src, pEFlags); \
4426 \
4427 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4428 IEM_MC_COMMIT_EFLAGS(EFlags); \
4429 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4430 IEM_MC_END(); \
4431 break; \
4432 } \
4433 \
4434 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4435 } \
4436 } \
4437 } \
4438 (void)0
4439
4440/* read-only version */
4441#define IEMOP_BODY_BINARY_Ev_Iz_RO(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
4442 if (IEM_IS_MODRM_REG_MODE(bRm)) \
4443 { \
4444 /* register target */ \
4445 switch (pVCpu->iem.s.enmEffOpSize) \
4446 { \
4447 case IEMMODE_16BIT: \
4448 { \
4449 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); \
4450 IEM_MC_BEGIN(3, 0, 0, 0); \
4451 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4452 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4453 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ u16Imm, 1); \
4454 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4455 \
4456 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4457 IEM_MC_REF_EFLAGS(pEFlags); \
4458 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4459 \
4460 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4461 IEM_MC_END(); \
4462 break; \
4463 } \
4464 \
4465 case IEMMODE_32BIT: \
4466 { \
4467 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); \
4468 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
4469 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4470 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4471 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ u32Imm, 1); \
4472 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4473 \
4474 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4475 IEM_MC_REF_EFLAGS(pEFlags); \
4476 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4477 \
4478 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4479 IEM_MC_END(); \
4480 break; \
4481 } \
4482 \
4483 case IEMMODE_64BIT: \
4484 { \
4485 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm); \
4486 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
4487 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4488 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4489 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ u64Imm, 1); \
4490 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4491 \
4492 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4493 IEM_MC_REF_EFLAGS(pEFlags); \
4494 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
4495 \
4496 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4497 IEM_MC_END(); \
4498 break; \
4499 } \
4500 \
4501 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4502 } \
4503 } \
4504 else \
4505 { \
4506 /* memory target */ \
4507 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
4508 { \
4509 switch (pVCpu->iem.s.enmEffOpSize) \
4510 { \
4511 case IEMMODE_16BIT: \
4512 { \
4513 IEM_MC_BEGIN(3, 3, 0, 0); \
4514 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4515 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2); \
4516 \
4517 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); \
4518 IEMOP_HLP_DONE_DECODING(); \
4519 \
4520 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4521 IEM_MC_ARG(uint16_t const *, pu16Dst, 0); \
4522 IEM_MC_MEM_MAP_U16_RO(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4523 \
4524 IEM_MC_ARG_CONST(uint16_t, u16Src, u16Imm, 1); \
4525 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4526 IEM_MC_FETCH_EFLAGS(EFlags); \
4527 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4528 \
4529 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
4530 IEM_MC_COMMIT_EFLAGS(EFlags); \
4531 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4532 IEM_MC_END(); \
4533 break; \
4534 } \
4535 \
4536 case IEMMODE_32BIT: \
4537 { \
4538 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
4539 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4540 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4); \
4541 \
4542 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm); \
4543 IEMOP_HLP_DONE_DECODING(); \
4544 \
4545 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4546 IEM_MC_ARG(uint32_t const *, pu32Dst, 0); \
4547 IEM_MC_MEM_MAP_U32_RO(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4548 \
4549 IEM_MC_ARG_CONST(uint32_t, u32Src, u32Imm, 1); \
4550 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4551 IEM_MC_FETCH_EFLAGS(EFlags); \
4552 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4553 \
4554 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
4555 IEM_MC_COMMIT_EFLAGS(EFlags); \
4556 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4557 IEM_MC_END(); \
4558 break; \
4559 } \
4560 \
4561 case IEMMODE_64BIT: \
4562 { \
4563 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
4564 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4565 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4); \
4566 \
4567 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm); \
4568 IEMOP_HLP_DONE_DECODING(); \
4569 \
4570 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4571 IEM_MC_ARG(uint64_t const *, pu64Dst, 0); \
4572 IEM_MC_MEM_MAP_U64_RO(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4573 \
4574 IEM_MC_ARG_CONST(uint64_t, u64Src, u64Imm, 1); \
4575 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4576 IEM_MC_FETCH_EFLAGS(EFlags); \
4577 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
4578 \
4579 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
4580 IEM_MC_COMMIT_EFLAGS(EFlags); \
4581 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4582 IEM_MC_END(); \
4583 break; \
4584 } \
4585 \
4586 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4587 } \
4588 } \
4589 else \
4590 { \
4591 IEMOP_HLP_DONE_DECODING(); \
4592 IEMOP_RAISE_INVALID_LOCK_PREFIX_RET(); \
4593 } \
4594 } \
4595 (void)0
4596
4597
4598/**
4599 * @opmaps grp1_81
4600 * @opcode /0
4601 */
4602FNIEMOP_DEF_1(iemOp_Grp1_add_Ev_Iz, uint8_t, bRm)
4603{
4604 IEMOP_MNEMONIC(add_Ev_Iz, "add Ev,Iz");
4605 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_add_u16, iemAImpl_add_u32, iemAImpl_add_u64);
4606 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_add_u16_locked, iemAImpl_add_u32_locked, iemAImpl_add_u64_locked);
4607}
4608
4609
4610/**
4611 * @opmaps grp1_81
4612 * @opcode /1
4613 */
4614FNIEMOP_DEF_1(iemOp_Grp1_or_Ev_Iz, uint8_t, bRm)
4615{
4616 IEMOP_MNEMONIC(or_Ev_Iz, "or Ev,Iz");
4617 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_or_u16, iemAImpl_or_u32, iemAImpl_or_u64);
4618 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_or_u16_locked, iemAImpl_or_u32_locked, iemAImpl_or_u64_locked);
4619}
4620
4621
4622/**
4623 * @opmaps grp1_81
4624 * @opcode /2
4625 */
4626FNIEMOP_DEF_1(iemOp_Grp1_adc_Ev_Iz, uint8_t, bRm)
4627{
4628 IEMOP_MNEMONIC(adc_Ev_Iz, "adc Ev,Iz");
4629 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_adc_u16, iemAImpl_adc_u32, iemAImpl_adc_u64);
4630 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_adc_u16_locked, iemAImpl_adc_u32_locked, iemAImpl_adc_u64_locked);
4631}
4632
4633
4634/**
4635 * @opmaps grp1_81
4636 * @opcode /3
4637 */
4638FNIEMOP_DEF_1(iemOp_Grp1_sbb_Ev_Iz, uint8_t, bRm)
4639{
4640 IEMOP_MNEMONIC(sbb_Ev_Iz, "sbb Ev,Iz");
4641 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_sbb_u16, iemAImpl_sbb_u32, iemAImpl_sbb_u64);
4642 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_sbb_u16_locked, iemAImpl_sbb_u32_locked, iemAImpl_sbb_u64_locked);
4643}
4644
4645
4646/**
4647 * @opmaps grp1_81
4648 * @opcode /4
4649 */
4650FNIEMOP_DEF_1(iemOp_Grp1_and_Ev_Iz, uint8_t, bRm)
4651{
4652 IEMOP_MNEMONIC(and_Ev_Iz, "and Ev,Iz");
4653 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64);
4654 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_and_u16_locked, iemAImpl_and_u32_locked, iemAImpl_and_u64_locked);
4655}
4656
4657
4658/**
4659 * @opmaps grp1_81
4660 * @opcode /5
4661 */
4662FNIEMOP_DEF_1(iemOp_Grp1_sub_Ev_Iz, uint8_t, bRm)
4663{
4664 IEMOP_MNEMONIC(sub_Ev_Iz, "sub Ev,Iz");
4665 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64);
4666 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_sub_u16_locked, iemAImpl_sub_u32_locked, iemAImpl_sub_u64_locked);
4667}
4668
4669
4670/**
4671 * @opmaps grp1_81
4672 * @opcode /6
4673 */
4674FNIEMOP_DEF_1(iemOp_Grp1_xor_Ev_Iz, uint8_t, bRm)
4675{
4676 IEMOP_MNEMONIC(xor_Ev_Iz, "xor Ev,Iz");
4677 IEMOP_BODY_BINARY_Ev_Iz_RW( iemAImpl_xor_u16, iemAImpl_xor_u32, iemAImpl_xor_u64);
4678 IEMOP_BODY_BINARY_Ev_Iz_LOCKED(iemAImpl_xor_u16_locked, iemAImpl_xor_u32_locked, iemAImpl_xor_u64_locked);
4679}
4680
4681
4682/**
4683 * @opmaps grp1_81
4684 * @opcode /7
4685 */
4686FNIEMOP_DEF_1(iemOp_Grp1_cmp_Ev_Iz, uint8_t, bRm)
4687{
4688 IEMOP_MNEMONIC(cmp_Ev_Iz, "cmp Ev,Iz");
4689 IEMOP_BODY_BINARY_Ev_Iz_RO(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64);
4690}
4691
4692
4693/**
4694 * @opcode 0x81
4695 */
4696FNIEMOP_DEF(iemOp_Grp1_Ev_Iz)
4697{
4698 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4699 switch (IEM_GET_MODRM_REG_8(bRm))
4700 {
4701 case 0: return FNIEMOP_CALL_1(iemOp_Grp1_add_Ev_Iz, bRm);
4702 case 1: return FNIEMOP_CALL_1(iemOp_Grp1_or_Ev_Iz, bRm);
4703 case 2: return FNIEMOP_CALL_1(iemOp_Grp1_adc_Ev_Iz, bRm);
4704 case 3: return FNIEMOP_CALL_1(iemOp_Grp1_sbb_Ev_Iz, bRm);
4705 case 4: return FNIEMOP_CALL_1(iemOp_Grp1_and_Ev_Iz, bRm);
4706 case 5: return FNIEMOP_CALL_1(iemOp_Grp1_sub_Ev_Iz, bRm);
4707 case 6: return FNIEMOP_CALL_1(iemOp_Grp1_xor_Ev_Iz, bRm);
4708 case 7: return FNIEMOP_CALL_1(iemOp_Grp1_cmp_Ev_Iz, bRm);
4709 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4710 }
4711}
4712
4713
4714/**
4715 * @opcode 0x82
4716 * @opmnemonic grp1_82
4717 * @opgroup og_groups
4718 */
4719FNIEMOP_DEF(iemOp_Grp1_Eb_Ib_82)
4720{
4721 IEMOP_HLP_NO_64BIT(); /** @todo do we need to decode the whole instruction or is this ok? */
4722 return FNIEMOP_CALL(iemOp_Grp1_Eb_Ib_80);
4723}
4724
4725
4726/**
4727 * Body for group 1 instruction (binary) w/ byte imm operand, dispatched via
4728 * iemOp_Grp1_Ev_Ib.
4729 */
4730#define IEMOP_BODY_BINARY_Ev_Ib_RW(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
4731 if (IEM_IS_MODRM_REG_MODE(bRm)) \
4732 { \
4733 /* \
4734 * Register target \
4735 */ \
4736 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4737 switch (pVCpu->iem.s.enmEffOpSize) \
4738 { \
4739 case IEMMODE_16BIT: \
4740 IEM_MC_BEGIN(3, 0, 0, 0); \
4741 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4742 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4743 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ (int8_t)u8Imm,1); \
4744 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4745 \
4746 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4747 IEM_MC_REF_EFLAGS(pEFlags); \
4748 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4749 \
4750 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4751 IEM_MC_END(); \
4752 break; \
4753 \
4754 case IEMMODE_32BIT: \
4755 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
4756 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4757 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4758 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ (int8_t)u8Imm,1); \
4759 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4760 \
4761 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4762 IEM_MC_REF_EFLAGS(pEFlags); \
4763 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4764 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm)); \
4765 \
4766 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4767 IEM_MC_END(); \
4768 break; \
4769 \
4770 case IEMMODE_64BIT: \
4771 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
4772 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4773 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4774 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int8_t)u8Imm,1); \
4775 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4776 \
4777 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4778 IEM_MC_REF_EFLAGS(pEFlags); \
4779 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
4780 \
4781 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4782 IEM_MC_END(); \
4783 break; \
4784 \
4785 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4786 } \
4787 } \
4788 else \
4789 { \
4790 /* \
4791 * Memory target. \
4792 */ \
4793 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
4794 { \
4795 switch (pVCpu->iem.s.enmEffOpSize) \
4796 { \
4797 case IEMMODE_16BIT: \
4798 IEM_MC_BEGIN(3, 3, 0, 0); \
4799 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4800 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4801 \
4802 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4803 IEMOP_HLP_DONE_DECODING(); \
4804 \
4805 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4806 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4807 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4808 \
4809 IEM_MC_ARG_CONST(uint16_t, u16Src, (int16_t)(int8_t)u8Imm, 1); \
4810 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4811 IEM_MC_FETCH_EFLAGS(EFlags); \
4812 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4813 \
4814 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4815 IEM_MC_COMMIT_EFLAGS(EFlags); \
4816 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4817 IEM_MC_END(); \
4818 break; \
4819 \
4820 case IEMMODE_32BIT: \
4821 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
4822 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4823 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4824 \
4825 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4826 IEMOP_HLP_DONE_DECODING(); \
4827 \
4828 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4829 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4830 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4831 \
4832 IEM_MC_ARG_CONST(uint32_t, u32Src, (int32_t)(int8_t)u8Imm, 1); \
4833 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4834 IEM_MC_FETCH_EFLAGS(EFlags); \
4835 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4836 \
4837 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4838 IEM_MC_COMMIT_EFLAGS(EFlags); \
4839 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4840 IEM_MC_END(); \
4841 break; \
4842 \
4843 case IEMMODE_64BIT: \
4844 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
4845 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4846 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4847 \
4848 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4849 IEMOP_HLP_DONE_DECODING(); \
4850 \
4851 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4852 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4853 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4854 \
4855 IEM_MC_ARG_CONST(uint64_t, u64Src, (int64_t)(int8_t)u8Imm, 1); \
4856 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4857 IEM_MC_FETCH_EFLAGS(EFlags); \
4858 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
4859 \
4860 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4861 IEM_MC_COMMIT_EFLAGS(EFlags); \
4862 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4863 IEM_MC_END(); \
4864 break; \
4865 \
4866 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4867 } \
4868 } \
4869 else \
4870 { \
4871 (void)0
4872/* Separate macro to work around parsing issue in IEMAllInstPython.py */
4873#define IEMOP_BODY_BINARY_Ev_Ib_LOCKED(a_fnLockedU16, a_fnLockedU32, a_fnLockedU64) \
4874 switch (pVCpu->iem.s.enmEffOpSize) \
4875 { \
4876 case IEMMODE_16BIT: \
4877 IEM_MC_BEGIN(3, 3, 0, 0); \
4878 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4879 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4880 \
4881 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4882 IEMOP_HLP_DONE_DECODING(); \
4883 \
4884 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4885 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4886 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4887 \
4888 IEM_MC_ARG_CONST(uint16_t, u16Src, (int16_t)(int8_t)u8Imm, 1); \
4889 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4890 IEM_MC_FETCH_EFLAGS(EFlags); \
4891 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU16, pu16Dst, u16Src, pEFlags); \
4892 \
4893 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4894 IEM_MC_COMMIT_EFLAGS(EFlags); \
4895 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4896 IEM_MC_END(); \
4897 break; \
4898 \
4899 case IEMMODE_32BIT: \
4900 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
4901 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4902 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4903 \
4904 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4905 IEMOP_HLP_DONE_DECODING(); \
4906 \
4907 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4908 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4909 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4910 \
4911 IEM_MC_ARG_CONST(uint32_t, u32Src, (int32_t)(int8_t)u8Imm, 1); \
4912 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4913 IEM_MC_FETCH_EFLAGS(EFlags); \
4914 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU32, pu32Dst, u32Src, pEFlags); \
4915 \
4916 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4917 IEM_MC_COMMIT_EFLAGS(EFlags); \
4918 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4919 IEM_MC_END(); \
4920 break; \
4921 \
4922 case IEMMODE_64BIT: \
4923 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
4924 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
4925 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
4926 \
4927 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4928 IEMOP_HLP_DONE_DECODING(); \
4929 \
4930 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
4931 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4932 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
4933 \
4934 IEM_MC_ARG_CONST(uint64_t, u64Src, (int64_t)(int8_t)u8Imm, 1); \
4935 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
4936 IEM_MC_FETCH_EFLAGS(EFlags); \
4937 IEM_MC_CALL_VOID_AIMPL_3(a_fnLockedU64, pu64Dst, u64Src, pEFlags); \
4938 \
4939 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
4940 IEM_MC_COMMIT_EFLAGS(EFlags); \
4941 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4942 IEM_MC_END(); \
4943 break; \
4944 \
4945 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4946 } \
4947 } \
4948 } \
4949 (void)0
4950
4951/* read-only variant */
4952#define IEMOP_BODY_BINARY_Ev_Ib_RO(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
4953 if (IEM_IS_MODRM_REG_MODE(bRm)) \
4954 { \
4955 /* \
4956 * Register target \
4957 */ \
4958 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
4959 switch (pVCpu->iem.s.enmEffOpSize) \
4960 { \
4961 case IEMMODE_16BIT: \
4962 IEM_MC_BEGIN(3, 0, 0, 0); \
4963 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4964 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
4965 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ (int8_t)u8Imm,1); \
4966 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4967 \
4968 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4969 IEM_MC_REF_EFLAGS(pEFlags); \
4970 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
4971 \
4972 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4973 IEM_MC_END(); \
4974 break; \
4975 \
4976 case IEMMODE_32BIT: \
4977 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0); \
4978 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4979 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
4980 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ (int8_t)u8Imm,1); \
4981 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4982 \
4983 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4984 IEM_MC_REF_EFLAGS(pEFlags); \
4985 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
4986 \
4987 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
4988 IEM_MC_END(); \
4989 break; \
4990 \
4991 case IEMMODE_64BIT: \
4992 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0); \
4993 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4994 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
4995 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int8_t)u8Imm,1); \
4996 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
4997 \
4998 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
4999 IEM_MC_REF_EFLAGS(pEFlags); \
5000 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
5001 \
5002 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5003 IEM_MC_END(); \
5004 break; \
5005 \
5006 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
5007 } \
5008 } \
5009 else \
5010 { \
5011 /* \
5012 * Memory target. \
5013 */ \
5014 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
5015 { \
5016 switch (pVCpu->iem.s.enmEffOpSize) \
5017 { \
5018 case IEMMODE_16BIT: \
5019 IEM_MC_BEGIN(3, 3, 0, 0); \
5020 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5021 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
5022 \
5023 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
5024 IEMOP_HLP_DONE_DECODING(); \
5025 \
5026 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5027 IEM_MC_ARG(uint16_t const *, pu16Dst, 0); \
5028 IEM_MC_MEM_MAP_U16_RO(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5029 \
5030 IEM_MC_ARG_CONST(uint16_t, u16Src, (int16_t)(int8_t)u8Imm, 1); \
5031 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
5032 IEM_MC_FETCH_EFLAGS(EFlags); \
5033 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU16, pu16Dst, u16Src, pEFlags); \
5034 \
5035 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
5036 IEM_MC_COMMIT_EFLAGS(EFlags); \
5037 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5038 IEM_MC_END(); \
5039 break; \
5040 \
5041 case IEMMODE_32BIT: \
5042 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
5043 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5044 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
5045 \
5046 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
5047 IEMOP_HLP_DONE_DECODING(); \
5048 \
5049 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5050 IEM_MC_ARG(uint32_t const *, pu32Dst, 0); \
5051 IEM_MC_MEM_MAP_U32_RO(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5052 \
5053 IEM_MC_ARG_CONST(uint32_t, u32Src, (int32_t)(int8_t)u8Imm, 1); \
5054 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
5055 IEM_MC_FETCH_EFLAGS(EFlags); \
5056 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU32, pu32Dst, u32Src, pEFlags); \
5057 \
5058 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
5059 IEM_MC_COMMIT_EFLAGS(EFlags); \
5060 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5061 IEM_MC_END(); \
5062 break; \
5063 \
5064 case IEMMODE_64BIT: \
5065 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
5066 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5067 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1); \
5068 \
5069 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); \
5070 IEMOP_HLP_DONE_DECODING(); \
5071 \
5072 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5073 IEM_MC_ARG(uint64_t const *, pu64Dst, 0); \
5074 IEM_MC_MEM_MAP_U64_RO(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5075 \
5076 IEM_MC_ARG_CONST(uint64_t, u64Src, (int64_t)(int8_t)u8Imm, 1); \
5077 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2); \
5078 IEM_MC_FETCH_EFLAGS(EFlags); \
5079 IEM_MC_CALL_VOID_AIMPL_3(a_fnNormalU64, pu64Dst, u64Src, pEFlags); \
5080 \
5081 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo); \
5082 IEM_MC_COMMIT_EFLAGS(EFlags); \
5083 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5084 IEM_MC_END(); \
5085 break; \
5086 \
5087 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
5088 } \
5089 } \
5090 else \
5091 { \
5092 IEMOP_HLP_DONE_DECODING(); \
5093 IEMOP_RAISE_INVALID_LOCK_PREFIX_RET(); \
5094 } \
5095 } \
5096 (void)0
5097
5098/**
5099 * @opmaps grp1_83
5100 * @opcode /0
5101 */
5102FNIEMOP_DEF_1(iemOp_Grp1_add_Ev_Ib, uint8_t, bRm)
5103{
5104 IEMOP_MNEMONIC(add_Ev_Ib, "add Ev,Ib");
5105 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_add_u16, iemAImpl_add_u32, iemAImpl_add_u64);
5106 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_add_u16_locked, iemAImpl_add_u32_locked, iemAImpl_add_u64_locked);
5107}
5108
5109
5110/**
5111 * @opmaps grp1_83
5112 * @opcode /1
5113 */
5114FNIEMOP_DEF_1(iemOp_Grp1_or_Ev_Ib, uint8_t, bRm)
5115{
5116 IEMOP_MNEMONIC(or_Ev_Ib, "or Ev,Ib");
5117 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_or_u16, iemAImpl_or_u32, iemAImpl_or_u64);
5118 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_or_u16_locked, iemAImpl_or_u32_locked, iemAImpl_or_u64_locked);
5119}
5120
5121
5122/**
5123 * @opmaps grp1_83
5124 * @opcode /2
5125 */
5126FNIEMOP_DEF_1(iemOp_Grp1_adc_Ev_Ib, uint8_t, bRm)
5127{
5128 IEMOP_MNEMONIC(adc_Ev_Ib, "adc Ev,Ib");
5129 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_adc_u16, iemAImpl_adc_u32, iemAImpl_adc_u64);
5130 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_adc_u16_locked, iemAImpl_adc_u32_locked, iemAImpl_adc_u64_locked);
5131}
5132
5133
5134/**
5135 * @opmaps grp1_83
5136 * @opcode /3
5137 */
5138FNIEMOP_DEF_1(iemOp_Grp1_sbb_Ev_Ib, uint8_t, bRm)
5139{
5140 IEMOP_MNEMONIC(sbb_Ev_Ib, "sbb Ev,Ib");
5141 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_sbb_u16, iemAImpl_sbb_u32, iemAImpl_sbb_u64);
5142 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_sbb_u16_locked, iemAImpl_sbb_u32_locked, iemAImpl_sbb_u64_locked);
5143}
5144
5145
5146/**
5147 * @opmaps grp1_83
5148 * @opcode /4
5149 */
5150FNIEMOP_DEF_1(iemOp_Grp1_and_Ev_Ib, uint8_t, bRm)
5151{
5152 IEMOP_MNEMONIC(and_Ev_Ib, "and Ev,Ib");
5153 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64);
5154 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_and_u16_locked, iemAImpl_and_u32_locked, iemAImpl_and_u64_locked);
5155}
5156
5157
5158/**
5159 * @opmaps grp1_83
5160 * @opcode /5
5161 */
5162FNIEMOP_DEF_1(iemOp_Grp1_sub_Ev_Ib, uint8_t, bRm)
5163{
5164 IEMOP_MNEMONIC(sub_Ev_Ib, "sub Ev,Ib");
5165 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64);
5166 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_sub_u16_locked, iemAImpl_sub_u32_locked, iemAImpl_sub_u64_locked);
5167}
5168
5169
5170/**
5171 * @opmaps grp1_83
5172 * @opcode /6
5173 */
5174FNIEMOP_DEF_1(iemOp_Grp1_xor_Ev_Ib, uint8_t, bRm)
5175{
5176 IEMOP_MNEMONIC(xor_Ev_Ib, "xor Ev,Ib");
5177 IEMOP_BODY_BINARY_Ev_Ib_RW( iemAImpl_xor_u16, iemAImpl_xor_u32, iemAImpl_xor_u64);
5178 IEMOP_BODY_BINARY_Ev_Ib_LOCKED(iemAImpl_xor_u16_locked, iemAImpl_xor_u32_locked, iemAImpl_xor_u64_locked);
5179}
5180
5181
5182/**
5183 * @opmaps grp1_83
5184 * @opcode /7
5185 */
5186FNIEMOP_DEF_1(iemOp_Grp1_cmp_Ev_Ib, uint8_t, bRm)
5187{
5188 IEMOP_MNEMONIC(cmp_Ev_Ib, "cmp Ev,Ib");
5189 IEMOP_BODY_BINARY_Ev_Ib_RO(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64);
5190}
5191
5192
5193/**
5194 * @opcode 0x83
5195 */
5196FNIEMOP_DEF(iemOp_Grp1_Ev_Ib)
5197{
5198 /* Note! Seems the OR, AND, and XOR instructions are present on CPUs prior
5199 to the 386 even if absent in the intel reference manuals and some
5200 3rd party opcode listings. */
5201 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5202 switch (IEM_GET_MODRM_REG_8(bRm))
5203 {
5204 case 0: return FNIEMOP_CALL_1(iemOp_Grp1_add_Ev_Ib, bRm);
5205 case 1: return FNIEMOP_CALL_1(iemOp_Grp1_or_Ev_Ib, bRm);
5206 case 2: return FNIEMOP_CALL_1(iemOp_Grp1_adc_Ev_Ib, bRm);
5207 case 3: return FNIEMOP_CALL_1(iemOp_Grp1_sbb_Ev_Ib, bRm);
5208 case 4: return FNIEMOP_CALL_1(iemOp_Grp1_and_Ev_Ib, bRm);
5209 case 5: return FNIEMOP_CALL_1(iemOp_Grp1_sub_Ev_Ib, bRm);
5210 case 6: return FNIEMOP_CALL_1(iemOp_Grp1_xor_Ev_Ib, bRm);
5211 case 7: return FNIEMOP_CALL_1(iemOp_Grp1_cmp_Ev_Ib, bRm);
5212 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5213 }
5214}
5215
5216
5217/**
5218 * @opcode 0x84
5219 */
5220FNIEMOP_DEF(iemOp_test_Eb_Gb)
5221{
5222 IEMOP_MNEMONIC(test_Eb_Gb, "test Eb,Gb");
5223 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
5224 IEMOP_BODY_BINARY_rm_r8_RO(iemAImpl_test_u8);
5225 IEMOP_BODY_BINARY_rm_r8_NO_LOCK();
5226}
5227
5228
5229/**
5230 * @opcode 0x85
5231 */
5232FNIEMOP_DEF(iemOp_test_Ev_Gv)
5233{
5234 IEMOP_MNEMONIC(test_Ev_Gv, "test Ev,Gv");
5235 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
5236 IEMOP_BODY_BINARY_rm_rv_RO(iemAImpl_test_u16, iemAImpl_test_u32, iemAImpl_test_u64);
5237}
5238
5239
5240/**
5241 * @opcode 0x86
5242 */
5243FNIEMOP_DEF(iemOp_xchg_Eb_Gb)
5244{
5245 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5246 IEMOP_MNEMONIC(xchg_Eb_Gb, "xchg Eb,Gb");
5247
5248 /*
5249 * If rm is denoting a register, no more instruction bytes.
5250 */
5251 if (IEM_IS_MODRM_REG_MODE(bRm))
5252 {
5253 IEM_MC_BEGIN(0, 2, 0, 0);
5254 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5255 IEM_MC_LOCAL(uint8_t, uTmp1);
5256 IEM_MC_LOCAL(uint8_t, uTmp2);
5257
5258 IEM_MC_FETCH_GREG_U8(uTmp1, IEM_GET_MODRM_REG(pVCpu, bRm));
5259 IEM_MC_FETCH_GREG_U8(uTmp2, IEM_GET_MODRM_RM(pVCpu, bRm));
5260 IEM_MC_STORE_GREG_U8(IEM_GET_MODRM_RM(pVCpu, bRm), uTmp1);
5261 IEM_MC_STORE_GREG_U8(IEM_GET_MODRM_REG(pVCpu, bRm), uTmp2);
5262
5263 IEM_MC_ADVANCE_RIP_AND_FINISH();
5264 IEM_MC_END();
5265 }
5266 else
5267 {
5268 /*
5269 * We're accessing memory.
5270 */
5271#define IEMOP_XCHG_BYTE(a_fnWorker) \
5272 IEM_MC_BEGIN(2, 4, 0, 0); \
5273 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5274 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5275 IEM_MC_LOCAL(uint8_t, uTmpReg); \
5276 IEM_MC_ARG(uint8_t *, pu8Mem, 0); \
5277 IEM_MC_ARG_LOCAL_REF(uint8_t *, pu8Reg, uTmpReg, 1); \
5278 \
5279 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
5280 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
5281 IEM_MC_MEM_MAP_U8_RW(pu8Mem, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5282 IEM_MC_FETCH_GREG_U8(uTmpReg, IEM_GET_MODRM_REG(pVCpu, bRm)); \
5283 IEM_MC_CALL_VOID_AIMPL_2(a_fnWorker, pu8Mem, pu8Reg); \
5284 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
5285 IEM_MC_STORE_GREG_U8(IEM_GET_MODRM_REG(pVCpu, bRm), uTmpReg); \
5286 \
5287 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5288 IEM_MC_END()
5289
5290 if (!(pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK))
5291 {
5292 IEMOP_XCHG_BYTE(iemAImpl_xchg_u8_locked);
5293 }
5294 else
5295 {
5296 IEMOP_XCHG_BYTE(iemAImpl_xchg_u8_unlocked);
5297 }
5298 }
5299}
5300
5301
5302/**
5303 * @opcode 0x87
5304 */
5305FNIEMOP_DEF(iemOp_xchg_Ev_Gv)
5306{
5307 IEMOP_MNEMONIC(xchg_Ev_Gv, "xchg Ev,Gv");
5308 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5309
5310 /*
5311 * If rm is denoting a register, no more instruction bytes.
5312 */
5313 if (IEM_IS_MODRM_REG_MODE(bRm))
5314 {
5315 switch (pVCpu->iem.s.enmEffOpSize)
5316 {
5317 case IEMMODE_16BIT:
5318 IEM_MC_BEGIN(0, 2, 0, 0);
5319 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5320 IEM_MC_LOCAL(uint16_t, uTmp1);
5321 IEM_MC_LOCAL(uint16_t, uTmp2);
5322
5323 IEM_MC_FETCH_GREG_U16(uTmp1, IEM_GET_MODRM_REG(pVCpu, bRm));
5324 IEM_MC_FETCH_GREG_U16(uTmp2, IEM_GET_MODRM_RM(pVCpu, bRm));
5325 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_RM(pVCpu, bRm), uTmp1);
5326 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), uTmp2);
5327
5328 IEM_MC_ADVANCE_RIP_AND_FINISH();
5329 IEM_MC_END();
5330 break;
5331
5332 case IEMMODE_32BIT:
5333 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
5334 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5335 IEM_MC_LOCAL(uint32_t, uTmp1);
5336 IEM_MC_LOCAL(uint32_t, uTmp2);
5337
5338 IEM_MC_FETCH_GREG_U32(uTmp1, IEM_GET_MODRM_REG(pVCpu, bRm));
5339 IEM_MC_FETCH_GREG_U32(uTmp2, IEM_GET_MODRM_RM(pVCpu, bRm));
5340 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_RM(pVCpu, bRm), uTmp1);
5341 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), uTmp2);
5342
5343 IEM_MC_ADVANCE_RIP_AND_FINISH();
5344 IEM_MC_END();
5345 break;
5346
5347 case IEMMODE_64BIT:
5348 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
5349 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5350 IEM_MC_LOCAL(uint64_t, uTmp1);
5351 IEM_MC_LOCAL(uint64_t, uTmp2);
5352
5353 IEM_MC_FETCH_GREG_U64(uTmp1, IEM_GET_MODRM_REG(pVCpu, bRm));
5354 IEM_MC_FETCH_GREG_U64(uTmp2, IEM_GET_MODRM_RM(pVCpu, bRm));
5355 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm), uTmp1);
5356 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), uTmp2);
5357
5358 IEM_MC_ADVANCE_RIP_AND_FINISH();
5359 IEM_MC_END();
5360 break;
5361
5362 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5363 }
5364 }
5365 else
5366 {
5367 /*
5368 * We're accessing memory.
5369 */
5370#define IEMOP_XCHG_EV_GV(a_fnWorker16, a_fnWorker32, a_fnWorker64) \
5371 do { \
5372 switch (pVCpu->iem.s.enmEffOpSize) \
5373 { \
5374 case IEMMODE_16BIT: \
5375 IEM_MC_BEGIN(2, 4, 0, 0); \
5376 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5377 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5378 IEM_MC_LOCAL(uint16_t, uTmpReg); \
5379 IEM_MC_ARG(uint16_t *, pu16Mem, 0); \
5380 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Reg, uTmpReg, 1); \
5381 \
5382 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
5383 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
5384 IEM_MC_MEM_MAP_U16_RW(pu16Mem, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5385 IEM_MC_FETCH_GREG_U16(uTmpReg, IEM_GET_MODRM_REG(pVCpu, bRm)); \
5386 IEM_MC_CALL_VOID_AIMPL_2(a_fnWorker16, pu16Mem, pu16Reg); \
5387 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
5388 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), uTmpReg); \
5389 \
5390 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5391 IEM_MC_END(); \
5392 break; \
5393 \
5394 case IEMMODE_32BIT: \
5395 IEM_MC_BEGIN(2, 4, IEM_MC_F_MIN_386, 0); \
5396 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5397 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5398 IEM_MC_LOCAL(uint32_t, uTmpReg); \
5399 IEM_MC_ARG(uint32_t *, pu32Mem, 0); \
5400 IEM_MC_ARG_LOCAL_REF(uint32_t *, pu32Reg, uTmpReg, 1); \
5401 \
5402 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
5403 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
5404 IEM_MC_MEM_MAP_U32_RW(pu32Mem, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5405 IEM_MC_FETCH_GREG_U32(uTmpReg, IEM_GET_MODRM_REG(pVCpu, bRm)); \
5406 IEM_MC_CALL_VOID_AIMPL_2(a_fnWorker32, pu32Mem, pu32Reg); \
5407 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
5408 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), uTmpReg); \
5409 \
5410 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5411 IEM_MC_END(); \
5412 break; \
5413 \
5414 case IEMMODE_64BIT: \
5415 IEM_MC_BEGIN(2, 4, IEM_MC_F_64BIT, 0); \
5416 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5417 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
5418 IEM_MC_LOCAL(uint64_t, uTmpReg); \
5419 IEM_MC_ARG(uint64_t *, pu64Mem, 0); \
5420 IEM_MC_ARG_LOCAL_REF(uint64_t *, pu64Reg, uTmpReg, 1); \
5421 \
5422 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
5423 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
5424 IEM_MC_MEM_MAP_U64_RW(pu64Mem, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5425 IEM_MC_FETCH_GREG_U64(uTmpReg, IEM_GET_MODRM_REG(pVCpu, bRm)); \
5426 IEM_MC_CALL_VOID_AIMPL_2(a_fnWorker64, pu64Mem, pu64Reg); \
5427 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
5428 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), uTmpReg); \
5429 \
5430 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
5431 IEM_MC_END(); \
5432 break; \
5433 \
5434 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
5435 } \
5436 } while (0)
5437 if (!(pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK))
5438 {
5439 IEMOP_XCHG_EV_GV(iemAImpl_xchg_u16_locked, iemAImpl_xchg_u32_locked, iemAImpl_xchg_u64_locked);
5440 }
5441 else
5442 {
5443 IEMOP_XCHG_EV_GV(iemAImpl_xchg_u16_unlocked, iemAImpl_xchg_u32_unlocked, iemAImpl_xchg_u64_unlocked);
5444 }
5445 }
5446}
5447
5448
5449/**
5450 * @opcode 0x88
5451 */
5452FNIEMOP_DEF(iemOp_mov_Eb_Gb)
5453{
5454 IEMOP_MNEMONIC(mov_Eb_Gb, "mov Eb,Gb");
5455
5456 uint8_t bRm;
5457 IEM_OPCODE_GET_NEXT_U8(&bRm);
5458
5459 /*
5460 * If rm is denoting a register, no more instruction bytes.
5461 */
5462 if (IEM_IS_MODRM_REG_MODE(bRm))
5463 {
5464 IEM_MC_BEGIN(0, 1, 0, 0);
5465 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5466 IEM_MC_LOCAL(uint8_t, u8Value);
5467 IEM_MC_FETCH_GREG_U8(u8Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5468 IEM_MC_STORE_GREG_U8(IEM_GET_MODRM_RM(pVCpu, bRm), u8Value);
5469 IEM_MC_ADVANCE_RIP_AND_FINISH();
5470 IEM_MC_END();
5471 }
5472 else
5473 {
5474 /*
5475 * We're writing a register to memory.
5476 */
5477 IEM_MC_BEGIN(0, 2, 0, 0);
5478 IEM_MC_LOCAL(uint8_t, u8Value);
5479 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5480 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5481 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5482 IEM_MC_FETCH_GREG_U8(u8Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5483 IEM_MC_STORE_MEM_U8(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u8Value);
5484 IEM_MC_ADVANCE_RIP_AND_FINISH();
5485 IEM_MC_END();
5486 }
5487}
5488
5489
5490/**
5491 * @opcode 0x89
5492 */
5493FNIEMOP_DEF(iemOp_mov_Ev_Gv)
5494{
5495 IEMOP_MNEMONIC(mov_Ev_Gv, "mov Ev,Gv");
5496
5497 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5498
5499 /*
5500 * If rm is denoting a register, no more instruction bytes.
5501 */
5502 if (IEM_IS_MODRM_REG_MODE(bRm))
5503 {
5504 switch (pVCpu->iem.s.enmEffOpSize)
5505 {
5506 case IEMMODE_16BIT:
5507 IEM_MC_BEGIN(0, 1, 0, 0);
5508 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5509 IEM_MC_LOCAL(uint16_t, u16Value);
5510 IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5511 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_RM(pVCpu, bRm), u16Value);
5512 IEM_MC_ADVANCE_RIP_AND_FINISH();
5513 IEM_MC_END();
5514 break;
5515
5516 case IEMMODE_32BIT:
5517 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
5518 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5519 IEM_MC_LOCAL(uint32_t, u32Value);
5520 IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5521 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_RM(pVCpu, bRm), u32Value);
5522 IEM_MC_ADVANCE_RIP_AND_FINISH();
5523 IEM_MC_END();
5524 break;
5525
5526 case IEMMODE_64BIT:
5527 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
5528 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5529 IEM_MC_LOCAL(uint64_t, u64Value);
5530 IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5531 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm), u64Value);
5532 IEM_MC_ADVANCE_RIP_AND_FINISH();
5533 IEM_MC_END();
5534 break;
5535
5536 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5537 }
5538 }
5539 else
5540 {
5541 /*
5542 * We're writing a register to memory.
5543 */
5544 switch (pVCpu->iem.s.enmEffOpSize)
5545 {
5546 case IEMMODE_16BIT:
5547 IEM_MC_BEGIN(0, 2, 0, 0);
5548 IEM_MC_LOCAL(uint16_t, u16Value);
5549 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5550 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5551 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5552 IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5553 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Value);
5554 IEM_MC_ADVANCE_RIP_AND_FINISH();
5555 IEM_MC_END();
5556 break;
5557
5558 case IEMMODE_32BIT:
5559 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
5560 IEM_MC_LOCAL(uint32_t, u32Value);
5561 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5562 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5563 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5564 IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5565 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u32Value);
5566 IEM_MC_ADVANCE_RIP_AND_FINISH();
5567 IEM_MC_END();
5568 break;
5569
5570 case IEMMODE_64BIT:
5571 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
5572 IEM_MC_LOCAL(uint64_t, u64Value);
5573 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5574 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5575 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5576 IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_REG(pVCpu, bRm));
5577 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u64Value);
5578 IEM_MC_ADVANCE_RIP_AND_FINISH();
5579 IEM_MC_END();
5580 break;
5581
5582 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5583 }
5584 }
5585}
5586
5587
5588/**
5589 * @opcode 0x8a
5590 */
5591FNIEMOP_DEF(iemOp_mov_Gb_Eb)
5592{
5593 IEMOP_MNEMONIC(mov_Gb_Eb, "mov Gb,Eb");
5594
5595 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5596
5597 /*
5598 * If rm is denoting a register, no more instruction bytes.
5599 */
5600 if (IEM_IS_MODRM_REG_MODE(bRm))
5601 {
5602 IEM_MC_BEGIN(0, 1, 0, 0);
5603 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5604 IEM_MC_LOCAL(uint8_t, u8Value);
5605 IEM_MC_FETCH_GREG_U8(u8Value, IEM_GET_MODRM_RM(pVCpu, bRm));
5606 IEM_MC_STORE_GREG_U8(IEM_GET_MODRM_REG(pVCpu, bRm), u8Value);
5607 IEM_MC_ADVANCE_RIP_AND_FINISH();
5608 IEM_MC_END();
5609 }
5610 else
5611 {
5612 /*
5613 * We're loading a register from memory.
5614 */
5615 IEM_MC_BEGIN(0, 2, 0, 0);
5616 IEM_MC_LOCAL(uint8_t, u8Value);
5617 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5618 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5619 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5620 IEM_MC_FETCH_MEM_U8(u8Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
5621 IEM_MC_STORE_GREG_U8(IEM_GET_MODRM_REG(pVCpu, bRm), u8Value);
5622 IEM_MC_ADVANCE_RIP_AND_FINISH();
5623 IEM_MC_END();
5624 }
5625}
5626
5627
5628/**
5629 * @opcode 0x8b
5630 */
5631FNIEMOP_DEF(iemOp_mov_Gv_Ev)
5632{
5633 IEMOP_MNEMONIC(mov_Gv_Ev, "mov Gv,Ev");
5634
5635 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5636
5637 /*
5638 * If rm is denoting a register, no more instruction bytes.
5639 */
5640 if (IEM_IS_MODRM_REG_MODE(bRm))
5641 {
5642 switch (pVCpu->iem.s.enmEffOpSize)
5643 {
5644 case IEMMODE_16BIT:
5645 IEM_MC_BEGIN(0, 1, 0, 0);
5646 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5647 IEM_MC_LOCAL(uint16_t, u16Value);
5648 IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_RM(pVCpu, bRm));
5649 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Value);
5650 IEM_MC_ADVANCE_RIP_AND_FINISH();
5651 IEM_MC_END();
5652 break;
5653
5654 case IEMMODE_32BIT:
5655 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
5656 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5657 IEM_MC_LOCAL(uint32_t, u32Value);
5658 IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_RM(pVCpu, bRm));
5659 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Value);
5660 IEM_MC_ADVANCE_RIP_AND_FINISH();
5661 IEM_MC_END();
5662 break;
5663
5664 case IEMMODE_64BIT:
5665 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
5666 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5667 IEM_MC_LOCAL(uint64_t, u64Value);
5668 IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_RM(pVCpu, bRm));
5669 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Value);
5670 IEM_MC_ADVANCE_RIP_AND_FINISH();
5671 IEM_MC_END();
5672 break;
5673
5674 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5675 }
5676 }
5677 else
5678 {
5679 /*
5680 * We're loading a register from memory.
5681 */
5682 switch (pVCpu->iem.s.enmEffOpSize)
5683 {
5684 case IEMMODE_16BIT:
5685 IEM_MC_BEGIN(0, 2, 0, 0);
5686 IEM_MC_LOCAL(uint16_t, u16Value);
5687 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5688 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5689 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5690 IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
5691 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Value);
5692 IEM_MC_ADVANCE_RIP_AND_FINISH();
5693 IEM_MC_END();
5694 break;
5695
5696 case IEMMODE_32BIT:
5697 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
5698 IEM_MC_LOCAL(uint32_t, u32Value);
5699 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5700 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5701 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5702 IEM_MC_FETCH_MEM_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
5703 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Value);
5704 IEM_MC_ADVANCE_RIP_AND_FINISH();
5705 IEM_MC_END();
5706 break;
5707
5708 case IEMMODE_64BIT:
5709 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
5710 IEM_MC_LOCAL(uint64_t, u64Value);
5711 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5712 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5713 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5714 IEM_MC_FETCH_MEM_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
5715 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), u64Value);
5716 IEM_MC_ADVANCE_RIP_AND_FINISH();
5717 IEM_MC_END();
5718 break;
5719
5720 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5721 }
5722 }
5723}
5724
5725
5726/**
5727 * opcode 0x63
5728 * @todo Table fixme
5729 */
5730FNIEMOP_DEF(iemOp_arpl_Ew_Gw_movsx_Gv_Ev)
5731{
5732 if (!IEM_IS_64BIT_CODE(pVCpu))
5733 return FNIEMOP_CALL(iemOp_arpl_Ew_Gw);
5734 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT)
5735 return FNIEMOP_CALL(iemOp_mov_Gv_Ev);
5736 return FNIEMOP_CALL(iemOp_movsxd_Gv_Ev);
5737}
5738
5739
5740/**
5741 * @opcode 0x8c
5742 */
5743FNIEMOP_DEF(iemOp_mov_Ev_Sw)
5744{
5745 IEMOP_MNEMONIC(mov_Ev_Sw, "mov Ev,Sw");
5746
5747 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5748
5749 /*
5750 * Check that the destination register exists. The REX.R prefix is ignored.
5751 */
5752 uint8_t const iSegReg = IEM_GET_MODRM_REG_8(bRm);
5753 if (iSegReg > X86_SREG_GS)
5754 IEMOP_RAISE_INVALID_OPCODE_RET(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
5755
5756 /*
5757 * If rm is denoting a register, no more instruction bytes.
5758 * In that case, the operand size is respected and the upper bits are
5759 * cleared (starting with some pentium).
5760 */
5761 if (IEM_IS_MODRM_REG_MODE(bRm))
5762 {
5763 switch (pVCpu->iem.s.enmEffOpSize)
5764 {
5765 case IEMMODE_16BIT:
5766 IEM_MC_BEGIN(0, 1, 0, 0);
5767 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5768 IEM_MC_LOCAL(uint16_t, u16Value);
5769 IEM_MC_FETCH_SREG_U16(u16Value, iSegReg);
5770 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_RM(pVCpu, bRm), u16Value);
5771 IEM_MC_ADVANCE_RIP_AND_FINISH();
5772 IEM_MC_END();
5773 break;
5774
5775 case IEMMODE_32BIT:
5776 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
5777 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5778 IEM_MC_LOCAL(uint32_t, u32Value);
5779 IEM_MC_FETCH_SREG_ZX_U32(u32Value, iSegReg);
5780 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_RM(pVCpu, bRm), u32Value);
5781 IEM_MC_ADVANCE_RIP_AND_FINISH();
5782 IEM_MC_END();
5783 break;
5784
5785 case IEMMODE_64BIT:
5786 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
5787 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5788 IEM_MC_LOCAL(uint64_t, u64Value);
5789 IEM_MC_FETCH_SREG_ZX_U64(u64Value, iSegReg);
5790 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm), u64Value);
5791 IEM_MC_ADVANCE_RIP_AND_FINISH();
5792 IEM_MC_END();
5793 break;
5794
5795 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5796 }
5797 }
5798 else
5799 {
5800 /*
5801 * We're saving the register to memory. The access is word sized
5802 * regardless of operand size prefixes.
5803 */
5804#if 0 /* not necessary */
5805 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_16BIT;
5806#endif
5807 IEM_MC_BEGIN(0, 2, 0, 0);
5808 IEM_MC_LOCAL(uint16_t, u16Value);
5809 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5810 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5811 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5812 IEM_MC_FETCH_SREG_U16(u16Value, iSegReg);
5813 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Value);
5814 IEM_MC_ADVANCE_RIP_AND_FINISH();
5815 IEM_MC_END();
5816 }
5817}
5818
5819
5820
5821
5822/**
5823 * @opcode 0x8d
5824 */
5825FNIEMOP_DEF(iemOp_lea_Gv_M)
5826{
5827 IEMOP_MNEMONIC(lea_Gv_M, "lea Gv,M");
5828 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5829 if (IEM_IS_MODRM_REG_MODE(bRm))
5830 IEMOP_RAISE_INVALID_OPCODE_RET(); /* no register form */
5831
5832 switch (pVCpu->iem.s.enmEffOpSize)
5833 {
5834 case IEMMODE_16BIT:
5835 IEM_MC_BEGIN(0, 2, 0, 0);
5836 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
5837 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
5838 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5839 /** @todo optimize: This value casting/masking can be skipped if addr-size ==
5840 * operand-size, which is usually the case. It'll save an instruction
5841 * and a register. */
5842 IEM_MC_LOCAL(uint16_t, u16Cast);
5843 IEM_MC_ASSIGN_TO_SMALLER(u16Cast, GCPtrEffSrc);
5844 IEM_MC_STORE_GREG_U16(IEM_GET_MODRM_REG(pVCpu, bRm), u16Cast);
5845 IEM_MC_ADVANCE_RIP_AND_FINISH();
5846 IEM_MC_END();
5847 break;
5848
5849 case IEMMODE_32BIT:
5850 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
5851 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
5852 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
5853 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5854 /** @todo optimize: This value casting/masking can be skipped if addr-size ==
5855 * operand-size, which is usually the case. It'll save an instruction
5856 * and a register. */
5857 IEM_MC_LOCAL(uint32_t, u32Cast);
5858 IEM_MC_ASSIGN_TO_SMALLER(u32Cast, GCPtrEffSrc);
5859 IEM_MC_STORE_GREG_U32(IEM_GET_MODRM_REG(pVCpu, bRm), u32Cast);
5860 IEM_MC_ADVANCE_RIP_AND_FINISH();
5861 IEM_MC_END();
5862 break;
5863
5864 case IEMMODE_64BIT:
5865 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
5866 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
5867 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
5868 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5869 IEM_MC_STORE_GREG_U64(IEM_GET_MODRM_REG(pVCpu, bRm), GCPtrEffSrc);
5870 IEM_MC_ADVANCE_RIP_AND_FINISH();
5871 IEM_MC_END();
5872 break;
5873
5874 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5875 }
5876}
5877
5878
5879/**
5880 * @opcode 0x8e
5881 */
5882FNIEMOP_DEF(iemOp_mov_Sw_Ev)
5883{
5884 IEMOP_MNEMONIC(mov_Sw_Ev, "mov Sw,Ev");
5885
5886 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5887
5888 /*
5889 * The practical operand size is 16-bit.
5890 */
5891#if 0 /* not necessary */
5892 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_16BIT;
5893#endif
5894
5895 /*
5896 * Check that the destination register exists and can be used with this
5897 * instruction. The REX.R prefix is ignored.
5898 */
5899 uint8_t const iSegReg = IEM_GET_MODRM_REG_8(bRm);
5900 /** @todo r=bird: What does 8086 do here wrt CS? */
5901 if ( iSegReg == X86_SREG_CS
5902 || iSegReg > X86_SREG_GS)
5903 IEMOP_RAISE_INVALID_OPCODE_RET(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
5904
5905 /*
5906 * If rm is denoting a register, no more instruction bytes.
5907 *
5908 * Note! Using IEMOP_MOV_SW_EV_REG_BODY here to specify different
5909 * IEM_CIMPL_F_XXX values depending on the CPU mode and target
5910 * register. This is a restriction of the current recompiler
5911 * approach.
5912 */
5913 if (IEM_IS_MODRM_REG_MODE(bRm))
5914 {
5915#define IEMOP_MOV_SW_EV_REG_BODY(a_fCImplFlags) \
5916 IEM_MC_BEGIN(2, 0, 0, a_fCImplFlags); \
5917 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
5918 IEM_MC_ARG_CONST(uint8_t, iSRegArg, iSegReg, 0); \
5919 IEM_MC_ARG(uint16_t, u16Value, 1); \
5920 IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
5921 IEM_MC_CALL_CIMPL_2(a_fCImplFlags, \
5922 RT_BIT_64(kIemNativeGstReg_SegSelFirst + iSegReg) \
5923 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + iSegReg) \
5924 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + iSegReg), \
5925 iemCImpl_load_SReg, iSRegArg, u16Value); \
5926 IEM_MC_END()
5927
5928 if (iSegReg == X86_SREG_SS)
5929 {
5930 if (IEM_IS_32BIT_CODE(pVCpu))
5931 {
5932 IEMOP_MOV_SW_EV_REG_BODY(IEM_CIMPL_F_INHIBIT_SHADOW | IEM_CIMPL_F_MODE);
5933 }
5934 else
5935 {
5936 IEMOP_MOV_SW_EV_REG_BODY(IEM_CIMPL_F_INHIBIT_SHADOW);
5937 }
5938 }
5939 else if (iSegReg >= X86_SREG_FS || !IEM_IS_32BIT_CODE(pVCpu))
5940 {
5941 IEMOP_MOV_SW_EV_REG_BODY(0);
5942 }
5943 else
5944 {
5945 IEMOP_MOV_SW_EV_REG_BODY(IEM_CIMPL_F_MODE);
5946 }
5947#undef IEMOP_MOV_SW_EV_REG_BODY
5948 }
5949 else
5950 {
5951 /*
5952 * We're loading the register from memory. The access is word sized
5953 * regardless of operand size prefixes.
5954 */
5955#define IEMOP_MOV_SW_EV_MEM_BODY(a_fCImplFlags) \
5956 IEM_MC_BEGIN(2, 1, 0, a_fCImplFlags); \
5957 IEM_MC_ARG_CONST(uint8_t, iSRegArg, iSegReg, 0); \
5958 IEM_MC_ARG(uint16_t, u16Value, 1); \
5959 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
5960 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
5961 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
5962 IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
5963 IEM_MC_CALL_CIMPL_2(a_fCImplFlags, \
5964 RT_BIT_64(kIemNativeGstReg_SegSelFirst + iSegReg) \
5965 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + iSegReg) \
5966 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + iSegReg), \
5967 iemCImpl_load_SReg, iSRegArg, u16Value); \
5968 IEM_MC_END()
5969
5970 if (iSegReg == X86_SREG_SS)
5971 {
5972 if (IEM_IS_32BIT_CODE(pVCpu))
5973 {
5974 IEMOP_MOV_SW_EV_MEM_BODY(IEM_CIMPL_F_INHIBIT_SHADOW | IEM_CIMPL_F_MODE);
5975 }
5976 else
5977 {
5978 IEMOP_MOV_SW_EV_MEM_BODY(IEM_CIMPL_F_INHIBIT_SHADOW);
5979 }
5980 }
5981 else if (iSegReg >= X86_SREG_FS || !IEM_IS_32BIT_CODE(pVCpu))
5982 {
5983 IEMOP_MOV_SW_EV_MEM_BODY(0);
5984 }
5985 else
5986 {
5987 IEMOP_MOV_SW_EV_MEM_BODY(IEM_CIMPL_F_MODE);
5988 }
5989#undef IEMOP_MOV_SW_EV_MEM_BODY
5990 }
5991}
5992
5993
5994/** Opcode 0x8f /0. */
5995FNIEMOP_DEF_1(iemOp_pop_Ev, uint8_t, bRm)
5996{
5997 /* This bugger is rather annoying as it requires rSP to be updated before
5998 doing the effective address calculations. Will eventually require a
5999 split between the R/M+SIB decoding and the effective address
6000 calculation - which is something that is required for any attempt at
6001 reusing this code for a recompiler. It may also be good to have if we
6002 need to delay #UD exception caused by invalid lock prefixes.
6003
6004 For now, we'll do a mostly safe interpreter-only implementation here. */
6005 /** @todo What's the deal with the 'reg' field and pop Ev? Ignorning it for
6006 * now until tests show it's checked.. */
6007 IEMOP_MNEMONIC(pop_Ev, "pop Ev");
6008
6009 /* Register access is relatively easy and can share code. */
6010 if (IEM_IS_MODRM_REG_MODE(bRm))
6011 return FNIEMOP_CALL_1(iemOpCommonPopGReg, IEM_GET_MODRM_RM(pVCpu, bRm));
6012
6013 /*
6014 * Memory target.
6015 *
6016 * Intel says that RSP is incremented before it's used in any effective
6017 * address calcuations. This means some serious extra annoyance here since
6018 * we decode and calculate the effective address in one step and like to
6019 * delay committing registers till everything is done.
6020 *
6021 * So, we'll decode and calculate the effective address twice. This will
6022 * require some recoding if turned into a recompiler.
6023 */
6024 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE(); /* The common code does this differently. */
6025
6026#if 1 /* This can be compiled, optimize later if needed. */
6027 switch (pVCpu->iem.s.enmEffOpSize)
6028 {
6029 case IEMMODE_16BIT:
6030 IEM_MC_BEGIN(2, 0, 0, 0);
6031 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
6032 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2 << 8);
6033 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6034 IEM_MC_ARG_CONST(uint8_t, iEffSeg, pVCpu->iem.s.iEffSeg, 0);
6035 IEM_MC_CALL_CIMPL_2(0, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP), iemCImpl_pop_mem16, iEffSeg, GCPtrEffDst);
6036 IEM_MC_END();
6037 break;
6038
6039 case IEMMODE_32BIT:
6040 IEM_MC_BEGIN(2, 0, IEM_MC_F_MIN_386, 0);
6041 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
6042 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4 << 8);
6043 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6044 IEM_MC_ARG_CONST(uint8_t, iEffSeg, pVCpu->iem.s.iEffSeg, 0);
6045 IEM_MC_CALL_CIMPL_2(0, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP), iemCImpl_pop_mem32, iEffSeg, GCPtrEffDst);
6046 IEM_MC_END();
6047 break;
6048
6049 case IEMMODE_64BIT:
6050 IEM_MC_BEGIN(2, 0, IEM_MC_F_64BIT, 0);
6051 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
6052 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 8 << 8);
6053 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6054 IEM_MC_ARG_CONST(uint8_t, iEffSeg, pVCpu->iem.s.iEffSeg, 0);
6055 IEM_MC_CALL_CIMPL_2(0, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP), iemCImpl_pop_mem64, iEffSeg, GCPtrEffDst);
6056 IEM_MC_END();
6057 break;
6058
6059 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6060 }
6061
6062#else
6063# ifndef TST_IEM_CHECK_MC
6064 /* Calc effective address with modified ESP. */
6065/** @todo testcase */
6066 RTGCPTR GCPtrEff;
6067 VBOXSTRICTRC rcStrict;
6068 switch (pVCpu->iem.s.enmEffOpSize)
6069 {
6070 case IEMMODE_16BIT: rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 2 << 8, &GCPtrEff); break;
6071 case IEMMODE_32BIT: rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 4 << 8, &GCPtrEff); break;
6072 case IEMMODE_64BIT: rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 8 << 8, &GCPtrEff); break;
6073 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6074 }
6075 if (rcStrict != VINF_SUCCESS)
6076 return rcStrict;
6077 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6078
6079 /* Perform the operation - this should be CImpl. */
6080 RTUINT64U TmpRsp;
6081 TmpRsp.u = pVCpu->cpum.GstCtx.rsp;
6082 switch (pVCpu->iem.s.enmEffOpSize)
6083 {
6084 case IEMMODE_16BIT:
6085 {
6086 uint16_t u16Value;
6087 rcStrict = iemMemStackPopU16Ex(pVCpu, &u16Value, &TmpRsp);
6088 if (rcStrict == VINF_SUCCESS)
6089 rcStrict = iemMemStoreDataU16(pVCpu, pVCpu->iem.s.iEffSeg, GCPtrEff, u16Value);
6090 break;
6091 }
6092
6093 case IEMMODE_32BIT:
6094 {
6095 uint32_t u32Value;
6096 rcStrict = iemMemStackPopU32Ex(pVCpu, &u32Value, &TmpRsp);
6097 if (rcStrict == VINF_SUCCESS)
6098 rcStrict = iemMemStoreDataU32(pVCpu, pVCpu->iem.s.iEffSeg, GCPtrEff, u32Value);
6099 break;
6100 }
6101
6102 case IEMMODE_64BIT:
6103 {
6104 uint64_t u64Value;
6105 rcStrict = iemMemStackPopU64Ex(pVCpu, &u64Value, &TmpRsp);
6106 if (rcStrict == VINF_SUCCESS)
6107 rcStrict = iemMemStoreDataU64(pVCpu, pVCpu->iem.s.iEffSeg, GCPtrEff, u64Value);
6108 break;
6109 }
6110
6111 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6112 }
6113 if (rcStrict == VINF_SUCCESS)
6114 {
6115 pVCpu->cpum.GstCtx.rsp = TmpRsp.u;
6116 return iemRegUpdateRipAndFinishClearingRF(pVCpu);
6117 }
6118 return rcStrict;
6119
6120# else
6121 return VERR_IEM_IPE_2;
6122# endif
6123#endif
6124}
6125
6126
6127/**
6128 * @opcode 0x8f
6129 */
6130FNIEMOP_DEF(iemOp_Grp1A__xop)
6131{
6132 /*
6133 * AMD has defined /1 thru /7 as XOP prefix. The prefix is similar to the
6134 * three byte VEX prefix, except that the mmmmm field cannot have the values
6135 * 0 thru 7, because it would then be confused with pop Ev (modrm.reg == 0).
6136 */
6137 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6138 if ((bRm & X86_MODRM_REG_MASK) == (0 << X86_MODRM_REG_SHIFT)) /* /0 */
6139 return FNIEMOP_CALL_1(iemOp_pop_Ev, bRm);
6140
6141 IEMOP_MNEMONIC(xop, "xop");
6142 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fXop)
6143 {
6144 /** @todo Test when exctly the XOP conformance checks kick in during
6145 * instruction decoding and fetching (using \#PF). */
6146 uint8_t bXop2; IEM_OPCODE_GET_NEXT_U8(&bXop2);
6147 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
6148 if ( ( pVCpu->iem.s.fPrefixes
6149 & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))
6150 == 0)
6151 {
6152 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_XOP;
6153 if ((bXop2 & 0x80 /* XOP.W */) && IEM_IS_64BIT_CODE(pVCpu))
6154 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_REX_W;
6155 pVCpu->iem.s.uRexReg = (~bRm >> (7 - 3)) & 0x8;
6156 pVCpu->iem.s.uRexIndex = (~bRm >> (6 - 3)) & 0x8;
6157 pVCpu->iem.s.uRexB = (~bRm >> (5 - 3)) & 0x8;
6158 pVCpu->iem.s.uVex3rdReg = (~bXop2 >> 3) & 0xf;
6159 pVCpu->iem.s.uVexLength = (bXop2 >> 2) & 1;
6160 pVCpu->iem.s.idxPrefix = bXop2 & 0x3;
6161
6162 /** @todo XOP: Just use new tables and decoders. */
6163 switch (bRm & 0x1f)
6164 {
6165 case 8: /* xop opcode map 8. */
6166 IEMOP_BITCH_ABOUT_STUB();
6167 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6168
6169 case 9: /* xop opcode map 9. */
6170 IEMOP_BITCH_ABOUT_STUB();
6171 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6172
6173 case 10: /* xop opcode map 10. */
6174 IEMOP_BITCH_ABOUT_STUB();
6175 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6176
6177 default:
6178 Log(("XOP: Invalid vvvv value: %#x!\n", bRm & 0x1f));
6179 IEMOP_RAISE_INVALID_OPCODE_RET();
6180 }
6181 }
6182 else
6183 Log(("XOP: Invalid prefix mix!\n"));
6184 }
6185 else
6186 Log(("XOP: XOP support disabled!\n"));
6187 IEMOP_RAISE_INVALID_OPCODE_RET();
6188}
6189
6190
6191/**
6192 * Common 'xchg reg,rAX' helper.
6193 */
6194FNIEMOP_DEF_1(iemOpCommonXchgGRegRax, uint8_t, iReg)
6195{
6196 iReg |= pVCpu->iem.s.uRexB;
6197 switch (pVCpu->iem.s.enmEffOpSize)
6198 {
6199 case IEMMODE_16BIT:
6200 IEM_MC_BEGIN(0, 2, 0, 0);
6201 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6202 IEM_MC_LOCAL(uint16_t, u16Tmp1);
6203 IEM_MC_LOCAL(uint16_t, u16Tmp2);
6204 IEM_MC_FETCH_GREG_U16(u16Tmp1, iReg);
6205 IEM_MC_FETCH_GREG_U16(u16Tmp2, X86_GREG_xAX);
6206 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp1);
6207 IEM_MC_STORE_GREG_U16(iReg, u16Tmp2);
6208 IEM_MC_ADVANCE_RIP_AND_FINISH();
6209 IEM_MC_END();
6210 break;
6211
6212 case IEMMODE_32BIT:
6213 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
6214 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6215 IEM_MC_LOCAL(uint32_t, u32Tmp1);
6216 IEM_MC_LOCAL(uint32_t, u32Tmp2);
6217 IEM_MC_FETCH_GREG_U32(u32Tmp1, iReg);
6218 IEM_MC_FETCH_GREG_U32(u32Tmp2, X86_GREG_xAX);
6219 IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Tmp1);
6220 IEM_MC_STORE_GREG_U32(iReg, u32Tmp2);
6221 IEM_MC_ADVANCE_RIP_AND_FINISH();
6222 IEM_MC_END();
6223 break;
6224
6225 case IEMMODE_64BIT:
6226 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
6227 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6228 IEM_MC_LOCAL(uint64_t, u64Tmp1);
6229 IEM_MC_LOCAL(uint64_t, u64Tmp2);
6230 IEM_MC_FETCH_GREG_U64(u64Tmp1, iReg);
6231 IEM_MC_FETCH_GREG_U64(u64Tmp2, X86_GREG_xAX);
6232 IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Tmp1);
6233 IEM_MC_STORE_GREG_U64(iReg, u64Tmp2);
6234 IEM_MC_ADVANCE_RIP_AND_FINISH();
6235 IEM_MC_END();
6236 break;
6237
6238 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6239 }
6240}
6241
6242
6243/**
6244 * @opcode 0x90
6245 */
6246FNIEMOP_DEF(iemOp_nop)
6247{
6248 /* R8/R8D and RAX/EAX can be exchanged. */
6249 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX_B)
6250 {
6251 IEMOP_MNEMONIC(xchg_r8_rAX, "xchg r8,rAX");
6252 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xAX);
6253 }
6254
6255 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK)
6256 {
6257 IEMOP_MNEMONIC(pause, "pause");
6258 /* ASSUMING that we keep the IEM_F_X86_CTX_IN_GUEST, IEM_F_X86_CTX_VMX
6259 and IEM_F_X86_CTX_SVM in the TB key, we can safely do the following: */
6260 if (!IEM_IS_IN_GUEST(pVCpu))
6261 { /* probable */ }
6262#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
6263 else if (pVCpu->iem.s.fExec & IEM_F_X86_CTX_VMX)
6264 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_VMEXIT, 0, iemCImpl_vmx_pause);
6265#endif
6266#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
6267 else if (pVCpu->iem.s.fExec & IEM_F_X86_CTX_SVM)
6268 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_VMEXIT, 0, iemCImpl_svm_pause);
6269#endif
6270 }
6271 else
6272 IEMOP_MNEMONIC(nop, "nop");
6273 /** @todo testcase: lock nop; lock pause */
6274 IEM_MC_BEGIN(0, 0, 0, 0);
6275 IEMOP_HLP_DONE_DECODING();
6276 IEM_MC_ADVANCE_RIP_AND_FINISH();
6277 IEM_MC_END();
6278}
6279
6280
6281/**
6282 * @opcode 0x91
6283 */
6284FNIEMOP_DEF(iemOp_xchg_eCX_eAX)
6285{
6286 IEMOP_MNEMONIC(xchg_rCX_rAX, "xchg rCX,rAX");
6287 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xCX);
6288}
6289
6290
6291/**
6292 * @opcode 0x92
6293 */
6294FNIEMOP_DEF(iemOp_xchg_eDX_eAX)
6295{
6296 IEMOP_MNEMONIC(xchg_rDX_rAX, "xchg rDX,rAX");
6297 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xDX);
6298}
6299
6300
6301/**
6302 * @opcode 0x93
6303 */
6304FNIEMOP_DEF(iemOp_xchg_eBX_eAX)
6305{
6306 IEMOP_MNEMONIC(xchg_rBX_rAX, "xchg rBX,rAX");
6307 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xBX);
6308}
6309
6310
6311/**
6312 * @opcode 0x94
6313 */
6314FNIEMOP_DEF(iemOp_xchg_eSP_eAX)
6315{
6316 IEMOP_MNEMONIC(xchg_rSX_rAX, "xchg rSX,rAX");
6317 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xSP);
6318}
6319
6320
6321/**
6322 * @opcode 0x95
6323 */
6324FNIEMOP_DEF(iemOp_xchg_eBP_eAX)
6325{
6326 IEMOP_MNEMONIC(xchg_rBP_rAX, "xchg rBP,rAX");
6327 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xBP);
6328}
6329
6330
6331/**
6332 * @opcode 0x96
6333 */
6334FNIEMOP_DEF(iemOp_xchg_eSI_eAX)
6335{
6336 IEMOP_MNEMONIC(xchg_rSI_rAX, "xchg rSI,rAX");
6337 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xSI);
6338}
6339
6340
6341/**
6342 * @opcode 0x97
6343 */
6344FNIEMOP_DEF(iemOp_xchg_eDI_eAX)
6345{
6346 IEMOP_MNEMONIC(xchg_rDI_rAX, "xchg rDI,rAX");
6347 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xDI);
6348}
6349
6350
6351/**
6352 * @opcode 0x98
6353 */
6354FNIEMOP_DEF(iemOp_cbw)
6355{
6356 switch (pVCpu->iem.s.enmEffOpSize)
6357 {
6358 case IEMMODE_16BIT:
6359 IEMOP_MNEMONIC(cbw, "cbw");
6360 IEM_MC_BEGIN(0, 1, 0, 0);
6361 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6362 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 7) {
6363 IEM_MC_OR_GREG_U16(X86_GREG_xAX, UINT16_C(0xff00));
6364 } IEM_MC_ELSE() {
6365 IEM_MC_AND_GREG_U16(X86_GREG_xAX, UINT16_C(0x00ff));
6366 } IEM_MC_ENDIF();
6367 IEM_MC_ADVANCE_RIP_AND_FINISH();
6368 IEM_MC_END();
6369 break;
6370
6371 case IEMMODE_32BIT:
6372 IEMOP_MNEMONIC(cwde, "cwde");
6373 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
6374 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6375 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 15) {
6376 IEM_MC_OR_GREG_U32(X86_GREG_xAX, UINT32_C(0xffff0000));
6377 } IEM_MC_ELSE() {
6378 IEM_MC_AND_GREG_U32(X86_GREG_xAX, UINT32_C(0x0000ffff));
6379 } IEM_MC_ENDIF();
6380 IEM_MC_ADVANCE_RIP_AND_FINISH();
6381 IEM_MC_END();
6382 break;
6383
6384 case IEMMODE_64BIT:
6385 IEMOP_MNEMONIC(cdqe, "cdqe");
6386 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
6387 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6388 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 31) {
6389 IEM_MC_OR_GREG_U64(X86_GREG_xAX, UINT64_C(0xffffffff00000000));
6390 } IEM_MC_ELSE() {
6391 IEM_MC_AND_GREG_U64(X86_GREG_xAX, UINT64_C(0x00000000ffffffff));
6392 } IEM_MC_ENDIF();
6393 IEM_MC_ADVANCE_RIP_AND_FINISH();
6394 IEM_MC_END();
6395 break;
6396
6397 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6398 }
6399}
6400
6401
6402/**
6403 * @opcode 0x99
6404 */
6405FNIEMOP_DEF(iemOp_cwd)
6406{
6407 switch (pVCpu->iem.s.enmEffOpSize)
6408 {
6409 case IEMMODE_16BIT:
6410 IEMOP_MNEMONIC(cwd, "cwd");
6411 IEM_MC_BEGIN(0, 1, 0, 0);
6412 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6413 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 15) {
6414 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xDX, UINT16_C(0xffff));
6415 } IEM_MC_ELSE() {
6416 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xDX, 0);
6417 } IEM_MC_ENDIF();
6418 IEM_MC_ADVANCE_RIP_AND_FINISH();
6419 IEM_MC_END();
6420 break;
6421
6422 case IEMMODE_32BIT:
6423 IEMOP_MNEMONIC(cdq, "cdq");
6424 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
6425 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6426 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 31) {
6427 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xDX, UINT32_C(0xffffffff));
6428 } IEM_MC_ELSE() {
6429 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xDX, 0);
6430 } IEM_MC_ENDIF();
6431 IEM_MC_ADVANCE_RIP_AND_FINISH();
6432 IEM_MC_END();
6433 break;
6434
6435 case IEMMODE_64BIT:
6436 IEMOP_MNEMONIC(cqo, "cqo");
6437 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
6438 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6439 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 63) {
6440 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xDX, UINT64_C(0xffffffffffffffff));
6441 } IEM_MC_ELSE() {
6442 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xDX, 0);
6443 } IEM_MC_ENDIF();
6444 IEM_MC_ADVANCE_RIP_AND_FINISH();
6445 IEM_MC_END();
6446 break;
6447
6448 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6449 }
6450}
6451
6452
6453/**
6454 * @opcode 0x9a
6455 */
6456FNIEMOP_DEF(iemOp_call_Ap)
6457{
6458 IEMOP_MNEMONIC(call_Ap, "call Ap");
6459 IEMOP_HLP_NO_64BIT();
6460
6461 /* Decode the far pointer address and pass it on to the far call C implementation. */
6462 uint32_t off32Seg;
6463 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_16BIT)
6464 IEM_OPCODE_GET_NEXT_U32(&off32Seg);
6465 else
6466 IEM_OPCODE_GET_NEXT_U16_ZX_U32(&off32Seg);
6467 uint16_t u16Sel; IEM_OPCODE_GET_NEXT_U16(&u16Sel);
6468 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6469 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_BRANCH_DIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK
6470 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, UINT64_MAX,
6471 iemCImpl_callf, u16Sel, off32Seg, pVCpu->iem.s.enmEffOpSize);
6472 /** @todo make task-switches, ring-switches, ++ return non-zero status */
6473}
6474
6475
6476/** Opcode 0x9b. (aka fwait) */
6477FNIEMOP_DEF(iemOp_wait)
6478{
6479 IEMOP_MNEMONIC(wait, "wait");
6480 IEM_MC_BEGIN(0, 0, 0, 0);
6481 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6482 IEM_MC_MAYBE_RAISE_WAIT_DEVICE_NOT_AVAILABLE();
6483 IEM_MC_MAYBE_RAISE_FPU_XCPT();
6484 IEM_MC_ADVANCE_RIP_AND_FINISH();
6485 IEM_MC_END();
6486}
6487
6488
6489/**
6490 * @opcode 0x9c
6491 */
6492FNIEMOP_DEF(iemOp_pushf_Fv)
6493{
6494 IEMOP_MNEMONIC(pushf_Fv, "pushf Fv");
6495 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6496 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6497 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP),
6498 iemCImpl_pushf, pVCpu->iem.s.enmEffOpSize);
6499}
6500
6501
6502/**
6503 * @opcode 0x9d
6504 */
6505FNIEMOP_DEF(iemOp_popf_Fv)
6506{
6507 IEMOP_MNEMONIC(popf_Fv, "popf Fv");
6508 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6509 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6510 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_CHECK_IRQ_BEFORE_AND_AFTER,
6511 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP),
6512 iemCImpl_popf, pVCpu->iem.s.enmEffOpSize);
6513}
6514
6515
6516/**
6517 * @opcode 0x9e
6518 */
6519FNIEMOP_DEF(iemOp_sahf)
6520{
6521 IEMOP_MNEMONIC(sahf, "sahf");
6522 if ( IEM_IS_64BIT_CODE(pVCpu)
6523 && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLahfSahf)
6524 IEMOP_RAISE_INVALID_OPCODE_RET();
6525 IEM_MC_BEGIN(0, 2, 0, 0);
6526 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6527 IEM_MC_LOCAL(uint32_t, u32Flags);
6528 IEM_MC_LOCAL(uint32_t, EFlags);
6529 IEM_MC_FETCH_EFLAGS(EFlags);
6530 IEM_MC_FETCH_GREG_U8_ZX_U32(u32Flags, X86_GREG_xSP/*=AH*/);
6531 IEM_MC_AND_LOCAL_U32(u32Flags, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
6532 IEM_MC_AND_LOCAL_U32(EFlags, UINT32_C(0xffffff00));
6533 IEM_MC_OR_LOCAL_U32(u32Flags, X86_EFL_1);
6534 IEM_MC_OR_2LOCS_U32(EFlags, u32Flags);
6535 IEM_MC_COMMIT_EFLAGS(EFlags);
6536 IEM_MC_ADVANCE_RIP_AND_FINISH();
6537 IEM_MC_END();
6538}
6539
6540
6541/**
6542 * @opcode 0x9f
6543 */
6544FNIEMOP_DEF(iemOp_lahf)
6545{
6546 IEMOP_MNEMONIC(lahf, "lahf");
6547 if ( IEM_IS_64BIT_CODE(pVCpu)
6548 && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLahfSahf)
6549 IEMOP_RAISE_INVALID_OPCODE_RET();
6550 IEM_MC_BEGIN(0, 1, 0, 0);
6551 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6552 IEM_MC_LOCAL(uint8_t, u8Flags);
6553 IEM_MC_FETCH_EFLAGS_U8(u8Flags);
6554 IEM_MC_STORE_GREG_U8(X86_GREG_xSP/*=AH*/, u8Flags);
6555 IEM_MC_ADVANCE_RIP_AND_FINISH();
6556 IEM_MC_END();
6557}
6558
6559
6560/**
6561 * Macro used by iemOp_mov_AL_Ob, iemOp_mov_rAX_Ov, iemOp_mov_Ob_AL and
6562 * iemOp_mov_Ov_rAX to fetch the moffsXX bit of the opcode.
6563 * Will return/throw on failures.
6564 * @param a_GCPtrMemOff The variable to store the offset in.
6565 */
6566#define IEMOP_FETCH_MOFFS_XX(a_GCPtrMemOff) \
6567 do \
6568 { \
6569 switch (pVCpu->iem.s.enmEffAddrMode) \
6570 { \
6571 case IEMMODE_16BIT: \
6572 IEM_OPCODE_GET_NEXT_U16_ZX_U64(&(a_GCPtrMemOff)); \
6573 break; \
6574 case IEMMODE_32BIT: \
6575 IEM_OPCODE_GET_NEXT_U32_ZX_U64(&(a_GCPtrMemOff)); \
6576 break; \
6577 case IEMMODE_64BIT: \
6578 IEM_OPCODE_GET_NEXT_U64(&(a_GCPtrMemOff)); \
6579 break; \
6580 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
6581 } \
6582 } while (0)
6583
6584/**
6585 * @opcode 0xa0
6586 */
6587FNIEMOP_DEF(iemOp_mov_AL_Ob)
6588{
6589 /*
6590 * Get the offset.
6591 */
6592 IEMOP_MNEMONIC(mov_AL_Ob, "mov AL,Ob");
6593 RTGCPTR GCPtrMemOffDecode;
6594 IEMOP_FETCH_MOFFS_XX(GCPtrMemOffDecode);
6595
6596 /*
6597 * Fetch AL.
6598 */
6599 IEM_MC_BEGIN(0, 2, 0, 0);
6600 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6601 IEM_MC_LOCAL(uint8_t, u8Tmp);
6602 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6603 IEM_MC_FETCH_MEM_U8(u8Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
6604 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
6605 IEM_MC_ADVANCE_RIP_AND_FINISH();
6606 IEM_MC_END();
6607}
6608
6609
6610/**
6611 * @opcode 0xa1
6612 */
6613FNIEMOP_DEF(iemOp_mov_rAX_Ov)
6614{
6615 /*
6616 * Get the offset.
6617 */
6618 IEMOP_MNEMONIC(mov_rAX_Ov, "mov rAX,Ov");
6619 RTGCPTR GCPtrMemOffDecode;
6620 IEMOP_FETCH_MOFFS_XX(GCPtrMemOffDecode);
6621
6622 /*
6623 * Fetch rAX.
6624 */
6625 switch (pVCpu->iem.s.enmEffOpSize)
6626 {
6627 case IEMMODE_16BIT:
6628 IEM_MC_BEGIN(0, 2, 0, 0);
6629 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6630 IEM_MC_LOCAL(uint16_t, u16Tmp);
6631 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6632 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
6633 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp);
6634 IEM_MC_ADVANCE_RIP_AND_FINISH();
6635 IEM_MC_END();
6636 break;
6637
6638 case IEMMODE_32BIT:
6639 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
6640 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6641 IEM_MC_LOCAL(uint32_t, u32Tmp);
6642 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6643 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
6644 IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Tmp);
6645 IEM_MC_ADVANCE_RIP_AND_FINISH();
6646 IEM_MC_END();
6647 break;
6648
6649 case IEMMODE_64BIT:
6650 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
6651 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6652 IEM_MC_LOCAL(uint64_t, u64Tmp);
6653 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6654 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
6655 IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Tmp);
6656 IEM_MC_ADVANCE_RIP_AND_FINISH();
6657 IEM_MC_END();
6658 break;
6659
6660 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6661 }
6662}
6663
6664
6665/**
6666 * @opcode 0xa2
6667 */
6668FNIEMOP_DEF(iemOp_mov_Ob_AL)
6669{
6670 /*
6671 * Get the offset.
6672 */
6673 IEMOP_MNEMONIC(mov_Ob_AL, "mov Ob,AL");
6674 RTGCPTR GCPtrMemOffDecode;
6675 IEMOP_FETCH_MOFFS_XX(GCPtrMemOffDecode);
6676
6677 /*
6678 * Store AL.
6679 */
6680 IEM_MC_BEGIN(0, 2, 0, 0);
6681 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6682 IEM_MC_LOCAL(uint8_t, u8Tmp);
6683 IEM_MC_FETCH_GREG_U8(u8Tmp, X86_GREG_xAX);
6684 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6685 IEM_MC_STORE_MEM_U8(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u8Tmp);
6686 IEM_MC_ADVANCE_RIP_AND_FINISH();
6687 IEM_MC_END();
6688}
6689
6690
6691/**
6692 * @opcode 0xa3
6693 */
6694FNIEMOP_DEF(iemOp_mov_Ov_rAX)
6695{
6696 /*
6697 * Get the offset.
6698 */
6699 IEMOP_MNEMONIC(mov_Ov_rAX, "mov Ov,rAX");
6700 RTGCPTR GCPtrMemOffDecode;
6701 IEMOP_FETCH_MOFFS_XX(GCPtrMemOffDecode);
6702
6703 /*
6704 * Store rAX.
6705 */
6706 switch (pVCpu->iem.s.enmEffOpSize)
6707 {
6708 case IEMMODE_16BIT:
6709 IEM_MC_BEGIN(0, 2, 0, 0);
6710 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6711 IEM_MC_LOCAL(uint16_t, u16Tmp);
6712 IEM_MC_FETCH_GREG_U16(u16Tmp, X86_GREG_xAX);
6713 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6714 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u16Tmp);
6715 IEM_MC_ADVANCE_RIP_AND_FINISH();
6716 IEM_MC_END();
6717 break;
6718
6719 case IEMMODE_32BIT:
6720 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
6721 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6722 IEM_MC_LOCAL(uint32_t, u32Tmp);
6723 IEM_MC_FETCH_GREG_U32(u32Tmp, X86_GREG_xAX);
6724 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6725 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u32Tmp);
6726 IEM_MC_ADVANCE_RIP_AND_FINISH();
6727 IEM_MC_END();
6728 break;
6729
6730 case IEMMODE_64BIT:
6731 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
6732 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6733 IEM_MC_LOCAL(uint64_t, u64Tmp);
6734 IEM_MC_FETCH_GREG_U64(u64Tmp, X86_GREG_xAX);
6735 IEM_MC_LOCAL_CONST(RTGCPTR, GCPtrMemOff, GCPtrMemOffDecode);
6736 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u64Tmp);
6737 IEM_MC_ADVANCE_RIP_AND_FINISH();
6738 IEM_MC_END();
6739 break;
6740
6741 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6742 }
6743}
6744
6745/** Macro used by iemOp_movsb_Xb_Yb and iemOp_movswd_Xv_Yv */
6746#define IEM_MOVS_CASE(ValBits, AddrBits, a_fMcFlags) \
6747 IEM_MC_BEGIN(0, 2, a_fMcFlags, 0); \
6748 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
6749 IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
6750 IEM_MC_LOCAL(RTGCPTR, uAddr); \
6751 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
6752 IEM_MC_FETCH_MEM_U##ValBits(uValue, pVCpu->iem.s.iEffSeg, uAddr); \
6753 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
6754 IEM_MC_STORE_MEM_U##ValBits(X86_SREG_ES, uAddr, uValue); \
6755 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
6756 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
6757 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
6758 } IEM_MC_ELSE() { \
6759 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
6760 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
6761 } IEM_MC_ENDIF(); \
6762 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
6763 IEM_MC_END() \
6764
6765/**
6766 * @opcode 0xa4
6767 */
6768FNIEMOP_DEF(iemOp_movsb_Xb_Yb)
6769{
6770 /*
6771 * Use the C implementation if a repeat prefix is encountered.
6772 */
6773 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
6774 {
6775 IEMOP_MNEMONIC(rep_movsb_Xb_Yb, "rep movsb Xb,Yb");
6776 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6777 switch (pVCpu->iem.s.enmEffAddrMode)
6778 {
6779 case IEMMODE_16BIT:
6780 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6781 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6782 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6783 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6784 iemCImpl_rep_movs_op8_addr16, pVCpu->iem.s.iEffSeg);
6785 case IEMMODE_32BIT:
6786 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6787 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6788 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6789 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6790 iemCImpl_rep_movs_op8_addr32, pVCpu->iem.s.iEffSeg);
6791 case IEMMODE_64BIT:
6792 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6793 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6794 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6795 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6796 iemCImpl_rep_movs_op8_addr64, pVCpu->iem.s.iEffSeg);
6797 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6798 }
6799 }
6800
6801 /*
6802 * Sharing case implementation with movs[wdq] below.
6803 */
6804 IEMOP_MNEMONIC(movsb_Xb_Yb, "movsb Xb,Yb");
6805 switch (pVCpu->iem.s.enmEffAddrMode)
6806 {
6807 case IEMMODE_16BIT: IEM_MOVS_CASE(8, 16, IEM_MC_F_NOT_64BIT); break;
6808 case IEMMODE_32BIT: IEM_MOVS_CASE(8, 32, IEM_MC_F_MIN_386); break;
6809 case IEMMODE_64BIT: IEM_MOVS_CASE(8, 64, IEM_MC_F_64BIT); break;
6810 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6811 }
6812}
6813
6814
6815/**
6816 * @opcode 0xa5
6817 */
6818FNIEMOP_DEF(iemOp_movswd_Xv_Yv)
6819{
6820
6821 /*
6822 * Use the C implementation if a repeat prefix is encountered.
6823 */
6824 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
6825 {
6826 IEMOP_MNEMONIC(rep_movs_Xv_Yv, "rep movs Xv,Yv");
6827 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6828 switch (pVCpu->iem.s.enmEffOpSize)
6829 {
6830 case IEMMODE_16BIT:
6831 switch (pVCpu->iem.s.enmEffAddrMode)
6832 {
6833 case IEMMODE_16BIT:
6834 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6835 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6836 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6837 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6838 iemCImpl_rep_movs_op16_addr16, pVCpu->iem.s.iEffSeg);
6839 case IEMMODE_32BIT:
6840 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6841 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6842 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6843 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6844 iemCImpl_rep_movs_op16_addr32, pVCpu->iem.s.iEffSeg);
6845 case IEMMODE_64BIT:
6846 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6847 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6848 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6849 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6850 iemCImpl_rep_movs_op16_addr64, pVCpu->iem.s.iEffSeg);
6851 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6852 }
6853 break;
6854 case IEMMODE_32BIT:
6855 switch (pVCpu->iem.s.enmEffAddrMode)
6856 {
6857 case IEMMODE_16BIT:
6858 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6859 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6860 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6861 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6862 iemCImpl_rep_movs_op32_addr16, pVCpu->iem.s.iEffSeg);
6863 case IEMMODE_32BIT:
6864 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6865 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6866 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6867 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6868 iemCImpl_rep_movs_op32_addr32, pVCpu->iem.s.iEffSeg);
6869 case IEMMODE_64BIT:
6870 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6871 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6872 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6873 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6874 iemCImpl_rep_movs_op32_addr64, pVCpu->iem.s.iEffSeg);
6875 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6876 }
6877 case IEMMODE_64BIT:
6878 switch (pVCpu->iem.s.enmEffAddrMode)
6879 {
6880 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_6);
6881 case IEMMODE_32BIT:
6882 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6883 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6884 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6885 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6886 iemCImpl_rep_movs_op64_addr32, pVCpu->iem.s.iEffSeg);
6887 case IEMMODE_64BIT:
6888 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
6889 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6890 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6891 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6892 iemCImpl_rep_movs_op64_addr64, pVCpu->iem.s.iEffSeg);
6893 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6894 }
6895 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6896 }
6897 }
6898
6899 /*
6900 * Annoying double switch here.
6901 * Using ugly macro for implementing the cases, sharing it with movsb.
6902 */
6903 IEMOP_MNEMONIC(movs_Xv_Yv, "movs Xv,Yv");
6904 switch (pVCpu->iem.s.enmEffOpSize)
6905 {
6906 case IEMMODE_16BIT:
6907 switch (pVCpu->iem.s.enmEffAddrMode)
6908 {
6909 case IEMMODE_16BIT: IEM_MOVS_CASE(16, 16, IEM_MC_F_NOT_64BIT); break;
6910 case IEMMODE_32BIT: IEM_MOVS_CASE(16, 32, IEM_MC_F_MIN_386); break;
6911 case IEMMODE_64BIT: IEM_MOVS_CASE(16, 64, IEM_MC_F_64BIT); break;
6912 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6913 }
6914 break;
6915
6916 case IEMMODE_32BIT:
6917 switch (pVCpu->iem.s.enmEffAddrMode)
6918 {
6919 case IEMMODE_16BIT: IEM_MOVS_CASE(32, 16, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT); break;
6920 case IEMMODE_32BIT: IEM_MOVS_CASE(32, 32, IEM_MC_F_MIN_386); break;
6921 case IEMMODE_64BIT: IEM_MOVS_CASE(32, 64, IEM_MC_F_64BIT); break;
6922 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6923 }
6924 break;
6925
6926 case IEMMODE_64BIT:
6927 switch (pVCpu->iem.s.enmEffAddrMode)
6928 {
6929 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
6930 case IEMMODE_32BIT: IEM_MOVS_CASE(64, 32, IEM_MC_F_64BIT); break;
6931 case IEMMODE_64BIT: IEM_MOVS_CASE(64, 64, IEM_MC_F_64BIT); break;
6932 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6933 }
6934 break;
6935 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6936 }
6937}
6938
6939#undef IEM_MOVS_CASE
6940
6941/** Macro used by iemOp_cmpsb_Xb_Yb and iemOp_cmpswd_Xv_Yv */
6942#define IEM_CMPS_CASE(ValBits, AddrBits, a_fMcFlags) \
6943 IEM_MC_BEGIN(3, 3, a_fMcFlags, 0); \
6944 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
6945 \
6946 IEM_MC_LOCAL(RTGCPTR, uAddr1); \
6947 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr1, X86_GREG_xSI); \
6948 IEM_MC_LOCAL(uint##ValBits##_t, uValue1); \
6949 IEM_MC_FETCH_MEM_U##ValBits(uValue1, pVCpu->iem.s.iEffSeg, uAddr1); \
6950 \
6951 IEM_MC_LOCAL(RTGCPTR, uAddr2); \
6952 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr2, X86_GREG_xDI); \
6953 IEM_MC_ARG(uint##ValBits##_t, uValue2, 1); \
6954 IEM_MC_FETCH_MEM_U##ValBits(uValue2, X86_SREG_ES, uAddr2); \
6955 \
6956 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
6957 IEM_MC_REF_EFLAGS(pEFlags); \
6958 IEM_MC_ARG_LOCAL_REF(uint##ValBits##_t *, puValue1, uValue1, 0); \
6959 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puValue1, uValue2, pEFlags); \
6960 \
6961 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
6962 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
6963 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
6964 } IEM_MC_ELSE() { \
6965 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
6966 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
6967 } IEM_MC_ENDIF(); \
6968 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
6969 IEM_MC_END() \
6970
6971/**
6972 * @opcode 0xa6
6973 */
6974FNIEMOP_DEF(iemOp_cmpsb_Xb_Yb)
6975{
6976
6977 /*
6978 * Use the C implementation if a repeat prefix is encountered.
6979 */
6980 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
6981 {
6982 IEMOP_MNEMONIC(repz_cmps_Xb_Yb, "repz cmps Xb,Yb");
6983 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6984 switch (pVCpu->iem.s.enmEffAddrMode)
6985 {
6986 case IEMMODE_16BIT:
6987 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
6988 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6989 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6990 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6991 iemCImpl_repe_cmps_op8_addr16, pVCpu->iem.s.iEffSeg);
6992 case IEMMODE_32BIT:
6993 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
6994 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
6995 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
6996 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
6997 iemCImpl_repe_cmps_op8_addr32, pVCpu->iem.s.iEffSeg);
6998 case IEMMODE_64BIT:
6999 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7000 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7001 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7002 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7003 iemCImpl_repe_cmps_op8_addr64, pVCpu->iem.s.iEffSeg);
7004 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7005 }
7006 }
7007 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
7008 {
7009 IEMOP_MNEMONIC(repnz_cmps_Xb_Yb, "repnz cmps Xb,Yb");
7010 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7011 switch (pVCpu->iem.s.enmEffAddrMode)
7012 {
7013 case IEMMODE_16BIT:
7014 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7015 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7016 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7017 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7018 iemCImpl_repne_cmps_op8_addr16, pVCpu->iem.s.iEffSeg);
7019 case IEMMODE_32BIT:
7020 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7021 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7022 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7023 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7024 iemCImpl_repne_cmps_op8_addr32, pVCpu->iem.s.iEffSeg);
7025 case IEMMODE_64BIT:
7026 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7027 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7028 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7029 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7030 iemCImpl_repne_cmps_op8_addr64, pVCpu->iem.s.iEffSeg);
7031 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7032 }
7033 }
7034
7035 /*
7036 * Sharing case implementation with cmps[wdq] below.
7037 */
7038 IEMOP_MNEMONIC(cmps_Xb_Yb, "cmps Xb,Yb");
7039 switch (pVCpu->iem.s.enmEffAddrMode)
7040 {
7041 case IEMMODE_16BIT: IEM_CMPS_CASE(8, 16, IEM_MC_F_NOT_64BIT); break;
7042 case IEMMODE_32BIT: IEM_CMPS_CASE(8, 32, IEM_MC_F_MIN_386); break;
7043 case IEMMODE_64BIT: IEM_CMPS_CASE(8, 64, IEM_MC_F_64BIT); break;
7044 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7045 }
7046}
7047
7048
7049/**
7050 * @opcode 0xa7
7051 */
7052FNIEMOP_DEF(iemOp_cmpswd_Xv_Yv)
7053{
7054 /*
7055 * Use the C implementation if a repeat prefix is encountered.
7056 */
7057 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
7058 {
7059 IEMOP_MNEMONIC(repe_cmps_Xv_Yv, "repe cmps Xv,Yv");
7060 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7061 switch (pVCpu->iem.s.enmEffOpSize)
7062 {
7063 case IEMMODE_16BIT:
7064 switch (pVCpu->iem.s.enmEffAddrMode)
7065 {
7066 case IEMMODE_16BIT:
7067 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7068 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7069 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7070 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7071 iemCImpl_repe_cmps_op16_addr16, pVCpu->iem.s.iEffSeg);
7072 case IEMMODE_32BIT:
7073 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7074 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7075 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7076 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7077 iemCImpl_repe_cmps_op16_addr32, pVCpu->iem.s.iEffSeg);
7078 case IEMMODE_64BIT:
7079 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7080 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7081 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7082 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7083 iemCImpl_repe_cmps_op16_addr64, pVCpu->iem.s.iEffSeg);
7084 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7085 }
7086 break;
7087 case IEMMODE_32BIT:
7088 switch (pVCpu->iem.s.enmEffAddrMode)
7089 {
7090 case IEMMODE_16BIT:
7091 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7092 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7093 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7094 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7095 iemCImpl_repe_cmps_op32_addr16, pVCpu->iem.s.iEffSeg);
7096 case IEMMODE_32BIT:
7097 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7098 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7099 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7100 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7101 iemCImpl_repe_cmps_op32_addr32, pVCpu->iem.s.iEffSeg);
7102 case IEMMODE_64BIT:
7103 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7104 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7105 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7106 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7107 iemCImpl_repe_cmps_op32_addr64, pVCpu->iem.s.iEffSeg);
7108 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7109 }
7110 case IEMMODE_64BIT:
7111 switch (pVCpu->iem.s.enmEffAddrMode)
7112 {
7113 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_4);
7114 case IEMMODE_32BIT:
7115 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7116 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7117 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7118 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7119 iemCImpl_repe_cmps_op64_addr32, pVCpu->iem.s.iEffSeg);
7120 case IEMMODE_64BIT:
7121 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7122 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7123 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7124 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7125 iemCImpl_repe_cmps_op64_addr64, pVCpu->iem.s.iEffSeg);
7126 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7127 }
7128 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7129 }
7130 }
7131
7132 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
7133 {
7134 IEMOP_MNEMONIC(repne_cmps_Xv_Yv, "repne cmps Xv,Yv");
7135 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7136 switch (pVCpu->iem.s.enmEffOpSize)
7137 {
7138 case IEMMODE_16BIT:
7139 switch (pVCpu->iem.s.enmEffAddrMode)
7140 {
7141 case IEMMODE_16BIT:
7142 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7143 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7144 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7145 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7146 iemCImpl_repne_cmps_op16_addr16, pVCpu->iem.s.iEffSeg);
7147 case IEMMODE_32BIT:
7148 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7149 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7150 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7151 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7152 iemCImpl_repne_cmps_op16_addr32, pVCpu->iem.s.iEffSeg);
7153 case IEMMODE_64BIT:
7154 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7155 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7156 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7157 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7158 iemCImpl_repne_cmps_op16_addr64, pVCpu->iem.s.iEffSeg);
7159 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7160 }
7161 break;
7162 case IEMMODE_32BIT:
7163 switch (pVCpu->iem.s.enmEffAddrMode)
7164 {
7165 case IEMMODE_16BIT:
7166 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7167 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7168 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7169 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7170 iemCImpl_repne_cmps_op32_addr16, pVCpu->iem.s.iEffSeg);
7171 case IEMMODE_32BIT:
7172 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7173 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7174 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7175 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7176 iemCImpl_repne_cmps_op32_addr32, pVCpu->iem.s.iEffSeg);
7177 case IEMMODE_64BIT:
7178 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7179 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7180 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7181 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7182 iemCImpl_repne_cmps_op32_addr64, pVCpu->iem.s.iEffSeg);
7183 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7184 }
7185 case IEMMODE_64BIT:
7186 switch (pVCpu->iem.s.enmEffAddrMode)
7187 {
7188 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_2);
7189 case IEMMODE_32BIT:
7190 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7191 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7192 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7193 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7194 iemCImpl_repne_cmps_op64_addr32, pVCpu->iem.s.iEffSeg);
7195 case IEMMODE_64BIT:
7196 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7197 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7198 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7199 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7200 iemCImpl_repne_cmps_op64_addr64, pVCpu->iem.s.iEffSeg);
7201 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7202 }
7203 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7204 }
7205 }
7206
7207 /*
7208 * Annoying double switch here.
7209 * Using ugly macro for implementing the cases, sharing it with cmpsb.
7210 */
7211 IEMOP_MNEMONIC(cmps_Xv_Yv, "cmps Xv,Yv");
7212 switch (pVCpu->iem.s.enmEffOpSize)
7213 {
7214 case IEMMODE_16BIT:
7215 switch (pVCpu->iem.s.enmEffAddrMode)
7216 {
7217 case IEMMODE_16BIT: IEM_CMPS_CASE(16, 16, IEM_MC_F_NOT_64BIT); break;
7218 case IEMMODE_32BIT: IEM_CMPS_CASE(16, 32, IEM_MC_F_MIN_386); break;
7219 case IEMMODE_64BIT: IEM_CMPS_CASE(16, 64, IEM_MC_F_64BIT); break;
7220 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7221 }
7222 break;
7223
7224 case IEMMODE_32BIT:
7225 switch (pVCpu->iem.s.enmEffAddrMode)
7226 {
7227 case IEMMODE_16BIT: IEM_CMPS_CASE(32, 16, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT); break;
7228 case IEMMODE_32BIT: IEM_CMPS_CASE(32, 32, IEM_MC_F_MIN_386); break;
7229 case IEMMODE_64BIT: IEM_CMPS_CASE(32, 64, IEM_MC_F_64BIT); break;
7230 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7231 }
7232 break;
7233
7234 case IEMMODE_64BIT:
7235 switch (pVCpu->iem.s.enmEffAddrMode)
7236 {
7237 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
7238 case IEMMODE_32BIT: IEM_CMPS_CASE(64, 32, IEM_MC_F_MIN_386); break;
7239 case IEMMODE_64BIT: IEM_CMPS_CASE(64, 64, IEM_MC_F_64BIT); break;
7240 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7241 }
7242 break;
7243 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7244 }
7245}
7246
7247#undef IEM_CMPS_CASE
7248
7249/**
7250 * @opcode 0xa8
7251 */
7252FNIEMOP_DEF(iemOp_test_AL_Ib)
7253{
7254 IEMOP_MNEMONIC(test_al_Ib, "test al,Ib");
7255 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
7256 IEMOP_BODY_BINARY_AL_Ib(iemAImpl_test_u8);
7257}
7258
7259
7260/**
7261 * @opcode 0xa9
7262 */
7263FNIEMOP_DEF(iemOp_test_eAX_Iz)
7264{
7265 IEMOP_MNEMONIC(test_rAX_Iz, "test rAX,Iz");
7266 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
7267 IEMOP_BODY_BINARY_rAX_Iz(iemAImpl_test_u16, iemAImpl_test_u32, iemAImpl_test_u64, 0);
7268}
7269
7270
7271/** Macro used by iemOp_stosb_Yb_AL and iemOp_stoswd_Yv_eAX */
7272#define IEM_STOS_CASE(ValBits, AddrBits, a_fMcFlags) \
7273 IEM_MC_BEGIN(0, 2, a_fMcFlags, 0); \
7274 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
7275 IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
7276 IEM_MC_LOCAL(RTGCPTR, uAddr); \
7277 IEM_MC_FETCH_GREG_U##ValBits(uValue, X86_GREG_xAX); \
7278 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
7279 IEM_MC_STORE_MEM_U##ValBits(X86_SREG_ES, uAddr, uValue); \
7280 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
7281 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
7282 } IEM_MC_ELSE() { \
7283 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
7284 } IEM_MC_ENDIF(); \
7285 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
7286 IEM_MC_END() \
7287
7288/**
7289 * @opcode 0xaa
7290 */
7291FNIEMOP_DEF(iemOp_stosb_Yb_AL)
7292{
7293 /*
7294 * Use the C implementation if a repeat prefix is encountered.
7295 */
7296 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
7297 {
7298 IEMOP_MNEMONIC(rep_stos_Yb_al, "rep stos Yb,al");
7299 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7300 switch (pVCpu->iem.s.enmEffAddrMode)
7301 {
7302 case IEMMODE_16BIT:
7303 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP,
7304 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7305 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7306 iemCImpl_stos_al_m16);
7307 case IEMMODE_32BIT:
7308 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP,
7309 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7310 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7311 iemCImpl_stos_al_m32);
7312 case IEMMODE_64BIT:
7313 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP,
7314 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7315 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7316 iemCImpl_stos_al_m64);
7317 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7318 }
7319 }
7320
7321 /*
7322 * Sharing case implementation with stos[wdq] below.
7323 */
7324 IEMOP_MNEMONIC(stos_Yb_al, "stos Yb,al");
7325 switch (pVCpu->iem.s.enmEffAddrMode)
7326 {
7327 case IEMMODE_16BIT: IEM_STOS_CASE(8, 16, IEM_MC_F_NOT_64BIT); break;
7328 case IEMMODE_32BIT: IEM_STOS_CASE(8, 32, IEM_MC_F_MIN_386); break;
7329 case IEMMODE_64BIT: IEM_STOS_CASE(8, 64, IEM_MC_F_64BIT); break;
7330 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7331 }
7332}
7333
7334
7335/**
7336 * @opcode 0xab
7337 */
7338FNIEMOP_DEF(iemOp_stoswd_Yv_eAX)
7339{
7340 /*
7341 * Use the C implementation if a repeat prefix is encountered.
7342 */
7343 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
7344 {
7345 IEMOP_MNEMONIC(rep_stos_Yv_rAX, "rep stos Yv,rAX");
7346 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7347 switch (pVCpu->iem.s.enmEffOpSize)
7348 {
7349 case IEMMODE_16BIT:
7350 switch (pVCpu->iem.s.enmEffAddrMode)
7351 {
7352 case IEMMODE_16BIT:
7353 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7354 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7355 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7356 iemCImpl_stos_ax_m16);
7357 case IEMMODE_32BIT:
7358 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7359 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7360 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7361 iemCImpl_stos_ax_m32);
7362 case IEMMODE_64BIT:
7363 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7364 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7365 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7366 iemCImpl_stos_ax_m64);
7367 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7368 }
7369 break;
7370 case IEMMODE_32BIT:
7371 switch (pVCpu->iem.s.enmEffAddrMode)
7372 {
7373 case IEMMODE_16BIT:
7374 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7375 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7376 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7377 iemCImpl_stos_eax_m16);
7378 case IEMMODE_32BIT:
7379 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7380 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7381 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7382 iemCImpl_stos_eax_m32);
7383 case IEMMODE_64BIT:
7384 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7385 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7386 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7387 iemCImpl_stos_eax_m64);
7388 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7389 }
7390 case IEMMODE_64BIT:
7391 switch (pVCpu->iem.s.enmEffAddrMode)
7392 {
7393 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_9);
7394 case IEMMODE_32BIT:
7395 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7396 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7397 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7398 iemCImpl_stos_rax_m32);
7399 case IEMMODE_64BIT:
7400 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_REP,
7401 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7402 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7403 iemCImpl_stos_rax_m64);
7404 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7405 }
7406 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7407 }
7408 }
7409
7410 /*
7411 * Annoying double switch here.
7412 * Using ugly macro for implementing the cases, sharing it with stosb.
7413 */
7414 IEMOP_MNEMONIC(stos_Yv_rAX, "stos Yv,rAX");
7415 switch (pVCpu->iem.s.enmEffOpSize)
7416 {
7417 case IEMMODE_16BIT:
7418 switch (pVCpu->iem.s.enmEffAddrMode)
7419 {
7420 case IEMMODE_16BIT: IEM_STOS_CASE(16, 16, IEM_MC_F_NOT_64BIT); break;
7421 case IEMMODE_32BIT: IEM_STOS_CASE(16, 32, IEM_MC_F_MIN_386); break;
7422 case IEMMODE_64BIT: IEM_STOS_CASE(16, 64, IEM_MC_F_64BIT); break;
7423 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7424 }
7425 break;
7426
7427 case IEMMODE_32BIT:
7428 switch (pVCpu->iem.s.enmEffAddrMode)
7429 {
7430 case IEMMODE_16BIT: IEM_STOS_CASE(32, 16, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT); break;
7431 case IEMMODE_32BIT: IEM_STOS_CASE(32, 32, IEM_MC_F_MIN_386); break;
7432 case IEMMODE_64BIT: IEM_STOS_CASE(32, 64, IEM_MC_F_64BIT); break;
7433 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7434 }
7435 break;
7436
7437 case IEMMODE_64BIT:
7438 switch (pVCpu->iem.s.enmEffAddrMode)
7439 {
7440 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
7441 case IEMMODE_32BIT: IEM_STOS_CASE(64, 32, IEM_MC_F_64BIT); break;
7442 case IEMMODE_64BIT: IEM_STOS_CASE(64, 64, IEM_MC_F_64BIT); break;
7443 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7444 }
7445 break;
7446 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7447 }
7448}
7449
7450#undef IEM_STOS_CASE
7451
7452/** Macro used by iemOp_lodsb_AL_Xb and iemOp_lodswd_eAX_Xv */
7453#define IEM_LODS_CASE(ValBits, AddrBits, a_fMcFlags) \
7454 IEM_MC_BEGIN(0, 2, a_fMcFlags, 0); \
7455 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
7456 IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
7457 IEM_MC_LOCAL(RTGCPTR, uAddr); \
7458 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
7459 IEM_MC_FETCH_MEM_U##ValBits(uValue, pVCpu->iem.s.iEffSeg, uAddr); \
7460 IEM_MC_STORE_GREG_U##ValBits(X86_GREG_xAX, uValue); \
7461 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
7462 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
7463 } IEM_MC_ELSE() { \
7464 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
7465 } IEM_MC_ENDIF(); \
7466 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
7467 IEM_MC_END() \
7468
7469/**
7470 * @opcode 0xac
7471 */
7472FNIEMOP_DEF(iemOp_lodsb_AL_Xb)
7473{
7474 /*
7475 * Use the C implementation if a repeat prefix is encountered.
7476 */
7477 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
7478 {
7479 IEMOP_MNEMONIC(rep_lodsb_AL_Xb, "rep lodsb AL,Xb");
7480 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7481 switch (pVCpu->iem.s.enmEffAddrMode)
7482 {
7483 case IEMMODE_16BIT:
7484 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7485 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7486 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7487 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7488 iemCImpl_lods_al_m16, pVCpu->iem.s.iEffSeg);
7489 case IEMMODE_32BIT:
7490 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7491 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7492 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7493 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7494 iemCImpl_lods_al_m32, pVCpu->iem.s.iEffSeg);
7495 case IEMMODE_64BIT:
7496 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7497 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7498 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7499 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7500 iemCImpl_lods_al_m64, pVCpu->iem.s.iEffSeg);
7501 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7502 }
7503 }
7504
7505 /*
7506 * Sharing case implementation with stos[wdq] below.
7507 */
7508 IEMOP_MNEMONIC(lodsb_AL_Xb, "lodsb AL,Xb");
7509 switch (pVCpu->iem.s.enmEffAddrMode)
7510 {
7511 case IEMMODE_16BIT: IEM_LODS_CASE(8, 16, IEM_MC_F_NOT_64BIT); break;
7512 case IEMMODE_32BIT: IEM_LODS_CASE(8, 32, IEM_MC_F_MIN_386); break;
7513 case IEMMODE_64BIT: IEM_LODS_CASE(8, 64, IEM_MC_F_64BIT); break;
7514 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7515 }
7516}
7517
7518
7519/**
7520 * @opcode 0xad
7521 */
7522FNIEMOP_DEF(iemOp_lodswd_eAX_Xv)
7523{
7524 /*
7525 * Use the C implementation if a repeat prefix is encountered.
7526 */
7527 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
7528 {
7529 IEMOP_MNEMONIC(rep_lods_rAX_Xv, "rep lods rAX,Xv");
7530 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7531 switch (pVCpu->iem.s.enmEffOpSize)
7532 {
7533 case IEMMODE_16BIT:
7534 switch (pVCpu->iem.s.enmEffAddrMode)
7535 {
7536 case IEMMODE_16BIT:
7537 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7538 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7539 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7540 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7541 iemCImpl_lods_ax_m16, pVCpu->iem.s.iEffSeg);
7542 case IEMMODE_32BIT:
7543 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7544 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7545 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7546 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7547 iemCImpl_lods_ax_m32, pVCpu->iem.s.iEffSeg);
7548 case IEMMODE_64BIT:
7549 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7550 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7551 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7552 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7553 iemCImpl_lods_ax_m64, pVCpu->iem.s.iEffSeg);
7554 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7555 }
7556 break;
7557 case IEMMODE_32BIT:
7558 switch (pVCpu->iem.s.enmEffAddrMode)
7559 {
7560 case IEMMODE_16BIT:
7561 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7562 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7563 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7564 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7565 iemCImpl_lods_eax_m16, pVCpu->iem.s.iEffSeg);
7566 case IEMMODE_32BIT:
7567 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7568 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7569 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7570 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7571 iemCImpl_lods_eax_m32, pVCpu->iem.s.iEffSeg);
7572 case IEMMODE_64BIT:
7573 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7574 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7575 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7576 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7577 iemCImpl_lods_eax_m64, pVCpu->iem.s.iEffSeg);
7578 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7579 }
7580 case IEMMODE_64BIT:
7581 switch (pVCpu->iem.s.enmEffAddrMode)
7582 {
7583 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_7);
7584 case IEMMODE_32BIT:
7585 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7586 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7587 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7588 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7589 iemCImpl_lods_rax_m32, pVCpu->iem.s.iEffSeg);
7590 case IEMMODE_64BIT:
7591 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_REP,
7592 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX)
7593 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSI)
7594 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7595 iemCImpl_lods_rax_m64, pVCpu->iem.s.iEffSeg);
7596 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7597 }
7598 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7599 }
7600 }
7601
7602 /*
7603 * Annoying double switch here.
7604 * Using ugly macro for implementing the cases, sharing it with lodsb.
7605 */
7606 IEMOP_MNEMONIC(lods_rAX_Xv, "lods rAX,Xv");
7607 switch (pVCpu->iem.s.enmEffOpSize)
7608 {
7609 case IEMMODE_16BIT:
7610 switch (pVCpu->iem.s.enmEffAddrMode)
7611 {
7612 case IEMMODE_16BIT: IEM_LODS_CASE(16, 16, IEM_MC_F_NOT_64BIT); break;
7613 case IEMMODE_32BIT: IEM_LODS_CASE(16, 32, IEM_MC_F_MIN_386); break;
7614 case IEMMODE_64BIT: IEM_LODS_CASE(16, 64, IEM_MC_F_64BIT); break;
7615 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7616 }
7617 break;
7618
7619 case IEMMODE_32BIT:
7620 switch (pVCpu->iem.s.enmEffAddrMode)
7621 {
7622 case IEMMODE_16BIT: IEM_LODS_CASE(32, 16, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT); break;
7623 case IEMMODE_32BIT: IEM_LODS_CASE(32, 32, IEM_MC_F_MIN_386); break;
7624 case IEMMODE_64BIT: IEM_LODS_CASE(32, 64, IEM_MC_F_64BIT); break;
7625 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7626 }
7627 break;
7628
7629 case IEMMODE_64BIT:
7630 switch (pVCpu->iem.s.enmEffAddrMode)
7631 {
7632 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
7633 case IEMMODE_32BIT: IEM_LODS_CASE(64, 32, IEM_MC_F_64BIT); break;
7634 case IEMMODE_64BIT: IEM_LODS_CASE(64, 64, IEM_MC_F_64BIT); break;
7635 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7636 }
7637 break;
7638 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7639 }
7640}
7641
7642#undef IEM_LODS_CASE
7643
7644/** Macro used by iemOp_scasb_AL_Xb and iemOp_scaswd_eAX_Xv */
7645#define IEM_SCAS_CASE(ValBits, AddrBits, a_fMcFlags) \
7646 IEM_MC_BEGIN(3, 2, a_fMcFlags, 0); \
7647 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
7648 IEM_MC_ARG(uint##ValBits##_t *, puRax, 0); \
7649 IEM_MC_ARG(uint##ValBits##_t, uValue, 1); \
7650 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
7651 IEM_MC_LOCAL(RTGCPTR, uAddr); \
7652 \
7653 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
7654 IEM_MC_FETCH_MEM_U##ValBits(uValue, X86_SREG_ES, uAddr); \
7655 IEM_MC_REF_GREG_U##ValBits(puRax, X86_GREG_xAX); \
7656 IEM_MC_REF_EFLAGS(pEFlags); \
7657 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puRax, uValue, pEFlags); \
7658 \
7659 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
7660 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
7661 } IEM_MC_ELSE() { \
7662 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
7663 } IEM_MC_ENDIF(); \
7664 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
7665 IEM_MC_END();
7666
7667/**
7668 * @opcode 0xae
7669 */
7670FNIEMOP_DEF(iemOp_scasb_AL_Xb)
7671{
7672 /*
7673 * Use the C implementation if a repeat prefix is encountered.
7674 */
7675 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
7676 {
7677 IEMOP_MNEMONIC(repe_scasb_AL_Xb, "repe scasb AL,Xb");
7678 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7679 switch (pVCpu->iem.s.enmEffAddrMode)
7680 {
7681 case IEMMODE_16BIT:
7682 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7683 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7684 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7685 iemCImpl_repe_scas_al_m16);
7686 case IEMMODE_32BIT:
7687 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7688 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7689 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7690 iemCImpl_repe_scas_al_m32);
7691 case IEMMODE_64BIT:
7692 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7693 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7694 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7695 iemCImpl_repe_scas_al_m64);
7696 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7697 }
7698 }
7699 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
7700 {
7701 IEMOP_MNEMONIC(repone_scasb_AL_Xb, "repne scasb AL,Xb");
7702 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7703 switch (pVCpu->iem.s.enmEffAddrMode)
7704 {
7705 case IEMMODE_16BIT:
7706 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7707 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7708 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7709 iemCImpl_repne_scas_al_m16);
7710 case IEMMODE_32BIT:
7711 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7712 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7713 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7714 iemCImpl_repne_scas_al_m32);
7715 case IEMMODE_64BIT:
7716 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7717 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7718 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7719 iemCImpl_repne_scas_al_m64);
7720 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7721 }
7722 }
7723
7724 /*
7725 * Sharing case implementation with stos[wdq] below.
7726 */
7727 IEMOP_MNEMONIC(scasb_AL_Xb, "scasb AL,Xb");
7728 switch (pVCpu->iem.s.enmEffAddrMode)
7729 {
7730 case IEMMODE_16BIT: IEM_SCAS_CASE(8, 16, IEM_MC_F_NOT_64BIT); break;
7731 case IEMMODE_32BIT: IEM_SCAS_CASE(8, 32, IEM_MC_F_MIN_386); break;
7732 case IEMMODE_64BIT: IEM_SCAS_CASE(8, 64, IEM_MC_F_64BIT); break;
7733 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7734 }
7735}
7736
7737
7738/**
7739 * @opcode 0xaf
7740 */
7741FNIEMOP_DEF(iemOp_scaswd_eAX_Xv)
7742{
7743 /*
7744 * Use the C implementation if a repeat prefix is encountered.
7745 */
7746 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
7747 {
7748 IEMOP_MNEMONIC(repe_scas_rAX_Xv, "repe scas rAX,Xv");
7749 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7750 switch (pVCpu->iem.s.enmEffOpSize)
7751 {
7752 case IEMMODE_16BIT:
7753 switch (pVCpu->iem.s.enmEffAddrMode)
7754 {
7755 case IEMMODE_16BIT:
7756 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7757 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7758 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7759 iemCImpl_repe_scas_ax_m16);
7760 case IEMMODE_32BIT:
7761 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7762 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7763 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7764 iemCImpl_repe_scas_ax_m32);
7765 case IEMMODE_64BIT:
7766 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7767 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7768 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7769 iemCImpl_repe_scas_ax_m64);
7770 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7771 }
7772 break;
7773 case IEMMODE_32BIT:
7774 switch (pVCpu->iem.s.enmEffAddrMode)
7775 {
7776 case IEMMODE_16BIT:
7777 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7778 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7779 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7780 iemCImpl_repe_scas_eax_m16);
7781 case IEMMODE_32BIT:
7782 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7783 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7784 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7785 iemCImpl_repe_scas_eax_m32);
7786 case IEMMODE_64BIT:
7787 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7788 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7789 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7790 iemCImpl_repe_scas_eax_m64);
7791 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7792 }
7793 case IEMMODE_64BIT:
7794 switch (pVCpu->iem.s.enmEffAddrMode)
7795 {
7796 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_6); /** @todo It's this wrong, we can do 16-bit addressing in 64-bit mode, but not 32-bit. right? */
7797 case IEMMODE_32BIT:
7798 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7799 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7800 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7801 iemCImpl_repe_scas_rax_m32);
7802 case IEMMODE_64BIT:
7803 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7804 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7805 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7806 iemCImpl_repe_scas_rax_m64);
7807 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7808 }
7809 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7810 }
7811 }
7812 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
7813 {
7814 IEMOP_MNEMONIC(repne_scas_rAX_Xv, "repne scas rAX,Xv");
7815 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7816 switch (pVCpu->iem.s.enmEffOpSize)
7817 {
7818 case IEMMODE_16BIT:
7819 switch (pVCpu->iem.s.enmEffAddrMode)
7820 {
7821 case IEMMODE_16BIT:
7822 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7823 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7824 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7825 iemCImpl_repne_scas_ax_m16);
7826 case IEMMODE_32BIT:
7827 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7828 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7829 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7830 iemCImpl_repne_scas_ax_m32);
7831 case IEMMODE_64BIT:
7832 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7833 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7834 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7835 iemCImpl_repne_scas_ax_m64);
7836 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7837 }
7838 break;
7839 case IEMMODE_32BIT:
7840 switch (pVCpu->iem.s.enmEffAddrMode)
7841 {
7842 case IEMMODE_16BIT:
7843 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7844 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7845 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7846 iemCImpl_repne_scas_eax_m16);
7847 case IEMMODE_32BIT:
7848 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7849 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7850 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7851 iemCImpl_repne_scas_eax_m32);
7852 case IEMMODE_64BIT:
7853 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7854 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7855 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7856 iemCImpl_repne_scas_eax_m64);
7857 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7858 }
7859 case IEMMODE_64BIT:
7860 switch (pVCpu->iem.s.enmEffAddrMode)
7861 {
7862 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_5);
7863 case IEMMODE_32BIT:
7864 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7865 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7866 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7867 iemCImpl_repne_scas_rax_m32);
7868 case IEMMODE_64BIT:
7869 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_REP | IEM_CIMPL_F_STATUS_FLAGS,
7870 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xDI)
7871 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xCX),
7872 iemCImpl_repne_scas_rax_m64);
7873 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7874 }
7875 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7876 }
7877 }
7878
7879 /*
7880 * Annoying double switch here.
7881 * Using ugly macro for implementing the cases, sharing it with scasb.
7882 */
7883 IEMOP_MNEMONIC(scas_rAX_Xv, "scas rAX,Xv");
7884 switch (pVCpu->iem.s.enmEffOpSize)
7885 {
7886 case IEMMODE_16BIT:
7887 switch (pVCpu->iem.s.enmEffAddrMode)
7888 {
7889 case IEMMODE_16BIT: IEM_SCAS_CASE(16, 16, IEM_MC_F_NOT_64BIT); break;
7890 case IEMMODE_32BIT: IEM_SCAS_CASE(16, 32, IEM_MC_F_MIN_386); break;
7891 case IEMMODE_64BIT: IEM_SCAS_CASE(16, 64, IEM_MC_F_64BIT); break;
7892 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7893 }
7894 break;
7895
7896 case IEMMODE_32BIT:
7897 switch (pVCpu->iem.s.enmEffAddrMode)
7898 {
7899 case IEMMODE_16BIT: IEM_SCAS_CASE(32, 16, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT); break;
7900 case IEMMODE_32BIT: IEM_SCAS_CASE(32, 32, IEM_MC_F_MIN_386); break;
7901 case IEMMODE_64BIT: IEM_SCAS_CASE(32, 64, IEM_MC_F_64BIT); break;
7902 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7903 }
7904 break;
7905
7906 case IEMMODE_64BIT:
7907 switch (pVCpu->iem.s.enmEffAddrMode)
7908 {
7909 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
7910 case IEMMODE_32BIT: IEM_SCAS_CASE(64, 32, IEM_MC_F_64BIT); break;
7911 case IEMMODE_64BIT: IEM_SCAS_CASE(64, 64, IEM_MC_F_64BIT); break;
7912 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7913 }
7914 break;
7915 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7916 }
7917}
7918
7919#undef IEM_SCAS_CASE
7920
7921/**
7922 * Common 'mov r8, imm8' helper.
7923 */
7924FNIEMOP_DEF_1(iemOpCommonMov_r8_Ib, uint8_t, iFixedReg)
7925{
7926 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
7927 IEM_MC_BEGIN(0, 0, 0, 0);
7928 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7929 IEM_MC_STORE_GREG_U8_CONST(iFixedReg, u8Imm);
7930 IEM_MC_ADVANCE_RIP_AND_FINISH();
7931 IEM_MC_END();
7932}
7933
7934
7935/**
7936 * @opcode 0xb0
7937 */
7938FNIEMOP_DEF(iemOp_mov_AL_Ib)
7939{
7940 IEMOP_MNEMONIC(mov_AL_Ib, "mov AL,Ib");
7941 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xAX | pVCpu->iem.s.uRexB);
7942}
7943
7944
7945/**
7946 * @opcode 0xb1
7947 */
7948FNIEMOP_DEF(iemOp_CL_Ib)
7949{
7950 IEMOP_MNEMONIC(mov_CL_Ib, "mov CL,Ib");
7951 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xCX | pVCpu->iem.s.uRexB);
7952}
7953
7954
7955/**
7956 * @opcode 0xb2
7957 */
7958FNIEMOP_DEF(iemOp_DL_Ib)
7959{
7960 IEMOP_MNEMONIC(mov_DL_Ib, "mov DL,Ib");
7961 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xDX | pVCpu->iem.s.uRexB);
7962}
7963
7964
7965/**
7966 * @opcode 0xb3
7967 */
7968FNIEMOP_DEF(iemOp_BL_Ib)
7969{
7970 IEMOP_MNEMONIC(mov_BL_Ib, "mov BL,Ib");
7971 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xBX | pVCpu->iem.s.uRexB);
7972}
7973
7974
7975/**
7976 * @opcode 0xb4
7977 */
7978FNIEMOP_DEF(iemOp_mov_AH_Ib)
7979{
7980 IEMOP_MNEMONIC(mov_AH_Ib, "mov AH,Ib");
7981 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xSP | pVCpu->iem.s.uRexB);
7982}
7983
7984
7985/**
7986 * @opcode 0xb5
7987 */
7988FNIEMOP_DEF(iemOp_CH_Ib)
7989{
7990 IEMOP_MNEMONIC(mov_CH_Ib, "mov CH,Ib");
7991 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xBP | pVCpu->iem.s.uRexB);
7992}
7993
7994
7995/**
7996 * @opcode 0xb6
7997 */
7998FNIEMOP_DEF(iemOp_DH_Ib)
7999{
8000 IEMOP_MNEMONIC(mov_DH_Ib, "mov DH,Ib");
8001 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xSI | pVCpu->iem.s.uRexB);
8002}
8003
8004
8005/**
8006 * @opcode 0xb7
8007 */
8008FNIEMOP_DEF(iemOp_BH_Ib)
8009{
8010 IEMOP_MNEMONIC(mov_BH_Ib, "mov BH,Ib");
8011 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xDI | pVCpu->iem.s.uRexB);
8012}
8013
8014
8015/**
8016 * Common 'mov regX,immX' helper.
8017 */
8018FNIEMOP_DEF_1(iemOpCommonMov_Rv_Iv, uint8_t, iFixedReg)
8019{
8020 switch (pVCpu->iem.s.enmEffOpSize)
8021 {
8022 case IEMMODE_16BIT:
8023 IEM_MC_BEGIN(0, 0, 0, 0);
8024 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
8025 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8026 IEM_MC_STORE_GREG_U16_CONST(iFixedReg, u16Imm);
8027 IEM_MC_ADVANCE_RIP_AND_FINISH();
8028 IEM_MC_END();
8029 break;
8030
8031 case IEMMODE_32BIT:
8032 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
8033 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
8034 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8035 IEM_MC_STORE_GREG_U32_CONST(iFixedReg, u32Imm);
8036 IEM_MC_ADVANCE_RIP_AND_FINISH();
8037 IEM_MC_END();
8038 break;
8039
8040 case IEMMODE_64BIT:
8041 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
8042 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_U64(&u64Imm); /* 64-bit immediate! */
8043 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8044 IEM_MC_STORE_GREG_U64_CONST(iFixedReg, u64Imm);
8045 IEM_MC_ADVANCE_RIP_AND_FINISH();
8046 IEM_MC_END();
8047 break;
8048 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8049 }
8050}
8051
8052
8053/**
8054 * @opcode 0xb8
8055 */
8056FNIEMOP_DEF(iemOp_eAX_Iv)
8057{
8058 IEMOP_MNEMONIC(mov_rAX_IV, "mov rAX,IV");
8059 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xAX | pVCpu->iem.s.uRexB);
8060}
8061
8062
8063/**
8064 * @opcode 0xb9
8065 */
8066FNIEMOP_DEF(iemOp_eCX_Iv)
8067{
8068 IEMOP_MNEMONIC(mov_rCX_IV, "mov rCX,IV");
8069 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xCX | pVCpu->iem.s.uRexB);
8070}
8071
8072
8073/**
8074 * @opcode 0xba
8075 */
8076FNIEMOP_DEF(iemOp_eDX_Iv)
8077{
8078 IEMOP_MNEMONIC(mov_rDX_IV, "mov rDX,IV");
8079 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xDX | pVCpu->iem.s.uRexB);
8080}
8081
8082
8083/**
8084 * @opcode 0xbb
8085 */
8086FNIEMOP_DEF(iemOp_eBX_Iv)
8087{
8088 IEMOP_MNEMONIC(mov_rBX_IV, "mov rBX,IV");
8089 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xBX | pVCpu->iem.s.uRexB);
8090}
8091
8092
8093/**
8094 * @opcode 0xbc
8095 */
8096FNIEMOP_DEF(iemOp_eSP_Iv)
8097{
8098 IEMOP_MNEMONIC(mov_rSP_IV, "mov rSP,IV");
8099 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xSP | pVCpu->iem.s.uRexB);
8100}
8101
8102
8103/**
8104 * @opcode 0xbd
8105 */
8106FNIEMOP_DEF(iemOp_eBP_Iv)
8107{
8108 IEMOP_MNEMONIC(mov_rBP_IV, "mov rBP,IV");
8109 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xBP | pVCpu->iem.s.uRexB);
8110}
8111
8112
8113/**
8114 * @opcode 0xbe
8115 */
8116FNIEMOP_DEF(iemOp_eSI_Iv)
8117{
8118 IEMOP_MNEMONIC(mov_rSI_IV, "mov rSI,IV");
8119 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xSI | pVCpu->iem.s.uRexB);
8120}
8121
8122
8123/**
8124 * @opcode 0xbf
8125 */
8126FNIEMOP_DEF(iemOp_eDI_Iv)
8127{
8128 IEMOP_MNEMONIC(mov_rDI_IV, "mov rDI,IV");
8129 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xDI | pVCpu->iem.s.uRexB);
8130}
8131
8132
8133/**
8134 * @opcode 0xc0
8135 */
8136FNIEMOP_DEF(iemOp_Grp2_Eb_Ib)
8137{
8138 IEMOP_HLP_MIN_186();
8139 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8140 PCIEMOPSHIFTSIZES pImpl;
8141 switch (IEM_GET_MODRM_REG_8(bRm))
8142 {
8143 case 0: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rol_eflags); IEMOP_MNEMONIC(rol_Eb_Ib, "rol Eb,Ib"); break;
8144 case 1: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_ror_eflags); IEMOP_MNEMONIC(ror_Eb_Ib, "ror Eb,Ib"); break;
8145 case 2: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcl_eflags); IEMOP_MNEMONIC(rcl_Eb_Ib, "rcl Eb,Ib"); break;
8146 case 3: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcr_eflags); IEMOP_MNEMONIC(rcr_Eb_Ib, "rcr Eb,Ib"); break;
8147 case 4: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shl_eflags); IEMOP_MNEMONIC(shl_Eb_Ib, "shl Eb,Ib"); break;
8148 case 5: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shr_eflags); IEMOP_MNEMONIC(shr_Eb_Ib, "shr Eb,Ib"); break;
8149 case 7: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_sar_eflags); IEMOP_MNEMONIC(sar_Eb_Ib, "sar Eb,Ib"); break;
8150 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
8151 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
8152 }
8153 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
8154
8155 if (IEM_IS_MODRM_REG_MODE(bRm))
8156 {
8157 /* register */
8158 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
8159 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_186, 0);
8160 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8161 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
8162 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8163 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8164 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8165 IEM_MC_REF_EFLAGS(pEFlags);
8166 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
8167 IEM_MC_ADVANCE_RIP_AND_FINISH();
8168 IEM_MC_END();
8169 }
8170 else
8171 {
8172 /* memory */
8173 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_186, 0);
8174 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8175 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
8176
8177 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
8178 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8179
8180 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8181 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
8182 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8183
8184 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8185 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
8186 IEM_MC_FETCH_EFLAGS(EFlags);
8187 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
8188
8189 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8190 IEM_MC_COMMIT_EFLAGS(EFlags);
8191 IEM_MC_ADVANCE_RIP_AND_FINISH();
8192 IEM_MC_END();
8193 }
8194}
8195
8196
8197/**
8198 * @opcode 0xc1
8199 */
8200FNIEMOP_DEF(iemOp_Grp2_Ev_Ib)
8201{
8202 IEMOP_HLP_MIN_186();
8203 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8204 PCIEMOPSHIFTSIZES pImpl;
8205 switch (IEM_GET_MODRM_REG_8(bRm))
8206 {
8207 case 0: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rol_eflags); IEMOP_MNEMONIC(rol_Ev_Ib, "rol Ev,Ib"); break;
8208 case 1: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_ror_eflags); IEMOP_MNEMONIC(ror_Ev_Ib, "ror Ev,Ib"); break;
8209 case 2: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcl_eflags); IEMOP_MNEMONIC(rcl_Ev_Ib, "rcl Ev,Ib"); break;
8210 case 3: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcr_eflags); IEMOP_MNEMONIC(rcr_Ev_Ib, "rcr Ev,Ib"); break;
8211 case 4: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shl_eflags); IEMOP_MNEMONIC(shl_Ev_Ib, "shl Ev,Ib"); break;
8212 case 5: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shr_eflags); IEMOP_MNEMONIC(shr_Ev_Ib, "shr Ev,Ib"); break;
8213 case 7: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_sar_eflags); IEMOP_MNEMONIC(sar_Ev_Ib, "sar Ev,Ib"); break;
8214 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
8215 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
8216 }
8217 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
8218
8219 if (IEM_IS_MODRM_REG_MODE(bRm))
8220 {
8221 /* register */
8222 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
8223 switch (pVCpu->iem.s.enmEffOpSize)
8224 {
8225 case IEMMODE_16BIT:
8226 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_186, 0);
8227 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8228 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
8229 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8230 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8231 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8232 IEM_MC_REF_EFLAGS(pEFlags);
8233 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
8234 IEM_MC_ADVANCE_RIP_AND_FINISH();
8235 IEM_MC_END();
8236 break;
8237
8238 case IEMMODE_32BIT:
8239 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0);
8240 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8241 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8242 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8243 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8244 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8245 IEM_MC_REF_EFLAGS(pEFlags);
8246 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
8247 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm));
8248 IEM_MC_ADVANCE_RIP_AND_FINISH();
8249 IEM_MC_END();
8250 break;
8251
8252 case IEMMODE_64BIT:
8253 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0);
8254 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8255 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8256 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8257 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8258 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8259 IEM_MC_REF_EFLAGS(pEFlags);
8260 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
8261 IEM_MC_ADVANCE_RIP_AND_FINISH();
8262 IEM_MC_END();
8263 break;
8264
8265 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8266 }
8267 }
8268 else
8269 {
8270 /* memory */
8271 switch (pVCpu->iem.s.enmEffOpSize)
8272 {
8273 case IEMMODE_16BIT:
8274 IEM_MC_BEGIN(3, 3, 0, 0);
8275 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8276 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
8277
8278 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
8279 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8280
8281 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8282 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
8283 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8284
8285 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8286 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
8287 IEM_MC_FETCH_EFLAGS(EFlags);
8288 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
8289
8290 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8291 IEM_MC_COMMIT_EFLAGS(EFlags);
8292 IEM_MC_ADVANCE_RIP_AND_FINISH();
8293 IEM_MC_END();
8294 break;
8295
8296 case IEMMODE_32BIT:
8297 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0);
8298 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8299 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
8300
8301 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
8302 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8303
8304 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8305 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8306 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8307
8308 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8309 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
8310 IEM_MC_FETCH_EFLAGS(EFlags);
8311 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
8312
8313 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8314 IEM_MC_COMMIT_EFLAGS(EFlags);
8315 IEM_MC_ADVANCE_RIP_AND_FINISH();
8316 IEM_MC_END();
8317 break;
8318
8319 case IEMMODE_64BIT:
8320 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0);
8321 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8322 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
8323
8324 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
8325 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8326
8327 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8328 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8329 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8330
8331 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
8332 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
8333 IEM_MC_FETCH_EFLAGS(EFlags);
8334 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
8335
8336 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8337 IEM_MC_COMMIT_EFLAGS(EFlags);
8338 IEM_MC_ADVANCE_RIP_AND_FINISH();
8339 IEM_MC_END();
8340 break;
8341
8342 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8343 }
8344 }
8345}
8346
8347
8348/**
8349 * @opcode 0xc2
8350 */
8351FNIEMOP_DEF(iemOp_retn_Iw)
8352{
8353 IEMOP_MNEMONIC(retn_Iw, "retn Iw");
8354 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
8355 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
8356 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8357 switch (pVCpu->iem.s.enmEffOpSize)
8358 {
8359 case IEMMODE_16BIT:
8360 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_retn_iw_16, u16Imm);
8361 case IEMMODE_32BIT:
8362 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_retn_iw_32, u16Imm);
8363 case IEMMODE_64BIT:
8364 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_retn_iw_64, u16Imm);
8365 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8366 }
8367}
8368
8369
8370/**
8371 * @opcode 0xc3
8372 */
8373FNIEMOP_DEF(iemOp_retn)
8374{
8375 IEMOP_MNEMONIC(retn, "retn");
8376 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
8377 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8378 switch (pVCpu->iem.s.enmEffOpSize)
8379 {
8380 case IEMMODE_16BIT:
8381 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_retn_16);
8382 case IEMMODE_32BIT:
8383 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_retn_32);
8384 case IEMMODE_64BIT:
8385 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_retn_64);
8386 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8387 }
8388}
8389
8390
8391/**
8392 * @opcode 0xc4
8393 */
8394FNIEMOP_DEF(iemOp_les_Gv_Mp__vex3)
8395{
8396 /* The LDS instruction is invalid 64-bit mode. In legacy and
8397 compatability mode it is invalid with MOD=3.
8398 The use as a VEX prefix is made possible by assigning the inverted
8399 REX.R and REX.X to the two MOD bits, since the REX bits are ignored
8400 outside of 64-bit mode. VEX is not available in real or v86 mode. */
8401 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8402 if ( IEM_IS_64BIT_CODE(pVCpu)
8403 || IEM_IS_MODRM_REG_MODE(bRm) )
8404 {
8405 IEMOP_MNEMONIC(vex3_prefix, "vex3");
8406 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVex)
8407 {
8408 /* Note! The real mode, v8086 mode and invalid prefix checks are done once
8409 the instruction is fully decoded. Even when XCR0=3 and CR4.OSXSAVE=0. */
8410 uint8_t bVex2; IEM_OPCODE_GET_NEXT_U8(&bVex2);
8411 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
8412 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
8413 if ((bVex2 & 0x80 /* VEX.W */) && IEM_IS_64BIT_CODE(pVCpu))
8414 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_REX_W;
8415 pVCpu->iem.s.uRexReg = (~bRm >> (7 - 3)) & 0x8;
8416 pVCpu->iem.s.uRexIndex = (~bRm >> (6 - 3)) & 0x8;
8417 pVCpu->iem.s.uRexB = (~bRm >> (5 - 3)) & 0x8;
8418 pVCpu->iem.s.uVex3rdReg = (~bVex2 >> 3) & 0xf;
8419 pVCpu->iem.s.uVexLength = (bVex2 >> 2) & 1;
8420 pVCpu->iem.s.idxPrefix = bVex2 & 0x3;
8421
8422 switch (bRm & 0x1f)
8423 {
8424 case 1: /* 0x0f lead opcode byte. */
8425#ifdef IEM_WITH_VEX
8426 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
8427#else
8428 IEMOP_BITCH_ABOUT_STUB();
8429 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
8430#endif
8431
8432 case 2: /* 0x0f 0x38 lead opcode bytes. */
8433#ifdef IEM_WITH_VEX
8434 return FNIEMOP_CALL(g_apfnVexMap2[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
8435#else
8436 IEMOP_BITCH_ABOUT_STUB();
8437 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
8438#endif
8439
8440 case 3: /* 0x0f 0x3a lead opcode bytes. */
8441#ifdef IEM_WITH_VEX
8442 return FNIEMOP_CALL(g_apfnVexMap3[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
8443#else
8444 IEMOP_BITCH_ABOUT_STUB();
8445 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
8446#endif
8447
8448 default:
8449 Log(("VEX3: Invalid vvvv value: %#x!\n", bRm & 0x1f));
8450 IEMOP_RAISE_INVALID_OPCODE_RET();
8451 }
8452 }
8453 Log(("VEX3: VEX support disabled!\n"));
8454 IEMOP_RAISE_INVALID_OPCODE_RET();
8455 }
8456
8457 IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");
8458 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);
8459}
8460
8461
8462/**
8463 * @opcode 0xc5
8464 */
8465FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex2)
8466{
8467 /* The LES instruction is invalid 64-bit mode. In legacy and
8468 compatability mode it is invalid with MOD=3.
8469 The use as a VEX prefix is made possible by assigning the inverted
8470 REX.R to the top MOD bit, and the top bit in the inverted register
8471 specifier to the bottom MOD bit, thereby effectively limiting 32-bit
8472 to accessing registers 0..7 in this VEX form. */
8473 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8474 if ( IEM_IS_64BIT_CODE(pVCpu)
8475 || IEM_IS_MODRM_REG_MODE(bRm))
8476 {
8477 IEMOP_MNEMONIC(vex2_prefix, "vex2");
8478 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVex)
8479 {
8480 /* Note! The real mode, v8086 mode and invalid prefix checks are done once
8481 the instruction is fully decoded. Even when XCR0=3 and CR4.OSXSAVE=0. */
8482 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
8483 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
8484 pVCpu->iem.s.uRexReg = (~bRm >> (7 - 3)) & 0x8;
8485 pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;
8486 pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;
8487 pVCpu->iem.s.idxPrefix = bRm & 0x3;
8488
8489#ifdef IEM_WITH_VEX
8490 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
8491#else
8492 IEMOP_BITCH_ABOUT_STUB();
8493 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
8494#endif
8495 }
8496
8497 /** @todo does intel completely decode the sequence with SIB/disp before \#UD? */
8498 Log(("VEX2: VEX support disabled!\n"));
8499 IEMOP_RAISE_INVALID_OPCODE_RET();
8500 }
8501
8502 IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp");
8503 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm);
8504}
8505
8506
8507/**
8508 * @opcode 0xc6
8509 */
8510FNIEMOP_DEF(iemOp_Grp11_Eb_Ib)
8511{
8512 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8513 if ((bRm & X86_MODRM_REG_MASK) != (0 << X86_MODRM_REG_SHIFT)) /* only mov Eb,Ib in this group. */
8514 IEMOP_RAISE_INVALID_OPCODE_RET();
8515 IEMOP_MNEMONIC(mov_Eb_Ib, "mov Eb,Ib");
8516
8517 if (IEM_IS_MODRM_REG_MODE(bRm))
8518 {
8519 /* register access */
8520 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
8521 IEM_MC_BEGIN(0, 0, 0, 0);
8522 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8523 IEM_MC_STORE_GREG_U8_CONST(IEM_GET_MODRM_RM(pVCpu, bRm), u8Imm);
8524 IEM_MC_ADVANCE_RIP_AND_FINISH();
8525 IEM_MC_END();
8526 }
8527 else
8528 {
8529 /* memory access. */
8530 IEM_MC_BEGIN(0, 1, 0, 0);
8531 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8532 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
8533 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
8534 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8535 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u8Imm);
8536 IEM_MC_ADVANCE_RIP_AND_FINISH();
8537 IEM_MC_END();
8538 }
8539}
8540
8541
8542/**
8543 * @opcode 0xc7
8544 */
8545FNIEMOP_DEF(iemOp_Grp11_Ev_Iz)
8546{
8547 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8548 if ((bRm & X86_MODRM_REG_MASK) != (0 << X86_MODRM_REG_SHIFT)) /* only mov Eb,Iz in this group. */
8549 IEMOP_RAISE_INVALID_OPCODE_RET();
8550 IEMOP_MNEMONIC(mov_Ev_Iz, "mov Ev,Iz");
8551
8552 if (IEM_IS_MODRM_REG_MODE(bRm))
8553 {
8554 /* register access */
8555 switch (pVCpu->iem.s.enmEffOpSize)
8556 {
8557 case IEMMODE_16BIT:
8558 IEM_MC_BEGIN(0, 0, 0, 0);
8559 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
8560 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8561 IEM_MC_STORE_GREG_U16_CONST(IEM_GET_MODRM_RM(pVCpu, bRm), u16Imm);
8562 IEM_MC_ADVANCE_RIP_AND_FINISH();
8563 IEM_MC_END();
8564 break;
8565
8566 case IEMMODE_32BIT:
8567 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
8568 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
8569 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8570 IEM_MC_STORE_GREG_U32_CONST(IEM_GET_MODRM_RM(pVCpu, bRm), u32Imm);
8571 IEM_MC_ADVANCE_RIP_AND_FINISH();
8572 IEM_MC_END();
8573 break;
8574
8575 case IEMMODE_64BIT:
8576 IEM_MC_BEGIN(0, 0, IEM_MC_F_64BIT, 0);
8577 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
8578 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8579 IEM_MC_STORE_GREG_U64_CONST(IEM_GET_MODRM_RM(pVCpu, bRm), u64Imm);
8580 IEM_MC_ADVANCE_RIP_AND_FINISH();
8581 IEM_MC_END();
8582 break;
8583
8584 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8585 }
8586 }
8587 else
8588 {
8589 /* memory access. */
8590 switch (pVCpu->iem.s.enmEffOpSize)
8591 {
8592 case IEMMODE_16BIT:
8593 IEM_MC_BEGIN(0, 1, 0, 0);
8594 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8595 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
8596 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
8597 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8598 IEM_MC_STORE_MEM_U16_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Imm);
8599 IEM_MC_ADVANCE_RIP_AND_FINISH();
8600 IEM_MC_END();
8601 break;
8602
8603 case IEMMODE_32BIT:
8604 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
8605 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8606 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
8607 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
8608 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8609 IEM_MC_STORE_MEM_U32_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u32Imm);
8610 IEM_MC_ADVANCE_RIP_AND_FINISH();
8611 IEM_MC_END();
8612 break;
8613
8614 case IEMMODE_64BIT:
8615 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
8616 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8617 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
8618 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
8619 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8620 IEM_MC_STORE_MEM_U64_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u64Imm);
8621 IEM_MC_ADVANCE_RIP_AND_FINISH();
8622 IEM_MC_END();
8623 break;
8624
8625 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8626 }
8627 }
8628}
8629
8630
8631
8632
8633/**
8634 * @opcode 0xc8
8635 */
8636FNIEMOP_DEF(iemOp_enter_Iw_Ib)
8637{
8638 IEMOP_MNEMONIC(enter_Iw_Ib, "enter Iw,Ib");
8639 IEMOP_HLP_MIN_186();
8640 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
8641 uint16_t cbFrame; IEM_OPCODE_GET_NEXT_U16(&cbFrame);
8642 uint8_t u8NestingLevel; IEM_OPCODE_GET_NEXT_U8(&u8NestingLevel);
8643 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8644 IEM_MC_DEFER_TO_CIMPL_3_RET(0,
8645 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
8646 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xBP),
8647 iemCImpl_enter, pVCpu->iem.s.enmEffOpSize, cbFrame, u8NestingLevel);
8648}
8649
8650
8651/**
8652 * @opcode 0xc9
8653 */
8654FNIEMOP_DEF(iemOp_leave)
8655{
8656 IEMOP_MNEMONIC(leave, "leave");
8657 IEMOP_HLP_MIN_186();
8658 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
8659 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8660 IEM_MC_DEFER_TO_CIMPL_1_RET(0,
8661 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xSP)
8662 | RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xBP),
8663 iemCImpl_leave, pVCpu->iem.s.enmEffOpSize);
8664}
8665
8666
8667/**
8668 * @opcode 0xca
8669 */
8670FNIEMOP_DEF(iemOp_retf_Iw)
8671{
8672 IEMOP_MNEMONIC(retf_Iw, "retf Iw");
8673 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
8674 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8675 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK
8676 | IEM_CIMPL_F_MODE,
8677 RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_DS)
8678 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_ES)
8679 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_FS)
8680 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_GS)
8681 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_DS)
8682 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_ES)
8683 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_FS)
8684 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_GS)
8685 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_DS)
8686 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_ES)
8687 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_FS)
8688 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_GS),
8689 iemCImpl_retf, pVCpu->iem.s.enmEffOpSize, u16Imm);
8690}
8691
8692
8693/**
8694 * @opcode 0xcb
8695 */
8696FNIEMOP_DEF(iemOp_retf)
8697{
8698 IEMOP_MNEMONIC(retf, "retf");
8699 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8700 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK
8701 | IEM_CIMPL_F_MODE,
8702 RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_DS)
8703 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_ES)
8704 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_FS)
8705 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_GS)
8706 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_DS)
8707 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_ES)
8708 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_FS)
8709 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_GS)
8710 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_DS)
8711 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_ES)
8712 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_FS)
8713 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_GS),
8714 iemCImpl_retf, pVCpu->iem.s.enmEffOpSize, 0);
8715}
8716
8717
8718/**
8719 * @opcode 0xcc
8720 */
8721FNIEMOP_DEF(iemOp_int3)
8722{
8723 IEMOP_MNEMONIC(int3, "int3");
8724 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8725 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK_FAR
8726 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_END_TB, 0,
8727 iemCImpl_int, X86_XCPT_BP, IEMINT_INT3);
8728}
8729
8730
8731/**
8732 * @opcode 0xcd
8733 */
8734FNIEMOP_DEF(iemOp_int_Ib)
8735{
8736 IEMOP_MNEMONIC(int_Ib, "int Ib");
8737 uint8_t u8Int; IEM_OPCODE_GET_NEXT_U8(&u8Int);
8738 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8739 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK_FAR
8740 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS, UINT64_MAX,
8741 iemCImpl_int, u8Int, IEMINT_INTN);
8742 /** @todo make task-switches, ring-switches, ++ return non-zero status */
8743}
8744
8745
8746/**
8747 * @opcode 0xce
8748 */
8749FNIEMOP_DEF(iemOp_into)
8750{
8751 IEMOP_MNEMONIC(into, "into");
8752 IEMOP_HLP_NO_64BIT();
8753 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK_FAR
8754 | IEM_CIMPL_F_BRANCH_CONDITIONAL | IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS,
8755 UINT64_MAX,
8756 iemCImpl_int, X86_XCPT_OF, IEMINT_INTO);
8757 /** @todo make task-switches, ring-switches, ++ return non-zero status */
8758}
8759
8760
8761/**
8762 * @opcode 0xcf
8763 */
8764FNIEMOP_DEF(iemOp_iret)
8765{
8766 IEMOP_MNEMONIC(iret, "iret");
8767 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8768 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK_FAR
8769 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_CHECK_IRQ_BEFORE | IEM_CIMPL_F_VMEXIT,
8770 RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_DS)
8771 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_DS)
8772 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_DS)
8773 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_ES)
8774 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_ES)
8775 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_ES)
8776 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_FS)
8777 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_FS)
8778 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_FS)
8779 | RT_BIT_64(kIemNativeGstReg_SegSelFirst + X86_SREG_GS)
8780 | RT_BIT_64(kIemNativeGstReg_SegBaseFirst + X86_SREG_GS)
8781 | RT_BIT_64(kIemNativeGstReg_SegLimitFirst + X86_SREG_GS),
8782 iemCImpl_iret, pVCpu->iem.s.enmEffOpSize);
8783 /* Segment registers are sanitized when returning to an outer ring, or fully
8784 reloaded when returning to v86 mode. Thus the large flush list above. */
8785}
8786
8787
8788/**
8789 * @opcode 0xd0
8790 */
8791FNIEMOP_DEF(iemOp_Grp2_Eb_1)
8792{
8793 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8794 PCIEMOPSHIFTSIZES pImpl;
8795 switch (IEM_GET_MODRM_REG_8(bRm))
8796 {
8797 case 0: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rol_eflags); IEMOP_MNEMONIC(rol_Eb_1, "rol Eb,1"); break;
8798 case 1: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_ror_eflags); IEMOP_MNEMONIC(ror_Eb_1, "ror Eb,1"); break;
8799 case 2: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcl_eflags); IEMOP_MNEMONIC(rcl_Eb_1, "rcl Eb,1"); break;
8800 case 3: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcr_eflags); IEMOP_MNEMONIC(rcr_Eb_1, "rcr Eb,1"); break;
8801 case 4: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shl_eflags); IEMOP_MNEMONIC(shl_Eb_1, "shl Eb,1"); break;
8802 case 5: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shr_eflags); IEMOP_MNEMONIC(shr_Eb_1, "shr Eb,1"); break;
8803 case 7: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_sar_eflags); IEMOP_MNEMONIC(sar_Eb_1, "sar Eb,1"); break;
8804 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
8805 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
8806 }
8807 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
8808
8809 if (IEM_IS_MODRM_REG_MODE(bRm))
8810 {
8811 /* register */
8812 IEM_MC_BEGIN(3, 0, 0, 0);
8813 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8814 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
8815 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=*/1, 1);
8816 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8817 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8818 IEM_MC_REF_EFLAGS(pEFlags);
8819 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
8820 IEM_MC_ADVANCE_RIP_AND_FINISH();
8821 IEM_MC_END();
8822 }
8823 else
8824 {
8825 /* memory */
8826 IEM_MC_BEGIN(3, 3, 0, 0);
8827 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
8828 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=*/1, 1);
8829 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8830 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8831 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8832
8833 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8834 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8835 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8836 IEM_MC_FETCH_EFLAGS(EFlags);
8837 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
8838
8839 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8840 IEM_MC_COMMIT_EFLAGS(EFlags);
8841 IEM_MC_ADVANCE_RIP_AND_FINISH();
8842 IEM_MC_END();
8843 }
8844}
8845
8846
8847
8848/**
8849 * @opcode 0xd1
8850 */
8851FNIEMOP_DEF(iemOp_Grp2_Ev_1)
8852{
8853 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8854 PCIEMOPSHIFTSIZES pImpl;
8855 switch (IEM_GET_MODRM_REG_8(bRm))
8856 {
8857 case 0: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rol_eflags); IEMOP_MNEMONIC(rol_Ev_1, "rol Ev,1"); break;
8858 case 1: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_ror_eflags); IEMOP_MNEMONIC(ror_Ev_1, "ror Ev,1"); break;
8859 case 2: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcl_eflags); IEMOP_MNEMONIC(rcl_Ev_1, "rcl Ev,1"); break;
8860 case 3: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcr_eflags); IEMOP_MNEMONIC(rcr_Ev_1, "rcr Ev,1"); break;
8861 case 4: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shl_eflags); IEMOP_MNEMONIC(shl_Ev_1, "shl Ev,1"); break;
8862 case 5: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shr_eflags); IEMOP_MNEMONIC(shr_Ev_1, "shr Ev,1"); break;
8863 case 7: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_sar_eflags); IEMOP_MNEMONIC(sar_Ev_1, "sar Ev,1"); break;
8864 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
8865 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
8866 }
8867 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
8868
8869 if (IEM_IS_MODRM_REG_MODE(bRm))
8870 {
8871 /* register */
8872 switch (pVCpu->iem.s.enmEffOpSize)
8873 {
8874 case IEMMODE_16BIT:
8875 IEM_MC_BEGIN(3, 0, 0, 0);
8876 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8877 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
8878 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
8879 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8880 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8881 IEM_MC_REF_EFLAGS(pEFlags);
8882 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
8883 IEM_MC_ADVANCE_RIP_AND_FINISH();
8884 IEM_MC_END();
8885 break;
8886
8887 case IEMMODE_32BIT:
8888 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0);
8889 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8890 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8891 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
8892 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8893 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8894 IEM_MC_REF_EFLAGS(pEFlags);
8895 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
8896 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm));
8897 IEM_MC_ADVANCE_RIP_AND_FINISH();
8898 IEM_MC_END();
8899 break;
8900
8901 case IEMMODE_64BIT:
8902 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0);
8903 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8904 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8905 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
8906 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8907 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
8908 IEM_MC_REF_EFLAGS(pEFlags);
8909 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
8910 IEM_MC_ADVANCE_RIP_AND_FINISH();
8911 IEM_MC_END();
8912 break;
8913
8914 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8915 }
8916 }
8917 else
8918 {
8919 /* memory */
8920 switch (pVCpu->iem.s.enmEffOpSize)
8921 {
8922 case IEMMODE_16BIT:
8923 IEM_MC_BEGIN(3, 3, 0, 0);
8924 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
8925 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
8926 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8927 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8928 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8929
8930 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8931 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8932 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8933 IEM_MC_FETCH_EFLAGS(EFlags);
8934 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
8935
8936 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8937 IEM_MC_COMMIT_EFLAGS(EFlags);
8938 IEM_MC_ADVANCE_RIP_AND_FINISH();
8939 IEM_MC_END();
8940 break;
8941
8942 case IEMMODE_32BIT:
8943 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0);
8944 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8945 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
8946 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8947 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8948 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8949
8950 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8951 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8952 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8953 IEM_MC_FETCH_EFLAGS(EFlags);
8954 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
8955
8956 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8957 IEM_MC_COMMIT_EFLAGS(EFlags);
8958 IEM_MC_ADVANCE_RIP_AND_FINISH();
8959 IEM_MC_END();
8960 break;
8961
8962 case IEMMODE_64BIT:
8963 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0);
8964 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8965 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
8966 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8967 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8968 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
8969
8970 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8971 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8972 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8973 IEM_MC_FETCH_EFLAGS(EFlags);
8974 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
8975
8976 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
8977 IEM_MC_COMMIT_EFLAGS(EFlags);
8978 IEM_MC_ADVANCE_RIP_AND_FINISH();
8979 IEM_MC_END();
8980 break;
8981
8982 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8983 }
8984 }
8985}
8986
8987
8988/**
8989 * @opcode 0xd2
8990 */
8991FNIEMOP_DEF(iemOp_Grp2_Eb_CL)
8992{
8993 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8994 PCIEMOPSHIFTSIZES pImpl;
8995 switch (IEM_GET_MODRM_REG_8(bRm))
8996 {
8997 case 0: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rol_eflags); IEMOP_MNEMONIC(rol_Eb_CL, "rol Eb,CL"); break;
8998 case 1: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_ror_eflags); IEMOP_MNEMONIC(ror_Eb_CL, "ror Eb,CL"); break;
8999 case 2: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcl_eflags); IEMOP_MNEMONIC(rcl_Eb_CL, "rcl Eb,CL"); break;
9000 case 3: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcr_eflags); IEMOP_MNEMONIC(rcr_Eb_CL, "rcr Eb,CL"); break;
9001 case 4: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shl_eflags); IEMOP_MNEMONIC(shl_Eb_CL, "shl Eb,CL"); break;
9002 case 5: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shr_eflags); IEMOP_MNEMONIC(shr_Eb_CL, "shr Eb,CL"); break;
9003 case 7: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_sar_eflags); IEMOP_MNEMONIC(sar_Eb_CL, "sar Eb,CL"); break;
9004 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
9005 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc, grr. */
9006 }
9007 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
9008
9009 if (IEM_IS_MODRM_REG_MODE(bRm))
9010 {
9011 /* register */
9012 IEM_MC_BEGIN(3, 0, 0, 0);
9013 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9014 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
9015 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9016 IEM_MC_ARG(uint32_t *, pEFlags, 2);
9017 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9018 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
9019 IEM_MC_REF_EFLAGS(pEFlags);
9020 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
9021 IEM_MC_ADVANCE_RIP_AND_FINISH();
9022 IEM_MC_END();
9023 }
9024 else
9025 {
9026 /* memory */
9027 IEM_MC_BEGIN(3, 3, 0, 0);
9028 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
9029 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9030 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
9031 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9032 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
9033
9034 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9035 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9036 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9037 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9038 IEM_MC_FETCH_EFLAGS(EFlags);
9039 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
9040
9041 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
9042 IEM_MC_COMMIT_EFLAGS(EFlags);
9043 IEM_MC_ADVANCE_RIP_AND_FINISH();
9044 IEM_MC_END();
9045 }
9046}
9047
9048
9049/**
9050 * @opcode 0xd3
9051 */
9052FNIEMOP_DEF(iemOp_Grp2_Ev_CL)
9053{
9054 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9055 PCIEMOPSHIFTSIZES pImpl;
9056 switch (IEM_GET_MODRM_REG_8(bRm))
9057 {
9058 case 0: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rol_eflags); IEMOP_MNEMONIC(rol_Ev_CL, "rol Ev,CL"); break;
9059 case 1: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_ror_eflags); IEMOP_MNEMONIC(ror_Ev_CL, "ror Ev,CL"); break;
9060 case 2: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcl_eflags); IEMOP_MNEMONIC(rcl_Ev_CL, "rcl Ev,CL"); break;
9061 case 3: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_rcr_eflags); IEMOP_MNEMONIC(rcr_Ev_CL, "rcr Ev,CL"); break;
9062 case 4: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shl_eflags); IEMOP_MNEMONIC(shl_Ev_CL, "shl Ev,CL"); break;
9063 case 5: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_shr_eflags); IEMOP_MNEMONIC(shr_Ev_CL, "shr Ev,CL"); break;
9064 case 7: pImpl = IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_sar_eflags); IEMOP_MNEMONIC(sar_Ev_CL, "sar Ev,CL"); break;
9065 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
9066 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
9067 }
9068 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
9069
9070 if (IEM_IS_MODRM_REG_MODE(bRm))
9071 {
9072 /* register */
9073 switch (pVCpu->iem.s.enmEffOpSize)
9074 {
9075 case IEMMODE_16BIT:
9076 IEM_MC_BEGIN(3, 0, 0, 0);
9077 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9078 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
9079 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9080 IEM_MC_ARG(uint32_t *, pEFlags, 2);
9081 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9082 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
9083 IEM_MC_REF_EFLAGS(pEFlags);
9084 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
9085 IEM_MC_ADVANCE_RIP_AND_FINISH();
9086 IEM_MC_END();
9087 break;
9088
9089 case IEMMODE_32BIT:
9090 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0);
9091 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9092 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
9093 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9094 IEM_MC_ARG(uint32_t *, pEFlags, 2);
9095 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9096 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
9097 IEM_MC_REF_EFLAGS(pEFlags);
9098 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
9099 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm));
9100 IEM_MC_ADVANCE_RIP_AND_FINISH();
9101 IEM_MC_END();
9102 break;
9103
9104 case IEMMODE_64BIT:
9105 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0);
9106 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9107 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
9108 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9109 IEM_MC_ARG(uint32_t *, pEFlags, 2);
9110 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9111 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
9112 IEM_MC_REF_EFLAGS(pEFlags);
9113 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
9114 IEM_MC_ADVANCE_RIP_AND_FINISH();
9115 IEM_MC_END();
9116 break;
9117
9118 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9119 }
9120 }
9121 else
9122 {
9123 /* memory */
9124 switch (pVCpu->iem.s.enmEffOpSize)
9125 {
9126 case IEMMODE_16BIT:
9127 IEM_MC_BEGIN(3, 3, 0, 0);
9128 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
9129 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9130 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
9131 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9132 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
9133
9134 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9135 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9136 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9137 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9138 IEM_MC_FETCH_EFLAGS(EFlags);
9139 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
9140
9141 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
9142 IEM_MC_COMMIT_EFLAGS(EFlags);
9143 IEM_MC_ADVANCE_RIP_AND_FINISH();
9144 IEM_MC_END();
9145 break;
9146
9147 case IEMMODE_32BIT:
9148 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0);
9149 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
9150 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9151 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
9152 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9153 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
9154
9155 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9156 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9157 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9158 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9159 IEM_MC_FETCH_EFLAGS(EFlags);
9160 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
9161
9162 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
9163 IEM_MC_COMMIT_EFLAGS(EFlags);
9164 IEM_MC_ADVANCE_RIP_AND_FINISH();
9165 IEM_MC_END();
9166 break;
9167
9168 case IEMMODE_64BIT:
9169 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0);
9170 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
9171 IEM_MC_ARG(uint8_t, cShiftArg, 1);
9172 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
9173 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9174 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
9175
9176 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9177 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9178 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
9179 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9180 IEM_MC_FETCH_EFLAGS(EFlags);
9181 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
9182
9183 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo);
9184 IEM_MC_COMMIT_EFLAGS(EFlags);
9185 IEM_MC_ADVANCE_RIP_AND_FINISH();
9186 IEM_MC_END();
9187 break;
9188
9189 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9190 }
9191 }
9192}
9193
9194/**
9195 * @opcode 0xd4
9196 */
9197FNIEMOP_DEF(iemOp_aam_Ib)
9198{
9199 IEMOP_MNEMONIC(aam_Ib, "aam Ib");
9200 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
9201 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9202 IEMOP_HLP_NO_64BIT();
9203 if (!bImm)
9204 IEMOP_RAISE_DIVIDE_ERROR_RET();
9205 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_STATUS_FLAGS, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX), iemCImpl_aam, bImm);
9206}
9207
9208
9209/**
9210 * @opcode 0xd5
9211 */
9212FNIEMOP_DEF(iemOp_aad_Ib)
9213{
9214 IEMOP_MNEMONIC(aad_Ib, "aad Ib");
9215 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
9216 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9217 IEMOP_HLP_NO_64BIT();
9218 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_STATUS_FLAGS, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX), iemCImpl_aad, bImm);
9219}
9220
9221
9222/**
9223 * @opcode 0xd6
9224 */
9225FNIEMOP_DEF(iemOp_salc)
9226{
9227 IEMOP_MNEMONIC(salc, "salc");
9228 IEMOP_HLP_NO_64BIT();
9229
9230 IEM_MC_BEGIN(0, 0, 0, 0);
9231 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9232 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
9233 IEM_MC_STORE_GREG_U8_CONST(X86_GREG_xAX, 0xff);
9234 } IEM_MC_ELSE() {
9235 IEM_MC_STORE_GREG_U8_CONST(X86_GREG_xAX, 0x00);
9236 } IEM_MC_ENDIF();
9237 IEM_MC_ADVANCE_RIP_AND_FINISH();
9238 IEM_MC_END();
9239}
9240
9241
9242/**
9243 * @opcode 0xd7
9244 */
9245FNIEMOP_DEF(iemOp_xlat)
9246{
9247 IEMOP_MNEMONIC(xlat, "xlat");
9248 switch (pVCpu->iem.s.enmEffAddrMode)
9249 {
9250 case IEMMODE_16BIT:
9251 IEM_MC_BEGIN(2, 0, 0, 0);
9252 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9253 IEM_MC_LOCAL(uint8_t, u8Tmp);
9254 IEM_MC_LOCAL(uint16_t, u16Addr);
9255 IEM_MC_FETCH_GREG_U8_ZX_U16(u16Addr, X86_GREG_xAX);
9256 IEM_MC_ADD_GREG_U16_TO_LOCAL(u16Addr, X86_GREG_xBX);
9257 IEM_MC_FETCH_MEM16_U8(u8Tmp, pVCpu->iem.s.iEffSeg, u16Addr);
9258 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
9259 IEM_MC_ADVANCE_RIP_AND_FINISH();
9260 IEM_MC_END();
9261 break;
9262
9263 case IEMMODE_32BIT:
9264 IEM_MC_BEGIN(2, 0, IEM_MC_F_MIN_386, 0);
9265 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9266 IEM_MC_LOCAL(uint8_t, u8Tmp);
9267 IEM_MC_LOCAL(uint32_t, u32Addr);
9268 IEM_MC_FETCH_GREG_U8_ZX_U32(u32Addr, X86_GREG_xAX);
9269 IEM_MC_ADD_GREG_U32_TO_LOCAL(u32Addr, X86_GREG_xBX);
9270 IEM_MC_FETCH_MEM32_U8(u8Tmp, pVCpu->iem.s.iEffSeg, u32Addr);
9271 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
9272 IEM_MC_ADVANCE_RIP_AND_FINISH();
9273 IEM_MC_END();
9274 break;
9275
9276 case IEMMODE_64BIT:
9277 IEM_MC_BEGIN(2, 0, IEM_MC_F_64BIT, 0);
9278 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9279 IEM_MC_LOCAL(uint8_t, u8Tmp);
9280 IEM_MC_LOCAL(uint64_t, u64Addr);
9281 IEM_MC_FETCH_GREG_U8_ZX_U64(u64Addr, X86_GREG_xAX);
9282 IEM_MC_ADD_GREG_U64_TO_LOCAL(u64Addr, X86_GREG_xBX);
9283 IEM_MC_FETCH_MEM_U8(u8Tmp, pVCpu->iem.s.iEffSeg, u64Addr);
9284 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
9285 IEM_MC_ADVANCE_RIP_AND_FINISH();
9286 IEM_MC_END();
9287 break;
9288
9289 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9290 }
9291}
9292
9293
9294/**
9295 * Common worker for FPU instructions working on ST0 and STn, and storing the
9296 * result in ST0.
9297 *
9298 * @param bRm Mod R/M byte.
9299 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9300 */
9301FNIEMOP_DEF_2(iemOpHlpFpu_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
9302{
9303 IEM_MC_BEGIN(3, 1, 0, 0);
9304 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9305 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9306 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9307 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9308 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
9309
9310 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9311 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9312 IEM_MC_PREPARE_FPU_USAGE();
9313 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, IEM_GET_MODRM_RM_8(bRm)) {
9314 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr80Value2);
9315 IEM_MC_STORE_FPU_RESULT(FpuRes, 0, pVCpu->iem.s.uFpuOpcode);
9316 } IEM_MC_ELSE() {
9317 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
9318 } IEM_MC_ENDIF();
9319 IEM_MC_ADVANCE_RIP_AND_FINISH();
9320
9321 IEM_MC_END();
9322}
9323
9324
9325/**
9326 * Common worker for FPU instructions working on ST0 and STn, and only affecting
9327 * flags.
9328 *
9329 * @param bRm Mod R/M byte.
9330 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9331 */
9332FNIEMOP_DEF_2(iemOpHlpFpuNoStore_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
9333{
9334 IEM_MC_BEGIN(3, 1, 0, 0);
9335 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9336 IEM_MC_LOCAL(uint16_t, u16Fsw);
9337 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9338 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9339 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
9340
9341 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9342 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9343 IEM_MC_PREPARE_FPU_USAGE();
9344 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, IEM_GET_MODRM_RM_8(bRm)) {
9345 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16Fsw, pr80Value1, pr80Value2);
9346 IEM_MC_UPDATE_FSW(u16Fsw, pVCpu->iem.s.uFpuOpcode);
9347 } IEM_MC_ELSE() {
9348 IEM_MC_FPU_STACK_UNDERFLOW(UINT8_MAX, pVCpu->iem.s.uFpuOpcode);
9349 } IEM_MC_ENDIF();
9350 IEM_MC_ADVANCE_RIP_AND_FINISH();
9351
9352 IEM_MC_END();
9353}
9354
9355
9356/**
9357 * Common worker for FPU instructions working on ST0 and STn, only affecting
9358 * flags, and popping when done.
9359 *
9360 * @param bRm Mod R/M byte.
9361 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9362 */
9363FNIEMOP_DEF_2(iemOpHlpFpuNoStore_st0_stN_pop, uint8_t, bRm, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
9364{
9365 IEM_MC_BEGIN(3, 1, 0, 0);
9366 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9367 IEM_MC_LOCAL(uint16_t, u16Fsw);
9368 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9369 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9370 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
9371
9372 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9373 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9374 IEM_MC_PREPARE_FPU_USAGE();
9375 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, IEM_GET_MODRM_RM_8(bRm)) {
9376 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16Fsw, pr80Value1, pr80Value2);
9377 IEM_MC_UPDATE_FSW_THEN_POP(u16Fsw, pVCpu->iem.s.uFpuOpcode);
9378 } IEM_MC_ELSE() {
9379 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(UINT8_MAX, pVCpu->iem.s.uFpuOpcode);
9380 } IEM_MC_ENDIF();
9381 IEM_MC_ADVANCE_RIP_AND_FINISH();
9382
9383 IEM_MC_END();
9384}
9385
9386
9387/** Opcode 0xd8 11/0. */
9388FNIEMOP_DEF_1(iemOp_fadd_stN, uint8_t, bRm)
9389{
9390 IEMOP_MNEMONIC(fadd_st0_stN, "fadd st0,stN");
9391 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fadd_r80_by_r80);
9392}
9393
9394
9395/** Opcode 0xd8 11/1. */
9396FNIEMOP_DEF_1(iemOp_fmul_stN, uint8_t, bRm)
9397{
9398 IEMOP_MNEMONIC(fmul_st0_stN, "fmul st0,stN");
9399 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fmul_r80_by_r80);
9400}
9401
9402
9403/** Opcode 0xd8 11/2. */
9404FNIEMOP_DEF_1(iemOp_fcom_stN, uint8_t, bRm)
9405{
9406 IEMOP_MNEMONIC(fcom_st0_stN, "fcom st0,stN");
9407 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN, bRm, iemAImpl_fcom_r80_by_r80);
9408}
9409
9410
9411/** Opcode 0xd8 11/3. */
9412FNIEMOP_DEF_1(iemOp_fcomp_stN, uint8_t, bRm)
9413{
9414 IEMOP_MNEMONIC(fcomp_st0_stN, "fcomp st0,stN");
9415 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN_pop, bRm, iemAImpl_fcom_r80_by_r80);
9416}
9417
9418
9419/** Opcode 0xd8 11/4. */
9420FNIEMOP_DEF_1(iemOp_fsub_stN, uint8_t, bRm)
9421{
9422 IEMOP_MNEMONIC(fsub_st0_stN, "fsub st0,stN");
9423 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fsub_r80_by_r80);
9424}
9425
9426
9427/** Opcode 0xd8 11/5. */
9428FNIEMOP_DEF_1(iemOp_fsubr_stN, uint8_t, bRm)
9429{
9430 IEMOP_MNEMONIC(fsubr_st0_stN, "fsubr st0,stN");
9431 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fsubr_r80_by_r80);
9432}
9433
9434
9435/** Opcode 0xd8 11/6. */
9436FNIEMOP_DEF_1(iemOp_fdiv_stN, uint8_t, bRm)
9437{
9438 IEMOP_MNEMONIC(fdiv_st0_stN, "fdiv st0,stN");
9439 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fdiv_r80_by_r80);
9440}
9441
9442
9443/** Opcode 0xd8 11/7. */
9444FNIEMOP_DEF_1(iemOp_fdivr_stN, uint8_t, bRm)
9445{
9446 IEMOP_MNEMONIC(fdivr_st0_stN, "fdivr st0,stN");
9447 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fdivr_r80_by_r80);
9448}
9449
9450
9451/**
9452 * Common worker for FPU instructions working on ST0 and an m32r, and storing
9453 * the result in ST0.
9454 *
9455 * @param bRm Mod R/M byte.
9456 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9457 */
9458FNIEMOP_DEF_2(iemOpHlpFpu_st0_m32r, uint8_t, bRm, PFNIEMAIMPLFPUR32, pfnAImpl)
9459{
9460 IEM_MC_BEGIN(3, 3, 0, 0);
9461 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9462 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9463 IEM_MC_LOCAL(RTFLOAT32U, r32Val2);
9464 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9465 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9466 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val2, r32Val2, 2);
9467
9468 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9469 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9470
9471 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9472 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9473 IEM_MC_FETCH_MEM_R32(r32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9474
9475 IEM_MC_PREPARE_FPU_USAGE();
9476 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
9477 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr32Val2);
9478 IEM_MC_STORE_FPU_RESULT(FpuRes, 0, pVCpu->iem.s.uFpuOpcode);
9479 } IEM_MC_ELSE() {
9480 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
9481 } IEM_MC_ENDIF();
9482 IEM_MC_ADVANCE_RIP_AND_FINISH();
9483
9484 IEM_MC_END();
9485}
9486
9487
9488/** Opcode 0xd8 !11/0. */
9489FNIEMOP_DEF_1(iemOp_fadd_m32r, uint8_t, bRm)
9490{
9491 IEMOP_MNEMONIC(fadd_st0_m32r, "fadd st0,m32r");
9492 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fadd_r80_by_r32);
9493}
9494
9495
9496/** Opcode 0xd8 !11/1. */
9497FNIEMOP_DEF_1(iemOp_fmul_m32r, uint8_t, bRm)
9498{
9499 IEMOP_MNEMONIC(fmul_st0_m32r, "fmul st0,m32r");
9500 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fmul_r80_by_r32);
9501}
9502
9503
9504/** Opcode 0xd8 !11/2. */
9505FNIEMOP_DEF_1(iemOp_fcom_m32r, uint8_t, bRm)
9506{
9507 IEMOP_MNEMONIC(fcom_st0_m32r, "fcom st0,m32r");
9508
9509 IEM_MC_BEGIN(3, 3, 0, 0);
9510 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9511 IEM_MC_LOCAL(uint16_t, u16Fsw);
9512 IEM_MC_LOCAL(RTFLOAT32U, r32Val2);
9513 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9514 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9515 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val2, r32Val2, 2);
9516
9517 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9518 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9519
9520 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9521 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9522 IEM_MC_FETCH_MEM_R32(r32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9523
9524 IEM_MC_PREPARE_FPU_USAGE();
9525 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
9526 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r32, pu16Fsw, pr80Value1, pr32Val2);
9527 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
9528 } IEM_MC_ELSE() {
9529 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
9530 } IEM_MC_ENDIF();
9531 IEM_MC_ADVANCE_RIP_AND_FINISH();
9532
9533 IEM_MC_END();
9534}
9535
9536
9537/** Opcode 0xd8 !11/3. */
9538FNIEMOP_DEF_1(iemOp_fcomp_m32r, uint8_t, bRm)
9539{
9540 IEMOP_MNEMONIC(fcomp_st0_m32r, "fcomp st0,m32r");
9541
9542 IEM_MC_BEGIN(3, 3, 0, 0);
9543 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9544 IEM_MC_LOCAL(uint16_t, u16Fsw);
9545 IEM_MC_LOCAL(RTFLOAT32U, r32Val2);
9546 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9547 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9548 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val2, r32Val2, 2);
9549
9550 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9551 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9552
9553 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9554 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9555 IEM_MC_FETCH_MEM_R32(r32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9556
9557 IEM_MC_PREPARE_FPU_USAGE();
9558 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
9559 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r32, pu16Fsw, pr80Value1, pr32Val2);
9560 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
9561 } IEM_MC_ELSE() {
9562 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
9563 } IEM_MC_ENDIF();
9564 IEM_MC_ADVANCE_RIP_AND_FINISH();
9565
9566 IEM_MC_END();
9567}
9568
9569
9570/** Opcode 0xd8 !11/4. */
9571FNIEMOP_DEF_1(iemOp_fsub_m32r, uint8_t, bRm)
9572{
9573 IEMOP_MNEMONIC(fsub_st0_m32r, "fsub st0,m32r");
9574 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fsub_r80_by_r32);
9575}
9576
9577
9578/** Opcode 0xd8 !11/5. */
9579FNIEMOP_DEF_1(iemOp_fsubr_m32r, uint8_t, bRm)
9580{
9581 IEMOP_MNEMONIC(fsubr_st0_m32r, "fsubr st0,m32r");
9582 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fsubr_r80_by_r32);
9583}
9584
9585
9586/** Opcode 0xd8 !11/6. */
9587FNIEMOP_DEF_1(iemOp_fdiv_m32r, uint8_t, bRm)
9588{
9589 IEMOP_MNEMONIC(fdiv_st0_m32r, "fdiv st0,m32r");
9590 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fdiv_r80_by_r32);
9591}
9592
9593
9594/** Opcode 0xd8 !11/7. */
9595FNIEMOP_DEF_1(iemOp_fdivr_m32r, uint8_t, bRm)
9596{
9597 IEMOP_MNEMONIC(fdivr_st0_m32r, "fdivr st0,m32r");
9598 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fdivr_r80_by_r32);
9599}
9600
9601
9602/**
9603 * @opcode 0xd8
9604 */
9605FNIEMOP_DEF(iemOp_EscF0)
9606{
9607 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9608 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xd8 & 0x7);
9609
9610 if (IEM_IS_MODRM_REG_MODE(bRm))
9611 {
9612 switch (IEM_GET_MODRM_REG_8(bRm))
9613 {
9614 case 0: return FNIEMOP_CALL_1(iemOp_fadd_stN, bRm);
9615 case 1: return FNIEMOP_CALL_1(iemOp_fmul_stN, bRm);
9616 case 2: return FNIEMOP_CALL_1(iemOp_fcom_stN, bRm);
9617 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_stN, bRm);
9618 case 4: return FNIEMOP_CALL_1(iemOp_fsub_stN, bRm);
9619 case 5: return FNIEMOP_CALL_1(iemOp_fsubr_stN, bRm);
9620 case 6: return FNIEMOP_CALL_1(iemOp_fdiv_stN, bRm);
9621 case 7: return FNIEMOP_CALL_1(iemOp_fdivr_stN, bRm);
9622 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9623 }
9624 }
9625 else
9626 {
9627 switch (IEM_GET_MODRM_REG_8(bRm))
9628 {
9629 case 0: return FNIEMOP_CALL_1(iemOp_fadd_m32r, bRm);
9630 case 1: return FNIEMOP_CALL_1(iemOp_fmul_m32r, bRm);
9631 case 2: return FNIEMOP_CALL_1(iemOp_fcom_m32r, bRm);
9632 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_m32r, bRm);
9633 case 4: return FNIEMOP_CALL_1(iemOp_fsub_m32r, bRm);
9634 case 5: return FNIEMOP_CALL_1(iemOp_fsubr_m32r, bRm);
9635 case 6: return FNIEMOP_CALL_1(iemOp_fdiv_m32r, bRm);
9636 case 7: return FNIEMOP_CALL_1(iemOp_fdivr_m32r, bRm);
9637 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9638 }
9639 }
9640}
9641
9642
9643/** Opcode 0xd9 /0 mem32real
9644 * @sa iemOp_fld_m64r */
9645FNIEMOP_DEF_1(iemOp_fld_m32r, uint8_t, bRm)
9646{
9647 IEMOP_MNEMONIC(fld_m32r, "fld m32r");
9648
9649 IEM_MC_BEGIN(2, 3, 0, 0);
9650 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9651 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9652 IEM_MC_LOCAL(RTFLOAT32U, r32Val);
9653 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9654 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val, r32Val, 1);
9655
9656 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9657 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9658
9659 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9660 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9661 IEM_MC_FETCH_MEM_R32(r32Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9662 IEM_MC_PREPARE_FPU_USAGE();
9663 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
9664 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r80_from_r32, pFpuRes, pr32Val);
9665 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
9666 } IEM_MC_ELSE() {
9667 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
9668 } IEM_MC_ENDIF();
9669 IEM_MC_ADVANCE_RIP_AND_FINISH();
9670
9671 IEM_MC_END();
9672}
9673
9674
9675/** Opcode 0xd9 !11/2 mem32real */
9676FNIEMOP_DEF_1(iemOp_fst_m32r, uint8_t, bRm)
9677{
9678 IEMOP_MNEMONIC(fst_m32r, "fst m32r");
9679 IEM_MC_BEGIN(3, 3, 0, 0);
9680 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9681 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9682
9683 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9684 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9685 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9686 IEM_MC_PREPARE_FPU_USAGE();
9687
9688 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
9689 IEM_MC_ARG(PRTFLOAT32U, pr32Dst, 1);
9690 IEM_MC_MEM_MAP_R32_WO(pr32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9691
9692 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
9693 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
9694 IEM_MC_LOCAL(uint16_t, u16Fsw);
9695 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
9696 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r32, pu16Fsw, pr32Dst, pr80Value);
9697 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
9698 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
9699 } IEM_MC_ELSE() {
9700 IEM_MC_IF_FCW_IM() {
9701 IEM_MC_STORE_MEM_NEG_QNAN_R32_BY_REF(pr32Dst);
9702 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
9703 } IEM_MC_ELSE() {
9704 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
9705 } IEM_MC_ENDIF();
9706 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
9707 } IEM_MC_ENDIF();
9708 IEM_MC_ADVANCE_RIP_AND_FINISH();
9709
9710 IEM_MC_END();
9711}
9712
9713
9714/** Opcode 0xd9 !11/3 */
9715FNIEMOP_DEF_1(iemOp_fstp_m32r, uint8_t, bRm)
9716{
9717 IEMOP_MNEMONIC(fstp_m32r, "fstp m32r");
9718 IEM_MC_BEGIN(3, 3, 0, 0);
9719 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9720 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9721
9722 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9723 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9724 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9725 IEM_MC_PREPARE_FPU_USAGE();
9726
9727 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
9728 IEM_MC_ARG(PRTFLOAT32U, pr32Dst, 1);
9729 IEM_MC_MEM_MAP_R32_WO(pr32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9730
9731 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
9732 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
9733 IEM_MC_LOCAL(uint16_t, u16Fsw);
9734 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
9735 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r32, pu16Fsw, pr32Dst, pr80Value);
9736 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
9737 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
9738 } IEM_MC_ELSE() {
9739 IEM_MC_IF_FCW_IM() {
9740 IEM_MC_STORE_MEM_NEG_QNAN_R32_BY_REF(pr32Dst);
9741 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
9742 } IEM_MC_ELSE() {
9743 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
9744 } IEM_MC_ENDIF();
9745 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
9746 } IEM_MC_ENDIF();
9747 IEM_MC_ADVANCE_RIP_AND_FINISH();
9748
9749 IEM_MC_END();
9750}
9751
9752
9753/** Opcode 0xd9 !11/4 */
9754FNIEMOP_DEF_1(iemOp_fldenv, uint8_t, bRm)
9755{
9756 IEMOP_MNEMONIC(fldenv, "fldenv m14/28byte");
9757 IEM_MC_BEGIN(3, 0, 0, 0);
9758 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 2);
9759 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9760
9761 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9762 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9763 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9764
9765 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
9766 IEM_MC_ARG_CONST(uint8_t, iEffSeg, /*=*/ pVCpu->iem.s.iEffSeg, 1);
9767 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_FPU, 0, iemCImpl_fldenv, enmEffOpSize, iEffSeg, GCPtrEffSrc);
9768 IEM_MC_END();
9769}
9770
9771
9772/** Opcode 0xd9 !11/5 */
9773FNIEMOP_DEF_1(iemOp_fldcw, uint8_t, bRm)
9774{
9775 IEMOP_MNEMONIC(fldcw_m2byte, "fldcw m2byte");
9776 IEM_MC_BEGIN(1, 1, 0, 0);
9777 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9778 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9779
9780 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9781 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9782 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9783
9784 IEM_MC_ARG(uint16_t, u16Fsw, 0);
9785 IEM_MC_FETCH_MEM_U16(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9786
9787 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_FPU, 0, iemCImpl_fldcw, u16Fsw);
9788 IEM_MC_END();
9789}
9790
9791
9792/** Opcode 0xd9 !11/6 */
9793FNIEMOP_DEF_1(iemOp_fnstenv, uint8_t, bRm)
9794{
9795 IEMOP_MNEMONIC(fstenv, "fstenv m14/m28byte");
9796 IEM_MC_BEGIN(3, 0, 0, 0);
9797 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 2);
9798 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9799
9800 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9801 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9802 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
9803
9804 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
9805 IEM_MC_ARG_CONST(uint8_t, iEffSeg, /*=*/ pVCpu->iem.s.iEffSeg, 1);
9806 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_FPU, 0, iemCImpl_fnstenv, enmEffOpSize, iEffSeg, GCPtrEffDst);
9807 IEM_MC_END();
9808}
9809
9810
9811/** Opcode 0xd9 !11/7 */
9812FNIEMOP_DEF_1(iemOp_fnstcw, uint8_t, bRm)
9813{
9814 IEMOP_MNEMONIC(fnstcw_m2byte, "fnstcw m2byte");
9815 IEM_MC_BEGIN(2, 0, 0, 0);
9816 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9817 IEM_MC_LOCAL(uint16_t, u16Fcw);
9818 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9819 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9820 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9821 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
9822 IEM_MC_FETCH_FCW(u16Fcw);
9823 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Fcw);
9824 IEM_MC_ADVANCE_RIP_AND_FINISH(); /* C0-C3 are documented as undefined, we leave them unmodified. */
9825 IEM_MC_END();
9826}
9827
9828
9829/** Opcode 0xd9 0xd0, 0xd9 0xd8-0xdf, ++?. */
9830FNIEMOP_DEF(iemOp_fnop)
9831{
9832 IEMOP_MNEMONIC(fnop, "fnop");
9833 IEM_MC_BEGIN(0, 0, 0, 0);
9834 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9835 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9836 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9837 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9838 /** @todo Testcase: looks like FNOP leaves FOP alone but updates FPUIP. Could be
9839 * intel optimizations. Investigate. */
9840 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
9841 IEM_MC_ADVANCE_RIP_AND_FINISH(); /* C0-C3 are documented as undefined, we leave them unmodified. */
9842 IEM_MC_END();
9843}
9844
9845
9846/** Opcode 0xd9 11/0 stN */
9847FNIEMOP_DEF_1(iemOp_fld_stN, uint8_t, bRm)
9848{
9849 IEMOP_MNEMONIC(fld_stN, "fld stN");
9850 /** @todo Testcase: Check if this raises \#MF? Intel mentioned it not. AMD
9851 * indicates that it does. */
9852 IEM_MC_BEGIN(0, 2, 0, 0);
9853 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9854 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value);
9855 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9856 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9857 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9858
9859 IEM_MC_PREPARE_FPU_USAGE();
9860 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, IEM_GET_MODRM_RM_8(bRm)) {
9861 IEM_MC_SET_FPU_RESULT(FpuRes, 0 /*FSW*/, pr80Value);
9862 IEM_MC_PUSH_FPU_RESULT(FpuRes, pVCpu->iem.s.uFpuOpcode);
9863 } IEM_MC_ELSE() {
9864 IEM_MC_FPU_STACK_PUSH_UNDERFLOW(pVCpu->iem.s.uFpuOpcode);
9865 } IEM_MC_ENDIF();
9866
9867 IEM_MC_ADVANCE_RIP_AND_FINISH();
9868 IEM_MC_END();
9869}
9870
9871
9872/** Opcode 0xd9 11/3 stN */
9873FNIEMOP_DEF_1(iemOp_fxch_stN, uint8_t, bRm)
9874{
9875 IEMOP_MNEMONIC(fxch_stN, "fxch stN");
9876 /** @todo Testcase: Check if this raises \#MF? Intel mentioned it not. AMD
9877 * indicates that it does. */
9878 IEM_MC_BEGIN(2, 3, 0, 0);
9879 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9880 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value1);
9881 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value2);
9882 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9883 IEM_MC_ARG_CONST(uint8_t, iStReg, /*=*/ IEM_GET_MODRM_RM_8(bRm), 0);
9884 IEM_MC_ARG_CONST(uint16_t, uFpuOpcode, /*=*/ pVCpu->iem.s.uFpuOpcode, 1);
9885 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9886 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9887
9888 IEM_MC_PREPARE_FPU_USAGE();
9889 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, IEM_GET_MODRM_RM_8(bRm)) {
9890 IEM_MC_SET_FPU_RESULT(FpuRes, X86_FSW_C1, pr80Value2);
9891 IEM_MC_STORE_FPUREG_R80_SRC_REF(IEM_GET_MODRM_RM_8(bRm), pr80Value1);
9892 IEM_MC_STORE_FPU_RESULT(FpuRes, 0, pVCpu->iem.s.uFpuOpcode);
9893 } IEM_MC_ELSE() {
9894 IEM_MC_CALL_CIMPL_2(IEM_CIMPL_F_FPU, 0, iemCImpl_fxch_underflow, iStReg, uFpuOpcode);
9895 } IEM_MC_ENDIF();
9896
9897 IEM_MC_ADVANCE_RIP_AND_FINISH();
9898 IEM_MC_END();
9899}
9900
9901
9902/** Opcode 0xd9 11/4, 0xdd 11/2. */
9903FNIEMOP_DEF_1(iemOp_fstp_stN, uint8_t, bRm)
9904{
9905 IEMOP_MNEMONIC(fstp_st0_stN, "fstp st0,stN");
9906
9907 /* fstp st0, st0 is frequently used as an official 'ffreep st0' sequence. */
9908 uint8_t const iDstReg = IEM_GET_MODRM_RM_8(bRm);
9909 if (!iDstReg)
9910 {
9911 IEM_MC_BEGIN(0, 1, 0, 0);
9912 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9913 IEM_MC_LOCAL_CONST(uint16_t, u16Fsw, /*=*/ 0);
9914 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9915 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9916
9917 IEM_MC_PREPARE_FPU_USAGE();
9918 IEM_MC_IF_FPUREG_NOT_EMPTY(0) {
9919 IEM_MC_UPDATE_FSW_THEN_POP(u16Fsw, pVCpu->iem.s.uFpuOpcode);
9920 } IEM_MC_ELSE() {
9921 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(0, pVCpu->iem.s.uFpuOpcode);
9922 } IEM_MC_ENDIF();
9923
9924 IEM_MC_ADVANCE_RIP_AND_FINISH();
9925 IEM_MC_END();
9926 }
9927 else
9928 {
9929 IEM_MC_BEGIN(0, 2, 0, 0);
9930 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9931 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value);
9932 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9933 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9934 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9935
9936 IEM_MC_PREPARE_FPU_USAGE();
9937 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
9938 IEM_MC_SET_FPU_RESULT(FpuRes, 0 /*FSW*/, pr80Value);
9939 IEM_MC_STORE_FPU_RESULT_THEN_POP(FpuRes, iDstReg, pVCpu->iem.s.uFpuOpcode);
9940 } IEM_MC_ELSE() {
9941 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(iDstReg, pVCpu->iem.s.uFpuOpcode);
9942 } IEM_MC_ENDIF();
9943
9944 IEM_MC_ADVANCE_RIP_AND_FINISH();
9945 IEM_MC_END();
9946 }
9947}
9948
9949
9950/**
9951 * Common worker for FPU instructions working on ST0 and replaces it with the
9952 * result, i.e. unary operators.
9953 *
9954 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9955 */
9956FNIEMOP_DEF_1(iemOpHlpFpu_st0, PFNIEMAIMPLFPUR80UNARY, pfnAImpl)
9957{
9958 IEM_MC_BEGIN(2, 1, 0, 0);
9959 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9960 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9961 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9962 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
9963
9964 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9965 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9966 IEM_MC_PREPARE_FPU_USAGE();
9967 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
9968 IEM_MC_CALL_FPU_AIMPL_2(pfnAImpl, pFpuRes, pr80Value);
9969 IEM_MC_STORE_FPU_RESULT(FpuRes, 0, pVCpu->iem.s.uFpuOpcode);
9970 } IEM_MC_ELSE() {
9971 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
9972 } IEM_MC_ENDIF();
9973 IEM_MC_ADVANCE_RIP_AND_FINISH();
9974
9975 IEM_MC_END();
9976}
9977
9978
9979/** Opcode 0xd9 0xe0. */
9980FNIEMOP_DEF(iemOp_fchs)
9981{
9982 IEMOP_MNEMONIC(fchs_st0, "fchs st0");
9983 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fchs_r80);
9984}
9985
9986
9987/** Opcode 0xd9 0xe1. */
9988FNIEMOP_DEF(iemOp_fabs)
9989{
9990 IEMOP_MNEMONIC(fabs_st0, "fabs st0");
9991 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fabs_r80);
9992}
9993
9994
9995/** Opcode 0xd9 0xe4. */
9996FNIEMOP_DEF(iemOp_ftst)
9997{
9998 IEMOP_MNEMONIC(ftst_st0, "ftst st0");
9999 IEM_MC_BEGIN(2, 1, 0, 0);
10000 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10001 IEM_MC_LOCAL(uint16_t, u16Fsw);
10002 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10003 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
10004
10005 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10006 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10007 IEM_MC_PREPARE_FPU_USAGE();
10008 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
10009 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_ftst_r80, pu16Fsw, pr80Value);
10010 IEM_MC_UPDATE_FSW(u16Fsw, pVCpu->iem.s.uFpuOpcode);
10011 } IEM_MC_ELSE() {
10012 IEM_MC_FPU_STACK_UNDERFLOW(UINT8_MAX, pVCpu->iem.s.uFpuOpcode);
10013 } IEM_MC_ENDIF();
10014 IEM_MC_ADVANCE_RIP_AND_FINISH();
10015
10016 IEM_MC_END();
10017}
10018
10019
10020/** Opcode 0xd9 0xe5. */
10021FNIEMOP_DEF(iemOp_fxam)
10022{
10023 IEMOP_MNEMONIC(fxam_st0, "fxam st0");
10024 IEM_MC_BEGIN(2, 1, 0, 0);
10025 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10026 IEM_MC_LOCAL(uint16_t, u16Fsw);
10027 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10028 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
10029
10030 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10031 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10032 IEM_MC_PREPARE_FPU_USAGE();
10033 IEM_MC_REF_FPUREG(pr80Value, 0);
10034 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fxam_r80, pu16Fsw, pr80Value);
10035 IEM_MC_UPDATE_FSW(u16Fsw, pVCpu->iem.s.uFpuOpcode);
10036 IEM_MC_ADVANCE_RIP_AND_FINISH();
10037
10038 IEM_MC_END();
10039}
10040
10041
10042/**
10043 * Common worker for FPU instructions pushing a constant onto the FPU stack.
10044 *
10045 * @param pfnAImpl Pointer to the instruction implementation (assembly).
10046 */
10047FNIEMOP_DEF_1(iemOpHlpFpuPushConstant, PFNIEMAIMPLFPUR80LDCONST, pfnAImpl)
10048{
10049 IEM_MC_BEGIN(1, 1, 0, 0);
10050 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10051 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
10052 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
10053
10054 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10055 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10056 IEM_MC_PREPARE_FPU_USAGE();
10057 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
10058 IEM_MC_CALL_FPU_AIMPL_1(pfnAImpl, pFpuRes);
10059 IEM_MC_PUSH_FPU_RESULT(FpuRes, pVCpu->iem.s.uFpuOpcode);
10060 } IEM_MC_ELSE() {
10061 IEM_MC_FPU_STACK_PUSH_OVERFLOW(pVCpu->iem.s.uFpuOpcode);
10062 } IEM_MC_ENDIF();
10063 IEM_MC_ADVANCE_RIP_AND_FINISH();
10064
10065 IEM_MC_END();
10066}
10067
10068
10069/** Opcode 0xd9 0xe8. */
10070FNIEMOP_DEF(iemOp_fld1)
10071{
10072 IEMOP_MNEMONIC(fld1, "fld1");
10073 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fld1);
10074}
10075
10076
10077/** Opcode 0xd9 0xe9. */
10078FNIEMOP_DEF(iemOp_fldl2t)
10079{
10080 IEMOP_MNEMONIC(fldl2t, "fldl2t");
10081 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldl2t);
10082}
10083
10084
10085/** Opcode 0xd9 0xea. */
10086FNIEMOP_DEF(iemOp_fldl2e)
10087{
10088 IEMOP_MNEMONIC(fldl2e, "fldl2e");
10089 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldl2e);
10090}
10091
10092/** Opcode 0xd9 0xeb. */
10093FNIEMOP_DEF(iemOp_fldpi)
10094{
10095 IEMOP_MNEMONIC(fldpi, "fldpi");
10096 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldpi);
10097}
10098
10099
10100/** Opcode 0xd9 0xec. */
10101FNIEMOP_DEF(iemOp_fldlg2)
10102{
10103 IEMOP_MNEMONIC(fldlg2, "fldlg2");
10104 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldlg2);
10105}
10106
10107/** Opcode 0xd9 0xed. */
10108FNIEMOP_DEF(iemOp_fldln2)
10109{
10110 IEMOP_MNEMONIC(fldln2, "fldln2");
10111 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldln2);
10112}
10113
10114
10115/** Opcode 0xd9 0xee. */
10116FNIEMOP_DEF(iemOp_fldz)
10117{
10118 IEMOP_MNEMONIC(fldz, "fldz");
10119 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldz);
10120}
10121
10122
10123/** Opcode 0xd9 0xf0.
10124 *
10125 * The f2xm1 instruction works on values +1.0 thru -1.0, currently (the range on
10126 * 287 & 8087 was +0.5 thru 0.0 according to docs). In addition is does appear
10127 * to produce proper results for +Inf and -Inf.
10128 *
10129 * This is probably usful in the implementation pow() and similar.
10130 */
10131FNIEMOP_DEF(iemOp_f2xm1)
10132{
10133 IEMOP_MNEMONIC(f2xm1_st0, "f2xm1 st0");
10134 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_f2xm1_r80);
10135}
10136
10137
10138/**
10139 * Common worker for FPU instructions working on STn and ST0, storing the result
10140 * in STn, and popping the stack unless IE, DE or ZE was raised.
10141 *
10142 * @param bRm Mod R/M byte.
10143 * @param pfnAImpl Pointer to the instruction implementation (assembly).
10144 */
10145FNIEMOP_DEF_2(iemOpHlpFpu_stN_st0_pop, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
10146{
10147 IEM_MC_BEGIN(3, 1, 0, 0);
10148 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10149 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
10150 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
10151 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
10152 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
10153
10154 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10155 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10156
10157 IEM_MC_PREPARE_FPU_USAGE();
10158 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, IEM_GET_MODRM_RM_8(bRm), pr80Value2, 0) {
10159 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr80Value2);
10160 IEM_MC_STORE_FPU_RESULT_THEN_POP(FpuRes, IEM_GET_MODRM_RM_8(bRm), pVCpu->iem.s.uFpuOpcode);
10161 } IEM_MC_ELSE() {
10162 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(IEM_GET_MODRM_RM_8(bRm), pVCpu->iem.s.uFpuOpcode);
10163 } IEM_MC_ENDIF();
10164 IEM_MC_ADVANCE_RIP_AND_FINISH();
10165
10166 IEM_MC_END();
10167}
10168
10169
10170/** Opcode 0xd9 0xf1. */
10171FNIEMOP_DEF(iemOp_fyl2x)
10172{
10173 IEMOP_MNEMONIC(fyl2x_st0, "fyl2x st1,st0");
10174 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, 1, iemAImpl_fyl2x_r80_by_r80);
10175}
10176
10177
10178/**
10179 * Common worker for FPU instructions working on ST0 and having two outputs, one
10180 * replacing ST0 and one pushed onto the stack.
10181 *
10182 * @param pfnAImpl Pointer to the instruction implementation (assembly).
10183 */
10184FNIEMOP_DEF_1(iemOpHlpFpuReplace_st0_push, PFNIEMAIMPLFPUR80UNARYTWO, pfnAImpl)
10185{
10186 IEM_MC_BEGIN(2, 1, 0, 0);
10187 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10188 IEM_MC_LOCAL(IEMFPURESULTTWO, FpuResTwo);
10189 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULTTWO, pFpuResTwo, FpuResTwo, 0);
10190 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
10191
10192 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10193 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10194 IEM_MC_PREPARE_FPU_USAGE();
10195 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
10196 IEM_MC_CALL_FPU_AIMPL_2(pfnAImpl, pFpuResTwo, pr80Value);
10197 IEM_MC_PUSH_FPU_RESULT_TWO(FpuResTwo, pVCpu->iem.s.uFpuOpcode);
10198 } IEM_MC_ELSE() {
10199 IEM_MC_FPU_STACK_PUSH_UNDERFLOW_TWO(pVCpu->iem.s.uFpuOpcode);
10200 } IEM_MC_ENDIF();
10201 IEM_MC_ADVANCE_RIP_AND_FINISH();
10202
10203 IEM_MC_END();
10204}
10205
10206
10207/** Opcode 0xd9 0xf2. */
10208FNIEMOP_DEF(iemOp_fptan)
10209{
10210 IEMOP_MNEMONIC(fptan_st0, "fptan st0");
10211 return FNIEMOP_CALL_1(iemOpHlpFpuReplace_st0_push, iemAImpl_fptan_r80_r80);
10212}
10213
10214
10215/** Opcode 0xd9 0xf3. */
10216FNIEMOP_DEF(iemOp_fpatan)
10217{
10218 IEMOP_MNEMONIC(fpatan_st1_st0, "fpatan st1,st0");
10219 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, 1, iemAImpl_fpatan_r80_by_r80);
10220}
10221
10222
10223/** Opcode 0xd9 0xf4. */
10224FNIEMOP_DEF(iemOp_fxtract)
10225{
10226 IEMOP_MNEMONIC(fxtract_st0, "fxtract st0");
10227 return FNIEMOP_CALL_1(iemOpHlpFpuReplace_st0_push, iemAImpl_fxtract_r80_r80);
10228}
10229
10230
10231/** Opcode 0xd9 0xf5. */
10232FNIEMOP_DEF(iemOp_fprem1)
10233{
10234 IEMOP_MNEMONIC(fprem1_st0_st1, "fprem1 st0,st1");
10235 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, 1, iemAImpl_fprem1_r80_by_r80);
10236}
10237
10238
10239/** Opcode 0xd9 0xf6. */
10240FNIEMOP_DEF(iemOp_fdecstp)
10241{
10242 IEMOP_MNEMONIC(fdecstp, "fdecstp");
10243 /* Note! C0, C2 and C3 are documented as undefined, we clear them. */
10244 /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
10245 * FINCSTP and FDECSTP. */
10246 IEM_MC_BEGIN(0, 0, 0, 0);
10247 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10248
10249 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10250 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10251
10252 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
10253 IEM_MC_FPU_STACK_DEC_TOP();
10254 IEM_MC_UPDATE_FSW_CONST(0, pVCpu->iem.s.uFpuOpcode);
10255
10256 IEM_MC_ADVANCE_RIP_AND_FINISH();
10257 IEM_MC_END();
10258}
10259
10260
10261/** Opcode 0xd9 0xf7. */
10262FNIEMOP_DEF(iemOp_fincstp)
10263{
10264 IEMOP_MNEMONIC(fincstp, "fincstp");
10265 /* Note! C0, C2 and C3 are documented as undefined, we clear them. */
10266 /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
10267 * FINCSTP and FDECSTP. */
10268 IEM_MC_BEGIN(0, 0, 0, 0);
10269 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10270
10271 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10272 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10273
10274 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
10275 IEM_MC_FPU_STACK_INC_TOP();
10276 IEM_MC_UPDATE_FSW_CONST(0, pVCpu->iem.s.uFpuOpcode);
10277
10278 IEM_MC_ADVANCE_RIP_AND_FINISH();
10279 IEM_MC_END();
10280}
10281
10282
10283/** Opcode 0xd9 0xf8. */
10284FNIEMOP_DEF(iemOp_fprem)
10285{
10286 IEMOP_MNEMONIC(fprem_st0_st1, "fprem st0,st1");
10287 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, 1, iemAImpl_fprem_r80_by_r80);
10288}
10289
10290
10291/** Opcode 0xd9 0xf9. */
10292FNIEMOP_DEF(iemOp_fyl2xp1)
10293{
10294 IEMOP_MNEMONIC(fyl2xp1_st1_st0, "fyl2xp1 st1,st0");
10295 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, 1, iemAImpl_fyl2xp1_r80_by_r80);
10296}
10297
10298
10299/** Opcode 0xd9 0xfa. */
10300FNIEMOP_DEF(iemOp_fsqrt)
10301{
10302 IEMOP_MNEMONIC(fsqrt_st0, "fsqrt st0");
10303 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fsqrt_r80);
10304}
10305
10306
10307/** Opcode 0xd9 0xfb. */
10308FNIEMOP_DEF(iemOp_fsincos)
10309{
10310 IEMOP_MNEMONIC(fsincos_st0, "fsincos st0");
10311 return FNIEMOP_CALL_1(iemOpHlpFpuReplace_st0_push, iemAImpl_fsincos_r80_r80);
10312}
10313
10314
10315/** Opcode 0xd9 0xfc. */
10316FNIEMOP_DEF(iemOp_frndint)
10317{
10318 IEMOP_MNEMONIC(frndint_st0, "frndint st0");
10319 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_frndint_r80);
10320}
10321
10322
10323/** Opcode 0xd9 0xfd. */
10324FNIEMOP_DEF(iemOp_fscale)
10325{
10326 IEMOP_MNEMONIC(fscale_st0_st1, "fscale st0,st1");
10327 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, 1, iemAImpl_fscale_r80_by_r80);
10328}
10329
10330
10331/** Opcode 0xd9 0xfe. */
10332FNIEMOP_DEF(iemOp_fsin)
10333{
10334 IEMOP_MNEMONIC(fsin_st0, "fsin st0");
10335 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fsin_r80);
10336}
10337
10338
10339/** Opcode 0xd9 0xff. */
10340FNIEMOP_DEF(iemOp_fcos)
10341{
10342 IEMOP_MNEMONIC(fcos_st0, "fcos st0");
10343 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fcos_r80);
10344}
10345
10346
10347/** Used by iemOp_EscF1. */
10348IEM_STATIC const PFNIEMOP g_apfnEscF1_E0toFF[32] =
10349{
10350 /* 0xe0 */ iemOp_fchs,
10351 /* 0xe1 */ iemOp_fabs,
10352 /* 0xe2 */ iemOp_Invalid,
10353 /* 0xe3 */ iemOp_Invalid,
10354 /* 0xe4 */ iemOp_ftst,
10355 /* 0xe5 */ iemOp_fxam,
10356 /* 0xe6 */ iemOp_Invalid,
10357 /* 0xe7 */ iemOp_Invalid,
10358 /* 0xe8 */ iemOp_fld1,
10359 /* 0xe9 */ iemOp_fldl2t,
10360 /* 0xea */ iemOp_fldl2e,
10361 /* 0xeb */ iemOp_fldpi,
10362 /* 0xec */ iemOp_fldlg2,
10363 /* 0xed */ iemOp_fldln2,
10364 /* 0xee */ iemOp_fldz,
10365 /* 0xef */ iemOp_Invalid,
10366 /* 0xf0 */ iemOp_f2xm1,
10367 /* 0xf1 */ iemOp_fyl2x,
10368 /* 0xf2 */ iemOp_fptan,
10369 /* 0xf3 */ iemOp_fpatan,
10370 /* 0xf4 */ iemOp_fxtract,
10371 /* 0xf5 */ iemOp_fprem1,
10372 /* 0xf6 */ iemOp_fdecstp,
10373 /* 0xf7 */ iemOp_fincstp,
10374 /* 0xf8 */ iemOp_fprem,
10375 /* 0xf9 */ iemOp_fyl2xp1,
10376 /* 0xfa */ iemOp_fsqrt,
10377 /* 0xfb */ iemOp_fsincos,
10378 /* 0xfc */ iemOp_frndint,
10379 /* 0xfd */ iemOp_fscale,
10380 /* 0xfe */ iemOp_fsin,
10381 /* 0xff */ iemOp_fcos
10382};
10383
10384
10385/**
10386 * @opcode 0xd9
10387 */
10388FNIEMOP_DEF(iemOp_EscF1)
10389{
10390 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
10391 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xd9 & 0x7);
10392
10393 if (IEM_IS_MODRM_REG_MODE(bRm))
10394 {
10395 switch (IEM_GET_MODRM_REG_8(bRm))
10396 {
10397 case 0: return FNIEMOP_CALL_1(iemOp_fld_stN, bRm);
10398 case 1: return FNIEMOP_CALL_1(iemOp_fxch_stN, bRm);
10399 case 2:
10400 if (bRm == 0xd0)
10401 return FNIEMOP_CALL(iemOp_fnop);
10402 IEMOP_RAISE_INVALID_OPCODE_RET();
10403 case 3: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm); /* Reserved. Intel behavior seems to be FSTP ST(i) though. */
10404 case 4:
10405 case 5:
10406 case 6:
10407 case 7:
10408 Assert((unsigned)bRm - 0xe0U < RT_ELEMENTS(g_apfnEscF1_E0toFF));
10409 return FNIEMOP_CALL(g_apfnEscF1_E0toFF[bRm - 0xe0]);
10410 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10411 }
10412 }
10413 else
10414 {
10415 switch (IEM_GET_MODRM_REG_8(bRm))
10416 {
10417 case 0: return FNIEMOP_CALL_1(iemOp_fld_m32r, bRm);
10418 case 1: IEMOP_RAISE_INVALID_OPCODE_RET();
10419 case 2: return FNIEMOP_CALL_1(iemOp_fst_m32r, bRm);
10420 case 3: return FNIEMOP_CALL_1(iemOp_fstp_m32r, bRm);
10421 case 4: return FNIEMOP_CALL_1(iemOp_fldenv, bRm);
10422 case 5: return FNIEMOP_CALL_1(iemOp_fldcw, bRm);
10423 case 6: return FNIEMOP_CALL_1(iemOp_fnstenv, bRm);
10424 case 7: return FNIEMOP_CALL_1(iemOp_fnstcw, bRm);
10425 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10426 }
10427 }
10428}
10429
10430
10431/** Opcode 0xda 11/0. */
10432FNIEMOP_DEF_1(iemOp_fcmovb_stN, uint8_t, bRm)
10433{
10434 IEMOP_MNEMONIC(fcmovb_st0_stN, "fcmovb st0,stN");
10435 IEM_MC_BEGIN(0, 1, 0, 0);
10436 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10437 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
10438
10439 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10440 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10441
10442 IEM_MC_PREPARE_FPU_USAGE();
10443 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
10444 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
10445 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
10446 } IEM_MC_ENDIF();
10447 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
10448 } IEM_MC_ELSE() {
10449 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
10450 } IEM_MC_ENDIF();
10451 IEM_MC_ADVANCE_RIP_AND_FINISH();
10452
10453 IEM_MC_END();
10454}
10455
10456
10457/** Opcode 0xda 11/1. */
10458FNIEMOP_DEF_1(iemOp_fcmove_stN, uint8_t, bRm)
10459{
10460 IEMOP_MNEMONIC(fcmove_st0_stN, "fcmove st0,stN");
10461 IEM_MC_BEGIN(0, 1, 0, 0);
10462 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10463 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
10464
10465 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10466 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10467
10468 IEM_MC_PREPARE_FPU_USAGE();
10469 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
10470 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
10471 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
10472 } IEM_MC_ENDIF();
10473 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
10474 } IEM_MC_ELSE() {
10475 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
10476 } IEM_MC_ENDIF();
10477 IEM_MC_ADVANCE_RIP_AND_FINISH();
10478
10479 IEM_MC_END();
10480}
10481
10482
10483/** Opcode 0xda 11/2. */
10484FNIEMOP_DEF_1(iemOp_fcmovbe_stN, uint8_t, bRm)
10485{
10486 IEMOP_MNEMONIC(fcmovbe_st0_stN, "fcmovbe st0,stN");
10487 IEM_MC_BEGIN(0, 1, 0, 0);
10488 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10489 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
10490
10491 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10492 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10493
10494 IEM_MC_PREPARE_FPU_USAGE();
10495 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
10496 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
10497 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
10498 } IEM_MC_ENDIF();
10499 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
10500 } IEM_MC_ELSE() {
10501 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
10502 } IEM_MC_ENDIF();
10503 IEM_MC_ADVANCE_RIP_AND_FINISH();
10504
10505 IEM_MC_END();
10506}
10507
10508
10509/** Opcode 0xda 11/3. */
10510FNIEMOP_DEF_1(iemOp_fcmovu_stN, uint8_t, bRm)
10511{
10512 IEMOP_MNEMONIC(fcmovu_st0_stN, "fcmovu st0,stN");
10513 IEM_MC_BEGIN(0, 1, 0, 0);
10514 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10515 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
10516
10517 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10518 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10519
10520 IEM_MC_PREPARE_FPU_USAGE();
10521 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
10522 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
10523 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
10524 } IEM_MC_ENDIF();
10525 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
10526 } IEM_MC_ELSE() {
10527 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
10528 } IEM_MC_ENDIF();
10529 IEM_MC_ADVANCE_RIP_AND_FINISH();
10530
10531 IEM_MC_END();
10532}
10533
10534
10535/**
10536 * Common worker for FPU instructions working on ST0 and ST1, only affecting
10537 * flags, and popping twice when done.
10538 *
10539 * @param pfnAImpl Pointer to the instruction implementation (assembly).
10540 */
10541FNIEMOP_DEF_1(iemOpHlpFpuNoStore_st0_st1_pop_pop, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
10542{
10543 IEM_MC_BEGIN(3, 1, 0, 0);
10544 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10545 IEM_MC_LOCAL(uint16_t, u16Fsw);
10546 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10547 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
10548 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
10549
10550 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10551 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10552
10553 IEM_MC_PREPARE_FPU_USAGE();
10554 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, 1) {
10555 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16Fsw, pr80Value1, pr80Value2);
10556 IEM_MC_UPDATE_FSW_THEN_POP_POP(u16Fsw, pVCpu->iem.s.uFpuOpcode);
10557 } IEM_MC_ELSE() {
10558 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP_POP(pVCpu->iem.s.uFpuOpcode);
10559 } IEM_MC_ENDIF();
10560 IEM_MC_ADVANCE_RIP_AND_FINISH();
10561
10562 IEM_MC_END();
10563}
10564
10565
10566/** Opcode 0xda 0xe9. */
10567FNIEMOP_DEF(iemOp_fucompp)
10568{
10569 IEMOP_MNEMONIC(fucompp, "fucompp");
10570 return FNIEMOP_CALL_1(iemOpHlpFpuNoStore_st0_st1_pop_pop, iemAImpl_fucom_r80_by_r80);
10571}
10572
10573
10574/**
10575 * Common worker for FPU instructions working on ST0 and an m32i, and storing
10576 * the result in ST0.
10577 *
10578 * @param bRm Mod R/M byte.
10579 * @param pfnAImpl Pointer to the instruction implementation (assembly).
10580 */
10581FNIEMOP_DEF_2(iemOpHlpFpu_st0_m32i, uint8_t, bRm, PFNIEMAIMPLFPUI32, pfnAImpl)
10582{
10583 IEM_MC_BEGIN(3, 3, 0, 0);
10584 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
10585 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
10586 IEM_MC_LOCAL(int32_t, i32Val2);
10587 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
10588 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
10589 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val2, i32Val2, 2);
10590
10591 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
10592 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10593
10594 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10595 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10596 IEM_MC_FETCH_MEM_I32(i32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10597
10598 IEM_MC_PREPARE_FPU_USAGE();
10599 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
10600 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pi32Val2);
10601 IEM_MC_STORE_FPU_RESULT(FpuRes, 0, pVCpu->iem.s.uFpuOpcode);
10602 } IEM_MC_ELSE() {
10603 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
10604 } IEM_MC_ENDIF();
10605 IEM_MC_ADVANCE_RIP_AND_FINISH();
10606
10607 IEM_MC_END();
10608}
10609
10610
10611/** Opcode 0xda !11/0. */
10612FNIEMOP_DEF_1(iemOp_fiadd_m32i, uint8_t, bRm)
10613{
10614 IEMOP_MNEMONIC(fiadd_m32i, "fiadd m32i");
10615 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fiadd_r80_by_i32);
10616}
10617
10618
10619/** Opcode 0xda !11/1. */
10620FNIEMOP_DEF_1(iemOp_fimul_m32i, uint8_t, bRm)
10621{
10622 IEMOP_MNEMONIC(fimul_m32i, "fimul m32i");
10623 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fimul_r80_by_i32);
10624}
10625
10626
10627/** Opcode 0xda !11/2. */
10628FNIEMOP_DEF_1(iemOp_ficom_m32i, uint8_t, bRm)
10629{
10630 IEMOP_MNEMONIC(ficom_st0_m32i, "ficom st0,m32i");
10631
10632 IEM_MC_BEGIN(3, 3, 0, 0);
10633 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
10634 IEM_MC_LOCAL(uint16_t, u16Fsw);
10635 IEM_MC_LOCAL(int32_t, i32Val2);
10636 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10637 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
10638 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val2, i32Val2, 2);
10639
10640 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
10641 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10642
10643 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10644 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10645 IEM_MC_FETCH_MEM_I32(i32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10646
10647 IEM_MC_PREPARE_FPU_USAGE();
10648 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
10649 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i32, pu16Fsw, pr80Value1, pi32Val2);
10650 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10651 } IEM_MC_ELSE() {
10652 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10653 } IEM_MC_ENDIF();
10654 IEM_MC_ADVANCE_RIP_AND_FINISH();
10655
10656 IEM_MC_END();
10657}
10658
10659
10660/** Opcode 0xda !11/3. */
10661FNIEMOP_DEF_1(iemOp_ficomp_m32i, uint8_t, bRm)
10662{
10663 IEMOP_MNEMONIC(ficomp_st0_m32i, "ficomp st0,m32i");
10664
10665 IEM_MC_BEGIN(3, 3, 0, 0);
10666 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
10667 IEM_MC_LOCAL(uint16_t, u16Fsw);
10668 IEM_MC_LOCAL(int32_t, i32Val2);
10669 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10670 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
10671 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val2, i32Val2, 2);
10672
10673 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
10674 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10675
10676 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10677 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10678 IEM_MC_FETCH_MEM_I32(i32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10679
10680 IEM_MC_PREPARE_FPU_USAGE();
10681 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
10682 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i32, pu16Fsw, pr80Value1, pi32Val2);
10683 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10684 } IEM_MC_ELSE() {
10685 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10686 } IEM_MC_ENDIF();
10687 IEM_MC_ADVANCE_RIP_AND_FINISH();
10688
10689 IEM_MC_END();
10690}
10691
10692
10693/** Opcode 0xda !11/4. */
10694FNIEMOP_DEF_1(iemOp_fisub_m32i, uint8_t, bRm)
10695{
10696 IEMOP_MNEMONIC(fisub_m32i, "fisub m32i");
10697 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fisub_r80_by_i32);
10698}
10699
10700
10701/** Opcode 0xda !11/5. */
10702FNIEMOP_DEF_1(iemOp_fisubr_m32i, uint8_t, bRm)
10703{
10704 IEMOP_MNEMONIC(fisubr_m32i, "fisubr m32i");
10705 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fisubr_r80_by_i32);
10706}
10707
10708
10709/** Opcode 0xda !11/6. */
10710FNIEMOP_DEF_1(iemOp_fidiv_m32i, uint8_t, bRm)
10711{
10712 IEMOP_MNEMONIC(fidiv_m32i, "fidiv m32i");
10713 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fidiv_r80_by_i32);
10714}
10715
10716
10717/** Opcode 0xda !11/7. */
10718FNIEMOP_DEF_1(iemOp_fidivr_m32i, uint8_t, bRm)
10719{
10720 IEMOP_MNEMONIC(fidivr_m32i, "fidivr m32i");
10721 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fidivr_r80_by_i32);
10722}
10723
10724
10725/**
10726 * @opcode 0xda
10727 */
10728FNIEMOP_DEF(iemOp_EscF2)
10729{
10730 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
10731 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xda & 0x7);
10732 if (IEM_IS_MODRM_REG_MODE(bRm))
10733 {
10734 switch (IEM_GET_MODRM_REG_8(bRm))
10735 {
10736 case 0: return FNIEMOP_CALL_1(iemOp_fcmovb_stN, bRm);
10737 case 1: return FNIEMOP_CALL_1(iemOp_fcmove_stN, bRm);
10738 case 2: return FNIEMOP_CALL_1(iemOp_fcmovbe_stN, bRm);
10739 case 3: return FNIEMOP_CALL_1(iemOp_fcmovu_stN, bRm);
10740 case 4: IEMOP_RAISE_INVALID_OPCODE_RET();
10741 case 5:
10742 if (bRm == 0xe9)
10743 return FNIEMOP_CALL(iemOp_fucompp);
10744 IEMOP_RAISE_INVALID_OPCODE_RET();
10745 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
10746 case 7: IEMOP_RAISE_INVALID_OPCODE_RET();
10747 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10748 }
10749 }
10750 else
10751 {
10752 switch (IEM_GET_MODRM_REG_8(bRm))
10753 {
10754 case 0: return FNIEMOP_CALL_1(iemOp_fiadd_m32i, bRm);
10755 case 1: return FNIEMOP_CALL_1(iemOp_fimul_m32i, bRm);
10756 case 2: return FNIEMOP_CALL_1(iemOp_ficom_m32i, bRm);
10757 case 3: return FNIEMOP_CALL_1(iemOp_ficomp_m32i, bRm);
10758 case 4: return FNIEMOP_CALL_1(iemOp_fisub_m32i, bRm);
10759 case 5: return FNIEMOP_CALL_1(iemOp_fisubr_m32i, bRm);
10760 case 6: return FNIEMOP_CALL_1(iemOp_fidiv_m32i, bRm);
10761 case 7: return FNIEMOP_CALL_1(iemOp_fidivr_m32i, bRm);
10762 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10763 }
10764 }
10765}
10766
10767
10768/** Opcode 0xdb !11/0. */
10769FNIEMOP_DEF_1(iemOp_fild_m32i, uint8_t, bRm)
10770{
10771 IEMOP_MNEMONIC(fild_m32i, "fild m32i");
10772
10773 IEM_MC_BEGIN(2, 3, 0, 0);
10774 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
10775 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
10776 IEM_MC_LOCAL(int32_t, i32Val);
10777 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
10778 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val, i32Val, 1);
10779
10780 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
10781 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10782
10783 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10784 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10785 IEM_MC_FETCH_MEM_I32(i32Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10786
10787 IEM_MC_PREPARE_FPU_USAGE();
10788 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
10789 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fild_r80_from_i32, pFpuRes, pi32Val);
10790 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10791 } IEM_MC_ELSE() {
10792 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10793 } IEM_MC_ENDIF();
10794 IEM_MC_ADVANCE_RIP_AND_FINISH();
10795
10796 IEM_MC_END();
10797}
10798
10799
10800/** Opcode 0xdb !11/1. */
10801FNIEMOP_DEF_1(iemOp_fisttp_m32i, uint8_t, bRm)
10802{
10803 IEMOP_MNEMONIC(fisttp_m32i, "fisttp m32i");
10804 IEM_MC_BEGIN(3, 3, 0, 0);
10805 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10806 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10807
10808 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10809 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10810 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10811 IEM_MC_PREPARE_FPU_USAGE();
10812
10813 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
10814 IEM_MC_ARG(int32_t *, pi32Dst, 1);
10815 IEM_MC_MEM_MAP_I32_WO(pi32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10816
10817 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10818 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
10819 IEM_MC_LOCAL(uint16_t, u16Fsw);
10820 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
10821 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
10822 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
10823 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10824 } IEM_MC_ELSE() {
10825 IEM_MC_IF_FCW_IM() {
10826 IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
10827 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
10828 } IEM_MC_ELSE() {
10829 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
10830 } IEM_MC_ENDIF();
10831 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10832 } IEM_MC_ENDIF();
10833 IEM_MC_ADVANCE_RIP_AND_FINISH();
10834
10835 IEM_MC_END();
10836}
10837
10838
10839/** Opcode 0xdb !11/2. */
10840FNIEMOP_DEF_1(iemOp_fist_m32i, uint8_t, bRm)
10841{
10842 IEMOP_MNEMONIC(fist_m32i, "fist m32i");
10843 IEM_MC_BEGIN(3, 3, 0, 0);
10844 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10845 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10846
10847 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10848 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10849 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10850 IEM_MC_PREPARE_FPU_USAGE();
10851
10852 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
10853 IEM_MC_ARG(int32_t *, pi32Dst, 1);
10854 IEM_MC_MEM_MAP_I32_WO(pi32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10855
10856 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10857 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
10858 IEM_MC_LOCAL(uint16_t, u16Fsw);
10859 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
10860 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
10861 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
10862 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10863 } IEM_MC_ELSE() {
10864 IEM_MC_IF_FCW_IM() {
10865 IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
10866 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
10867 } IEM_MC_ELSE() {
10868 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
10869 } IEM_MC_ENDIF();
10870 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10871 } IEM_MC_ENDIF();
10872 IEM_MC_ADVANCE_RIP_AND_FINISH();
10873
10874 IEM_MC_END();
10875}
10876
10877
10878/** Opcode 0xdb !11/3. */
10879FNIEMOP_DEF_1(iemOp_fistp_m32i, uint8_t, bRm)
10880{
10881 IEMOP_MNEMONIC(fistp_m32i, "fistp m32i");
10882 IEM_MC_BEGIN(3, 2, 0, 0);
10883 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10884 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10885
10886 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10887 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10888 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10889 IEM_MC_PREPARE_FPU_USAGE();
10890
10891 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
10892 IEM_MC_ARG(int32_t *, pi32Dst, 1);
10893 IEM_MC_MEM_MAP_I32_WO(pi32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10894
10895 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10896 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
10897 IEM_MC_LOCAL(uint16_t, u16Fsw);
10898 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
10899 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
10900 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
10901 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10902 } IEM_MC_ELSE() {
10903 IEM_MC_IF_FCW_IM() {
10904 IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
10905 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
10906 } IEM_MC_ELSE() {
10907 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
10908 } IEM_MC_ENDIF();
10909 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10910 } IEM_MC_ENDIF();
10911 IEM_MC_ADVANCE_RIP_AND_FINISH();
10912
10913 IEM_MC_END();
10914}
10915
10916
10917/** Opcode 0xdb !11/5. */
10918FNIEMOP_DEF_1(iemOp_fld_m80r, uint8_t, bRm)
10919{
10920 IEMOP_MNEMONIC(fld_m80r, "fld m80r");
10921
10922 IEM_MC_BEGIN(2, 3, 0, 0);
10923 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
10924 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
10925 IEM_MC_LOCAL(RTFLOAT80U, r80Val);
10926 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
10927 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT80U, pr80Val, r80Val, 1);
10928
10929 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
10930 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10931
10932 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10933 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10934 IEM_MC_FETCH_MEM_R80(r80Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10935
10936 IEM_MC_PREPARE_FPU_USAGE();
10937 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
10938 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r80_from_r80, pFpuRes, pr80Val);
10939 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10940 } IEM_MC_ELSE() {
10941 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
10942 } IEM_MC_ENDIF();
10943 IEM_MC_ADVANCE_RIP_AND_FINISH();
10944
10945 IEM_MC_END();
10946}
10947
10948
10949/** Opcode 0xdb !11/7. */
10950FNIEMOP_DEF_1(iemOp_fstp_m80r, uint8_t, bRm)
10951{
10952 IEMOP_MNEMONIC(fstp_m80r, "fstp m80r");
10953 IEM_MC_BEGIN(3, 3, 0, 0);
10954 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10955 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10956
10957 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10958 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10959 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10960 IEM_MC_PREPARE_FPU_USAGE();
10961
10962 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
10963 IEM_MC_ARG(PRTFLOAT80U, pr80Dst, 1);
10964 IEM_MC_MEM_MAP_R80_WO(pr80Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10965
10966 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10967 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
10968 IEM_MC_LOCAL(uint16_t, u16Fsw);
10969 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
10970 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r80, pu16Fsw, pr80Dst, pr80Value);
10971 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
10972 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10973 } IEM_MC_ELSE() {
10974 IEM_MC_IF_FCW_IM() {
10975 IEM_MC_STORE_MEM_NEG_QNAN_R80_BY_REF(pr80Dst);
10976 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
10977 } IEM_MC_ELSE() {
10978 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
10979 } IEM_MC_ENDIF();
10980 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
10981 } IEM_MC_ENDIF();
10982 IEM_MC_ADVANCE_RIP_AND_FINISH();
10983
10984 IEM_MC_END();
10985}
10986
10987
10988/** Opcode 0xdb 11/0. */
10989FNIEMOP_DEF_1(iemOp_fcmovnb_stN, uint8_t, bRm)
10990{
10991 IEMOP_MNEMONIC(fcmovnb_st0_stN, "fcmovnb st0,stN");
10992 IEM_MC_BEGIN(0, 1, 0, 0);
10993 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10994 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
10995
10996 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10997 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10998
10999 IEM_MC_PREPARE_FPU_USAGE();
11000 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
11001 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_CF) {
11002 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
11003 } IEM_MC_ENDIF();
11004 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
11005 } IEM_MC_ELSE() {
11006 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
11007 } IEM_MC_ENDIF();
11008 IEM_MC_ADVANCE_RIP_AND_FINISH();
11009
11010 IEM_MC_END();
11011}
11012
11013
11014/** Opcode 0xdb 11/1. */
11015FNIEMOP_DEF_1(iemOp_fcmovne_stN, uint8_t, bRm)
11016{
11017 IEMOP_MNEMONIC(fcmovne_st0_stN, "fcmovne st0,stN");
11018 IEM_MC_BEGIN(0, 1, 0, 0);
11019 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11020 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
11021
11022 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11023 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11024
11025 IEM_MC_PREPARE_FPU_USAGE();
11026 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
11027 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF) {
11028 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
11029 } IEM_MC_ENDIF();
11030 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
11031 } IEM_MC_ELSE() {
11032 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
11033 } IEM_MC_ENDIF();
11034 IEM_MC_ADVANCE_RIP_AND_FINISH();
11035
11036 IEM_MC_END();
11037}
11038
11039
11040/** Opcode 0xdb 11/2. */
11041FNIEMOP_DEF_1(iemOp_fcmovnbe_stN, uint8_t, bRm)
11042{
11043 IEMOP_MNEMONIC(fcmovnbe_st0_stN, "fcmovnbe st0,stN");
11044 IEM_MC_BEGIN(0, 1, 0, 0);
11045 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11046 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
11047
11048 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11049 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11050
11051 IEM_MC_PREPARE_FPU_USAGE();
11052 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
11053 IEM_MC_IF_EFL_NO_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
11054 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
11055 } IEM_MC_ENDIF();
11056 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
11057 } IEM_MC_ELSE() {
11058 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
11059 } IEM_MC_ENDIF();
11060 IEM_MC_ADVANCE_RIP_AND_FINISH();
11061
11062 IEM_MC_END();
11063}
11064
11065
11066/** Opcode 0xdb 11/3. */
11067FNIEMOP_DEF_1(iemOp_fcmovnnu_stN, uint8_t, bRm)
11068{
11069 IEMOP_MNEMONIC(fcmovnnu_st0_stN, "fcmovnnu st0,stN");
11070 IEM_MC_BEGIN(0, 1, 0, 0);
11071 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11072 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
11073
11074 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11075 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11076
11077 IEM_MC_PREPARE_FPU_USAGE();
11078 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, IEM_GET_MODRM_RM_8(bRm), 0) {
11079 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_PF) {
11080 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
11081 } IEM_MC_ENDIF();
11082 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
11083 } IEM_MC_ELSE() {
11084 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
11085 } IEM_MC_ENDIF();
11086 IEM_MC_ADVANCE_RIP_AND_FINISH();
11087
11088 IEM_MC_END();
11089}
11090
11091
11092/** Opcode 0xdb 0xe0. */
11093FNIEMOP_DEF(iemOp_fneni)
11094{
11095 IEMOP_MNEMONIC(fneni, "fneni (8087/ign)");
11096 IEM_MC_BEGIN(0, 0, 0, 0);
11097 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11098 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11099 IEM_MC_ADVANCE_RIP_AND_FINISH();
11100 IEM_MC_END();
11101}
11102
11103
11104/** Opcode 0xdb 0xe1. */
11105FNIEMOP_DEF(iemOp_fndisi)
11106{
11107 IEMOP_MNEMONIC(fndisi, "fndisi (8087/ign)");
11108 IEM_MC_BEGIN(0, 0, 0, 0);
11109 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11110 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11111 IEM_MC_ADVANCE_RIP_AND_FINISH();
11112 IEM_MC_END();
11113}
11114
11115
11116/** Opcode 0xdb 0xe2. */
11117FNIEMOP_DEF(iemOp_fnclex)
11118{
11119 IEMOP_MNEMONIC(fnclex, "fnclex");
11120 IEM_MC_BEGIN(0, 0, 0, 0);
11121 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11122 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11123 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
11124 IEM_MC_CLEAR_FSW_EX();
11125 IEM_MC_ADVANCE_RIP_AND_FINISH();
11126 IEM_MC_END();
11127}
11128
11129
11130/** Opcode 0xdb 0xe3. */
11131FNIEMOP_DEF(iemOp_fninit)
11132{
11133 IEMOP_MNEMONIC(fninit, "fninit");
11134 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11135 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_FPU, 0, iemCImpl_finit, false /*fCheckXcpts*/);
11136}
11137
11138
11139/** Opcode 0xdb 0xe4. */
11140FNIEMOP_DEF(iemOp_fnsetpm)
11141{
11142 IEMOP_MNEMONIC(fnsetpm, "fnsetpm (80287/ign)"); /* set protected mode on fpu. */
11143 IEM_MC_BEGIN(0, 0, 0, 0);
11144 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11145 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11146 IEM_MC_ADVANCE_RIP_AND_FINISH();
11147 IEM_MC_END();
11148}
11149
11150
11151/** Opcode 0xdb 0xe5. */
11152FNIEMOP_DEF(iemOp_frstpm)
11153{
11154 IEMOP_MNEMONIC(frstpm, "frstpm (80287XL/ign)"); /* reset pm, back to real mode. */
11155#if 0 /* #UDs on newer CPUs */
11156 IEM_MC_BEGIN(0, 0, 0, 0);
11157 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11158 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11159 IEM_MC_ADVANCE_RIP_AND_FINISH();
11160 IEM_MC_END();
11161 return VINF_SUCCESS;
11162#else
11163 IEMOP_RAISE_INVALID_OPCODE_RET();
11164#endif
11165}
11166
11167
11168/** Opcode 0xdb 11/5. */
11169FNIEMOP_DEF_1(iemOp_fucomi_stN, uint8_t, bRm)
11170{
11171 IEMOP_MNEMONIC(fucomi_st0_stN, "fucomi st0,stN");
11172 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_FPU | IEM_CIMPL_F_STATUS_FLAGS, 0,
11173 iemCImpl_fcomi_fucomi, IEM_GET_MODRM_RM_8(bRm), true /*fUCmp*/,
11174 0 /*fPop*/ | pVCpu->iem.s.uFpuOpcode);
11175}
11176
11177
11178/** Opcode 0xdb 11/6. */
11179FNIEMOP_DEF_1(iemOp_fcomi_stN, uint8_t, bRm)
11180{
11181 IEMOP_MNEMONIC(fcomi_st0_stN, "fcomi st0,stN");
11182 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_FPU | IEM_CIMPL_F_STATUS_FLAGS, 0,
11183 iemCImpl_fcomi_fucomi, IEM_GET_MODRM_RM_8(bRm), false /*fUCmp*/,
11184 false /*fPop*/ | pVCpu->iem.s.uFpuOpcode);
11185}
11186
11187
11188/**
11189 * @opcode 0xdb
11190 */
11191FNIEMOP_DEF(iemOp_EscF3)
11192{
11193 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11194 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdb & 0x7);
11195 if (IEM_IS_MODRM_REG_MODE(bRm))
11196 {
11197 switch (IEM_GET_MODRM_REG_8(bRm))
11198 {
11199 case 0: return FNIEMOP_CALL_1(iemOp_fcmovnb_stN, bRm);
11200 case 1: return FNIEMOP_CALL_1(iemOp_fcmovne_stN, bRm);
11201 case 2: return FNIEMOP_CALL_1(iemOp_fcmovnbe_stN, bRm);
11202 case 3: return FNIEMOP_CALL_1(iemOp_fcmovnnu_stN, bRm);
11203 case 4:
11204 switch (bRm)
11205 {
11206 case 0xe0: return FNIEMOP_CALL(iemOp_fneni);
11207 case 0xe1: return FNIEMOP_CALL(iemOp_fndisi);
11208 case 0xe2: return FNIEMOP_CALL(iemOp_fnclex);
11209 case 0xe3: return FNIEMOP_CALL(iemOp_fninit);
11210 case 0xe4: return FNIEMOP_CALL(iemOp_fnsetpm);
11211 case 0xe5: return FNIEMOP_CALL(iemOp_frstpm);
11212 case 0xe6: IEMOP_RAISE_INVALID_OPCODE_RET();
11213 case 0xe7: IEMOP_RAISE_INVALID_OPCODE_RET();
11214 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11215 }
11216 break;
11217 case 5: return FNIEMOP_CALL_1(iemOp_fucomi_stN, bRm);
11218 case 6: return FNIEMOP_CALL_1(iemOp_fcomi_stN, bRm);
11219 case 7: IEMOP_RAISE_INVALID_OPCODE_RET();
11220 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11221 }
11222 }
11223 else
11224 {
11225 switch (IEM_GET_MODRM_REG_8(bRm))
11226 {
11227 case 0: return FNIEMOP_CALL_1(iemOp_fild_m32i, bRm);
11228 case 1: return FNIEMOP_CALL_1(iemOp_fisttp_m32i,bRm);
11229 case 2: return FNIEMOP_CALL_1(iemOp_fist_m32i, bRm);
11230 case 3: return FNIEMOP_CALL_1(iemOp_fistp_m32i, bRm);
11231 case 4: IEMOP_RAISE_INVALID_OPCODE_RET();
11232 case 5: return FNIEMOP_CALL_1(iemOp_fld_m80r, bRm);
11233 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
11234 case 7: return FNIEMOP_CALL_1(iemOp_fstp_m80r, bRm);
11235 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11236 }
11237 }
11238}
11239
11240
11241/**
11242 * Common worker for FPU instructions working on STn and ST0, and storing the
11243 * result in STn unless IE, DE or ZE was raised.
11244 *
11245 * @param bRm Mod R/M byte.
11246 * @param pfnAImpl Pointer to the instruction implementation (assembly).
11247 */
11248FNIEMOP_DEF_2(iemOpHlpFpu_stN_st0, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
11249{
11250 IEM_MC_BEGIN(3, 1, 0, 0);
11251 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11252 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
11253 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
11254 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
11255 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
11256
11257 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11258 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11259
11260 IEM_MC_PREPARE_FPU_USAGE();
11261 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, IEM_GET_MODRM_RM_8(bRm), pr80Value2, 0) {
11262 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr80Value2);
11263 IEM_MC_STORE_FPU_RESULT(FpuRes, IEM_GET_MODRM_RM_8(bRm), pVCpu->iem.s.uFpuOpcode);
11264 } IEM_MC_ELSE() {
11265 IEM_MC_FPU_STACK_UNDERFLOW(IEM_GET_MODRM_RM_8(bRm), pVCpu->iem.s.uFpuOpcode);
11266 } IEM_MC_ENDIF();
11267 IEM_MC_ADVANCE_RIP_AND_FINISH();
11268
11269 IEM_MC_END();
11270}
11271
11272
11273/** Opcode 0xdc 11/0. */
11274FNIEMOP_DEF_1(iemOp_fadd_stN_st0, uint8_t, bRm)
11275{
11276 IEMOP_MNEMONIC(fadd_stN_st0, "fadd stN,st0");
11277 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fadd_r80_by_r80);
11278}
11279
11280
11281/** Opcode 0xdc 11/1. */
11282FNIEMOP_DEF_1(iemOp_fmul_stN_st0, uint8_t, bRm)
11283{
11284 IEMOP_MNEMONIC(fmul_stN_st0, "fmul stN,st0");
11285 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fmul_r80_by_r80);
11286}
11287
11288
11289/** Opcode 0xdc 11/4. */
11290FNIEMOP_DEF_1(iemOp_fsubr_stN_st0, uint8_t, bRm)
11291{
11292 IEMOP_MNEMONIC(fsubr_stN_st0, "fsubr stN,st0");
11293 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fsubr_r80_by_r80);
11294}
11295
11296
11297/** Opcode 0xdc 11/5. */
11298FNIEMOP_DEF_1(iemOp_fsub_stN_st0, uint8_t, bRm)
11299{
11300 IEMOP_MNEMONIC(fsub_stN_st0, "fsub stN,st0");
11301 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fsub_r80_by_r80);
11302}
11303
11304
11305/** Opcode 0xdc 11/6. */
11306FNIEMOP_DEF_1(iemOp_fdivr_stN_st0, uint8_t, bRm)
11307{
11308 IEMOP_MNEMONIC(fdivr_stN_st0, "fdivr stN,st0");
11309 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fdivr_r80_by_r80);
11310}
11311
11312
11313/** Opcode 0xdc 11/7. */
11314FNIEMOP_DEF_1(iemOp_fdiv_stN_st0, uint8_t, bRm)
11315{
11316 IEMOP_MNEMONIC(fdiv_stN_st0, "fdiv stN,st0");
11317 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fdiv_r80_by_r80);
11318}
11319
11320
11321/**
11322 * Common worker for FPU instructions working on ST0 and a 64-bit floating point
11323 * memory operand, and storing the result in ST0.
11324 *
11325 * @param bRm Mod R/M byte.
11326 * @param pfnImpl Pointer to the instruction implementation (assembly).
11327 */
11328FNIEMOP_DEF_2(iemOpHlpFpu_ST0_m64r, uint8_t, bRm, PFNIEMAIMPLFPUR64, pfnImpl)
11329{
11330 IEM_MC_BEGIN(3, 3, 0, 0);
11331 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11332 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
11333 IEM_MC_LOCAL(RTFLOAT64U, r64Factor2);
11334 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
11335 IEM_MC_ARG(PCRTFLOAT80U, pr80Factor1, 1);
11336 IEM_MC_ARG_LOCAL_REF(PRTFLOAT64U, pr64Factor2, r64Factor2, 2);
11337
11338 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11339 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11340 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11341 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11342
11343 IEM_MC_FETCH_MEM_R64(r64Factor2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11344 IEM_MC_PREPARE_FPU_USAGE();
11345 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Factor1, 0) {
11346 IEM_MC_CALL_FPU_AIMPL_3(pfnImpl, pFpuRes, pr80Factor1, pr64Factor2);
11347 IEM_MC_STORE_FPU_RESULT_MEM_OP(FpuRes, 0, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11348 } IEM_MC_ELSE() {
11349 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(0, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11350 } IEM_MC_ENDIF();
11351 IEM_MC_ADVANCE_RIP_AND_FINISH();
11352
11353 IEM_MC_END();
11354}
11355
11356
11357/** Opcode 0xdc !11/0. */
11358FNIEMOP_DEF_1(iemOp_fadd_m64r, uint8_t, bRm)
11359{
11360 IEMOP_MNEMONIC(fadd_m64r, "fadd m64r");
11361 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fadd_r80_by_r64);
11362}
11363
11364
11365/** Opcode 0xdc !11/1. */
11366FNIEMOP_DEF_1(iemOp_fmul_m64r, uint8_t, bRm)
11367{
11368 IEMOP_MNEMONIC(fmul_m64r, "fmul m64r");
11369 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fmul_r80_by_r64);
11370}
11371
11372
11373/** Opcode 0xdc !11/2. */
11374FNIEMOP_DEF_1(iemOp_fcom_m64r, uint8_t, bRm)
11375{
11376 IEMOP_MNEMONIC(fcom_st0_m64r, "fcom st0,m64r");
11377
11378 IEM_MC_BEGIN(3, 3, 0, 0);
11379 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11380 IEM_MC_LOCAL(uint16_t, u16Fsw);
11381 IEM_MC_LOCAL(RTFLOAT64U, r64Val2);
11382 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
11383 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
11384 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val2, r64Val2, 2);
11385
11386 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11387 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11388
11389 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11390 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11391 IEM_MC_FETCH_MEM_R64(r64Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11392
11393 IEM_MC_PREPARE_FPU_USAGE();
11394 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
11395 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r64, pu16Fsw, pr80Value1, pr64Val2);
11396 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11397 } IEM_MC_ELSE() {
11398 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11399 } IEM_MC_ENDIF();
11400 IEM_MC_ADVANCE_RIP_AND_FINISH();
11401
11402 IEM_MC_END();
11403}
11404
11405
11406/** Opcode 0xdc !11/3. */
11407FNIEMOP_DEF_1(iemOp_fcomp_m64r, uint8_t, bRm)
11408{
11409 IEMOP_MNEMONIC(fcomp_st0_m64r, "fcomp st0,m64r");
11410
11411 IEM_MC_BEGIN(3, 3, 0, 0);
11412 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11413 IEM_MC_LOCAL(uint16_t, u16Fsw);
11414 IEM_MC_LOCAL(RTFLOAT64U, r64Val2);
11415 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
11416 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
11417 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val2, r64Val2, 2);
11418
11419 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11420 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11421
11422 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11423 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11424 IEM_MC_FETCH_MEM_R64(r64Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11425
11426 IEM_MC_PREPARE_FPU_USAGE();
11427 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
11428 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r64, pu16Fsw, pr80Value1, pr64Val2);
11429 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11430 } IEM_MC_ELSE() {
11431 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11432 } IEM_MC_ENDIF();
11433 IEM_MC_ADVANCE_RIP_AND_FINISH();
11434
11435 IEM_MC_END();
11436}
11437
11438
11439/** Opcode 0xdc !11/4. */
11440FNIEMOP_DEF_1(iemOp_fsub_m64r, uint8_t, bRm)
11441{
11442 IEMOP_MNEMONIC(fsub_m64r, "fsub m64r");
11443 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fsub_r80_by_r64);
11444}
11445
11446
11447/** Opcode 0xdc !11/5. */
11448FNIEMOP_DEF_1(iemOp_fsubr_m64r, uint8_t, bRm)
11449{
11450 IEMOP_MNEMONIC(fsubr_m64r, "fsubr m64r");
11451 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fsubr_r80_by_r64);
11452}
11453
11454
11455/** Opcode 0xdc !11/6. */
11456FNIEMOP_DEF_1(iemOp_fdiv_m64r, uint8_t, bRm)
11457{
11458 IEMOP_MNEMONIC(fdiv_m64r, "fdiv m64r");
11459 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fdiv_r80_by_r64);
11460}
11461
11462
11463/** Opcode 0xdc !11/7. */
11464FNIEMOP_DEF_1(iemOp_fdivr_m64r, uint8_t, bRm)
11465{
11466 IEMOP_MNEMONIC(fdivr_m64r, "fdivr m64r");
11467 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fdivr_r80_by_r64);
11468}
11469
11470
11471/**
11472 * @opcode 0xdc
11473 */
11474FNIEMOP_DEF(iemOp_EscF4)
11475{
11476 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11477 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdc & 0x7);
11478 if (IEM_IS_MODRM_REG_MODE(bRm))
11479 {
11480 switch (IEM_GET_MODRM_REG_8(bRm))
11481 {
11482 case 0: return FNIEMOP_CALL_1(iemOp_fadd_stN_st0, bRm);
11483 case 1: return FNIEMOP_CALL_1(iemOp_fmul_stN_st0, bRm);
11484 case 2: return FNIEMOP_CALL_1(iemOp_fcom_stN, bRm); /* Marked reserved, intel behavior is that of FCOM ST(i). */
11485 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_stN, bRm); /* Marked reserved, intel behavior is that of FCOMP ST(i). */
11486 case 4: return FNIEMOP_CALL_1(iemOp_fsubr_stN_st0, bRm);
11487 case 5: return FNIEMOP_CALL_1(iemOp_fsub_stN_st0, bRm);
11488 case 6: return FNIEMOP_CALL_1(iemOp_fdivr_stN_st0, bRm);
11489 case 7: return FNIEMOP_CALL_1(iemOp_fdiv_stN_st0, bRm);
11490 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11491 }
11492 }
11493 else
11494 {
11495 switch (IEM_GET_MODRM_REG_8(bRm))
11496 {
11497 case 0: return FNIEMOP_CALL_1(iemOp_fadd_m64r, bRm);
11498 case 1: return FNIEMOP_CALL_1(iemOp_fmul_m64r, bRm);
11499 case 2: return FNIEMOP_CALL_1(iemOp_fcom_m64r, bRm);
11500 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_m64r, bRm);
11501 case 4: return FNIEMOP_CALL_1(iemOp_fsub_m64r, bRm);
11502 case 5: return FNIEMOP_CALL_1(iemOp_fsubr_m64r, bRm);
11503 case 6: return FNIEMOP_CALL_1(iemOp_fdiv_m64r, bRm);
11504 case 7: return FNIEMOP_CALL_1(iemOp_fdivr_m64r, bRm);
11505 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11506 }
11507 }
11508}
11509
11510
11511/** Opcode 0xdd !11/0.
11512 * @sa iemOp_fld_m32r */
11513FNIEMOP_DEF_1(iemOp_fld_m64r, uint8_t, bRm)
11514{
11515 IEMOP_MNEMONIC(fld_m64r, "fld m64r");
11516
11517 IEM_MC_BEGIN(2, 3, 0, 0);
11518 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11519 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
11520 IEM_MC_LOCAL(RTFLOAT64U, r64Val);
11521 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
11522 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val, r64Val, 1);
11523
11524 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11525 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11526 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11527 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11528
11529 IEM_MC_FETCH_MEM_R64(r64Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11530 IEM_MC_PREPARE_FPU_USAGE();
11531 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
11532 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r80_from_r64, pFpuRes, pr64Val);
11533 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11534 } IEM_MC_ELSE() {
11535 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11536 } IEM_MC_ENDIF();
11537 IEM_MC_ADVANCE_RIP_AND_FINISH();
11538
11539 IEM_MC_END();
11540}
11541
11542
11543/** Opcode 0xdd !11/0. */
11544FNIEMOP_DEF_1(iemOp_fisttp_m64i, uint8_t, bRm)
11545{
11546 IEMOP_MNEMONIC(fisttp_m64i, "fisttp m64i");
11547 IEM_MC_BEGIN(3, 3, 0, 0);
11548 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11549 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11550
11551 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11552 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11553 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11554 IEM_MC_PREPARE_FPU_USAGE();
11555
11556 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
11557 IEM_MC_ARG(int64_t *, pi64Dst, 1);
11558 IEM_MC_MEM_MAP_I64_WO(pi64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11559
11560 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
11561 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
11562 IEM_MC_LOCAL(uint16_t, u16Fsw);
11563 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
11564 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i64, pu16Fsw, pi64Dst, pr80Value);
11565 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
11566 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
11567 } IEM_MC_ELSE() {
11568 IEM_MC_IF_FCW_IM() {
11569 IEM_MC_STORE_MEM_I64_CONST_BY_REF(pi64Dst, INT64_MIN /* (integer indefinite) */);
11570 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
11571 } IEM_MC_ELSE() {
11572 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
11573 } IEM_MC_ENDIF();
11574 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
11575 } IEM_MC_ENDIF();
11576 IEM_MC_ADVANCE_RIP_AND_FINISH();
11577
11578 IEM_MC_END();
11579}
11580
11581
11582/** Opcode 0xdd !11/0. */
11583FNIEMOP_DEF_1(iemOp_fst_m64r, uint8_t, bRm)
11584{
11585 IEMOP_MNEMONIC(fst_m64r, "fst m64r");
11586 IEM_MC_BEGIN(3, 3, 0, 0);
11587 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11588 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11589
11590 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11591 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11592 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11593 IEM_MC_PREPARE_FPU_USAGE();
11594
11595 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
11596 IEM_MC_ARG(PRTFLOAT64U, pr64Dst, 1);
11597 IEM_MC_MEM_MAP_R64_WO(pr64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11598
11599 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
11600 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
11601 IEM_MC_LOCAL(uint16_t, u16Fsw);
11602 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
11603 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r64, pu16Fsw, pr64Dst, pr80Value);
11604 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
11605 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
11606 } IEM_MC_ELSE() {
11607 IEM_MC_IF_FCW_IM() {
11608 IEM_MC_STORE_MEM_NEG_QNAN_R64_BY_REF(pr64Dst);
11609 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
11610 } IEM_MC_ELSE() {
11611 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
11612 } IEM_MC_ENDIF();
11613 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
11614 } IEM_MC_ENDIF();
11615 IEM_MC_ADVANCE_RIP_AND_FINISH();
11616
11617 IEM_MC_END();
11618}
11619
11620
11621
11622
11623/** Opcode 0xdd !11/0. */
11624FNIEMOP_DEF_1(iemOp_fstp_m64r, uint8_t, bRm)
11625{
11626 IEMOP_MNEMONIC(fstp_m64r, "fstp m64r");
11627 IEM_MC_BEGIN(3, 3, 0, 0);
11628 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11629 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11630
11631 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11632 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11633 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11634 IEM_MC_PREPARE_FPU_USAGE();
11635
11636 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
11637 IEM_MC_ARG(PRTFLOAT64U, pr64Dst, 1);
11638 IEM_MC_MEM_MAP_R64_WO(pr64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11639
11640 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
11641 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
11642 IEM_MC_LOCAL(uint16_t, u16Fsw);
11643 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
11644 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r64, pu16Fsw, pr64Dst, pr80Value);
11645 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
11646 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
11647 } IEM_MC_ELSE() {
11648 IEM_MC_IF_FCW_IM() {
11649 IEM_MC_STORE_MEM_NEG_QNAN_R64_BY_REF(pr64Dst);
11650 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
11651 } IEM_MC_ELSE() {
11652 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
11653 } IEM_MC_ENDIF();
11654 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
11655 } IEM_MC_ENDIF();
11656 IEM_MC_ADVANCE_RIP_AND_FINISH();
11657
11658 IEM_MC_END();
11659}
11660
11661
11662/** Opcode 0xdd !11/0. */
11663FNIEMOP_DEF_1(iemOp_frstor, uint8_t, bRm)
11664{
11665 IEMOP_MNEMONIC(frstor, "frstor m94/108byte");
11666 IEM_MC_BEGIN(3, 0, 0, 0);
11667 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 2);
11668 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11669
11670 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11671 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11672 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
11673
11674 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
11675 IEM_MC_ARG_CONST(uint8_t, iEffSeg, /*=*/ pVCpu->iem.s.iEffSeg, 1);
11676 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_FPU, 0, iemCImpl_frstor, enmEffOpSize, iEffSeg, GCPtrEffSrc);
11677 IEM_MC_END();
11678}
11679
11680
11681/** Opcode 0xdd !11/0. */
11682FNIEMOP_DEF_1(iemOp_fnsave, uint8_t, bRm)
11683{
11684 IEMOP_MNEMONIC(fnsave, "fnsave m94/108byte");
11685 IEM_MC_BEGIN(3, 0, 0, 0);
11686 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 2);
11687 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11688
11689 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11690 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11691 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE(); /* Note! Implicit fninit after the save, do not use FOR_READ here! */
11692
11693 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
11694 IEM_MC_ARG_CONST(uint8_t, iEffSeg, /*=*/ pVCpu->iem.s.iEffSeg, 1);
11695 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_FPU, 0, iemCImpl_fnsave, enmEffOpSize, iEffSeg, GCPtrEffDst);
11696 IEM_MC_END();
11697}
11698
11699/** Opcode 0xdd !11/0. */
11700FNIEMOP_DEF_1(iemOp_fnstsw, uint8_t, bRm)
11701{
11702 IEMOP_MNEMONIC(fnstsw_m16, "fnstsw m16");
11703
11704 IEM_MC_BEGIN(0, 2, 0, 0);
11705 IEM_MC_LOCAL(uint16_t, u16Tmp);
11706 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11707
11708 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11709 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11710 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11711
11712 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
11713 IEM_MC_FETCH_FSW(u16Tmp);
11714 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Tmp);
11715 IEM_MC_ADVANCE_RIP_AND_FINISH();
11716
11717/** @todo Debug / drop a hint to the verifier that things may differ
11718 * from REM. Seen 0x4020 (iem) vs 0x4000 (rem) at 0008:801c6b88 booting
11719 * NT4SP1. (X86_FSW_PE) */
11720 IEM_MC_END();
11721}
11722
11723
11724/** Opcode 0xdd 11/0. */
11725FNIEMOP_DEF_1(iemOp_ffree_stN, uint8_t, bRm)
11726{
11727 IEMOP_MNEMONIC(ffree_stN, "ffree stN");
11728 /* Note! C0, C1, C2 and C3 are documented as undefined, we leave the
11729 unmodified. */
11730 IEM_MC_BEGIN(0, 0, 0, 0);
11731 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11732
11733 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11734 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11735
11736 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
11737 IEM_MC_FPU_STACK_FREE(IEM_GET_MODRM_RM_8(bRm));
11738 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
11739
11740 IEM_MC_ADVANCE_RIP_AND_FINISH();
11741 IEM_MC_END();
11742}
11743
11744
11745/** Opcode 0xdd 11/1. */
11746FNIEMOP_DEF_1(iemOp_fst_stN, uint8_t, bRm)
11747{
11748 IEMOP_MNEMONIC(fst_st0_stN, "fst st0,stN");
11749 IEM_MC_BEGIN(0, 2, 0, 0);
11750 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11751 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value);
11752 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
11753 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11754 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11755
11756 IEM_MC_PREPARE_FPU_USAGE();
11757 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
11758 IEM_MC_SET_FPU_RESULT(FpuRes, 0 /*FSW*/, pr80Value);
11759 IEM_MC_STORE_FPU_RESULT(FpuRes, IEM_GET_MODRM_RM_8(bRm), pVCpu->iem.s.uFpuOpcode);
11760 } IEM_MC_ELSE() {
11761 IEM_MC_FPU_STACK_UNDERFLOW(IEM_GET_MODRM_RM_8(bRm), pVCpu->iem.s.uFpuOpcode);
11762 } IEM_MC_ENDIF();
11763
11764 IEM_MC_ADVANCE_RIP_AND_FINISH();
11765 IEM_MC_END();
11766}
11767
11768
11769/** Opcode 0xdd 11/3. */
11770FNIEMOP_DEF_1(iemOp_fucom_stN_st0, uint8_t, bRm)
11771{
11772 IEMOP_MNEMONIC(fucom_st0_stN, "fucom st0,stN");
11773 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN, bRm, iemAImpl_fucom_r80_by_r80);
11774}
11775
11776
11777/** Opcode 0xdd 11/4. */
11778FNIEMOP_DEF_1(iemOp_fucomp_stN, uint8_t, bRm)
11779{
11780 IEMOP_MNEMONIC(fucomp_st0_stN, "fucomp st0,stN");
11781 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN_pop, bRm, iemAImpl_fucom_r80_by_r80);
11782}
11783
11784
11785/**
11786 * @opcode 0xdd
11787 */
11788FNIEMOP_DEF(iemOp_EscF5)
11789{
11790 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11791 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdd & 0x7);
11792 if (IEM_IS_MODRM_REG_MODE(bRm))
11793 {
11794 switch (IEM_GET_MODRM_REG_8(bRm))
11795 {
11796 case 0: return FNIEMOP_CALL_1(iemOp_ffree_stN, bRm);
11797 case 1: return FNIEMOP_CALL_1(iemOp_fxch_stN, bRm); /* Reserved, intel behavior is that of XCHG ST(i). */
11798 case 2: return FNIEMOP_CALL_1(iemOp_fst_stN, bRm);
11799 case 3: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm);
11800 case 4: return FNIEMOP_CALL_1(iemOp_fucom_stN_st0,bRm);
11801 case 5: return FNIEMOP_CALL_1(iemOp_fucomp_stN, bRm);
11802 case 6: IEMOP_RAISE_INVALID_OPCODE_RET();
11803 case 7: IEMOP_RAISE_INVALID_OPCODE_RET();
11804 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11805 }
11806 }
11807 else
11808 {
11809 switch (IEM_GET_MODRM_REG_8(bRm))
11810 {
11811 case 0: return FNIEMOP_CALL_1(iemOp_fld_m64r, bRm);
11812 case 1: return FNIEMOP_CALL_1(iemOp_fisttp_m64i, bRm);
11813 case 2: return FNIEMOP_CALL_1(iemOp_fst_m64r, bRm);
11814 case 3: return FNIEMOP_CALL_1(iemOp_fstp_m64r, bRm);
11815 case 4: return FNIEMOP_CALL_1(iemOp_frstor, bRm);
11816 case 5: IEMOP_RAISE_INVALID_OPCODE_RET();
11817 case 6: return FNIEMOP_CALL_1(iemOp_fnsave, bRm);
11818 case 7: return FNIEMOP_CALL_1(iemOp_fnstsw, bRm);
11819 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11820 }
11821 }
11822}
11823
11824
11825/** Opcode 0xde 11/0. */
11826FNIEMOP_DEF_1(iemOp_faddp_stN_st0, uint8_t, bRm)
11827{
11828 IEMOP_MNEMONIC(faddp_stN_st0, "faddp stN,st0");
11829 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fadd_r80_by_r80);
11830}
11831
11832
11833/** Opcode 0xde 11/0. */
11834FNIEMOP_DEF_1(iemOp_fmulp_stN_st0, uint8_t, bRm)
11835{
11836 IEMOP_MNEMONIC(fmulp_stN_st0, "fmulp stN,st0");
11837 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fmul_r80_by_r80);
11838}
11839
11840
11841/** Opcode 0xde 0xd9. */
11842FNIEMOP_DEF(iemOp_fcompp)
11843{
11844 IEMOP_MNEMONIC(fcompp, "fcompp");
11845 return FNIEMOP_CALL_1(iemOpHlpFpuNoStore_st0_st1_pop_pop, iemAImpl_fcom_r80_by_r80);
11846}
11847
11848
11849/** Opcode 0xde 11/4. */
11850FNIEMOP_DEF_1(iemOp_fsubrp_stN_st0, uint8_t, bRm)
11851{
11852 IEMOP_MNEMONIC(fsubrp_stN_st0, "fsubrp stN,st0");
11853 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fsubr_r80_by_r80);
11854}
11855
11856
11857/** Opcode 0xde 11/5. */
11858FNIEMOP_DEF_1(iemOp_fsubp_stN_st0, uint8_t, bRm)
11859{
11860 IEMOP_MNEMONIC(fsubp_stN_st0, "fsubp stN,st0");
11861 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fsub_r80_by_r80);
11862}
11863
11864
11865/** Opcode 0xde 11/6. */
11866FNIEMOP_DEF_1(iemOp_fdivrp_stN_st0, uint8_t, bRm)
11867{
11868 IEMOP_MNEMONIC(fdivrp_stN_st0, "fdivrp stN,st0");
11869 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fdivr_r80_by_r80);
11870}
11871
11872
11873/** Opcode 0xde 11/7. */
11874FNIEMOP_DEF_1(iemOp_fdivp_stN_st0, uint8_t, bRm)
11875{
11876 IEMOP_MNEMONIC(fdivp_stN_st0, "fdivp stN,st0");
11877 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fdiv_r80_by_r80);
11878}
11879
11880
11881/**
11882 * Common worker for FPU instructions working on ST0 and an m16i, and storing
11883 * the result in ST0.
11884 *
11885 * @param bRm Mod R/M byte.
11886 * @param pfnAImpl Pointer to the instruction implementation (assembly).
11887 */
11888FNIEMOP_DEF_2(iemOpHlpFpu_st0_m16i, uint8_t, bRm, PFNIEMAIMPLFPUI16, pfnAImpl)
11889{
11890 IEM_MC_BEGIN(3, 3, 0, 0);
11891 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11892 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
11893 IEM_MC_LOCAL(int16_t, i16Val2);
11894 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
11895 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
11896 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val2, i16Val2, 2);
11897
11898 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11899 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11900
11901 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11902 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11903 IEM_MC_FETCH_MEM_I16(i16Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11904
11905 IEM_MC_PREPARE_FPU_USAGE();
11906 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
11907 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pi16Val2);
11908 IEM_MC_STORE_FPU_RESULT(FpuRes, 0, pVCpu->iem.s.uFpuOpcode);
11909 } IEM_MC_ELSE() {
11910 IEM_MC_FPU_STACK_UNDERFLOW(0, pVCpu->iem.s.uFpuOpcode);
11911 } IEM_MC_ENDIF();
11912 IEM_MC_ADVANCE_RIP_AND_FINISH();
11913
11914 IEM_MC_END();
11915}
11916
11917
11918/** Opcode 0xde !11/0. */
11919FNIEMOP_DEF_1(iemOp_fiadd_m16i, uint8_t, bRm)
11920{
11921 IEMOP_MNEMONIC(fiadd_m16i, "fiadd m16i");
11922 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fiadd_r80_by_i16);
11923}
11924
11925
11926/** Opcode 0xde !11/1. */
11927FNIEMOP_DEF_1(iemOp_fimul_m16i, uint8_t, bRm)
11928{
11929 IEMOP_MNEMONIC(fimul_m16i, "fimul m16i");
11930 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fimul_r80_by_i16);
11931}
11932
11933
11934/** Opcode 0xde !11/2. */
11935FNIEMOP_DEF_1(iemOp_ficom_m16i, uint8_t, bRm)
11936{
11937 IEMOP_MNEMONIC(ficom_st0_m16i, "ficom st0,m16i");
11938
11939 IEM_MC_BEGIN(3, 3, 0, 0);
11940 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11941 IEM_MC_LOCAL(uint16_t, u16Fsw);
11942 IEM_MC_LOCAL(int16_t, i16Val2);
11943 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
11944 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
11945 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val2, i16Val2, 2);
11946
11947 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11948 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11949
11950 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11951 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11952 IEM_MC_FETCH_MEM_I16(i16Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11953
11954 IEM_MC_PREPARE_FPU_USAGE();
11955 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
11956 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i16, pu16Fsw, pr80Value1, pi16Val2);
11957 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11958 } IEM_MC_ELSE() {
11959 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11960 } IEM_MC_ENDIF();
11961 IEM_MC_ADVANCE_RIP_AND_FINISH();
11962
11963 IEM_MC_END();
11964}
11965
11966
11967/** Opcode 0xde !11/3. */
11968FNIEMOP_DEF_1(iemOp_ficomp_m16i, uint8_t, bRm)
11969{
11970 IEMOP_MNEMONIC(ficomp_st0_m16i, "ficomp st0,m16i");
11971
11972 IEM_MC_BEGIN(3, 3, 0, 0);
11973 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11974 IEM_MC_LOCAL(uint16_t, u16Fsw);
11975 IEM_MC_LOCAL(int16_t, i16Val2);
11976 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
11977 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
11978 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val2, i16Val2, 2);
11979
11980 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11981 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11982
11983 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
11984 IEM_MC_MAYBE_RAISE_FPU_XCPT();
11985 IEM_MC_FETCH_MEM_I16(i16Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11986
11987 IEM_MC_PREPARE_FPU_USAGE();
11988 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0) {
11989 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i16, pu16Fsw, pr80Value1, pi16Val2);
11990 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11991 } IEM_MC_ELSE() {
11992 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
11993 } IEM_MC_ENDIF();
11994 IEM_MC_ADVANCE_RIP_AND_FINISH();
11995
11996 IEM_MC_END();
11997}
11998
11999
12000/** Opcode 0xde !11/4. */
12001FNIEMOP_DEF_1(iemOp_fisub_m16i, uint8_t, bRm)
12002{
12003 IEMOP_MNEMONIC(fisub_m16i, "fisub m16i");
12004 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fisub_r80_by_i16);
12005}
12006
12007
12008/** Opcode 0xde !11/5. */
12009FNIEMOP_DEF_1(iemOp_fisubr_m16i, uint8_t, bRm)
12010{
12011 IEMOP_MNEMONIC(fisubr_m16i, "fisubr m16i");
12012 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fisubr_r80_by_i16);
12013}
12014
12015
12016/** Opcode 0xde !11/6. */
12017FNIEMOP_DEF_1(iemOp_fidiv_m16i, uint8_t, bRm)
12018{
12019 IEMOP_MNEMONIC(fidiv_m16i, "fidiv m16i");
12020 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fidiv_r80_by_i16);
12021}
12022
12023
12024/** Opcode 0xde !11/7. */
12025FNIEMOP_DEF_1(iemOp_fidivr_m16i, uint8_t, bRm)
12026{
12027 IEMOP_MNEMONIC(fidivr_m16i, "fidivr m16i");
12028 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fidivr_r80_by_i16);
12029}
12030
12031
12032/**
12033 * @opcode 0xde
12034 */
12035FNIEMOP_DEF(iemOp_EscF6)
12036{
12037 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
12038 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xde & 0x7);
12039 if (IEM_IS_MODRM_REG_MODE(bRm))
12040 {
12041 switch (IEM_GET_MODRM_REG_8(bRm))
12042 {
12043 case 0: return FNIEMOP_CALL_1(iemOp_faddp_stN_st0, bRm);
12044 case 1: return FNIEMOP_CALL_1(iemOp_fmulp_stN_st0, bRm);
12045 case 2: return FNIEMOP_CALL_1(iemOp_fcomp_stN, bRm);
12046 case 3: if (bRm == 0xd9)
12047 return FNIEMOP_CALL(iemOp_fcompp);
12048 IEMOP_RAISE_INVALID_OPCODE_RET();
12049 case 4: return FNIEMOP_CALL_1(iemOp_fsubrp_stN_st0, bRm);
12050 case 5: return FNIEMOP_CALL_1(iemOp_fsubp_stN_st0, bRm);
12051 case 6: return FNIEMOP_CALL_1(iemOp_fdivrp_stN_st0, bRm);
12052 case 7: return FNIEMOP_CALL_1(iemOp_fdivp_stN_st0, bRm);
12053 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12054 }
12055 }
12056 else
12057 {
12058 switch (IEM_GET_MODRM_REG_8(bRm))
12059 {
12060 case 0: return FNIEMOP_CALL_1(iemOp_fiadd_m16i, bRm);
12061 case 1: return FNIEMOP_CALL_1(iemOp_fimul_m16i, bRm);
12062 case 2: return FNIEMOP_CALL_1(iemOp_ficom_m16i, bRm);
12063 case 3: return FNIEMOP_CALL_1(iemOp_ficomp_m16i, bRm);
12064 case 4: return FNIEMOP_CALL_1(iemOp_fisub_m16i, bRm);
12065 case 5: return FNIEMOP_CALL_1(iemOp_fisubr_m16i, bRm);
12066 case 6: return FNIEMOP_CALL_1(iemOp_fidiv_m16i, bRm);
12067 case 7: return FNIEMOP_CALL_1(iemOp_fidivr_m16i, bRm);
12068 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12069 }
12070 }
12071}
12072
12073
12074/** Opcode 0xdf 11/0.
12075 * Undocument instruction, assumed to work like ffree + fincstp. */
12076FNIEMOP_DEF_1(iemOp_ffreep_stN, uint8_t, bRm)
12077{
12078 IEMOP_MNEMONIC(ffreep_stN, "ffreep stN");
12079 IEM_MC_BEGIN(0, 0, 0, 0);
12080 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12081
12082 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12083 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12084
12085 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
12086 IEM_MC_FPU_STACK_FREE(IEM_GET_MODRM_RM_8(bRm));
12087 IEM_MC_FPU_STACK_INC_TOP();
12088 IEM_MC_UPDATE_FPU_OPCODE_IP(pVCpu->iem.s.uFpuOpcode);
12089
12090 IEM_MC_ADVANCE_RIP_AND_FINISH();
12091 IEM_MC_END();
12092}
12093
12094
12095/** Opcode 0xdf 0xe0. */
12096FNIEMOP_DEF(iemOp_fnstsw_ax)
12097{
12098 IEMOP_MNEMONIC(fnstsw_ax, "fnstsw ax");
12099 IEM_MC_BEGIN(0, 1, 0, 0);
12100 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12101 IEM_MC_LOCAL(uint16_t, u16Tmp);
12102 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12103 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
12104 IEM_MC_FETCH_FSW(u16Tmp);
12105 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp);
12106 IEM_MC_ADVANCE_RIP_AND_FINISH();
12107 IEM_MC_END();
12108}
12109
12110
12111/** Opcode 0xdf 11/5. */
12112FNIEMOP_DEF_1(iemOp_fucomip_st0_stN, uint8_t, bRm)
12113{
12114 IEMOP_MNEMONIC(fucomip_st0_stN, "fucomip st0,stN");
12115 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_FPU | IEM_CIMPL_F_STATUS_FLAGS, 0,
12116 iemCImpl_fcomi_fucomi, IEM_GET_MODRM_RM_8(bRm), false /*fUCmp*/,
12117 RT_BIT_32(31) /*fPop*/ | pVCpu->iem.s.uFpuOpcode);
12118}
12119
12120
12121/** Opcode 0xdf 11/6. */
12122FNIEMOP_DEF_1(iemOp_fcomip_st0_stN, uint8_t, bRm)
12123{
12124 IEMOP_MNEMONIC(fcomip_st0_stN, "fcomip st0,stN");
12125 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_FPU | IEM_CIMPL_F_STATUS_FLAGS, 0,
12126 iemCImpl_fcomi_fucomi, IEM_GET_MODRM_RM_8(bRm), false /*fUCmp*/,
12127 RT_BIT_32(31) /*fPop*/ | pVCpu->iem.s.uFpuOpcode);
12128}
12129
12130
12131/** Opcode 0xdf !11/0. */
12132FNIEMOP_DEF_1(iemOp_fild_m16i, uint8_t, bRm)
12133{
12134 IEMOP_MNEMONIC(fild_m16i, "fild m16i");
12135
12136 IEM_MC_BEGIN(2, 3, 0, 0);
12137 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
12138 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
12139 IEM_MC_LOCAL(int16_t, i16Val);
12140 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
12141 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val, i16Val, 1);
12142
12143 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
12144 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12145
12146 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12147 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12148 IEM_MC_FETCH_MEM_I16(i16Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
12149
12150 IEM_MC_PREPARE_FPU_USAGE();
12151 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
12152 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fild_r80_from_i16, pFpuRes, pi16Val);
12153 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
12154 } IEM_MC_ELSE() {
12155 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
12156 } IEM_MC_ENDIF();
12157 IEM_MC_ADVANCE_RIP_AND_FINISH();
12158
12159 IEM_MC_END();
12160}
12161
12162
12163/** Opcode 0xdf !11/1. */
12164FNIEMOP_DEF_1(iemOp_fisttp_m16i, uint8_t, bRm)
12165{
12166 IEMOP_MNEMONIC(fisttp_m16i, "fisttp m16i");
12167 IEM_MC_BEGIN(3, 3, 0, 0);
12168 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
12169 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
12170
12171 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12172 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12173 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12174 IEM_MC_PREPARE_FPU_USAGE();
12175
12176 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
12177 IEM_MC_ARG(int16_t *, pi16Dst, 1);
12178 IEM_MC_MEM_MAP_I16_WO(pi16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
12179
12180 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
12181 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
12182 IEM_MC_LOCAL(uint16_t, u16Fsw);
12183 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
12184 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i16, pu16Fsw, pi16Dst, pr80Value);
12185 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
12186 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12187 } IEM_MC_ELSE() {
12188 IEM_MC_IF_FCW_IM() {
12189 IEM_MC_STORE_MEM_I16_CONST_BY_REF(pi16Dst, INT16_MIN /* (integer indefinite) */);
12190 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
12191 } IEM_MC_ELSE() {
12192 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
12193 } IEM_MC_ENDIF();
12194 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12195 } IEM_MC_ENDIF();
12196 IEM_MC_ADVANCE_RIP_AND_FINISH();
12197
12198 IEM_MC_END();
12199}
12200
12201
12202/** Opcode 0xdf !11/2. */
12203FNIEMOP_DEF_1(iemOp_fist_m16i, uint8_t, bRm)
12204{
12205 IEMOP_MNEMONIC(fist_m16i, "fist m16i");
12206 IEM_MC_BEGIN(3, 3, 0, 0);
12207 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
12208 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
12209
12210 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12211 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12212 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12213 IEM_MC_PREPARE_FPU_USAGE();
12214
12215 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
12216 IEM_MC_ARG(int16_t *, pi16Dst, 1);
12217 IEM_MC_MEM_MAP_I16_WO(pi16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
12218
12219 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
12220 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
12221 IEM_MC_LOCAL(uint16_t, u16Fsw);
12222 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
12223 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i16, pu16Fsw, pi16Dst, pr80Value);
12224 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
12225 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12226 } IEM_MC_ELSE() {
12227 IEM_MC_IF_FCW_IM() {
12228 IEM_MC_STORE_MEM_I16_CONST_BY_REF(pi16Dst, INT16_MIN /* (integer indefinite) */);
12229 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
12230 } IEM_MC_ELSE() {
12231 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
12232 } IEM_MC_ENDIF();
12233 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12234 } IEM_MC_ENDIF();
12235 IEM_MC_ADVANCE_RIP_AND_FINISH();
12236
12237 IEM_MC_END();
12238}
12239
12240
12241/** Opcode 0xdf !11/3. */
12242FNIEMOP_DEF_1(iemOp_fistp_m16i, uint8_t, bRm)
12243{
12244 IEMOP_MNEMONIC(fistp_m16i, "fistp m16i");
12245 IEM_MC_BEGIN(3, 3, 0, 0);
12246 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
12247 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
12248
12249 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12250 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12251 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12252 IEM_MC_PREPARE_FPU_USAGE();
12253
12254 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
12255 IEM_MC_ARG(int16_t *, pi16Dst, 1);
12256 IEM_MC_MEM_MAP_I16_WO(pi16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
12257
12258 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
12259 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
12260 IEM_MC_LOCAL(uint16_t, u16Fsw);
12261 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
12262 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i16, pu16Fsw, pi16Dst, pr80Value);
12263 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
12264 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12265 } IEM_MC_ELSE() {
12266 IEM_MC_IF_FCW_IM() {
12267 IEM_MC_STORE_MEM_I16_CONST_BY_REF(pi16Dst, INT16_MIN /* (integer indefinite) */);
12268 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
12269 } IEM_MC_ELSE() {
12270 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
12271 } IEM_MC_ENDIF();
12272 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12273 } IEM_MC_ENDIF();
12274 IEM_MC_ADVANCE_RIP_AND_FINISH();
12275
12276 IEM_MC_END();
12277}
12278
12279
12280/** Opcode 0xdf !11/4. */
12281FNIEMOP_DEF_1(iemOp_fbld_m80d, uint8_t, bRm)
12282{
12283 IEMOP_MNEMONIC(fbld_m80d, "fbld m80d");
12284
12285 IEM_MC_BEGIN(2, 3, 0, 0);
12286 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
12287 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
12288 IEM_MC_LOCAL(RTPBCD80U, d80Val);
12289 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
12290 IEM_MC_ARG_LOCAL_REF(PCRTPBCD80U, pd80Val, d80Val, 1);
12291
12292 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
12293 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12294
12295 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12296 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12297 IEM_MC_FETCH_MEM_D80(d80Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
12298
12299 IEM_MC_PREPARE_FPU_USAGE();
12300 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
12301 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r80_from_d80, pFpuRes, pd80Val);
12302 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
12303 } IEM_MC_ELSE() {
12304 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
12305 } IEM_MC_ENDIF();
12306 IEM_MC_ADVANCE_RIP_AND_FINISH();
12307
12308 IEM_MC_END();
12309}
12310
12311
12312/** Opcode 0xdf !11/5. */
12313FNIEMOP_DEF_1(iemOp_fild_m64i, uint8_t, bRm)
12314{
12315 IEMOP_MNEMONIC(fild_m64i, "fild m64i");
12316
12317 IEM_MC_BEGIN(2, 3, 0, 0);
12318 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
12319 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
12320 IEM_MC_LOCAL(int64_t, i64Val);
12321 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
12322 IEM_MC_ARG_LOCAL_REF(int64_t const *, pi64Val, i64Val, 1);
12323
12324 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
12325 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12326
12327 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12328 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12329 IEM_MC_FETCH_MEM_I64(i64Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
12330
12331 IEM_MC_PREPARE_FPU_USAGE();
12332 IEM_MC_IF_FPUREG_IS_EMPTY(7) {
12333 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fild_r80_from_i64, pFpuRes, pi64Val);
12334 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
12335 } IEM_MC_ELSE() {
12336 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, pVCpu->iem.s.uFpuOpcode);
12337 } IEM_MC_ENDIF();
12338 IEM_MC_ADVANCE_RIP_AND_FINISH();
12339
12340 IEM_MC_END();
12341}
12342
12343
12344/** Opcode 0xdf !11/6. */
12345FNIEMOP_DEF_1(iemOp_fbstp_m80d, uint8_t, bRm)
12346{
12347 IEMOP_MNEMONIC(fbstp_m80d, "fbstp m80d");
12348 IEM_MC_BEGIN(3, 3, 0, 0);
12349 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
12350 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
12351
12352 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12353 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12354 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12355 IEM_MC_PREPARE_FPU_USAGE();
12356
12357 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
12358 IEM_MC_ARG(PRTPBCD80U, pd80Dst, 1);
12359 IEM_MC_MEM_MAP_D80_WO(pd80Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
12360
12361 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
12362 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
12363 IEM_MC_LOCAL(uint16_t, u16Fsw);
12364 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
12365 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_d80, pu16Fsw, pd80Dst, pr80Value);
12366 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
12367 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12368 } IEM_MC_ELSE() {
12369 IEM_MC_IF_FCW_IM() {
12370 IEM_MC_STORE_MEM_INDEF_D80_BY_REF(pd80Dst);
12371 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
12372 } IEM_MC_ELSE() {
12373 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
12374 } IEM_MC_ENDIF();
12375 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12376 } IEM_MC_ENDIF();
12377 IEM_MC_ADVANCE_RIP_AND_FINISH();
12378
12379 IEM_MC_END();
12380}
12381
12382
12383/** Opcode 0xdf !11/7. */
12384FNIEMOP_DEF_1(iemOp_fistp_m64i, uint8_t, bRm)
12385{
12386 IEMOP_MNEMONIC(fistp_m64i, "fistp m64i");
12387 IEM_MC_BEGIN(3, 3, 0, 0);
12388 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
12389 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
12390
12391 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12392 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
12393 IEM_MC_MAYBE_RAISE_FPU_XCPT();
12394 IEM_MC_PREPARE_FPU_USAGE();
12395
12396 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
12397 IEM_MC_ARG(int64_t *, pi64Dst, 1);
12398 IEM_MC_MEM_MAP_I64_WO(pi64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
12399
12400 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
12401 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
12402 IEM_MC_LOCAL(uint16_t, u16Fsw);
12403 IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw, u16Fsw, 0);
12404 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i64, pu16Fsw, pi64Dst, pr80Value);
12405 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(bUnmapInfo, u16Fsw);
12406 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12407 } IEM_MC_ELSE() {
12408 IEM_MC_IF_FCW_IM() {
12409 IEM_MC_STORE_MEM_I64_CONST_BY_REF(pi64Dst, INT64_MIN /* (integer indefinite) */);
12410 IEM_MC_MEM_COMMIT_AND_UNMAP_WO(bUnmapInfo);
12411 } IEM_MC_ELSE() {
12412 IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(bUnmapInfo);
12413 } IEM_MC_ENDIF();
12414 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
12415 } IEM_MC_ENDIF();
12416 IEM_MC_ADVANCE_RIP_AND_FINISH();
12417
12418 IEM_MC_END();
12419}
12420
12421
12422/**
12423 * @opcode 0xdf
12424 */
12425FNIEMOP_DEF(iemOp_EscF7)
12426{
12427 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
12428 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdf & 0x7);
12429 if (IEM_IS_MODRM_REG_MODE(bRm))
12430 {
12431 switch (IEM_GET_MODRM_REG_8(bRm))
12432 {
12433 case 0: return FNIEMOP_CALL_1(iemOp_ffreep_stN, bRm); /* ffree + pop afterwards, since forever according to AMD. */
12434 case 1: return FNIEMOP_CALL_1(iemOp_fxch_stN, bRm); /* Reserved, behaves like FXCH ST(i) on intel. */
12435 case 2: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm); /* Reserved, behaves like FSTP ST(i) on intel. */
12436 case 3: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm); /* Reserved, behaves like FSTP ST(i) on intel. */
12437 case 4: if (bRm == 0xe0)
12438 return FNIEMOP_CALL(iemOp_fnstsw_ax);
12439 IEMOP_RAISE_INVALID_OPCODE_RET();
12440 case 5: return FNIEMOP_CALL_1(iemOp_fucomip_st0_stN, bRm);
12441 case 6: return FNIEMOP_CALL_1(iemOp_fcomip_st0_stN, bRm);
12442 case 7: IEMOP_RAISE_INVALID_OPCODE_RET();
12443 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12444 }
12445 }
12446 else
12447 {
12448 switch (IEM_GET_MODRM_REG_8(bRm))
12449 {
12450 case 0: return FNIEMOP_CALL_1(iemOp_fild_m16i, bRm);
12451 case 1: return FNIEMOP_CALL_1(iemOp_fisttp_m16i, bRm);
12452 case 2: return FNIEMOP_CALL_1(iemOp_fist_m16i, bRm);
12453 case 3: return FNIEMOP_CALL_1(iemOp_fistp_m16i, bRm);
12454 case 4: return FNIEMOP_CALL_1(iemOp_fbld_m80d, bRm);
12455 case 5: return FNIEMOP_CALL_1(iemOp_fild_m64i, bRm);
12456 case 6: return FNIEMOP_CALL_1(iemOp_fbstp_m80d, bRm);
12457 case 7: return FNIEMOP_CALL_1(iemOp_fistp_m64i, bRm);
12458 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12459 }
12460 }
12461}
12462
12463
12464/**
12465 * @opcode 0xe0
12466 */
12467FNIEMOP_DEF(iemOp_loopne_Jb)
12468{
12469 IEMOP_MNEMONIC(loopne_Jb, "loopne Jb");
12470 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
12471 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
12472
12473 switch (pVCpu->iem.s.enmEffAddrMode)
12474 {
12475 case IEMMODE_16BIT:
12476 IEM_MC_BEGIN(0, 0, IEM_MC_F_NOT_64BIT, 0);
12477 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12478 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
12479 IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
12480 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12481 } IEM_MC_ELSE() {
12482 IEM_MC_ADVANCE_RIP_AND_FINISH();
12483 } IEM_MC_ENDIF();
12484 IEM_MC_END();
12485 break;
12486
12487 case IEMMODE_32BIT:
12488 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
12489 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12490 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
12491 IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
12492 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12493 } IEM_MC_ELSE() {
12494 IEM_MC_ADVANCE_RIP_AND_FINISH();
12495 } IEM_MC_ENDIF();
12496 IEM_MC_END();
12497 break;
12498
12499 case IEMMODE_64BIT:
12500 IEM_MC_BEGIN(0, 0, IEM_MC_F_64BIT, 0);
12501 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12502 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
12503 IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
12504 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12505 } IEM_MC_ELSE() {
12506 IEM_MC_ADVANCE_RIP_AND_FINISH();
12507 } IEM_MC_ENDIF();
12508 IEM_MC_END();
12509 break;
12510
12511 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12512 }
12513}
12514
12515
12516/**
12517 * @opcode 0xe1
12518 */
12519FNIEMOP_DEF(iemOp_loope_Jb)
12520{
12521 IEMOP_MNEMONIC(loope_Jb, "loope Jb");
12522 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
12523 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
12524
12525 switch (pVCpu->iem.s.enmEffAddrMode)
12526 {
12527 case IEMMODE_16BIT:
12528 IEM_MC_BEGIN(0, 0, IEM_MC_F_NOT_64BIT, 0);
12529 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12530 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
12531 IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
12532 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12533 } IEM_MC_ELSE() {
12534 IEM_MC_ADVANCE_RIP_AND_FINISH();
12535 } IEM_MC_ENDIF();
12536 IEM_MC_END();
12537 break;
12538
12539 case IEMMODE_32BIT:
12540 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
12541 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12542 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
12543 IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
12544 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12545 } IEM_MC_ELSE() {
12546 IEM_MC_ADVANCE_RIP_AND_FINISH();
12547 } IEM_MC_ENDIF();
12548 IEM_MC_END();
12549 break;
12550
12551 case IEMMODE_64BIT:
12552 IEM_MC_BEGIN(0, 0, IEM_MC_F_64BIT, 0);
12553 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12554 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
12555 IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
12556 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12557 } IEM_MC_ELSE() {
12558 IEM_MC_ADVANCE_RIP_AND_FINISH();
12559 } IEM_MC_ENDIF();
12560 IEM_MC_END();
12561 break;
12562
12563 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12564 }
12565}
12566
12567
12568/**
12569 * @opcode 0xe2
12570 */
12571FNIEMOP_DEF(iemOp_loop_Jb)
12572{
12573 IEMOP_MNEMONIC(loop_Jb, "loop Jb");
12574 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
12575 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
12576
12577 /** @todo Check out the \#GP case if EIP < CS.Base or EIP > CS.Limit when
12578 * using the 32-bit operand size override. How can that be restarted? See
12579 * weird pseudo code in intel manual. */
12580
12581 /* NB: At least Windows for Workgroups 3.11 (NDIS.386) and Windows 95 (NDIS.VXD, IOS)
12582 * use LOOP $-2 to implement NdisStallExecution and other CPU stall APIs. Shortcutting
12583 * the loop causes guest crashes, but when logging it's nice to skip a few million
12584 * lines of useless output. */
12585#if defined(LOG_ENABLED)
12586 if ((LogIs3Enabled() || LogIs4Enabled()) && -(int8_t)IEM_GET_INSTR_LEN(pVCpu) == i8Imm)
12587 switch (pVCpu->iem.s.enmEffAddrMode)
12588 {
12589 case IEMMODE_16BIT:
12590 IEM_MC_BEGIN(0, 0, IEM_MC_F_NOT_64BIT, 0);
12591 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12592 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xCX, 0);
12593 IEM_MC_ADVANCE_RIP_AND_FINISH();
12594 IEM_MC_END();
12595 break;
12596
12597 case IEMMODE_32BIT:
12598 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
12599 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12600 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xCX, 0);
12601 IEM_MC_ADVANCE_RIP_AND_FINISH();
12602 IEM_MC_END();
12603 break;
12604
12605 case IEMMODE_64BIT:
12606 IEM_MC_BEGIN(0, 0, IEM_MC_F_64BIT, 0);
12607 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12608 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xCX, 0);
12609 IEM_MC_ADVANCE_RIP_AND_FINISH();
12610 IEM_MC_END();
12611 break;
12612
12613 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12614 }
12615#endif
12616
12617 switch (pVCpu->iem.s.enmEffAddrMode)
12618 {
12619 case IEMMODE_16BIT:
12620 IEM_MC_BEGIN(0, 0, IEM_MC_F_NOT_64BIT, 0);
12621 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12622 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
12623 IEM_MC_IF_CX_IS_NZ() {
12624 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12625 } IEM_MC_ELSE() {
12626 IEM_MC_ADVANCE_RIP_AND_FINISH();
12627 } IEM_MC_ENDIF();
12628 IEM_MC_END();
12629 break;
12630
12631 case IEMMODE_32BIT:
12632 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
12633 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12634 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
12635 IEM_MC_IF_ECX_IS_NZ() {
12636 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12637 } IEM_MC_ELSE() {
12638 IEM_MC_ADVANCE_RIP_AND_FINISH();
12639 } IEM_MC_ENDIF();
12640 IEM_MC_END();
12641 break;
12642
12643 case IEMMODE_64BIT:
12644 IEM_MC_BEGIN(0, 0, IEM_MC_F_64BIT, 0);
12645 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12646 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
12647 IEM_MC_IF_RCX_IS_NZ() {
12648 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12649 } IEM_MC_ELSE() {
12650 IEM_MC_ADVANCE_RIP_AND_FINISH();
12651 } IEM_MC_ENDIF();
12652 IEM_MC_END();
12653 break;
12654
12655 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12656 }
12657}
12658
12659
12660/**
12661 * @opcode 0xe3
12662 */
12663FNIEMOP_DEF(iemOp_jecxz_Jb)
12664{
12665 IEMOP_MNEMONIC(jecxz_Jb, "jecxz Jb");
12666 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
12667 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
12668
12669 switch (pVCpu->iem.s.enmEffAddrMode)
12670 {
12671 case IEMMODE_16BIT:
12672 IEM_MC_BEGIN(0, 0, IEM_MC_F_NOT_64BIT, 0);
12673 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12674 IEM_MC_IF_CX_IS_NZ() {
12675 IEM_MC_ADVANCE_RIP_AND_FINISH();
12676 } IEM_MC_ELSE() {
12677 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12678 } IEM_MC_ENDIF();
12679 IEM_MC_END();
12680 break;
12681
12682 case IEMMODE_32BIT:
12683 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
12684 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12685 IEM_MC_IF_ECX_IS_NZ() {
12686 IEM_MC_ADVANCE_RIP_AND_FINISH();
12687 } IEM_MC_ELSE() {
12688 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12689 } IEM_MC_ENDIF();
12690 IEM_MC_END();
12691 break;
12692
12693 case IEMMODE_64BIT:
12694 IEM_MC_BEGIN(0, 0, IEM_MC_F_64BIT, 0);
12695 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12696 IEM_MC_IF_RCX_IS_NZ() {
12697 IEM_MC_ADVANCE_RIP_AND_FINISH();
12698 } IEM_MC_ELSE() {
12699 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12700 } IEM_MC_ENDIF();
12701 IEM_MC_END();
12702 break;
12703
12704 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12705 }
12706}
12707
12708
12709/** Opcode 0xe4 */
12710FNIEMOP_DEF(iemOp_in_AL_Ib)
12711{
12712 IEMOP_MNEMONIC(in_AL_Ib, "in AL,Ib");
12713 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
12714 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12715 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX),
12716 iemCImpl_in, u8Imm, 1, 0x80 /* fImm */ | pVCpu->iem.s.enmEffAddrMode);
12717}
12718
12719
12720/** Opcode 0xe5 */
12721FNIEMOP_DEF(iemOp_in_eAX_Ib)
12722{
12723 IEMOP_MNEMONIC(in_eAX_Ib, "in eAX,Ib");
12724 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
12725 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12726 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO, RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX),
12727 iemCImpl_in, u8Imm, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4,
12728 0x80 /* fImm */ | pVCpu->iem.s.enmEffAddrMode);
12729}
12730
12731
12732/** Opcode 0xe6 */
12733FNIEMOP_DEF(iemOp_out_Ib_AL)
12734{
12735 IEMOP_MNEMONIC(out_Ib_AL, "out Ib,AL");
12736 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
12737 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12738 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO, 0,
12739 iemCImpl_out, u8Imm, 1, 0x80 /* fImm */ | pVCpu->iem.s.enmEffAddrMode);
12740}
12741
12742
12743/** Opcode 0xe7 */
12744FNIEMOP_DEF(iemOp_out_Ib_eAX)
12745{
12746 IEMOP_MNEMONIC(out_Ib_eAX, "out Ib,eAX");
12747 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
12748 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12749 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO, 0,
12750 iemCImpl_out, u8Imm, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4,
12751 0x80 /* fImm */ | pVCpu->iem.s.enmEffAddrMode);
12752}
12753
12754
12755/**
12756 * @opcode 0xe8
12757 */
12758FNIEMOP_DEF(iemOp_call_Jv)
12759{
12760 IEMOP_MNEMONIC(call_Jv, "call Jv");
12761 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
12762 switch (pVCpu->iem.s.enmEffOpSize)
12763 {
12764 case IEMMODE_16BIT:
12765 {
12766 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
12767 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_RELATIVE | IEM_CIMPL_F_BRANCH_STACK, 0,
12768 iemCImpl_call_rel_16, (int16_t)u16Imm);
12769 }
12770
12771 case IEMMODE_32BIT:
12772 {
12773 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
12774 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_RELATIVE | IEM_CIMPL_F_BRANCH_STACK, 0,
12775 iemCImpl_call_rel_32, (int32_t)u32Imm);
12776 }
12777
12778 case IEMMODE_64BIT:
12779 {
12780 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
12781 IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_RELATIVE | IEM_CIMPL_F_BRANCH_STACK, 0,
12782 iemCImpl_call_rel_64, u64Imm);
12783 }
12784
12785 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12786 }
12787}
12788
12789
12790/**
12791 * @opcode 0xe9
12792 */
12793FNIEMOP_DEF(iemOp_jmp_Jv)
12794{
12795 IEMOP_MNEMONIC(jmp_Jv, "jmp Jv");
12796 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
12797 switch (pVCpu->iem.s.enmEffOpSize)
12798 {
12799 case IEMMODE_16BIT:
12800 IEM_MC_BEGIN(0, 0, 0, 0);
12801 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
12802 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12803 IEM_MC_REL_JMP_S16_AND_FINISH(i16Imm);
12804 IEM_MC_END();
12805 break;
12806
12807 case IEMMODE_64BIT:
12808 case IEMMODE_32BIT:
12809 IEM_MC_BEGIN(0, 0, IEM_MC_F_MIN_386, 0);
12810 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
12811 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12812 IEM_MC_REL_JMP_S32_AND_FINISH(i32Imm);
12813 IEM_MC_END();
12814 break;
12815
12816 IEM_NOT_REACHED_DEFAULT_CASE_RET();
12817 }
12818}
12819
12820
12821/**
12822 * @opcode 0xea
12823 */
12824FNIEMOP_DEF(iemOp_jmp_Ap)
12825{
12826 IEMOP_MNEMONIC(jmp_Ap, "jmp Ap");
12827 IEMOP_HLP_NO_64BIT();
12828
12829 /* Decode the far pointer address and pass it on to the far call C implementation. */
12830 uint32_t off32Seg;
12831 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_16BIT)
12832 IEM_OPCODE_GET_NEXT_U32(&off32Seg);
12833 else
12834 IEM_OPCODE_GET_NEXT_U16_ZX_U32(&off32Seg);
12835 uint16_t u16Sel; IEM_OPCODE_GET_NEXT_U16(&u16Sel);
12836 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12837 IEM_MC_DEFER_TO_CIMPL_3_RET(IEM_CIMPL_F_BRANCH_DIRECT | IEM_CIMPL_F_BRANCH_FAR
12838 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, UINT64_MAX,
12839 iemCImpl_FarJmp, u16Sel, off32Seg, pVCpu->iem.s.enmEffOpSize);
12840 /** @todo make task-switches, ring-switches, ++ return non-zero status */
12841}
12842
12843
12844/**
12845 * @opcode 0xeb
12846 */
12847FNIEMOP_DEF(iemOp_jmp_Jb)
12848{
12849 IEMOP_MNEMONIC(jmp_Jb, "jmp Jb");
12850 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
12851 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
12852
12853 IEM_MC_BEGIN(0, 0, 0, 0);
12854 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12855 IEM_MC_REL_JMP_S8_AND_FINISH(i8Imm);
12856 IEM_MC_END();
12857}
12858
12859
12860/** Opcode 0xec */
12861FNIEMOP_DEF(iemOp_in_AL_DX)
12862{
12863 IEMOP_MNEMONIC(in_AL_DX, "in AL,DX");
12864 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12865 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
12866 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX),
12867 iemCImpl_in_eAX_DX, 1, pVCpu->iem.s.enmEffAddrMode);
12868}
12869
12870
12871/** Opcode 0xed */
12872FNIEMOP_DEF(iemOp_in_eAX_DX)
12873{
12874 IEMOP_MNEMONIC(in_eAX_DX, "in eAX,DX");
12875 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12876 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO,
12877 RT_BIT_64(kIemNativeGstReg_GprFirst + X86_GREG_xAX),
12878 iemCImpl_in_eAX_DX, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4,
12879 pVCpu->iem.s.enmEffAddrMode);
12880}
12881
12882
12883/** Opcode 0xee */
12884FNIEMOP_DEF(iemOp_out_DX_AL)
12885{
12886 IEMOP_MNEMONIC(out_DX_AL, "out DX,AL");
12887 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12888 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO, 0,
12889 iemCImpl_out_DX_eAX, 1, pVCpu->iem.s.enmEffAddrMode);
12890}
12891
12892
12893/** Opcode 0xef */
12894FNIEMOP_DEF(iemOp_out_DX_eAX)
12895{
12896 IEMOP_MNEMONIC(out_DX_eAX, "out DX,eAX");
12897 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12898 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_IO, 0,
12899 iemCImpl_out_DX_eAX, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4,
12900 pVCpu->iem.s.enmEffAddrMode);
12901}
12902
12903
12904/**
12905 * @opcode 0xf0
12906 */
12907FNIEMOP_DEF(iemOp_lock)
12908{
12909 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("lock");
12910 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_LOCK;
12911
12912 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
12913 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
12914}
12915
12916
12917/**
12918 * @opcode 0xf1
12919 */
12920FNIEMOP_DEF(iemOp_int1)
12921{
12922 IEMOP_MNEMONIC(int1, "int1"); /* icebp */
12923 /** @todo Does not generate \#UD on 286, or so they say... Was allegedly a
12924 * prefix byte on 8086 and/or/maybe 80286 without meaning according to the 286
12925 * LOADALL memo. Needs some testing. */
12926 IEMOP_HLP_MIN_386();
12927 /** @todo testcase! */
12928 IEM_MC_DEFER_TO_CIMPL_2_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_STACK_FAR
12929 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_END_TB, 0,
12930 iemCImpl_int, X86_XCPT_DB, IEMINT_INT1);
12931}
12932
12933
12934/**
12935 * @opcode 0xf2
12936 */
12937FNIEMOP_DEF(iemOp_repne)
12938{
12939 /* This overrides any previous REPE prefix. */
12940 pVCpu->iem.s.fPrefixes &= ~IEM_OP_PRF_REPZ;
12941 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("repne");
12942 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REPNZ;
12943
12944 /* For the 4 entry opcode tables, REPNZ overrides any previous
12945 REPZ and operand size prefixes. */
12946 pVCpu->iem.s.idxPrefix = 3;
12947
12948 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
12949 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
12950}
12951
12952
12953/**
12954 * @opcode 0xf3
12955 */
12956FNIEMOP_DEF(iemOp_repe)
12957{
12958 /* This overrides any previous REPNE prefix. */
12959 pVCpu->iem.s.fPrefixes &= ~IEM_OP_PRF_REPNZ;
12960 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("repe");
12961 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REPZ;
12962
12963 /* For the 4 entry opcode tables, REPNZ overrides any previous
12964 REPNZ and operand size prefixes. */
12965 pVCpu->iem.s.idxPrefix = 2;
12966
12967 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
12968 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
12969}
12970
12971
12972/**
12973 * @opcode 0xf4
12974 */
12975FNIEMOP_DEF(iemOp_hlt)
12976{
12977 IEMOP_MNEMONIC(hlt, "hlt");
12978 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12979 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_END_TB | IEM_CIMPL_F_VMEXIT, 0, iemCImpl_hlt);
12980}
12981
12982
12983/**
12984 * @opcode 0xf5
12985 */
12986FNIEMOP_DEF(iemOp_cmc)
12987{
12988 IEMOP_MNEMONIC(cmc, "cmc");
12989 IEM_MC_BEGIN(0, 0, 0, 0);
12990 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
12991 IEM_MC_FLIP_EFL_BIT(X86_EFL_CF);
12992 IEM_MC_ADVANCE_RIP_AND_FINISH();
12993 IEM_MC_END();
12994}
12995
12996
12997/**
12998 * Body for of 'inc/dec/not/neg Eb'.
12999 */
13000#define IEMOP_BODY_UNARY_Eb(a_bRm, a_fnNormalU8, a_fnLockedU8) \
13001 if (IEM_IS_MODRM_REG_MODE(a_bRm)) \
13002 { \
13003 /* register access */ \
13004 IEM_MC_BEGIN(2, 0, 0, 0); \
13005 IEMOP_HLP_DONE_DECODING(); \
13006 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
13007 IEM_MC_ARG(uint32_t *, pEFlags, 1); \
13008 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
13009 IEM_MC_REF_EFLAGS(pEFlags); \
13010 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU8, pu8Dst, pEFlags); \
13011 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13012 IEM_MC_END(); \
13013 } \
13014 else \
13015 { \
13016 /* memory access. */ \
13017 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
13018 { \
13019 IEM_MC_BEGIN(2, 2, 0, 0); \
13020 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
13021 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13022 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13023 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13024 \
13025 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
13026 IEMOP_HLP_DONE_DECODING(); \
13027 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13028 IEM_MC_FETCH_EFLAGS(EFlags); \
13029 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU8, pu8Dst, pEFlags); \
13030 \
13031 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13032 IEM_MC_COMMIT_EFLAGS(EFlags); \
13033 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13034 IEM_MC_END(); \
13035 } \
13036 else \
13037 { \
13038 IEM_MC_BEGIN(2, 2, 0, 0); \
13039 IEM_MC_ARG(uint8_t *, pu8Dst, 0); \
13040 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13041 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13042 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13043 \
13044 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
13045 IEMOP_HLP_DONE_DECODING(); \
13046 IEM_MC_MEM_MAP_U8_RW(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13047 IEM_MC_FETCH_EFLAGS(EFlags); \
13048 IEM_MC_CALL_VOID_AIMPL_2(a_fnLockedU8, pu8Dst, pEFlags); \
13049 \
13050 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13051 IEM_MC_COMMIT_EFLAGS(EFlags); \
13052 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13053 IEM_MC_END(); \
13054 } \
13055 } \
13056 (void)0
13057
13058
13059/**
13060 * Body for 'inc/dec/not/neg Ev' (groups 3 and 5).
13061 */
13062#define IEMOP_BODY_UNARY_Ev(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64) \
13063 if (IEM_IS_MODRM_REG_MODE(bRm)) \
13064 { \
13065 /* \
13066 * Register target \
13067 */ \
13068 switch (pVCpu->iem.s.enmEffOpSize) \
13069 { \
13070 case IEMMODE_16BIT: \
13071 IEM_MC_BEGIN(2, 0, 0, 0); \
13072 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
13073 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
13074 IEM_MC_ARG(uint32_t *, pEFlags, 1); \
13075 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
13076 IEM_MC_REF_EFLAGS(pEFlags); \
13077 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU16, pu16Dst, pEFlags); \
13078 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13079 IEM_MC_END(); \
13080 break; \
13081 \
13082 case IEMMODE_32BIT: \
13083 IEM_MC_BEGIN(2, 0, IEM_MC_F_MIN_386, 0); \
13084 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
13085 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
13086 IEM_MC_ARG(uint32_t *, pEFlags, 1); \
13087 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
13088 IEM_MC_REF_EFLAGS(pEFlags); \
13089 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU32, pu32Dst, pEFlags); \
13090 IEM_MC_CLEAR_HIGH_GREG_U64(IEM_GET_MODRM_RM(pVCpu, bRm)); \
13091 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13092 IEM_MC_END(); \
13093 break; \
13094 \
13095 case IEMMODE_64BIT: \
13096 IEM_MC_BEGIN(2, 0, IEM_MC_F_64BIT, 0); \
13097 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
13098 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
13099 IEM_MC_ARG(uint32_t *, pEFlags, 1); \
13100 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
13101 IEM_MC_REF_EFLAGS(pEFlags); \
13102 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU64, pu64Dst, pEFlags); \
13103 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13104 IEM_MC_END(); \
13105 break; \
13106 \
13107 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
13108 } \
13109 } \
13110 else \
13111 { \
13112 /* \
13113 * Memory target. \
13114 */ \
13115 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK) || (pVCpu->iem.s.fExec & IEM_F_X86_DISREGARD_LOCK)) \
13116 { \
13117 switch (pVCpu->iem.s.enmEffOpSize) \
13118 { \
13119 case IEMMODE_16BIT: \
13120 IEM_MC_BEGIN(2, 3, 0, 0); \
13121 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
13122 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13123 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13124 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13125 \
13126 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
13127 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
13128 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13129 IEM_MC_FETCH_EFLAGS(EFlags); \
13130 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU16, pu16Dst, pEFlags); \
13131 \
13132 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13133 IEM_MC_COMMIT_EFLAGS(EFlags); \
13134 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13135 IEM_MC_END(); \
13136 break; \
13137 \
13138 case IEMMODE_32BIT: \
13139 IEM_MC_BEGIN(2, 3, IEM_MC_F_MIN_386, 0); \
13140 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
13141 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13142 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13143 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13144 \
13145 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
13146 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
13147 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13148 IEM_MC_FETCH_EFLAGS(EFlags); \
13149 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU32, pu32Dst, pEFlags); \
13150 \
13151 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13152 IEM_MC_COMMIT_EFLAGS(EFlags); \
13153 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13154 IEM_MC_END(); \
13155 break; \
13156 \
13157 case IEMMODE_64BIT: \
13158 IEM_MC_BEGIN(2, 3, IEM_MC_F_64BIT, 0); \
13159 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
13160 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13161 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13162 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13163 \
13164 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
13165 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
13166 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13167 IEM_MC_FETCH_EFLAGS(EFlags); \
13168 IEM_MC_CALL_VOID_AIMPL_2(a_fnNormalU64, pu64Dst, pEFlags); \
13169 \
13170 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13171 IEM_MC_COMMIT_EFLAGS(EFlags); \
13172 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13173 IEM_MC_END(); \
13174 break; \
13175 \
13176 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
13177 } \
13178 } \
13179 else \
13180 { \
13181 (void)0
13182
13183#define IEMOP_BODY_UNARY_Ev_LOCKED(a_fnLockedU16, a_fnLockedU32, a_fnLockedU64) \
13184 switch (pVCpu->iem.s.enmEffOpSize) \
13185 { \
13186 case IEMMODE_16BIT: \
13187 IEM_MC_BEGIN(2, 3, 0, 0); \
13188 IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
13189 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13190 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13191 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13192 \
13193 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
13194 IEMOP_HLP_DONE_DECODING(); \
13195 IEM_MC_MEM_MAP_U16_RW(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13196 IEM_MC_FETCH_EFLAGS(EFlags); \
13197 IEM_MC_CALL_VOID_AIMPL_2(a_fnLockedU16, pu16Dst, pEFlags); \
13198 \
13199 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13200 IEM_MC_COMMIT_EFLAGS(EFlags); \
13201 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13202 IEM_MC_END(); \
13203 break; \
13204 \
13205 case IEMMODE_32BIT: \
13206 IEM_MC_BEGIN(2, 3, IEM_MC_F_MIN_386, 0); \
13207 IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
13208 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13209 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13210 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13211 \
13212 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
13213 IEMOP_HLP_DONE_DECODING(); \
13214 IEM_MC_MEM_MAP_U32_RW(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13215 IEM_MC_FETCH_EFLAGS(EFlags); \
13216 IEM_MC_CALL_VOID_AIMPL_2(a_fnLockedU32, pu32Dst, pEFlags); \
13217 \
13218 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13219 IEM_MC_COMMIT_EFLAGS(EFlags); \
13220 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13221 IEM_MC_END(); \
13222 break; \
13223 \
13224 case IEMMODE_64BIT: \
13225 IEM_MC_BEGIN(2, 3, IEM_MC_F_64BIT, 0); \
13226 IEM_MC_ARG(uint64_t *, pu64Dst, 0); \
13227 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1); \
13228 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
13229 IEM_MC_LOCAL(uint8_t, bUnmapInfo); \
13230 \
13231 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
13232 IEMOP_HLP_DONE_DECODING(); \
13233 IEM_MC_MEM_MAP_U64_RW(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
13234 IEM_MC_FETCH_EFLAGS(EFlags); \
13235 IEM_MC_CALL_VOID_AIMPL_2(a_fnLockedU64, pu64Dst, pEFlags); \
13236 \
13237 IEM_MC_MEM_COMMIT_AND_UNMAP_RW(bUnmapInfo); \
13238 IEM_MC_COMMIT_EFLAGS(EFlags); \
13239 IEM_MC_ADVANCE_RIP_AND_FINISH(); \
13240 IEM_MC_END(); \
13241 break; \
13242 \
13243 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
13244 } \
13245 } \
13246 } \
13247 (void)0
13248
13249
13250/**
13251 * @opmaps grp3_f6
13252 * @opcode /0
13253 * @todo also /1
13254 */
13255FNIEMOP_DEF_1(iemOp_grp3_test_Eb, uint8_t, bRm)
13256{
13257 IEMOP_MNEMONIC(test_Eb_Ib, "test Eb,Ib");
13258 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
13259
13260 if (IEM_IS_MODRM_REG_MODE(bRm))
13261 {
13262 /* register access */
13263 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
13264 IEM_MC_BEGIN(3, 0, 0, 0);
13265 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13266 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
13267 IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/u8Imm, 1);
13268 IEM_MC_ARG(uint32_t *, pEFlags, 2);
13269 IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
13270 IEM_MC_REF_EFLAGS(pEFlags);
13271 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
13272 IEM_MC_ADVANCE_RIP_AND_FINISH();
13273 IEM_MC_END();
13274 }
13275 else
13276 {
13277 /* memory access. */
13278 IEM_MC_BEGIN(3, 3, 0, 0);
13279 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13280 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
13281
13282 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
13283 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13284
13285 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
13286 IEM_MC_ARG(uint8_t const *, pu8Dst, 0);
13287 IEM_MC_MEM_MAP_U8_RO(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13288
13289 IEM_MC_ARG_CONST(uint8_t, u8Src, u8Imm, 1);
13290 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
13291 IEM_MC_FETCH_EFLAGS(EFlags);
13292 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
13293
13294 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo);
13295 IEM_MC_COMMIT_EFLAGS(EFlags);
13296 IEM_MC_ADVANCE_RIP_AND_FINISH();
13297 IEM_MC_END();
13298 }
13299}
13300
13301
13302/** Opcode 0xf6 /4, /5, /6 and /7. */
13303FNIEMOP_DEF_2(iemOpCommonGrp3MulDivEb, uint8_t, bRm, PFNIEMAIMPLMULDIVU8, pfnU8)
13304{
13305 if (IEM_IS_MODRM_REG_MODE(bRm))
13306 {
13307 /* register access */
13308 IEM_MC_BEGIN(3, 1, 0, 0);
13309 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13310 IEM_MC_ARG(uint16_t *, pu16AX, 0);
13311 IEM_MC_ARG(uint8_t, u8Value, 1);
13312 IEM_MC_ARG(uint32_t *, pEFlags, 2);
13313 IEM_MC_LOCAL(int32_t, rc);
13314
13315 IEM_MC_FETCH_GREG_U8(u8Value, IEM_GET_MODRM_RM(pVCpu, bRm));
13316 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
13317 IEM_MC_REF_EFLAGS(pEFlags);
13318 IEM_MC_CALL_AIMPL_3(rc, pfnU8, pu16AX, u8Value, pEFlags);
13319 IEM_MC_IF_LOCAL_IS_Z(rc) {
13320 IEM_MC_ADVANCE_RIP_AND_FINISH();
13321 } IEM_MC_ELSE() {
13322 IEM_MC_RAISE_DIVIDE_ERROR();
13323 } IEM_MC_ENDIF();
13324
13325 IEM_MC_END();
13326 }
13327 else
13328 {
13329 /* memory access. */
13330 IEM_MC_BEGIN(3, 2, 0, 0);
13331 IEM_MC_ARG(uint16_t *, pu16AX, 0);
13332 IEM_MC_ARG(uint8_t, u8Value, 1);
13333 IEM_MC_ARG(uint32_t *, pEFlags, 2);
13334 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13335 IEM_MC_LOCAL(int32_t, rc);
13336
13337 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
13338 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13339 IEM_MC_FETCH_MEM_U8(u8Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13340 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
13341 IEM_MC_REF_EFLAGS(pEFlags);
13342 IEM_MC_CALL_AIMPL_3(rc, pfnU8, pu16AX, u8Value, pEFlags);
13343 IEM_MC_IF_LOCAL_IS_Z(rc) {
13344 IEM_MC_ADVANCE_RIP_AND_FINISH();
13345 } IEM_MC_ELSE() {
13346 IEM_MC_RAISE_DIVIDE_ERROR();
13347 } IEM_MC_ENDIF();
13348
13349 IEM_MC_END();
13350 }
13351}
13352
13353
13354/** Opcode 0xf7 /4, /5, /6 and /7. */
13355FNIEMOP_DEF_2(iemOpCommonGrp3MulDivEv, uint8_t, bRm, PCIEMOPMULDIVSIZES, pImpl)
13356{
13357 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
13358
13359 if (IEM_IS_MODRM_REG_MODE(bRm))
13360 {
13361 /* register access */
13362 switch (pVCpu->iem.s.enmEffOpSize)
13363 {
13364 case IEMMODE_16BIT:
13365 IEM_MC_BEGIN(4, 1, 0, 0);
13366 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13367 IEM_MC_ARG(uint16_t *, pu16AX, 0);
13368 IEM_MC_ARG(uint16_t *, pu16DX, 1);
13369 IEM_MC_ARG(uint16_t, u16Value, 2);
13370 IEM_MC_ARG(uint32_t *, pEFlags, 3);
13371 IEM_MC_LOCAL(int32_t, rc);
13372
13373 IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_RM(pVCpu, bRm));
13374 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
13375 IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX);
13376 IEM_MC_REF_EFLAGS(pEFlags);
13377 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags);
13378 IEM_MC_IF_LOCAL_IS_Z(rc) {
13379 IEM_MC_ADVANCE_RIP_AND_FINISH();
13380 } IEM_MC_ELSE() {
13381 IEM_MC_RAISE_DIVIDE_ERROR();
13382 } IEM_MC_ENDIF();
13383
13384 IEM_MC_END();
13385 break;
13386
13387 case IEMMODE_32BIT:
13388 IEM_MC_BEGIN(4, 1, IEM_MC_F_MIN_386, 0);
13389 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13390 IEM_MC_ARG(uint32_t *, pu32AX, 0);
13391 IEM_MC_ARG(uint32_t *, pu32DX, 1);
13392 IEM_MC_ARG(uint32_t, u32Value, 2);
13393 IEM_MC_ARG(uint32_t *, pEFlags, 3);
13394 IEM_MC_LOCAL(int32_t, rc);
13395
13396 IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_RM(pVCpu, bRm));
13397 IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX);
13398 IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX);
13399 IEM_MC_REF_EFLAGS(pEFlags);
13400 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags);
13401 IEM_MC_IF_LOCAL_IS_Z(rc) {
13402 IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX);
13403 IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xDX);
13404 IEM_MC_ADVANCE_RIP_AND_FINISH();
13405 } IEM_MC_ELSE() {
13406 IEM_MC_RAISE_DIVIDE_ERROR();
13407 } IEM_MC_ENDIF();
13408
13409 IEM_MC_END();
13410 break;
13411
13412 case IEMMODE_64BIT:
13413 IEM_MC_BEGIN(4, 1, IEM_MC_F_64BIT, 0);
13414 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13415 IEM_MC_ARG(uint64_t *, pu64AX, 0);
13416 IEM_MC_ARG(uint64_t *, pu64DX, 1);
13417 IEM_MC_ARG(uint64_t, u64Value, 2);
13418 IEM_MC_ARG(uint32_t *, pEFlags, 3);
13419 IEM_MC_LOCAL(int32_t, rc);
13420
13421 IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_RM(pVCpu, bRm));
13422 IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX);
13423 IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX);
13424 IEM_MC_REF_EFLAGS(pEFlags);
13425 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags);
13426 IEM_MC_IF_LOCAL_IS_Z(rc) {
13427 IEM_MC_ADVANCE_RIP_AND_FINISH();
13428 } IEM_MC_ELSE() {
13429 IEM_MC_RAISE_DIVIDE_ERROR();
13430 } IEM_MC_ENDIF();
13431
13432 IEM_MC_END();
13433 break;
13434
13435 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13436 }
13437 }
13438 else
13439 {
13440 /* memory access. */
13441 switch (pVCpu->iem.s.enmEffOpSize)
13442 {
13443 case IEMMODE_16BIT:
13444 IEM_MC_BEGIN(4, 2, 0, 0);
13445 IEM_MC_ARG(uint16_t *, pu16AX, 0);
13446 IEM_MC_ARG(uint16_t *, pu16DX, 1);
13447 IEM_MC_ARG(uint16_t, u16Value, 2);
13448 IEM_MC_ARG(uint32_t *, pEFlags, 3);
13449 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13450 IEM_MC_LOCAL(int32_t, rc);
13451
13452 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
13453 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13454 IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13455 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
13456 IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX);
13457 IEM_MC_REF_EFLAGS(pEFlags);
13458 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags);
13459 IEM_MC_IF_LOCAL_IS_Z(rc) {
13460 IEM_MC_ADVANCE_RIP_AND_FINISH();
13461 } IEM_MC_ELSE() {
13462 IEM_MC_RAISE_DIVIDE_ERROR();
13463 } IEM_MC_ENDIF();
13464
13465 IEM_MC_END();
13466 break;
13467
13468 case IEMMODE_32BIT:
13469 IEM_MC_BEGIN(4, 2, IEM_MC_F_MIN_386, 0);
13470 IEM_MC_ARG(uint32_t *, pu32AX, 0);
13471 IEM_MC_ARG(uint32_t *, pu32DX, 1);
13472 IEM_MC_ARG(uint32_t, u32Value, 2);
13473 IEM_MC_ARG(uint32_t *, pEFlags, 3);
13474 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13475 IEM_MC_LOCAL(int32_t, rc);
13476
13477 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
13478 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13479 IEM_MC_FETCH_MEM_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13480 IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX);
13481 IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX);
13482 IEM_MC_REF_EFLAGS(pEFlags);
13483 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags);
13484 IEM_MC_IF_LOCAL_IS_Z(rc) {
13485 IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX);
13486 IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xDX);
13487 IEM_MC_ADVANCE_RIP_AND_FINISH();
13488 } IEM_MC_ELSE() {
13489 IEM_MC_RAISE_DIVIDE_ERROR();
13490 } IEM_MC_ENDIF();
13491
13492 IEM_MC_END();
13493 break;
13494
13495 case IEMMODE_64BIT:
13496 IEM_MC_BEGIN(4, 2, IEM_MC_F_64BIT, 0);
13497 IEM_MC_ARG(uint64_t *, pu64AX, 0);
13498 IEM_MC_ARG(uint64_t *, pu64DX, 1);
13499 IEM_MC_ARG(uint64_t, u64Value, 2);
13500 IEM_MC_ARG(uint32_t *, pEFlags, 3);
13501 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13502 IEM_MC_LOCAL(int32_t, rc);
13503
13504 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
13505 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13506 IEM_MC_FETCH_MEM_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13507 IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX);
13508 IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX);
13509 IEM_MC_REF_EFLAGS(pEFlags);
13510 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags);
13511 IEM_MC_IF_LOCAL_IS_Z(rc) {
13512 IEM_MC_ADVANCE_RIP_AND_FINISH();
13513 } IEM_MC_ELSE() {
13514 IEM_MC_RAISE_DIVIDE_ERROR();
13515 } IEM_MC_ENDIF();
13516
13517 IEM_MC_END();
13518 break;
13519
13520 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13521 }
13522 }
13523}
13524
13525
13526/**
13527 * @opmaps grp3_f6
13528 * @opcode /2
13529 */
13530FNIEMOP_DEF_1(iemOp_grp3_not_Eb, uint8_t, bRm)
13531{
13532 IEMOP_MNEMONIC(not_Eb, "not Eb");
13533 IEMOP_BODY_UNARY_Eb(bRm, iemAImpl_not_u8, iemAImpl_not_u8_locked);
13534}
13535
13536
13537/**
13538 * @opmaps grp3_f6
13539 * @opcode /3
13540 */
13541FNIEMOP_DEF_1(iemOp_grp3_neg_Eb, uint8_t, bRm)
13542{
13543 IEMOP_MNEMONIC(net_Eb, "neg Eb");
13544 IEMOP_BODY_UNARY_Eb(bRm, iemAImpl_neg_u8, iemAImpl_neg_u8_locked);
13545}
13546
13547
13548/**
13549 * @opcode 0xf6
13550 */
13551FNIEMOP_DEF(iemOp_Grp3_Eb)
13552{
13553 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
13554 switch (IEM_GET_MODRM_REG_8(bRm))
13555 {
13556 case 0: return FNIEMOP_CALL_1(iemOp_grp3_test_Eb, bRm);
13557 case 1: return FNIEMOP_CALL_1(iemOp_grp3_test_Eb, bRm);
13558 case 2: return FNIEMOP_CALL_1(iemOp_grp3_not_Eb, bRm);
13559 case 3: return FNIEMOP_CALL_1(iemOp_grp3_neg_Eb, bRm);
13560 case 4:
13561 IEMOP_MNEMONIC(mul_Eb, "mul Eb");
13562 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
13563 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_mul_u8_eflags));
13564 case 5:
13565 IEMOP_MNEMONIC(imul_Eb, "imul Eb");
13566 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
13567 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_u8_eflags));
13568 case 6:
13569 IEMOP_MNEMONIC(div_Eb, "div Eb");
13570 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
13571 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_div_u8_eflags));
13572 case 7:
13573 IEMOP_MNEMONIC(idiv_Eb, "idiv Eb");
13574 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
13575 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_idiv_u8_eflags));
13576 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13577 }
13578}
13579
13580
13581/** Opcode 0xf7 /0. */
13582FNIEMOP_DEF_1(iemOp_grp3_test_Ev, uint8_t, bRm)
13583{
13584 IEMOP_MNEMONIC(test_Ev_Iv, "test Ev,Iv");
13585 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
13586
13587 if (IEM_IS_MODRM_REG_MODE(bRm))
13588 {
13589 /* register access */
13590 switch (pVCpu->iem.s.enmEffOpSize)
13591 {
13592 case IEMMODE_16BIT:
13593 IEM_MC_BEGIN(3, 0, 0, 0);
13594 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
13595 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13596 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
13597 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/u16Imm, 1);
13598 IEM_MC_ARG(uint32_t *, pEFlags, 2);
13599 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
13600 IEM_MC_REF_EFLAGS(pEFlags);
13601 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
13602 IEM_MC_ADVANCE_RIP_AND_FINISH();
13603 IEM_MC_END();
13604 break;
13605
13606 case IEMMODE_32BIT:
13607 IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0);
13608 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
13609 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13610 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
13611 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/u32Imm, 1);
13612 IEM_MC_ARG(uint32_t *, pEFlags, 2);
13613 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
13614 IEM_MC_REF_EFLAGS(pEFlags);
13615 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
13616 /* No clearing the high dword here - test doesn't write back the result. */
13617 IEM_MC_ADVANCE_RIP_AND_FINISH();
13618 IEM_MC_END();
13619 break;
13620
13621 case IEMMODE_64BIT:
13622 IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0);
13623 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
13624 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13625 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
13626 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/u64Imm, 1);
13627 IEM_MC_ARG(uint32_t *, pEFlags, 2);
13628 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
13629 IEM_MC_REF_EFLAGS(pEFlags);
13630 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
13631 IEM_MC_ADVANCE_RIP_AND_FINISH();
13632 IEM_MC_END();
13633 break;
13634
13635 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13636 }
13637 }
13638 else
13639 {
13640 /* memory access. */
13641 switch (pVCpu->iem.s.enmEffOpSize)
13642 {
13643 case IEMMODE_16BIT:
13644 IEM_MC_BEGIN(3, 3, 0, 0);
13645 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13646 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
13647
13648 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
13649 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13650
13651 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
13652 IEM_MC_ARG(uint16_t const *, pu16Dst, 0);
13653 IEM_MC_MEM_MAP_U16_RO(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13654
13655 IEM_MC_ARG_CONST(uint16_t, u16Src, u16Imm, 1);
13656 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
13657 IEM_MC_FETCH_EFLAGS(EFlags);
13658 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
13659
13660 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo);
13661 IEM_MC_COMMIT_EFLAGS(EFlags);
13662 IEM_MC_ADVANCE_RIP_AND_FINISH();
13663 IEM_MC_END();
13664 break;
13665
13666 case IEMMODE_32BIT:
13667 IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0);
13668 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13669 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
13670
13671 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
13672 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13673
13674 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
13675 IEM_MC_ARG(uint32_t const *, pu32Dst, 0);
13676 IEM_MC_MEM_MAP_U32_RO(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13677
13678 IEM_MC_ARG_CONST(uint32_t, u32Src, u32Imm, 1);
13679 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
13680 IEM_MC_FETCH_EFLAGS(EFlags);
13681 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
13682
13683 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo);
13684 IEM_MC_COMMIT_EFLAGS(EFlags);
13685 IEM_MC_ADVANCE_RIP_AND_FINISH();
13686 IEM_MC_END();
13687 break;
13688
13689 case IEMMODE_64BIT:
13690 IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0);
13691 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
13692 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
13693
13694 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
13695 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13696
13697 IEM_MC_ARG(uint64_t const *, pu64Dst, 0);
13698 IEM_MC_LOCAL(uint8_t, bUnmapInfo);
13699 IEM_MC_MEM_MAP_U64_RO(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
13700
13701 IEM_MC_ARG_CONST(uint64_t, u64Src, u64Imm, 1);
13702 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
13703 IEM_MC_FETCH_EFLAGS(EFlags);
13704 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
13705
13706 IEM_MC_MEM_COMMIT_AND_UNMAP_RO(bUnmapInfo);
13707 IEM_MC_COMMIT_EFLAGS(EFlags);
13708 IEM_MC_ADVANCE_RIP_AND_FINISH();
13709 IEM_MC_END();
13710 break;
13711
13712 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13713 }
13714 }
13715}
13716
13717
13718/** Opcode 0xf7 /2. */
13719FNIEMOP_DEF_1(iemOp_grp3_not_Ev, uint8_t, bRm)
13720{
13721 IEMOP_MNEMONIC(not_Ev, "not Ev");
13722 IEMOP_BODY_UNARY_Ev( iemAImpl_not_u16, iemAImpl_not_u32, iemAImpl_not_u64);
13723 IEMOP_BODY_UNARY_Ev_LOCKED(iemAImpl_not_u16_locked, iemAImpl_not_u32_locked, iemAImpl_not_u64_locked);
13724}
13725
13726
13727/** Opcode 0xf7 /3. */
13728FNIEMOP_DEF_1(iemOp_grp3_neg_Ev, uint8_t, bRm)
13729{
13730 IEMOP_MNEMONIC(neg_Ev, "neg Ev");
13731 IEMOP_BODY_UNARY_Ev( iemAImpl_neg_u16, iemAImpl_neg_u32, iemAImpl_neg_u64);
13732 IEMOP_BODY_UNARY_Ev_LOCKED(iemAImpl_neg_u16_locked, iemAImpl_neg_u32_locked, iemAImpl_neg_u64_locked);
13733}
13734
13735
13736/**
13737 * @opcode 0xf7
13738 */
13739FNIEMOP_DEF(iemOp_Grp3_Ev)
13740{
13741 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
13742 switch (IEM_GET_MODRM_REG_8(bRm))
13743 {
13744 case 0: return FNIEMOP_CALL_1(iemOp_grp3_test_Ev, bRm);
13745 case 1: return FNIEMOP_CALL_1(iemOp_grp3_test_Ev, bRm);
13746 case 2: return FNIEMOP_CALL_1(iemOp_grp3_not_Ev, bRm);
13747 case 3: return FNIEMOP_CALL_1(iemOp_grp3_neg_Ev, bRm);
13748 case 4:
13749 IEMOP_MNEMONIC(mul_Ev, "mul Ev");
13750 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
13751 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_mul_eflags));
13752 case 5:
13753 IEMOP_MNEMONIC(imul_Ev, "imul Ev");
13754 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
13755 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_eflags));
13756 case 6:
13757 IEMOP_MNEMONIC(div_Ev, "div Ev");
13758 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
13759 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_div_eflags));
13760 case 7:
13761 IEMOP_MNEMONIC(idiv_Ev, "idiv Ev");
13762 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
13763 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_idiv_eflags));
13764 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13765 }
13766}
13767
13768
13769/**
13770 * @opcode 0xf8
13771 */
13772FNIEMOP_DEF(iemOp_clc)
13773{
13774 IEMOP_MNEMONIC(clc, "clc");
13775 IEM_MC_BEGIN(0, 0, 0, 0);
13776 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13777 IEM_MC_CLEAR_EFL_BIT(X86_EFL_CF);
13778 IEM_MC_ADVANCE_RIP_AND_FINISH();
13779 IEM_MC_END();
13780}
13781
13782
13783/**
13784 * @opcode 0xf9
13785 */
13786FNIEMOP_DEF(iemOp_stc)
13787{
13788 IEMOP_MNEMONIC(stc, "stc");
13789 IEM_MC_BEGIN(0, 0, 0, 0);
13790 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13791 IEM_MC_SET_EFL_BIT(X86_EFL_CF);
13792 IEM_MC_ADVANCE_RIP_AND_FINISH();
13793 IEM_MC_END();
13794}
13795
13796
13797/**
13798 * @opcode 0xfa
13799 */
13800FNIEMOP_DEF(iemOp_cli)
13801{
13802 IEMOP_MNEMONIC(cli, "cli");
13803 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13804 IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_CHECK_IRQ_BEFORE, 0, iemCImpl_cli);
13805}
13806
13807
13808FNIEMOP_DEF(iemOp_sti)
13809{
13810 IEMOP_MNEMONIC(sti, "sti");
13811 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13812 IEM_MC_DEFER_TO_CIMPL_0_RET( IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_CHECK_IRQ_AFTER
13813 | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_INHIBIT_SHADOW, 0, iemCImpl_sti);
13814}
13815
13816
13817/**
13818 * @opcode 0xfc
13819 */
13820FNIEMOP_DEF(iemOp_cld)
13821{
13822 IEMOP_MNEMONIC(cld, "cld");
13823 IEM_MC_BEGIN(0, 0, 0, 0);
13824 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13825 IEM_MC_CLEAR_EFL_BIT(X86_EFL_DF);
13826 IEM_MC_ADVANCE_RIP_AND_FINISH();
13827 IEM_MC_END();
13828}
13829
13830
13831/**
13832 * @opcode 0xfd
13833 */
13834FNIEMOP_DEF(iemOp_std)
13835{
13836 IEMOP_MNEMONIC(std, "std");
13837 IEM_MC_BEGIN(0, 0, 0, 0);
13838 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13839 IEM_MC_SET_EFL_BIT(X86_EFL_DF);
13840 IEM_MC_ADVANCE_RIP_AND_FINISH();
13841 IEM_MC_END();
13842}
13843
13844
13845/**
13846 * @opmaps grp4
13847 * @opcode /0
13848 */
13849FNIEMOP_DEF_1(iemOp_Grp4_inc_Eb, uint8_t, bRm)
13850{
13851 IEMOP_MNEMONIC(inc_Eb, "inc Eb");
13852 IEMOP_BODY_UNARY_Eb(bRm, iemAImpl_inc_u8, iemAImpl_inc_u8_locked);
13853}
13854
13855
13856/**
13857 * @opmaps grp4
13858 * @opcode /1
13859 */
13860FNIEMOP_DEF_1(iemOp_Grp4_dec_Eb, uint8_t, bRm)
13861{
13862 IEMOP_MNEMONIC(dec_Eb, "dec Eb");
13863 IEMOP_BODY_UNARY_Eb(bRm, iemAImpl_dec_u8, iemAImpl_dec_u8_locked);
13864}
13865
13866
13867/**
13868 * @opcode 0xfe
13869 */
13870FNIEMOP_DEF(iemOp_Grp4)
13871{
13872 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
13873 switch (IEM_GET_MODRM_REG_8(bRm))
13874 {
13875 case 0: return FNIEMOP_CALL_1(iemOp_Grp4_inc_Eb, bRm);
13876 case 1: return FNIEMOP_CALL_1(iemOp_Grp4_dec_Eb, bRm);
13877 default:
13878 /** @todo is the eff-addr decoded? */
13879 IEMOP_MNEMONIC(grp4_ud, "grp4-ud");
13880 IEMOP_RAISE_INVALID_OPCODE_RET();
13881 }
13882}
13883
13884/** Opcode 0xff /0. */
13885FNIEMOP_DEF_1(iemOp_Grp5_inc_Ev, uint8_t, bRm)
13886{
13887 IEMOP_MNEMONIC(inc_Ev, "inc Ev");
13888 IEMOP_BODY_UNARY_Ev( iemAImpl_inc_u16, iemAImpl_inc_u32, iemAImpl_inc_u64);
13889 IEMOP_BODY_UNARY_Ev_LOCKED(iemAImpl_inc_u16_locked, iemAImpl_inc_u32_locked, iemAImpl_inc_u64_locked);
13890}
13891
13892
13893/** Opcode 0xff /1. */
13894FNIEMOP_DEF_1(iemOp_Grp5_dec_Ev, uint8_t, bRm)
13895{
13896 IEMOP_MNEMONIC(dec_Ev, "dec Ev");
13897 IEMOP_BODY_UNARY_Ev( iemAImpl_dec_u16, iemAImpl_dec_u32, iemAImpl_dec_u64);
13898 IEMOP_BODY_UNARY_Ev_LOCKED(iemAImpl_dec_u16_locked, iemAImpl_dec_u32_locked, iemAImpl_dec_u64_locked);
13899}
13900
13901
13902/**
13903 * Opcode 0xff /2.
13904 * @param bRm The RM byte.
13905 */
13906FNIEMOP_DEF_1(iemOp_Grp5_calln_Ev, uint8_t, bRm)
13907{
13908 IEMOP_MNEMONIC(calln_Ev, "calln Ev");
13909 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
13910
13911 if (IEM_IS_MODRM_REG_MODE(bRm))
13912 {
13913 /* The new RIP is taken from a register. */
13914 switch (pVCpu->iem.s.enmEffOpSize)
13915 {
13916 case IEMMODE_16BIT:
13917 IEM_MC_BEGIN(1, 0, 0, 0);
13918 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13919 IEM_MC_ARG(uint16_t, u16Target, 0);
13920 IEM_MC_FETCH_GREG_U16(u16Target, IEM_GET_MODRM_RM(pVCpu, bRm));
13921 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_call_16, u16Target);
13922 IEM_MC_END();
13923 break;
13924
13925 case IEMMODE_32BIT:
13926 IEM_MC_BEGIN(1, 0, IEM_MC_F_MIN_386, 0);
13927 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13928 IEM_MC_ARG(uint32_t, u32Target, 0);
13929 IEM_MC_FETCH_GREG_U32(u32Target, IEM_GET_MODRM_RM(pVCpu, bRm));
13930 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_call_32, u32Target);
13931 IEM_MC_END();
13932 break;
13933
13934 case IEMMODE_64BIT:
13935 IEM_MC_BEGIN(1, 0, IEM_MC_F_64BIT, 0);
13936 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13937 IEM_MC_ARG(uint64_t, u64Target, 0);
13938 IEM_MC_FETCH_GREG_U64(u64Target, IEM_GET_MODRM_RM(pVCpu, bRm));
13939 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_call_64, u64Target);
13940 IEM_MC_END();
13941 break;
13942
13943 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13944 }
13945 }
13946 else
13947 {
13948 /* The new RIP is taken from a register. */
13949 switch (pVCpu->iem.s.enmEffOpSize)
13950 {
13951 case IEMMODE_16BIT:
13952 IEM_MC_BEGIN(1, 1, 0, 0);
13953 IEM_MC_ARG(uint16_t, u16Target, 0);
13954 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
13955 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
13956 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13957 IEM_MC_FETCH_MEM_U16(u16Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
13958 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_call_16, u16Target);
13959 IEM_MC_END();
13960 break;
13961
13962 case IEMMODE_32BIT:
13963 IEM_MC_BEGIN(1, 1, IEM_MC_F_MIN_386, 0);
13964 IEM_MC_ARG(uint32_t, u32Target, 0);
13965 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
13966 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
13967 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13968 IEM_MC_FETCH_MEM_U32(u32Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
13969 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_call_32, u32Target);
13970 IEM_MC_END();
13971 break;
13972
13973 case IEMMODE_64BIT:
13974 IEM_MC_BEGIN(1, 1, IEM_MC_F_64BIT, 0);
13975 IEM_MC_ARG(uint64_t, u64Target, 0);
13976 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
13977 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
13978 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
13979 IEM_MC_FETCH_MEM_U64(u64Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
13980 IEM_MC_CALL_CIMPL_1(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_STACK, 0, iemCImpl_call_64, u64Target);
13981 IEM_MC_END();
13982 break;
13983
13984 IEM_NOT_REACHED_DEFAULT_CASE_RET();
13985 }
13986 }
13987}
13988
13989#define IEMOP_BODY_GRP5_FAR_EP(a_bRm, a_fnCImpl, a_fCImplExtra) \
13990 /* Registers? How?? */ \
13991 if (RT_LIKELY(IEM_IS_MODRM_MEM_MODE(a_bRm))) \
13992 { /* likely */ } \
13993 else \
13994 IEMOP_RAISE_INVALID_OPCODE_RET(); /* callf eax is not legal */ \
13995 \
13996 /* 64-bit mode: Default is 32-bit, but only intel respects a REX.W prefix. */ \
13997 /** @todo what does VIA do? */ \
13998 if (!IEM_IS_64BIT_CODE(pVCpu) || pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT || IEM_IS_GUEST_CPU_INTEL(pVCpu)) \
13999 { /* likely */ } \
14000 else \
14001 pVCpu->iem.s.enmEffOpSize = IEMMODE_32BIT; \
14002 \
14003 /* Far pointer loaded from memory. */ \
14004 switch (pVCpu->iem.s.enmEffOpSize) \
14005 { \
14006 case IEMMODE_16BIT: \
14007 IEM_MC_BEGIN(3, 1, 0, 0); \
14008 IEM_MC_ARG(uint16_t, u16Sel, 0); \
14009 IEM_MC_ARG(uint16_t, offSeg, 1); \
14010 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2); \
14011 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
14012 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, a_bRm, 0); \
14013 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
14014 IEM_MC_FETCH_MEM_U16(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
14015 IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 2); \
14016 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | (a_fCImplExtra) \
14017 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, 0, \
14018 a_fnCImpl, u16Sel, offSeg, enmEffOpSize); \
14019 IEM_MC_END(); \
14020 break; \
14021 \
14022 case IEMMODE_32BIT: \
14023 IEM_MC_BEGIN(3, 1, IEM_MC_F_MIN_386, 0); \
14024 IEM_MC_ARG(uint16_t, u16Sel, 0); \
14025 IEM_MC_ARG(uint32_t, offSeg, 1); \
14026 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_32BIT, 2); \
14027 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
14028 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, a_bRm, 0); \
14029 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
14030 IEM_MC_FETCH_MEM_U32(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
14031 IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 4); \
14032 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | (a_fCImplExtra) \
14033 | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, 0, \
14034 a_fnCImpl, u16Sel, offSeg, enmEffOpSize); \
14035 IEM_MC_END(); \
14036 break; \
14037 \
14038 case IEMMODE_64BIT: \
14039 Assert(!IEM_IS_GUEST_CPU_AMD(pVCpu)); \
14040 IEM_MC_BEGIN(3, 1, IEM_MC_F_64BIT, 0); \
14041 IEM_MC_ARG(uint16_t, u16Sel, 0); \
14042 IEM_MC_ARG(uint64_t, offSeg, 1); \
14043 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_64BIT, 2); \
14044 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
14045 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, a_bRm, 0); \
14046 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
14047 IEM_MC_FETCH_MEM_U64(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
14048 IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 8); \
14049 IEM_MC_CALL_CIMPL_3(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR | (a_fCImplExtra) \
14050 | IEM_CIMPL_F_MODE /* no gates */, 0, \
14051 a_fnCImpl, u16Sel, offSeg, enmEffOpSize); \
14052 IEM_MC_END(); \
14053 break; \
14054 \
14055 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
14056 } do {} while (0)
14057
14058
14059/**
14060 * Opcode 0xff /3.
14061 * @param bRm The RM byte.
14062 */
14063FNIEMOP_DEF_1(iemOp_Grp5_callf_Ep, uint8_t, bRm)
14064{
14065 IEMOP_MNEMONIC(callf_Ep, "callf Ep");
14066 IEMOP_BODY_GRP5_FAR_EP(bRm, iemCImpl_callf, IEM_CIMPL_F_BRANCH_STACK);
14067}
14068
14069
14070/**
14071 * Opcode 0xff /4.
14072 * @param bRm The RM byte.
14073 */
14074FNIEMOP_DEF_1(iemOp_Grp5_jmpn_Ev, uint8_t, bRm)
14075{
14076 IEMOP_MNEMONIC(jmpn_Ev, "jmpn Ev");
14077 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
14078
14079 if (IEM_IS_MODRM_REG_MODE(bRm))
14080 {
14081 /* The new RIP is taken from a register. */
14082 switch (pVCpu->iem.s.enmEffOpSize)
14083 {
14084 case IEMMODE_16BIT:
14085 IEM_MC_BEGIN(0, 1, 0, 0);
14086 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14087 IEM_MC_LOCAL(uint16_t, u16Target);
14088 IEM_MC_FETCH_GREG_U16(u16Target, IEM_GET_MODRM_RM(pVCpu, bRm));
14089 IEM_MC_SET_RIP_U16_AND_FINISH(u16Target);
14090 IEM_MC_END();
14091 break;
14092
14093 case IEMMODE_32BIT:
14094 IEM_MC_BEGIN(0, 1, IEM_MC_F_MIN_386, 0);
14095 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14096 IEM_MC_LOCAL(uint32_t, u32Target);
14097 IEM_MC_FETCH_GREG_U32(u32Target, IEM_GET_MODRM_RM(pVCpu, bRm));
14098 IEM_MC_SET_RIP_U32_AND_FINISH(u32Target);
14099 IEM_MC_END();
14100 break;
14101
14102 case IEMMODE_64BIT:
14103 IEM_MC_BEGIN(0, 1, IEM_MC_F_64BIT, 0);
14104 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14105 IEM_MC_LOCAL(uint64_t, u64Target);
14106 IEM_MC_FETCH_GREG_U64(u64Target, IEM_GET_MODRM_RM(pVCpu, bRm));
14107 IEM_MC_SET_RIP_U64_AND_FINISH(u64Target);
14108 IEM_MC_END();
14109 break;
14110
14111 IEM_NOT_REACHED_DEFAULT_CASE_RET();
14112 }
14113 }
14114 else
14115 {
14116 /* The new RIP is taken from a memory location. */
14117 switch (pVCpu->iem.s.enmEffOpSize)
14118 {
14119 case IEMMODE_16BIT:
14120 IEM_MC_BEGIN(0, 2, 0, 0);
14121 IEM_MC_LOCAL(uint16_t, u16Target);
14122 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
14123 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
14124 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14125 IEM_MC_FETCH_MEM_U16(u16Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
14126 IEM_MC_SET_RIP_U16_AND_FINISH(u16Target);
14127 IEM_MC_END();
14128 break;
14129
14130 case IEMMODE_32BIT:
14131 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386, 0);
14132 IEM_MC_LOCAL(uint32_t, u32Target);
14133 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
14134 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
14135 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14136 IEM_MC_FETCH_MEM_U32(u32Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
14137 IEM_MC_SET_RIP_U32_AND_FINISH(u32Target);
14138 IEM_MC_END();
14139 break;
14140
14141 case IEMMODE_64BIT:
14142 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
14143 IEM_MC_LOCAL(uint64_t, u64Target);
14144 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
14145 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
14146 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14147 IEM_MC_FETCH_MEM_U64(u64Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
14148 IEM_MC_SET_RIP_U64_AND_FINISH(u64Target);
14149 IEM_MC_END();
14150 break;
14151
14152 IEM_NOT_REACHED_DEFAULT_CASE_RET();
14153 }
14154 }
14155}
14156
14157
14158/**
14159 * Opcode 0xff /5.
14160 * @param bRm The RM byte.
14161 */
14162FNIEMOP_DEF_1(iemOp_Grp5_jmpf_Ep, uint8_t, bRm)
14163{
14164 IEMOP_MNEMONIC(jmpf_Ep, "jmpf Ep");
14165 IEMOP_BODY_GRP5_FAR_EP(bRm, iemCImpl_FarJmp, 0);
14166}
14167
14168
14169/**
14170 * Opcode 0xff /6.
14171 * @param bRm The RM byte.
14172 */
14173FNIEMOP_DEF_1(iemOp_Grp5_push_Ev, uint8_t, bRm)
14174{
14175 IEMOP_MNEMONIC(push_Ev, "push Ev");
14176
14177 /* Registers are handled by a common worker. */
14178 if (IEM_IS_MODRM_REG_MODE(bRm))
14179 return FNIEMOP_CALL_1(iemOpCommonPushGReg, IEM_GET_MODRM_RM(pVCpu, bRm));
14180
14181 /* Memory we do here. */
14182 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
14183 switch (pVCpu->iem.s.enmEffOpSize)
14184 {
14185 case IEMMODE_16BIT:
14186 IEM_MC_BEGIN(0, 2, 0, 0);
14187 IEM_MC_LOCAL(uint16_t, u16Src);
14188 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
14189 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
14190 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14191 IEM_MC_FETCH_MEM_U16(u16Src, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
14192 IEM_MC_PUSH_U16(u16Src);
14193 IEM_MC_ADVANCE_RIP_AND_FINISH();
14194 IEM_MC_END();
14195 break;
14196
14197 case IEMMODE_32BIT:
14198 IEM_MC_BEGIN(0, 2, IEM_MC_F_MIN_386 | IEM_MC_F_NOT_64BIT, 0);
14199 IEM_MC_LOCAL(uint32_t, u32Src);
14200 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
14201 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
14202 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14203 IEM_MC_FETCH_MEM_U32(u32Src, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
14204 IEM_MC_PUSH_U32(u32Src);
14205 IEM_MC_ADVANCE_RIP_AND_FINISH();
14206 IEM_MC_END();
14207 break;
14208
14209 case IEMMODE_64BIT:
14210 IEM_MC_BEGIN(0, 2, IEM_MC_F_64BIT, 0);
14211 IEM_MC_LOCAL(uint64_t, u64Src);
14212 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
14213 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
14214 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
14215 IEM_MC_FETCH_MEM_U64(u64Src, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
14216 IEM_MC_PUSH_U64(u64Src);
14217 IEM_MC_ADVANCE_RIP_AND_FINISH();
14218 IEM_MC_END();
14219 break;
14220
14221 IEM_NOT_REACHED_DEFAULT_CASE_RET();
14222 }
14223}
14224
14225
14226/**
14227 * @opcode 0xff
14228 */
14229FNIEMOP_DEF(iemOp_Grp5)
14230{
14231 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
14232 switch (IEM_GET_MODRM_REG_8(bRm))
14233 {
14234 case 0:
14235 return FNIEMOP_CALL_1(iemOp_Grp5_inc_Ev, bRm);
14236 case 1:
14237 return FNIEMOP_CALL_1(iemOp_Grp5_dec_Ev, bRm);
14238 case 2:
14239 return FNIEMOP_CALL_1(iemOp_Grp5_calln_Ev, bRm);
14240 case 3:
14241 return FNIEMOP_CALL_1(iemOp_Grp5_callf_Ep, bRm);
14242 case 4:
14243 return FNIEMOP_CALL_1(iemOp_Grp5_jmpn_Ev, bRm);
14244 case 5:
14245 return FNIEMOP_CALL_1(iemOp_Grp5_jmpf_Ep, bRm);
14246 case 6:
14247 return FNIEMOP_CALL_1(iemOp_Grp5_push_Ev, bRm);
14248 case 7:
14249 IEMOP_MNEMONIC(grp5_ud, "grp5-ud");
14250 IEMOP_RAISE_INVALID_OPCODE_RET();
14251 }
14252 AssertFailedReturn(VERR_IEM_IPE_3);
14253}
14254
14255
14256
14257const PFNIEMOP g_apfnOneByteMap[256] =
14258{
14259 /* 0x00 */ iemOp_add_Eb_Gb, iemOp_add_Ev_Gv, iemOp_add_Gb_Eb, iemOp_add_Gv_Ev,
14260 /* 0x04 */ iemOp_add_Al_Ib, iemOp_add_eAX_Iz, iemOp_push_ES, iemOp_pop_ES,
14261 /* 0x08 */ iemOp_or_Eb_Gb, iemOp_or_Ev_Gv, iemOp_or_Gb_Eb, iemOp_or_Gv_Ev,
14262 /* 0x0c */ iemOp_or_Al_Ib, iemOp_or_eAX_Iz, iemOp_push_CS, iemOp_2byteEscape,
14263 /* 0x10 */ iemOp_adc_Eb_Gb, iemOp_adc_Ev_Gv, iemOp_adc_Gb_Eb, iemOp_adc_Gv_Ev,
14264 /* 0x14 */ iemOp_adc_Al_Ib, iemOp_adc_eAX_Iz, iemOp_push_SS, iemOp_pop_SS,
14265 /* 0x18 */ iemOp_sbb_Eb_Gb, iemOp_sbb_Ev_Gv, iemOp_sbb_Gb_Eb, iemOp_sbb_Gv_Ev,
14266 /* 0x1c */ iemOp_sbb_Al_Ib, iemOp_sbb_eAX_Iz, iemOp_push_DS, iemOp_pop_DS,
14267 /* 0x20 */ iemOp_and_Eb_Gb, iemOp_and_Ev_Gv, iemOp_and_Gb_Eb, iemOp_and_Gv_Ev,
14268 /* 0x24 */ iemOp_and_Al_Ib, iemOp_and_eAX_Iz, iemOp_seg_ES, iemOp_daa,
14269 /* 0x28 */ iemOp_sub_Eb_Gb, iemOp_sub_Ev_Gv, iemOp_sub_Gb_Eb, iemOp_sub_Gv_Ev,
14270 /* 0x2c */ iemOp_sub_Al_Ib, iemOp_sub_eAX_Iz, iemOp_seg_CS, iemOp_das,
14271 /* 0x30 */ iemOp_xor_Eb_Gb, iemOp_xor_Ev_Gv, iemOp_xor_Gb_Eb, iemOp_xor_Gv_Ev,
14272 /* 0x34 */ iemOp_xor_Al_Ib, iemOp_xor_eAX_Iz, iemOp_seg_SS, iemOp_aaa,
14273 /* 0x38 */ iemOp_cmp_Eb_Gb, iemOp_cmp_Ev_Gv, iemOp_cmp_Gb_Eb, iemOp_cmp_Gv_Ev,
14274 /* 0x3c */ iemOp_cmp_Al_Ib, iemOp_cmp_eAX_Iz, iemOp_seg_DS, iemOp_aas,
14275 /* 0x40 */ iemOp_inc_eAX, iemOp_inc_eCX, iemOp_inc_eDX, iemOp_inc_eBX,
14276 /* 0x44 */ iemOp_inc_eSP, iemOp_inc_eBP, iemOp_inc_eSI, iemOp_inc_eDI,
14277 /* 0x48 */ iemOp_dec_eAX, iemOp_dec_eCX, iemOp_dec_eDX, iemOp_dec_eBX,
14278 /* 0x4c */ iemOp_dec_eSP, iemOp_dec_eBP, iemOp_dec_eSI, iemOp_dec_eDI,
14279 /* 0x50 */ iemOp_push_eAX, iemOp_push_eCX, iemOp_push_eDX, iemOp_push_eBX,
14280 /* 0x54 */ iemOp_push_eSP, iemOp_push_eBP, iemOp_push_eSI, iemOp_push_eDI,
14281 /* 0x58 */ iemOp_pop_eAX, iemOp_pop_eCX, iemOp_pop_eDX, iemOp_pop_eBX,
14282 /* 0x5c */ iemOp_pop_eSP, iemOp_pop_eBP, iemOp_pop_eSI, iemOp_pop_eDI,
14283 /* 0x60 */ iemOp_pusha, iemOp_popa__mvex, iemOp_bound_Gv_Ma__evex, iemOp_arpl_Ew_Gw_movsx_Gv_Ev,
14284 /* 0x64 */ iemOp_seg_FS, iemOp_seg_GS, iemOp_op_size, iemOp_addr_size,
14285 /* 0x68 */ iemOp_push_Iz, iemOp_imul_Gv_Ev_Iz, iemOp_push_Ib, iemOp_imul_Gv_Ev_Ib,
14286 /* 0x6c */ iemOp_insb_Yb_DX, iemOp_inswd_Yv_DX, iemOp_outsb_Yb_DX, iemOp_outswd_Yv_DX,
14287 /* 0x70 */ iemOp_jo_Jb, iemOp_jno_Jb, iemOp_jc_Jb, iemOp_jnc_Jb,
14288 /* 0x74 */ iemOp_je_Jb, iemOp_jne_Jb, iemOp_jbe_Jb, iemOp_jnbe_Jb,
14289 /* 0x78 */ iemOp_js_Jb, iemOp_jns_Jb, iemOp_jp_Jb, iemOp_jnp_Jb,
14290 /* 0x7c */ iemOp_jl_Jb, iemOp_jnl_Jb, iemOp_jle_Jb, iemOp_jnle_Jb,
14291 /* 0x80 */ iemOp_Grp1_Eb_Ib_80, iemOp_Grp1_Ev_Iz, iemOp_Grp1_Eb_Ib_82, iemOp_Grp1_Ev_Ib,
14292 /* 0x84 */ iemOp_test_Eb_Gb, iemOp_test_Ev_Gv, iemOp_xchg_Eb_Gb, iemOp_xchg_Ev_Gv,
14293 /* 0x88 */ iemOp_mov_Eb_Gb, iemOp_mov_Ev_Gv, iemOp_mov_Gb_Eb, iemOp_mov_Gv_Ev,
14294 /* 0x8c */ iemOp_mov_Ev_Sw, iemOp_lea_Gv_M, iemOp_mov_Sw_Ev, iemOp_Grp1A__xop,
14295 /* 0x90 */ iemOp_nop, iemOp_xchg_eCX_eAX, iemOp_xchg_eDX_eAX, iemOp_xchg_eBX_eAX,
14296 /* 0x94 */ iemOp_xchg_eSP_eAX, iemOp_xchg_eBP_eAX, iemOp_xchg_eSI_eAX, iemOp_xchg_eDI_eAX,
14297 /* 0x98 */ iemOp_cbw, iemOp_cwd, iemOp_call_Ap, iemOp_wait,
14298 /* 0x9c */ iemOp_pushf_Fv, iemOp_popf_Fv, iemOp_sahf, iemOp_lahf,
14299 /* 0xa0 */ iemOp_mov_AL_Ob, iemOp_mov_rAX_Ov, iemOp_mov_Ob_AL, iemOp_mov_Ov_rAX,
14300 /* 0xa4 */ iemOp_movsb_Xb_Yb, iemOp_movswd_Xv_Yv, iemOp_cmpsb_Xb_Yb, iemOp_cmpswd_Xv_Yv,
14301 /* 0xa8 */ iemOp_test_AL_Ib, iemOp_test_eAX_Iz, iemOp_stosb_Yb_AL, iemOp_stoswd_Yv_eAX,
14302 /* 0xac */ iemOp_lodsb_AL_Xb, iemOp_lodswd_eAX_Xv, iemOp_scasb_AL_Xb, iemOp_scaswd_eAX_Xv,
14303 /* 0xb0 */ iemOp_mov_AL_Ib, iemOp_CL_Ib, iemOp_DL_Ib, iemOp_BL_Ib,
14304 /* 0xb4 */ iemOp_mov_AH_Ib, iemOp_CH_Ib, iemOp_DH_Ib, iemOp_BH_Ib,
14305 /* 0xb8 */ iemOp_eAX_Iv, iemOp_eCX_Iv, iemOp_eDX_Iv, iemOp_eBX_Iv,
14306 /* 0xbc */ iemOp_eSP_Iv, iemOp_eBP_Iv, iemOp_eSI_Iv, iemOp_eDI_Iv,
14307 /* 0xc0 */ iemOp_Grp2_Eb_Ib, iemOp_Grp2_Ev_Ib, iemOp_retn_Iw, iemOp_retn,
14308 /* 0xc4 */ iemOp_les_Gv_Mp__vex3, iemOp_lds_Gv_Mp__vex2, iemOp_Grp11_Eb_Ib, iemOp_Grp11_Ev_Iz,
14309 /* 0xc8 */ iemOp_enter_Iw_Ib, iemOp_leave, iemOp_retf_Iw, iemOp_retf,
14310 /* 0xcc */ iemOp_int3, iemOp_int_Ib, iemOp_into, iemOp_iret,
14311 /* 0xd0 */ iemOp_Grp2_Eb_1, iemOp_Grp2_Ev_1, iemOp_Grp2_Eb_CL, iemOp_Grp2_Ev_CL,
14312 /* 0xd4 */ iemOp_aam_Ib, iemOp_aad_Ib, iemOp_salc, iemOp_xlat,
14313 /* 0xd8 */ iemOp_EscF0, iemOp_EscF1, iemOp_EscF2, iemOp_EscF3,
14314 /* 0xdc */ iemOp_EscF4, iemOp_EscF5, iemOp_EscF6, iemOp_EscF7,
14315 /* 0xe0 */ iemOp_loopne_Jb, iemOp_loope_Jb, iemOp_loop_Jb, iemOp_jecxz_Jb,
14316 /* 0xe4 */ iemOp_in_AL_Ib, iemOp_in_eAX_Ib, iemOp_out_Ib_AL, iemOp_out_Ib_eAX,
14317 /* 0xe8 */ iemOp_call_Jv, iemOp_jmp_Jv, iemOp_jmp_Ap, iemOp_jmp_Jb,
14318 /* 0xec */ iemOp_in_AL_DX, iemOp_in_eAX_DX, iemOp_out_DX_AL, iemOp_out_DX_eAX,
14319 /* 0xf0 */ iemOp_lock, iemOp_int1, iemOp_repne, iemOp_repe,
14320 /* 0xf4 */ iemOp_hlt, iemOp_cmc, iemOp_Grp3_Eb, iemOp_Grp3_Ev,
14321 /* 0xf8 */ iemOp_clc, iemOp_stc, iemOp_cli, iemOp_sti,
14322 /* 0xfc */ iemOp_cld, iemOp_std, iemOp_Grp4, iemOp_Grp5,
14323};
14324
14325
14326/** @} */
14327
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