VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h@ 90803

Last change on this file since 90803 was 86183, checked in by vboxsync, 4 years ago

VMM: Implemented sysenter and sysexit in IEM (limited testing). Added an longmode emulation of sysenter/sysexit to SVM.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 343.3 KB
Line 
1/* $Id: IEMAllInstructionsTwoByte0f.cpp.h 86183 2020-09-20 11:58:23Z vboxsync $ */
2/** @file
3 * IEM - Instruction Decoding and Emulation.
4 *
5 * @remarks IEMAllInstructionsVexMap1.cpp.h is a VEX mirror of this file.
6 * Any update here is likely needed in that file too.
7 */
8
9/*
10 * Copyright (C) 2011-2020 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21
22/** @name Two byte opcodes (first byte 0x0f).
23 *
24 * @{
25 */
26
27/** Opcode 0x0f 0x00 /0. */
28FNIEMOPRM_DEF(iemOp_Grp6_sldt)
29{
30 IEMOP_MNEMONIC(sldt, "sldt Rv/Mw");
31 IEMOP_HLP_MIN_286();
32 IEMOP_HLP_NO_REAL_OR_V86_MODE();
33
34 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
35 {
36 IEMOP_HLP_DECODED_NL_1(OP_SLDT, IEMOPFORM_M_REG, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
37 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_sldt_reg, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, pVCpu->iem.s.enmEffOpSize);
38 }
39
40 /* Ignore operand size here, memory refs are always 16-bit. */
41 IEM_MC_BEGIN(2, 0);
42 IEM_MC_ARG(uint16_t, iEffSeg, 0);
43 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
44 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
45 IEMOP_HLP_DECODED_NL_1(OP_SLDT, IEMOPFORM_M_MEM, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
46 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
47 IEM_MC_CALL_CIMPL_2(iemCImpl_sldt_mem, iEffSeg, GCPtrEffDst);
48 IEM_MC_END();
49 return VINF_SUCCESS;
50}
51
52
53/** Opcode 0x0f 0x00 /1. */
54FNIEMOPRM_DEF(iemOp_Grp6_str)
55{
56 IEMOP_MNEMONIC(str, "str Rv/Mw");
57 IEMOP_HLP_MIN_286();
58 IEMOP_HLP_NO_REAL_OR_V86_MODE();
59
60
61 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
62 {
63 IEMOP_HLP_DECODED_NL_1(OP_STR, IEMOPFORM_M_REG, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
64 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_str_reg, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, pVCpu->iem.s.enmEffOpSize);
65 }
66
67 /* Ignore operand size here, memory refs are always 16-bit. */
68 IEM_MC_BEGIN(2, 0);
69 IEM_MC_ARG(uint16_t, iEffSeg, 0);
70 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
71 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
72 IEMOP_HLP_DECODED_NL_1(OP_STR, IEMOPFORM_M_MEM, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
73 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
74 IEM_MC_CALL_CIMPL_2(iemCImpl_str_mem, iEffSeg, GCPtrEffDst);
75 IEM_MC_END();
76 return VINF_SUCCESS;
77}
78
79
80/** Opcode 0x0f 0x00 /2. */
81FNIEMOPRM_DEF(iemOp_Grp6_lldt)
82{
83 IEMOP_MNEMONIC(lldt, "lldt Ew");
84 IEMOP_HLP_MIN_286();
85 IEMOP_HLP_NO_REAL_OR_V86_MODE();
86
87 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
88 {
89 IEMOP_HLP_DECODED_NL_1(OP_LLDT, IEMOPFORM_M_REG, OP_PARM_Ew, DISOPTYPE_DANGEROUS);
90 IEM_MC_BEGIN(1, 0);
91 IEM_MC_ARG(uint16_t, u16Sel, 0);
92 IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
93 IEM_MC_CALL_CIMPL_1(iemCImpl_lldt, u16Sel);
94 IEM_MC_END();
95 }
96 else
97 {
98 IEM_MC_BEGIN(1, 1);
99 IEM_MC_ARG(uint16_t, u16Sel, 0);
100 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
101 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
102 IEMOP_HLP_DECODED_NL_1(OP_LLDT, IEMOPFORM_M_MEM, OP_PARM_Ew, DISOPTYPE_DANGEROUS);
103 IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO(); /** @todo test order */
104 IEM_MC_FETCH_MEM_U16(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
105 IEM_MC_CALL_CIMPL_1(iemCImpl_lldt, u16Sel);
106 IEM_MC_END();
107 }
108 return VINF_SUCCESS;
109}
110
111
112/** Opcode 0x0f 0x00 /3. */
113FNIEMOPRM_DEF(iemOp_Grp6_ltr)
114{
115 IEMOP_MNEMONIC(ltr, "ltr Ew");
116 IEMOP_HLP_MIN_286();
117 IEMOP_HLP_NO_REAL_OR_V86_MODE();
118
119 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
120 {
121 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
122 IEM_MC_BEGIN(1, 0);
123 IEM_MC_ARG(uint16_t, u16Sel, 0);
124 IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
125 IEM_MC_CALL_CIMPL_1(iemCImpl_ltr, u16Sel);
126 IEM_MC_END();
127 }
128 else
129 {
130 IEM_MC_BEGIN(1, 1);
131 IEM_MC_ARG(uint16_t, u16Sel, 0);
132 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
133 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
134 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
135 IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO(); /** @todo test order */
136 IEM_MC_FETCH_MEM_U16(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
137 IEM_MC_CALL_CIMPL_1(iemCImpl_ltr, u16Sel);
138 IEM_MC_END();
139 }
140 return VINF_SUCCESS;
141}
142
143
144/** Opcode 0x0f 0x00 /3. */
145FNIEMOP_DEF_2(iemOpCommonGrp6VerX, uint8_t, bRm, bool, fWrite)
146{
147 IEMOP_HLP_MIN_286();
148 IEMOP_HLP_NO_REAL_OR_V86_MODE();
149
150 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
151 {
152 IEMOP_HLP_DECODED_NL_1(fWrite ? OP_VERW : OP_VERR, IEMOPFORM_M_MEM, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
153 IEM_MC_BEGIN(2, 0);
154 IEM_MC_ARG(uint16_t, u16Sel, 0);
155 IEM_MC_ARG_CONST(bool, fWriteArg, fWrite, 1);
156 IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
157 IEM_MC_CALL_CIMPL_2(iemCImpl_VerX, u16Sel, fWriteArg);
158 IEM_MC_END();
159 }
160 else
161 {
162 IEM_MC_BEGIN(2, 1);
163 IEM_MC_ARG(uint16_t, u16Sel, 0);
164 IEM_MC_ARG_CONST(bool, fWriteArg, fWrite, 1);
165 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
166 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
167 IEMOP_HLP_DECODED_NL_1(fWrite ? OP_VERW : OP_VERR, IEMOPFORM_M_MEM, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
168 IEM_MC_FETCH_MEM_U16(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
169 IEM_MC_CALL_CIMPL_2(iemCImpl_VerX, u16Sel, fWriteArg);
170 IEM_MC_END();
171 }
172 return VINF_SUCCESS;
173}
174
175
176/** Opcode 0x0f 0x00 /4. */
177FNIEMOPRM_DEF(iemOp_Grp6_verr)
178{
179 IEMOP_MNEMONIC(verr, "verr Ew");
180 IEMOP_HLP_MIN_286();
181 return FNIEMOP_CALL_2(iemOpCommonGrp6VerX, bRm, false);
182}
183
184
185/** Opcode 0x0f 0x00 /5. */
186FNIEMOPRM_DEF(iemOp_Grp6_verw)
187{
188 IEMOP_MNEMONIC(verw, "verw Ew");
189 IEMOP_HLP_MIN_286();
190 return FNIEMOP_CALL_2(iemOpCommonGrp6VerX, bRm, true);
191}
192
193
194/**
195 * Group 6 jump table.
196 */
197IEM_STATIC const PFNIEMOPRM g_apfnGroup6[8] =
198{
199 iemOp_Grp6_sldt,
200 iemOp_Grp6_str,
201 iemOp_Grp6_lldt,
202 iemOp_Grp6_ltr,
203 iemOp_Grp6_verr,
204 iemOp_Grp6_verw,
205 iemOp_InvalidWithRM,
206 iemOp_InvalidWithRM
207};
208
209/** Opcode 0x0f 0x00. */
210FNIEMOP_DEF(iemOp_Grp6)
211{
212 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
213 return FNIEMOP_CALL_1(g_apfnGroup6[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK], bRm);
214}
215
216
217/** Opcode 0x0f 0x01 /0. */
218FNIEMOP_DEF_1(iemOp_Grp7_sgdt, uint8_t, bRm)
219{
220 IEMOP_MNEMONIC(sgdt, "sgdt Ms");
221 IEMOP_HLP_MIN_286();
222 IEMOP_HLP_64BIT_OP_SIZE();
223 IEM_MC_BEGIN(2, 1);
224 IEM_MC_ARG(uint8_t, iEffSeg, 0);
225 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
226 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
227 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
228 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
229 IEM_MC_CALL_CIMPL_2(iemCImpl_sgdt, iEffSeg, GCPtrEffSrc);
230 IEM_MC_END();
231 return VINF_SUCCESS;
232}
233
234
235/** Opcode 0x0f 0x01 /0. */
236FNIEMOP_DEF(iemOp_Grp7_vmcall)
237{
238 IEMOP_MNEMONIC(vmcall, "vmcall");
239 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the VMX instructions. ASSUMING no lock for now. */
240
241 /* Note! We do not check any CPUMFEATURES::fSvm here as we (GIM) generally
242 want all hypercalls regardless of instruction used, and if a
243 hypercall isn't handled by GIM or HMSvm will raise an #UD.
244 (NEM/win makes ASSUMPTIONS about this behavior.) */
245 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmcall);
246}
247
248
249/** Opcode 0x0f 0x01 /0. */
250#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
251FNIEMOP_DEF(iemOp_Grp7_vmlaunch)
252{
253 IEMOP_MNEMONIC(vmlaunch, "vmlaunch");
254 IEMOP_HLP_IN_VMX_OPERATION("vmlaunch", kVmxVDiag_Vmentry);
255 IEMOP_HLP_VMX_INSTR("vmlaunch", kVmxVDiag_Vmentry);
256 IEMOP_HLP_DONE_DECODING();
257 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmlaunch);
258}
259#else
260FNIEMOP_DEF(iemOp_Grp7_vmlaunch)
261{
262 IEMOP_BITCH_ABOUT_STUB();
263 return IEMOP_RAISE_INVALID_OPCODE();
264}
265#endif
266
267
268/** Opcode 0x0f 0x01 /0. */
269#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
270FNIEMOP_DEF(iemOp_Grp7_vmresume)
271{
272 IEMOP_MNEMONIC(vmresume, "vmresume");
273 IEMOP_HLP_IN_VMX_OPERATION("vmresume", kVmxVDiag_Vmentry);
274 IEMOP_HLP_VMX_INSTR("vmresume", kVmxVDiag_Vmentry);
275 IEMOP_HLP_DONE_DECODING();
276 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmresume);
277}
278#else
279FNIEMOP_DEF(iemOp_Grp7_vmresume)
280{
281 IEMOP_BITCH_ABOUT_STUB();
282 return IEMOP_RAISE_INVALID_OPCODE();
283}
284#endif
285
286
287/** Opcode 0x0f 0x01 /0. */
288#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
289FNIEMOP_DEF(iemOp_Grp7_vmxoff)
290{
291 IEMOP_MNEMONIC(vmxoff, "vmxoff");
292 IEMOP_HLP_IN_VMX_OPERATION("vmxoff", kVmxVDiag_Vmxoff);
293 IEMOP_HLP_VMX_INSTR("vmxoff", kVmxVDiag_Vmxoff);
294 IEMOP_HLP_DONE_DECODING();
295 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmxoff);
296}
297#else
298FNIEMOP_DEF(iemOp_Grp7_vmxoff)
299{
300 IEMOP_BITCH_ABOUT_STUB();
301 return IEMOP_RAISE_INVALID_OPCODE();
302}
303#endif
304
305
306/** Opcode 0x0f 0x01 /1. */
307FNIEMOP_DEF_1(iemOp_Grp7_sidt, uint8_t, bRm)
308{
309 IEMOP_MNEMONIC(sidt, "sidt Ms");
310 IEMOP_HLP_MIN_286();
311 IEMOP_HLP_64BIT_OP_SIZE();
312 IEM_MC_BEGIN(2, 1);
313 IEM_MC_ARG(uint8_t, iEffSeg, 0);
314 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
315 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
316 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
317 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
318 IEM_MC_CALL_CIMPL_2(iemCImpl_sidt, iEffSeg, GCPtrEffSrc);
319 IEM_MC_END();
320 return VINF_SUCCESS;
321}
322
323
324/** Opcode 0x0f 0x01 /1. */
325FNIEMOP_DEF(iemOp_Grp7_monitor)
326{
327 IEMOP_MNEMONIC(monitor, "monitor");
328 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo Verify that monitor is allergic to lock prefixes. */
329 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_monitor, pVCpu->iem.s.iEffSeg);
330}
331
332
333/** Opcode 0x0f 0x01 /1. */
334FNIEMOP_DEF(iemOp_Grp7_mwait)
335{
336 IEMOP_MNEMONIC(mwait, "mwait"); /** @todo Verify that mwait is allergic to lock prefixes. */
337 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
338 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_mwait);
339}
340
341
342/** Opcode 0x0f 0x01 /2. */
343FNIEMOP_DEF_1(iemOp_Grp7_lgdt, uint8_t, bRm)
344{
345 IEMOP_MNEMONIC(lgdt, "lgdt");
346 IEMOP_HLP_64BIT_OP_SIZE();
347 IEM_MC_BEGIN(3, 1);
348 IEM_MC_ARG(uint8_t, iEffSeg, 0);
349 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
350 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSizeArg,/*=*/pVCpu->iem.s.enmEffOpSize, 2);
351 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
352 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
353 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
354 IEM_MC_CALL_CIMPL_3(iemCImpl_lgdt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
355 IEM_MC_END();
356 return VINF_SUCCESS;
357}
358
359
360/** Opcode 0x0f 0x01 0xd0. */
361FNIEMOP_DEF(iemOp_Grp7_xgetbv)
362{
363 IEMOP_MNEMONIC(xgetbv, "xgetbv");
364 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fXSaveRstor)
365 {
366 /** @todo r=ramshankar: We should use
367 * IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX and
368 * IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES here. */
369 IEMOP_HLP_DONE_DECODING_NO_LOCK_REPZ_OR_REPNZ_PREFIXES();
370 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_xgetbv);
371 }
372 return IEMOP_RAISE_INVALID_OPCODE();
373}
374
375
376/** Opcode 0x0f 0x01 0xd1. */
377FNIEMOP_DEF(iemOp_Grp7_xsetbv)
378{
379 IEMOP_MNEMONIC(xsetbv, "xsetbv");
380 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fXSaveRstor)
381 {
382 /** @todo r=ramshankar: We should use
383 * IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX and
384 * IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES here. */
385 IEMOP_HLP_DONE_DECODING_NO_LOCK_REPZ_OR_REPNZ_PREFIXES();
386 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_xsetbv);
387 }
388 return IEMOP_RAISE_INVALID_OPCODE();
389}
390
391
392/** Opcode 0x0f 0x01 /3. */
393FNIEMOP_DEF_1(iemOp_Grp7_lidt, uint8_t, bRm)
394{
395 IEMOP_MNEMONIC(lidt, "lidt");
396 IEMMODE enmEffOpSize = pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
397 ? IEMMODE_64BIT
398 : pVCpu->iem.s.enmEffOpSize;
399 IEM_MC_BEGIN(3, 1);
400 IEM_MC_ARG(uint8_t, iEffSeg, 0);
401 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
402 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSizeArg,/*=*/enmEffOpSize, 2);
403 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
404 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
405 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
406 IEM_MC_CALL_CIMPL_3(iemCImpl_lidt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
407 IEM_MC_END();
408 return VINF_SUCCESS;
409}
410
411
412/** Opcode 0x0f 0x01 0xd8. */
413#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
414FNIEMOP_DEF(iemOp_Grp7_Amd_vmrun)
415{
416 IEMOP_MNEMONIC(vmrun, "vmrun");
417 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
418 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmrun);
419}
420#else
421FNIEMOP_UD_STUB(iemOp_Grp7_Amd_vmrun);
422#endif
423
424/** Opcode 0x0f 0x01 0xd9. */
425FNIEMOP_DEF(iemOp_Grp7_Amd_vmmcall)
426{
427 IEMOP_MNEMONIC(vmmcall, "vmmcall");
428 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
429
430 /* Note! We do not check any CPUMFEATURES::fSvm here as we (GIM) generally
431 want all hypercalls regardless of instruction used, and if a
432 hypercall isn't handled by GIM or HMSvm will raise an #UD.
433 (NEM/win makes ASSUMPTIONS about this behavior.) */
434 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmmcall);
435}
436
437/** Opcode 0x0f 0x01 0xda. */
438#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
439FNIEMOP_DEF(iemOp_Grp7_Amd_vmload)
440{
441 IEMOP_MNEMONIC(vmload, "vmload");
442 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
443 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmload);
444}
445#else
446FNIEMOP_UD_STUB(iemOp_Grp7_Amd_vmload);
447#endif
448
449
450/** Opcode 0x0f 0x01 0xdb. */
451#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
452FNIEMOP_DEF(iemOp_Grp7_Amd_vmsave)
453{
454 IEMOP_MNEMONIC(vmsave, "vmsave");
455 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
456 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmsave);
457}
458#else
459FNIEMOP_UD_STUB(iemOp_Grp7_Amd_vmsave);
460#endif
461
462
463/** Opcode 0x0f 0x01 0xdc. */
464#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
465FNIEMOP_DEF(iemOp_Grp7_Amd_stgi)
466{
467 IEMOP_MNEMONIC(stgi, "stgi");
468 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
469 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stgi);
470}
471#else
472FNIEMOP_UD_STUB(iemOp_Grp7_Amd_stgi);
473#endif
474
475
476/** Opcode 0x0f 0x01 0xdd. */
477#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
478FNIEMOP_DEF(iemOp_Grp7_Amd_clgi)
479{
480 IEMOP_MNEMONIC(clgi, "clgi");
481 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
482 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_clgi);
483}
484#else
485FNIEMOP_UD_STUB(iemOp_Grp7_Amd_clgi);
486#endif
487
488
489/** Opcode 0x0f 0x01 0xdf. */
490#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
491FNIEMOP_DEF(iemOp_Grp7_Amd_invlpga)
492{
493 IEMOP_MNEMONIC(invlpga, "invlpga");
494 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
495 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_invlpga);
496}
497#else
498FNIEMOP_UD_STUB(iemOp_Grp7_Amd_invlpga);
499#endif
500
501
502/** Opcode 0x0f 0x01 0xde. */
503#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
504FNIEMOP_DEF(iemOp_Grp7_Amd_skinit)
505{
506 IEMOP_MNEMONIC(skinit, "skinit");
507 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); /** @todo check prefix effect on the SVM instructions. ASSUMING no lock for now. */
508 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_skinit);
509}
510#else
511FNIEMOP_UD_STUB(iemOp_Grp7_Amd_skinit);
512#endif
513
514
515/** Opcode 0x0f 0x01 /4. */
516FNIEMOP_DEF_1(iemOp_Grp7_smsw, uint8_t, bRm)
517{
518 IEMOP_MNEMONIC(smsw, "smsw");
519 IEMOP_HLP_MIN_286();
520 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
521 {
522 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
523 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_smsw_reg, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, pVCpu->iem.s.enmEffOpSize);
524 }
525
526 /* Ignore operand size here, memory refs are always 16-bit. */
527 IEM_MC_BEGIN(2, 0);
528 IEM_MC_ARG(uint16_t, iEffSeg, 0);
529 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
530 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
531 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
532 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
533 IEM_MC_CALL_CIMPL_2(iemCImpl_smsw_mem, iEffSeg, GCPtrEffDst);
534 IEM_MC_END();
535 return VINF_SUCCESS;
536}
537
538
539/** Opcode 0x0f 0x01 /6. */
540FNIEMOP_DEF_1(iemOp_Grp7_lmsw, uint8_t, bRm)
541{
542 /* The operand size is effectively ignored, all is 16-bit and only the
543 lower 3-bits are used. */
544 IEMOP_MNEMONIC(lmsw, "lmsw");
545 IEMOP_HLP_MIN_286();
546 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
547 {
548 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
549 IEM_MC_BEGIN(2, 0);
550 IEM_MC_ARG(uint16_t, u16Tmp, 0);
551 IEM_MC_ARG_CONST(RTGCPTR, GCPtrEffDst, NIL_RTGCPTR, 1);
552 IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
553 IEM_MC_CALL_CIMPL_2(iemCImpl_lmsw, u16Tmp, GCPtrEffDst);
554 IEM_MC_END();
555 }
556 else
557 {
558 IEM_MC_BEGIN(2, 0);
559 IEM_MC_ARG(uint16_t, u16Tmp, 0);
560 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
561 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
562 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
563 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
564 IEM_MC_CALL_CIMPL_2(iemCImpl_lmsw, u16Tmp, GCPtrEffDst);
565 IEM_MC_END();
566 }
567 return VINF_SUCCESS;
568}
569
570
571/** Opcode 0x0f 0x01 /7. */
572FNIEMOP_DEF_1(iemOp_Grp7_invlpg, uint8_t, bRm)
573{
574 IEMOP_MNEMONIC(invlpg, "invlpg");
575 IEMOP_HLP_MIN_486();
576 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
577 IEM_MC_BEGIN(1, 1);
578 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 0);
579 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
580 IEM_MC_CALL_CIMPL_1(iemCImpl_invlpg, GCPtrEffDst);
581 IEM_MC_END();
582 return VINF_SUCCESS;
583}
584
585
586/** Opcode 0x0f 0x01 /7. */
587FNIEMOP_DEF(iemOp_Grp7_swapgs)
588{
589 IEMOP_MNEMONIC(swapgs, "swapgs");
590 IEMOP_HLP_ONLY_64BIT();
591 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
592 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_swapgs);
593}
594
595
596/** Opcode 0x0f 0x01 /7. */
597FNIEMOP_DEF(iemOp_Grp7_rdtscp)
598{
599 IEMOP_MNEMONIC(rdtscp, "rdtscp");
600 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
601 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rdtscp);
602}
603
604
605/**
606 * Group 7 jump table, memory variant.
607 */
608IEM_STATIC const PFNIEMOPRM g_apfnGroup7Mem[8] =
609{
610 iemOp_Grp7_sgdt,
611 iemOp_Grp7_sidt,
612 iemOp_Grp7_lgdt,
613 iemOp_Grp7_lidt,
614 iemOp_Grp7_smsw,
615 iemOp_InvalidWithRM,
616 iemOp_Grp7_lmsw,
617 iemOp_Grp7_invlpg
618};
619
620
621/** Opcode 0x0f 0x01. */
622FNIEMOP_DEF(iemOp_Grp7)
623{
624 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
625 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
626 return FNIEMOP_CALL_1(g_apfnGroup7Mem[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK], bRm);
627
628 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
629 {
630 case 0:
631 switch (bRm & X86_MODRM_RM_MASK)
632 {
633 case 1: return FNIEMOP_CALL(iemOp_Grp7_vmcall);
634 case 2: return FNIEMOP_CALL(iemOp_Grp7_vmlaunch);
635 case 3: return FNIEMOP_CALL(iemOp_Grp7_vmresume);
636 case 4: return FNIEMOP_CALL(iemOp_Grp7_vmxoff);
637 }
638 return IEMOP_RAISE_INVALID_OPCODE();
639
640 case 1:
641 switch (bRm & X86_MODRM_RM_MASK)
642 {
643 case 0: return FNIEMOP_CALL(iemOp_Grp7_monitor);
644 case 1: return FNIEMOP_CALL(iemOp_Grp7_mwait);
645 }
646 return IEMOP_RAISE_INVALID_OPCODE();
647
648 case 2:
649 switch (bRm & X86_MODRM_RM_MASK)
650 {
651 case 0: return FNIEMOP_CALL(iemOp_Grp7_xgetbv);
652 case 1: return FNIEMOP_CALL(iemOp_Grp7_xsetbv);
653 }
654 return IEMOP_RAISE_INVALID_OPCODE();
655
656 case 3:
657 switch (bRm & X86_MODRM_RM_MASK)
658 {
659 case 0: return FNIEMOP_CALL(iemOp_Grp7_Amd_vmrun);
660 case 1: return FNIEMOP_CALL(iemOp_Grp7_Amd_vmmcall);
661 case 2: return FNIEMOP_CALL(iemOp_Grp7_Amd_vmload);
662 case 3: return FNIEMOP_CALL(iemOp_Grp7_Amd_vmsave);
663 case 4: return FNIEMOP_CALL(iemOp_Grp7_Amd_stgi);
664 case 5: return FNIEMOP_CALL(iemOp_Grp7_Amd_clgi);
665 case 6: return FNIEMOP_CALL(iemOp_Grp7_Amd_skinit);
666 case 7: return FNIEMOP_CALL(iemOp_Grp7_Amd_invlpga);
667 IEM_NOT_REACHED_DEFAULT_CASE_RET();
668 }
669
670 case 4:
671 return FNIEMOP_CALL_1(iemOp_Grp7_smsw, bRm);
672
673 case 5:
674 return IEMOP_RAISE_INVALID_OPCODE();
675
676 case 6:
677 return FNIEMOP_CALL_1(iemOp_Grp7_lmsw, bRm);
678
679 case 7:
680 switch (bRm & X86_MODRM_RM_MASK)
681 {
682 case 0: return FNIEMOP_CALL(iemOp_Grp7_swapgs);
683 case 1: return FNIEMOP_CALL(iemOp_Grp7_rdtscp);
684 }
685 return IEMOP_RAISE_INVALID_OPCODE();
686
687 IEM_NOT_REACHED_DEFAULT_CASE_RET();
688 }
689}
690
691/** Opcode 0x0f 0x00 /3. */
692FNIEMOP_DEF_1(iemOpCommonLarLsl_Gv_Ew, bool, fIsLar)
693{
694 IEMOP_HLP_NO_REAL_OR_V86_MODE();
695 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
696
697 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
698 {
699 IEMOP_HLP_DECODED_NL_2(fIsLar ? OP_LAR : OP_LSL, IEMOPFORM_RM_REG, OP_PARM_Gv, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
700 switch (pVCpu->iem.s.enmEffOpSize)
701 {
702 case IEMMODE_16BIT:
703 {
704 IEM_MC_BEGIN(3, 0);
705 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
706 IEM_MC_ARG(uint16_t, u16Sel, 1);
707 IEM_MC_ARG_CONST(bool, fIsLarArg, fIsLar, 2);
708
709 IEM_MC_REF_GREG_U16(pu16Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
710 IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
711 IEM_MC_CALL_CIMPL_3(iemCImpl_LarLsl_u16, pu16Dst, u16Sel, fIsLarArg);
712
713 IEM_MC_END();
714 return VINF_SUCCESS;
715 }
716
717 case IEMMODE_32BIT:
718 case IEMMODE_64BIT:
719 {
720 IEM_MC_BEGIN(3, 0);
721 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
722 IEM_MC_ARG(uint16_t, u16Sel, 1);
723 IEM_MC_ARG_CONST(bool, fIsLarArg, fIsLar, 2);
724
725 IEM_MC_REF_GREG_U64(pu64Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
726 IEM_MC_FETCH_GREG_U16(u16Sel, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
727 IEM_MC_CALL_CIMPL_3(iemCImpl_LarLsl_u64, pu64Dst, u16Sel, fIsLarArg);
728
729 IEM_MC_END();
730 return VINF_SUCCESS;
731 }
732
733 IEM_NOT_REACHED_DEFAULT_CASE_RET();
734 }
735 }
736 else
737 {
738 switch (pVCpu->iem.s.enmEffOpSize)
739 {
740 case IEMMODE_16BIT:
741 {
742 IEM_MC_BEGIN(3, 1);
743 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
744 IEM_MC_ARG(uint16_t, u16Sel, 1);
745 IEM_MC_ARG_CONST(bool, fIsLarArg, fIsLar, 2);
746 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
747
748 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
749 IEMOP_HLP_DECODED_NL_2(fIsLar ? OP_LAR : OP_LSL, IEMOPFORM_RM_MEM, OP_PARM_Gv, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
750
751 IEM_MC_FETCH_MEM_U16(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
752 IEM_MC_REF_GREG_U16(pu16Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
753 IEM_MC_CALL_CIMPL_3(iemCImpl_LarLsl_u16, pu16Dst, u16Sel, fIsLarArg);
754
755 IEM_MC_END();
756 return VINF_SUCCESS;
757 }
758
759 case IEMMODE_32BIT:
760 case IEMMODE_64BIT:
761 {
762 IEM_MC_BEGIN(3, 1);
763 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
764 IEM_MC_ARG(uint16_t, u16Sel, 1);
765 IEM_MC_ARG_CONST(bool, fIsLarArg, fIsLar, 2);
766 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
767
768 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
769 IEMOP_HLP_DECODED_NL_2(fIsLar ? OP_LAR : OP_LSL, IEMOPFORM_RM_MEM, OP_PARM_Gv, OP_PARM_Ew, DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP);
770/** @todo testcase: make sure it's a 16-bit read. */
771
772 IEM_MC_FETCH_MEM_U16(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
773 IEM_MC_REF_GREG_U64(pu64Dst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
774 IEM_MC_CALL_CIMPL_3(iemCImpl_LarLsl_u64, pu64Dst, u16Sel, fIsLarArg);
775
776 IEM_MC_END();
777 return VINF_SUCCESS;
778 }
779
780 IEM_NOT_REACHED_DEFAULT_CASE_RET();
781 }
782 }
783}
784
785
786
787/** Opcode 0x0f 0x02. */
788FNIEMOP_DEF(iemOp_lar_Gv_Ew)
789{
790 IEMOP_MNEMONIC(lar, "lar Gv,Ew");
791 return FNIEMOP_CALL_1(iemOpCommonLarLsl_Gv_Ew, true);
792}
793
794
795/** Opcode 0x0f 0x03. */
796FNIEMOP_DEF(iemOp_lsl_Gv_Ew)
797{
798 IEMOP_MNEMONIC(lsl, "lsl Gv,Ew");
799 return FNIEMOP_CALL_1(iemOpCommonLarLsl_Gv_Ew, false);
800}
801
802
803/** Opcode 0x0f 0x05. */
804FNIEMOP_DEF(iemOp_syscall)
805{
806 IEMOP_MNEMONIC(syscall, "syscall"); /** @todo 286 LOADALL */
807 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
808 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_syscall);
809}
810
811
812/** Opcode 0x0f 0x06. */
813FNIEMOP_DEF(iemOp_clts)
814{
815 IEMOP_MNEMONIC(clts, "clts");
816 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
817 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_clts);
818}
819
820
821/** Opcode 0x0f 0x07. */
822FNIEMOP_DEF(iemOp_sysret)
823{
824 IEMOP_MNEMONIC(sysret, "sysret"); /** @todo 386 LOADALL */
825 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
826 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_sysret);
827}
828
829
830/** Opcode 0x0f 0x08. */
831FNIEMOP_DEF(iemOp_invd)
832{
833 IEMOP_MNEMONIC0(FIXED, INVD, invd, DISOPTYPE_PRIVILEGED, 0);
834 IEMOP_HLP_MIN_486();
835 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
836 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_invd);
837}
838
839
840/** Opcode 0x0f 0x09. */
841FNIEMOP_DEF(iemOp_wbinvd)
842{
843 IEMOP_MNEMONIC0(FIXED, WBINVD, wbinvd, DISOPTYPE_PRIVILEGED, 0);
844 IEMOP_HLP_MIN_486();
845 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
846 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_wbinvd);
847}
848
849
850/** Opcode 0x0f 0x0b. */
851FNIEMOP_DEF(iemOp_ud2)
852{
853 IEMOP_MNEMONIC(ud2, "ud2");
854 return IEMOP_RAISE_INVALID_OPCODE();
855}
856
857/** Opcode 0x0f 0x0d. */
858FNIEMOP_DEF(iemOp_nop_Ev_GrpP)
859{
860 /* AMD prefetch group, Intel implements this as NOP Ev (and so do we). */
861 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->f3DNowPrefetch)
862 {
863 IEMOP_MNEMONIC(GrpPNotSupported, "GrpP");
864 return IEMOP_RAISE_INVALID_OPCODE();
865 }
866
867 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
868 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
869 {
870 IEMOP_MNEMONIC(GrpPInvalid, "GrpP");
871 return IEMOP_RAISE_INVALID_OPCODE();
872 }
873
874 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
875 {
876 case 2: /* Aliased to /0 for the time being. */
877 case 4: /* Aliased to /0 for the time being. */
878 case 5: /* Aliased to /0 for the time being. */
879 case 6: /* Aliased to /0 for the time being. */
880 case 7: /* Aliased to /0 for the time being. */
881 case 0: IEMOP_MNEMONIC(prefetch, "prefetch"); break;
882 case 1: IEMOP_MNEMONIC(prefetchw_1, "prefetchw"); break;
883 case 3: IEMOP_MNEMONIC(prefetchw_3, "prefetchw"); break;
884 IEM_NOT_REACHED_DEFAULT_CASE_RET();
885 }
886
887 IEM_MC_BEGIN(0, 1);
888 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
889 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
890 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
891 /* Currently a NOP. */
892 NOREF(GCPtrEffSrc);
893 IEM_MC_ADVANCE_RIP();
894 IEM_MC_END();
895 return VINF_SUCCESS;
896}
897
898
899/** Opcode 0x0f 0x0e. */
900FNIEMOP_DEF(iemOp_femms)
901{
902 IEMOP_MNEMONIC(femms, "femms");
903 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
904
905 IEM_MC_BEGIN(0,0);
906 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
907 IEM_MC_MAYBE_RAISE_FPU_XCPT();
908 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
909 IEM_MC_FPU_FROM_MMX_MODE();
910 IEM_MC_ADVANCE_RIP();
911 IEM_MC_END();
912 return VINF_SUCCESS;
913}
914
915
916/** Opcode 0x0f 0x0f. */
917FNIEMOP_DEF(iemOp_3Dnow)
918{
919 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->f3DNow)
920 {
921 IEMOP_MNEMONIC(Inv3Dnow, "3Dnow");
922 return IEMOP_RAISE_INVALID_OPCODE();
923 }
924
925#ifdef IEM_WITH_3DNOW
926 /* This is pretty sparse, use switch instead of table. */
927 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
928 return FNIEMOP_CALL_1(iemOp_3DNowDispatcher, b);
929#else
930 IEMOP_BITCH_ABOUT_STUB();
931 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
932#endif
933}
934
935
936/**
937 * @opcode 0x10
938 * @oppfx none
939 * @opcpuid sse
940 * @opgroup og_sse_simdfp_datamove
941 * @opxcpttype 4UA
942 * @optest op1=1 op2=2 -> op1=2
943 * @optest op1=0 op2=-22 -> op1=-22
944 */
945FNIEMOP_DEF(iemOp_movups_Vps_Wps)
946{
947 IEMOP_MNEMONIC2(RM, MOVUPS, movups, Vps_WO, Wps, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
948 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
949 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
950 {
951 /*
952 * Register, register.
953 */
954 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
955 IEM_MC_BEGIN(0, 0);
956 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
957 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
958 IEM_MC_COPY_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg,
959 (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
960 IEM_MC_ADVANCE_RIP();
961 IEM_MC_END();
962 }
963 else
964 {
965 /*
966 * Memory, register.
967 */
968 IEM_MC_BEGIN(0, 2);
969 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
970 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
971
972 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
973 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
974 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
975 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
976
977 IEM_MC_FETCH_MEM_U128(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
978 IEM_MC_STORE_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
979
980 IEM_MC_ADVANCE_RIP();
981 IEM_MC_END();
982 }
983 return VINF_SUCCESS;
984
985}
986
987
988/**
989 * @opcode 0x10
990 * @oppfx 0x66
991 * @opcpuid sse2
992 * @opgroup og_sse2_pcksclr_datamove
993 * @opxcpttype 4UA
994 * @optest op1=1 op2=2 -> op1=2
995 * @optest op1=0 op2=-42 -> op1=-42
996 */
997FNIEMOP_DEF(iemOp_movupd_Vpd_Wpd)
998{
999 IEMOP_MNEMONIC2(RM, MOVUPD, movupd, Vpd_WO, Wpd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1000 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1001 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1002 {
1003 /*
1004 * Register, register.
1005 */
1006 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1007 IEM_MC_BEGIN(0, 0);
1008 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1009 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1010 IEM_MC_COPY_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg,
1011 (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1012 IEM_MC_ADVANCE_RIP();
1013 IEM_MC_END();
1014 }
1015 else
1016 {
1017 /*
1018 * Memory, register.
1019 */
1020 IEM_MC_BEGIN(0, 2);
1021 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
1022 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1023
1024 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1025 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1026 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1027 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1028
1029 IEM_MC_FETCH_MEM_U128(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1030 IEM_MC_STORE_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1031
1032 IEM_MC_ADVANCE_RIP();
1033 IEM_MC_END();
1034 }
1035 return VINF_SUCCESS;
1036}
1037
1038
1039/**
1040 * @opcode 0x10
1041 * @oppfx 0xf3
1042 * @opcpuid sse
1043 * @opgroup og_sse_simdfp_datamove
1044 * @opxcpttype 5
1045 * @optest op1=1 op2=2 -> op1=2
1046 * @optest op1=0 op2=-22 -> op1=-22
1047 */
1048FNIEMOP_DEF(iemOp_movss_Vss_Wss)
1049{
1050 IEMOP_MNEMONIC2(RM, MOVSS, movss, VssZx_WO, Wss, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1051 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1052 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1053 {
1054 /*
1055 * Register, register.
1056 */
1057 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1058 IEM_MC_BEGIN(0, 1);
1059 IEM_MC_LOCAL(uint32_t, uSrc);
1060
1061 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1062 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1063 IEM_MC_FETCH_XREG_U32(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1064 IEM_MC_STORE_XREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1065
1066 IEM_MC_ADVANCE_RIP();
1067 IEM_MC_END();
1068 }
1069 else
1070 {
1071 /*
1072 * Memory, register.
1073 */
1074 IEM_MC_BEGIN(0, 2);
1075 IEM_MC_LOCAL(uint32_t, uSrc);
1076 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1077
1078 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1079 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1080 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1081 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1082
1083 IEM_MC_FETCH_MEM_U32(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1084 IEM_MC_STORE_XREG_U32_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1085
1086 IEM_MC_ADVANCE_RIP();
1087 IEM_MC_END();
1088 }
1089 return VINF_SUCCESS;
1090}
1091
1092
1093/**
1094 * @opcode 0x10
1095 * @oppfx 0xf2
1096 * @opcpuid sse2
1097 * @opgroup og_sse2_pcksclr_datamove
1098 * @opxcpttype 5
1099 * @optest op1=1 op2=2 -> op1=2
1100 * @optest op1=0 op2=-42 -> op1=-42
1101 */
1102FNIEMOP_DEF(iemOp_movsd_Vsd_Wsd)
1103{
1104 IEMOP_MNEMONIC2(RM, MOVSD, movsd, VsdZx_WO, Wsd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1105 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1106 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1107 {
1108 /*
1109 * Register, register.
1110 */
1111 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1112 IEM_MC_BEGIN(0, 1);
1113 IEM_MC_LOCAL(uint64_t, uSrc);
1114
1115 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1116 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1117 IEM_MC_FETCH_XREG_U64(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1118 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1119
1120 IEM_MC_ADVANCE_RIP();
1121 IEM_MC_END();
1122 }
1123 else
1124 {
1125 /*
1126 * Memory, register.
1127 */
1128 IEM_MC_BEGIN(0, 2);
1129 IEM_MC_LOCAL(uint64_t, uSrc);
1130 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1131
1132 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1133 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1134 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1135 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1136
1137 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1138 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1139
1140 IEM_MC_ADVANCE_RIP();
1141 IEM_MC_END();
1142 }
1143 return VINF_SUCCESS;
1144}
1145
1146
1147/**
1148 * @opcode 0x11
1149 * @oppfx none
1150 * @opcpuid sse
1151 * @opgroup og_sse_simdfp_datamove
1152 * @opxcpttype 4UA
1153 * @optest op1=1 op2=2 -> op1=2
1154 * @optest op1=0 op2=-42 -> op1=-42
1155 */
1156FNIEMOP_DEF(iemOp_movups_Wps_Vps)
1157{
1158 IEMOP_MNEMONIC2(MR, MOVUPS, movups, Wps_WO, Vps, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1159 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1160 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1161 {
1162 /*
1163 * Register, register.
1164 */
1165 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1166 IEM_MC_BEGIN(0, 0);
1167 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1168 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1169 IEM_MC_COPY_XREG_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB,
1170 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1171 IEM_MC_ADVANCE_RIP();
1172 IEM_MC_END();
1173 }
1174 else
1175 {
1176 /*
1177 * Memory, register.
1178 */
1179 IEM_MC_BEGIN(0, 2);
1180 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
1181 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1182
1183 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1184 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1185 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1186 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1187
1188 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1189 IEM_MC_STORE_MEM_U128(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1190
1191 IEM_MC_ADVANCE_RIP();
1192 IEM_MC_END();
1193 }
1194 return VINF_SUCCESS;
1195}
1196
1197
1198/**
1199 * @opcode 0x11
1200 * @oppfx 0x66
1201 * @opcpuid sse2
1202 * @opgroup og_sse2_pcksclr_datamove
1203 * @opxcpttype 4UA
1204 * @optest op1=1 op2=2 -> op1=2
1205 * @optest op1=0 op2=-42 -> op1=-42
1206 */
1207FNIEMOP_DEF(iemOp_movupd_Wpd_Vpd)
1208{
1209 IEMOP_MNEMONIC2(MR, MOVUPD, movupd, Wpd_WO, Vpd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1210 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1211 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1212 {
1213 /*
1214 * Register, register.
1215 */
1216 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1217 IEM_MC_BEGIN(0, 0);
1218 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1219 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1220 IEM_MC_COPY_XREG_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB,
1221 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1222 IEM_MC_ADVANCE_RIP();
1223 IEM_MC_END();
1224 }
1225 else
1226 {
1227 /*
1228 * Memory, register.
1229 */
1230 IEM_MC_BEGIN(0, 2);
1231 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
1232 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1233
1234 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1235 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1236 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1237 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1238
1239 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1240 IEM_MC_STORE_MEM_U128(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1241
1242 IEM_MC_ADVANCE_RIP();
1243 IEM_MC_END();
1244 }
1245 return VINF_SUCCESS;
1246}
1247
1248
1249/**
1250 * @opcode 0x11
1251 * @oppfx 0xf3
1252 * @opcpuid sse
1253 * @opgroup og_sse_simdfp_datamove
1254 * @opxcpttype 5
1255 * @optest op1=1 op2=2 -> op1=2
1256 * @optest op1=0 op2=-22 -> op1=-22
1257 */
1258FNIEMOP_DEF(iemOp_movss_Wss_Vss)
1259{
1260 IEMOP_MNEMONIC2(MR, MOVSS, movss, Wss_WO, Vss, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1261 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1262 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1263 {
1264 /*
1265 * Register, register.
1266 */
1267 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1268 IEM_MC_BEGIN(0, 1);
1269 IEM_MC_LOCAL(uint32_t, uSrc);
1270
1271 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1272 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1273 IEM_MC_FETCH_XREG_U32(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1274 IEM_MC_STORE_XREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uSrc);
1275
1276 IEM_MC_ADVANCE_RIP();
1277 IEM_MC_END();
1278 }
1279 else
1280 {
1281 /*
1282 * Memory, register.
1283 */
1284 IEM_MC_BEGIN(0, 2);
1285 IEM_MC_LOCAL(uint32_t, uSrc);
1286 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1287
1288 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1289 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1290 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1291 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1292
1293 IEM_MC_FETCH_XREG_U32(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1294 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1295
1296 IEM_MC_ADVANCE_RIP();
1297 IEM_MC_END();
1298 }
1299 return VINF_SUCCESS;
1300}
1301
1302
1303/**
1304 * @opcode 0x11
1305 * @oppfx 0xf2
1306 * @opcpuid sse2
1307 * @opgroup og_sse2_pcksclr_datamove
1308 * @opxcpttype 5
1309 * @optest op1=1 op2=2 -> op1=2
1310 * @optest op1=0 op2=-42 -> op1=-42
1311 */
1312FNIEMOP_DEF(iemOp_movsd_Wsd_Vsd)
1313{
1314 IEMOP_MNEMONIC2(MR, MOVSD, movsd, Wsd_WO, Vsd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1315 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1316 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1317 {
1318 /*
1319 * Register, register.
1320 */
1321 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1322 IEM_MC_BEGIN(0, 1);
1323 IEM_MC_LOCAL(uint64_t, uSrc);
1324
1325 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1326 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1327 IEM_MC_FETCH_XREG_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1328 IEM_MC_STORE_XREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uSrc);
1329
1330 IEM_MC_ADVANCE_RIP();
1331 IEM_MC_END();
1332 }
1333 else
1334 {
1335 /*
1336 * Memory, register.
1337 */
1338 IEM_MC_BEGIN(0, 2);
1339 IEM_MC_LOCAL(uint64_t, uSrc);
1340 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1341
1342 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1343 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1344 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1345 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1346
1347 IEM_MC_FETCH_XREG_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1348 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1349
1350 IEM_MC_ADVANCE_RIP();
1351 IEM_MC_END();
1352 }
1353 return VINF_SUCCESS;
1354}
1355
1356
1357FNIEMOP_DEF(iemOp_movlps_Vq_Mq__movhlps)
1358{
1359 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1360 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1361 {
1362 /**
1363 * @opcode 0x12
1364 * @opcodesub 11 mr/reg
1365 * @oppfx none
1366 * @opcpuid sse
1367 * @opgroup og_sse_simdfp_datamove
1368 * @opxcpttype 5
1369 * @optest op1=1 op2=2 -> op1=2
1370 * @optest op1=0 op2=-42 -> op1=-42
1371 */
1372 IEMOP_MNEMONIC2(RM_REG, MOVHLPS, movhlps, Vq_WO, UqHi, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1373
1374 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1375 IEM_MC_BEGIN(0, 1);
1376 IEM_MC_LOCAL(uint64_t, uSrc);
1377
1378 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1379 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1380 IEM_MC_FETCH_XREG_HI_U64(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1381 IEM_MC_STORE_XREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1382
1383 IEM_MC_ADVANCE_RIP();
1384 IEM_MC_END();
1385 }
1386 else
1387 {
1388 /**
1389 * @opdone
1390 * @opcode 0x12
1391 * @opcodesub !11 mr/reg
1392 * @oppfx none
1393 * @opcpuid sse
1394 * @opgroup og_sse_simdfp_datamove
1395 * @opxcpttype 5
1396 * @optest op1=1 op2=2 -> op1=2
1397 * @optest op1=0 op2=-42 -> op1=-42
1398 * @opfunction iemOp_movlps_Vq_Mq__vmovhlps
1399 */
1400 IEMOP_MNEMONIC2(RM_MEM, MOVLPS, movlps, Vq_WO, Mq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1401
1402 IEM_MC_BEGIN(0, 2);
1403 IEM_MC_LOCAL(uint64_t, uSrc);
1404 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1405
1406 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1407 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1408 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1409 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1410
1411 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1412 IEM_MC_STORE_XREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1413
1414 IEM_MC_ADVANCE_RIP();
1415 IEM_MC_END();
1416 }
1417 return VINF_SUCCESS;
1418}
1419
1420
1421/**
1422 * @opcode 0x12
1423 * @opcodesub !11 mr/reg
1424 * @oppfx 0x66
1425 * @opcpuid sse2
1426 * @opgroup og_sse2_pcksclr_datamove
1427 * @opxcpttype 5
1428 * @optest op1=1 op2=2 -> op1=2
1429 * @optest op1=0 op2=-42 -> op1=-42
1430 */
1431FNIEMOP_DEF(iemOp_movlpd_Vq_Mq)
1432{
1433 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1434 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
1435 {
1436 IEMOP_MNEMONIC2(RM_MEM, MOVLPD, movlpd, Vq_WO, Mq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1437
1438 IEM_MC_BEGIN(0, 2);
1439 IEM_MC_LOCAL(uint64_t, uSrc);
1440 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1441
1442 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1443 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1444 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1445 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1446
1447 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1448 IEM_MC_STORE_XREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1449
1450 IEM_MC_ADVANCE_RIP();
1451 IEM_MC_END();
1452 return VINF_SUCCESS;
1453 }
1454
1455 /**
1456 * @opdone
1457 * @opmnemonic ud660f12m3
1458 * @opcode 0x12
1459 * @opcodesub 11 mr/reg
1460 * @oppfx 0x66
1461 * @opunused immediate
1462 * @opcpuid sse
1463 * @optest ->
1464 */
1465 return IEMOP_RAISE_INVALID_OPCODE();
1466}
1467
1468
1469/**
1470 * @opcode 0x12
1471 * @oppfx 0xf3
1472 * @opcpuid sse3
1473 * @opgroup og_sse3_pcksclr_datamove
1474 * @opxcpttype 4
1475 * @optest op1=-1 op2=0xdddddddd00000002eeeeeeee00000001 ->
1476 * op1=0x00000002000000020000000100000001
1477 */
1478FNIEMOP_DEF(iemOp_movsldup_Vdq_Wdq)
1479{
1480 IEMOP_MNEMONIC2(RM, MOVSLDUP, movsldup, Vdq_WO, Wdq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1481 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1482 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1483 {
1484 /*
1485 * Register, register.
1486 */
1487 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1488 IEM_MC_BEGIN(2, 0);
1489 IEM_MC_ARG(PRTUINT128U, puDst, 0);
1490 IEM_MC_ARG(PCRTUINT128U, puSrc, 1);
1491
1492 IEM_MC_MAYBE_RAISE_SSE3_RELATED_XCPT();
1493 IEM_MC_PREPARE_SSE_USAGE();
1494
1495 IEM_MC_REF_XREG_U128_CONST(puSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1496 IEM_MC_REF_XREG_U128(puDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1497 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_movsldup, puDst, puSrc);
1498
1499 IEM_MC_ADVANCE_RIP();
1500 IEM_MC_END();
1501 }
1502 else
1503 {
1504 /*
1505 * Register, memory.
1506 */
1507 IEM_MC_BEGIN(2, 2);
1508 IEM_MC_LOCAL(RTUINT128U, uSrc);
1509 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1510 IEM_MC_ARG(PRTUINT128U, puDst, 0);
1511 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, puSrc, uSrc, 1);
1512
1513 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1514 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1515 IEM_MC_MAYBE_RAISE_SSE3_RELATED_XCPT();
1516 IEM_MC_PREPARE_SSE_USAGE();
1517
1518 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1519 IEM_MC_REF_XREG_U128(puDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1520 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_movsldup, puDst, puSrc);
1521
1522 IEM_MC_ADVANCE_RIP();
1523 IEM_MC_END();
1524 }
1525 return VINF_SUCCESS;
1526}
1527
1528
1529/**
1530 * @opcode 0x12
1531 * @oppfx 0xf2
1532 * @opcpuid sse3
1533 * @opgroup og_sse3_pcksclr_datamove
1534 * @opxcpttype 5
1535 * @optest op1=-1 op2=0xddddddddeeeeeeee2222222211111111 ->
1536 * op1=0x22222222111111112222222211111111
1537 */
1538FNIEMOP_DEF(iemOp_movddup_Vdq_Wdq)
1539{
1540 IEMOP_MNEMONIC2(RM, MOVDDUP, movddup, Vdq_WO, Wdq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1541 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1542 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1543 {
1544 /*
1545 * Register, register.
1546 */
1547 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1548 IEM_MC_BEGIN(2, 0);
1549 IEM_MC_ARG(PRTUINT128U, puDst, 0);
1550 IEM_MC_ARG(uint64_t, uSrc, 1);
1551
1552 IEM_MC_MAYBE_RAISE_SSE3_RELATED_XCPT();
1553 IEM_MC_PREPARE_SSE_USAGE();
1554
1555 IEM_MC_FETCH_XREG_U64(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1556 IEM_MC_REF_XREG_U128(puDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1557 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_movddup, puDst, uSrc);
1558
1559 IEM_MC_ADVANCE_RIP();
1560 IEM_MC_END();
1561 }
1562 else
1563 {
1564 /*
1565 * Register, memory.
1566 */
1567 IEM_MC_BEGIN(2, 2);
1568 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1569 IEM_MC_ARG(PRTUINT128U, puDst, 0);
1570 IEM_MC_ARG(uint64_t, uSrc, 1);
1571
1572 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1573 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1574 IEM_MC_MAYBE_RAISE_SSE3_RELATED_XCPT();
1575 IEM_MC_PREPARE_SSE_USAGE();
1576
1577 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1578 IEM_MC_REF_XREG_U128(puDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1579 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_movddup, puDst, uSrc);
1580
1581 IEM_MC_ADVANCE_RIP();
1582 IEM_MC_END();
1583 }
1584 return VINF_SUCCESS;
1585}
1586
1587
1588/**
1589 * @opcode 0x13
1590 * @opcodesub !11 mr/reg
1591 * @oppfx none
1592 * @opcpuid sse
1593 * @opgroup og_sse_simdfp_datamove
1594 * @opxcpttype 5
1595 * @optest op1=1 op2=2 -> op1=2
1596 * @optest op1=0 op2=-42 -> op1=-42
1597 */
1598FNIEMOP_DEF(iemOp_movlps_Mq_Vq)
1599{
1600 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1601 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
1602 {
1603 IEMOP_MNEMONIC2(MR_MEM, MOVLPS, movlps, Mq_WO, Vq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1604
1605 IEM_MC_BEGIN(0, 2);
1606 IEM_MC_LOCAL(uint64_t, uSrc);
1607 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1608
1609 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1610 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1611 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1612 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1613
1614 IEM_MC_FETCH_XREG_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1615 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1616
1617 IEM_MC_ADVANCE_RIP();
1618 IEM_MC_END();
1619 return VINF_SUCCESS;
1620 }
1621
1622 /**
1623 * @opdone
1624 * @opmnemonic ud0f13m3
1625 * @opcode 0x13
1626 * @opcodesub 11 mr/reg
1627 * @oppfx none
1628 * @opunused immediate
1629 * @opcpuid sse
1630 * @optest ->
1631 */
1632 return IEMOP_RAISE_INVALID_OPCODE();
1633}
1634
1635
1636/**
1637 * @opcode 0x13
1638 * @opcodesub !11 mr/reg
1639 * @oppfx 0x66
1640 * @opcpuid sse2
1641 * @opgroup og_sse2_pcksclr_datamove
1642 * @opxcpttype 5
1643 * @optest op1=1 op2=2 -> op1=2
1644 * @optest op1=0 op2=-42 -> op1=-42
1645 */
1646FNIEMOP_DEF(iemOp_movlpd_Mq_Vq)
1647{
1648 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1649 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
1650 {
1651 IEMOP_MNEMONIC2(MR_MEM, MOVLPD, movlpd, Mq_WO, Vq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1652 IEM_MC_BEGIN(0, 2);
1653 IEM_MC_LOCAL(uint64_t, uSrc);
1654 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1655
1656 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1657 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1658 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1659 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1660
1661 IEM_MC_FETCH_XREG_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1662 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1663
1664 IEM_MC_ADVANCE_RIP();
1665 IEM_MC_END();
1666 return VINF_SUCCESS;
1667 }
1668
1669 /**
1670 * @opdone
1671 * @opmnemonic ud660f13m3
1672 * @opcode 0x13
1673 * @opcodesub 11 mr/reg
1674 * @oppfx 0x66
1675 * @opunused immediate
1676 * @opcpuid sse
1677 * @optest ->
1678 */
1679 return IEMOP_RAISE_INVALID_OPCODE();
1680}
1681
1682
1683/**
1684 * @opmnemonic udf30f13
1685 * @opcode 0x13
1686 * @oppfx 0xf3
1687 * @opunused intel-modrm
1688 * @opcpuid sse
1689 * @optest ->
1690 * @opdone
1691 */
1692
1693/**
1694 * @opmnemonic udf20f13
1695 * @opcode 0x13
1696 * @oppfx 0xf2
1697 * @opunused intel-modrm
1698 * @opcpuid sse
1699 * @optest ->
1700 * @opdone
1701 */
1702
1703/** Opcode 0x0f 0x14 - unpcklps Vx, Wx*/
1704FNIEMOP_STUB(iemOp_unpcklps_Vx_Wx);
1705/** Opcode 0x66 0x0f 0x14 - unpcklpd Vx, Wx */
1706FNIEMOP_STUB(iemOp_unpcklpd_Vx_Wx);
1707
1708/**
1709 * @opdone
1710 * @opmnemonic udf30f14
1711 * @opcode 0x14
1712 * @oppfx 0xf3
1713 * @opunused intel-modrm
1714 * @opcpuid sse
1715 * @optest ->
1716 * @opdone
1717 */
1718
1719/**
1720 * @opmnemonic udf20f14
1721 * @opcode 0x14
1722 * @oppfx 0xf2
1723 * @opunused intel-modrm
1724 * @opcpuid sse
1725 * @optest ->
1726 * @opdone
1727 */
1728
1729/** Opcode 0x0f 0x15 - unpckhps Vx, Wx */
1730FNIEMOP_STUB(iemOp_unpckhps_Vx_Wx);
1731/** Opcode 0x66 0x0f 0x15 - unpckhpd Vx, Wx */
1732FNIEMOP_STUB(iemOp_unpckhpd_Vx_Wx);
1733/* Opcode 0xf3 0x0f 0x15 - invalid */
1734/* Opcode 0xf2 0x0f 0x15 - invalid */
1735
1736/**
1737 * @opdone
1738 * @opmnemonic udf30f15
1739 * @opcode 0x15
1740 * @oppfx 0xf3
1741 * @opunused intel-modrm
1742 * @opcpuid sse
1743 * @optest ->
1744 * @opdone
1745 */
1746
1747/**
1748 * @opmnemonic udf20f15
1749 * @opcode 0x15
1750 * @oppfx 0xf2
1751 * @opunused intel-modrm
1752 * @opcpuid sse
1753 * @optest ->
1754 * @opdone
1755 */
1756
1757FNIEMOP_DEF(iemOp_movhps_Vdq_Mq__movlhps_Vdq_Uq)
1758{
1759 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1760 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1761 {
1762 /**
1763 * @opcode 0x16
1764 * @opcodesub 11 mr/reg
1765 * @oppfx none
1766 * @opcpuid sse
1767 * @opgroup og_sse_simdfp_datamove
1768 * @opxcpttype 5
1769 * @optest op1=1 op2=2 -> op1=2
1770 * @optest op1=0 op2=-42 -> op1=-42
1771 */
1772 IEMOP_MNEMONIC2(RM_REG, MOVLHPS, movlhps, VqHi_WO, Uq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1773
1774 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1775 IEM_MC_BEGIN(0, 1);
1776 IEM_MC_LOCAL(uint64_t, uSrc);
1777
1778 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1779 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1780 IEM_MC_FETCH_XREG_U64(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1781 IEM_MC_STORE_XREG_HI_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1782
1783 IEM_MC_ADVANCE_RIP();
1784 IEM_MC_END();
1785 }
1786 else
1787 {
1788 /**
1789 * @opdone
1790 * @opcode 0x16
1791 * @opcodesub !11 mr/reg
1792 * @oppfx none
1793 * @opcpuid sse
1794 * @opgroup og_sse_simdfp_datamove
1795 * @opxcpttype 5
1796 * @optest op1=1 op2=2 -> op1=2
1797 * @optest op1=0 op2=-42 -> op1=-42
1798 * @opfunction iemOp_movhps_Vdq_Mq__movlhps_Vdq_Uq
1799 */
1800 IEMOP_MNEMONIC2(RM_MEM, MOVHPS, movhps, VqHi_WO, Mq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1801
1802 IEM_MC_BEGIN(0, 2);
1803 IEM_MC_LOCAL(uint64_t, uSrc);
1804 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1805
1806 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1807 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1808 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1809 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1810
1811 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1812 IEM_MC_STORE_XREG_HI_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1813
1814 IEM_MC_ADVANCE_RIP();
1815 IEM_MC_END();
1816 }
1817 return VINF_SUCCESS;
1818}
1819
1820
1821/**
1822 * @opcode 0x16
1823 * @opcodesub !11 mr/reg
1824 * @oppfx 0x66
1825 * @opcpuid sse2
1826 * @opgroup og_sse2_pcksclr_datamove
1827 * @opxcpttype 5
1828 * @optest op1=1 op2=2 -> op1=2
1829 * @optest op1=0 op2=-42 -> op1=-42
1830 */
1831FNIEMOP_DEF(iemOp_movhpd_Vdq_Mq)
1832{
1833 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1834 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
1835 {
1836 IEMOP_MNEMONIC2(RM_MEM, MOVHPD, movhpd, VqHi_WO, Mq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1837 IEM_MC_BEGIN(0, 2);
1838 IEM_MC_LOCAL(uint64_t, uSrc);
1839 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1840
1841 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1842 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1843 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
1844 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
1845
1846 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1847 IEM_MC_STORE_XREG_HI_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
1848
1849 IEM_MC_ADVANCE_RIP();
1850 IEM_MC_END();
1851 return VINF_SUCCESS;
1852 }
1853
1854 /**
1855 * @opdone
1856 * @opmnemonic ud660f16m3
1857 * @opcode 0x16
1858 * @opcodesub 11 mr/reg
1859 * @oppfx 0x66
1860 * @opunused immediate
1861 * @opcpuid sse
1862 * @optest ->
1863 */
1864 return IEMOP_RAISE_INVALID_OPCODE();
1865}
1866
1867
1868/**
1869 * @opcode 0x16
1870 * @oppfx 0xf3
1871 * @opcpuid sse3
1872 * @opgroup og_sse3_pcksclr_datamove
1873 * @opxcpttype 4
1874 * @optest op1=-1 op2=0x00000002dddddddd00000001eeeeeeee ->
1875 * op1=0x00000002000000020000000100000001
1876 */
1877FNIEMOP_DEF(iemOp_movshdup_Vdq_Wdq)
1878{
1879 IEMOP_MNEMONIC2(RM, MOVSHDUP, movshdup, Vdq_WO, Wdq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1880 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1881 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1882 {
1883 /*
1884 * Register, register.
1885 */
1886 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1887 IEM_MC_BEGIN(2, 0);
1888 IEM_MC_ARG(PRTUINT128U, puDst, 0);
1889 IEM_MC_ARG(PCRTUINT128U, puSrc, 1);
1890
1891 IEM_MC_MAYBE_RAISE_SSE3_RELATED_XCPT();
1892 IEM_MC_PREPARE_SSE_USAGE();
1893
1894 IEM_MC_REF_XREG_U128_CONST(puSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
1895 IEM_MC_REF_XREG_U128(puDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1896 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_movshdup, puDst, puSrc);
1897
1898 IEM_MC_ADVANCE_RIP();
1899 IEM_MC_END();
1900 }
1901 else
1902 {
1903 /*
1904 * Register, memory.
1905 */
1906 IEM_MC_BEGIN(2, 2);
1907 IEM_MC_LOCAL(RTUINT128U, uSrc);
1908 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1909 IEM_MC_ARG(PRTUINT128U, puDst, 0);
1910 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, puSrc, uSrc, 1);
1911
1912 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1913 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1914 IEM_MC_MAYBE_RAISE_SSE3_RELATED_XCPT();
1915 IEM_MC_PREPARE_SSE_USAGE();
1916
1917 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1918 IEM_MC_REF_XREG_U128(puDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1919 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_movshdup, puDst, puSrc);
1920
1921 IEM_MC_ADVANCE_RIP();
1922 IEM_MC_END();
1923 }
1924 return VINF_SUCCESS;
1925}
1926
1927/**
1928 * @opdone
1929 * @opmnemonic udf30f16
1930 * @opcode 0x16
1931 * @oppfx 0xf2
1932 * @opunused intel-modrm
1933 * @opcpuid sse
1934 * @optest ->
1935 * @opdone
1936 */
1937
1938
1939/**
1940 * @opcode 0x17
1941 * @opcodesub !11 mr/reg
1942 * @oppfx none
1943 * @opcpuid sse
1944 * @opgroup og_sse_simdfp_datamove
1945 * @opxcpttype 5
1946 * @optest op1=1 op2=2 -> op1=2
1947 * @optest op1=0 op2=-42 -> op1=-42
1948 */
1949FNIEMOP_DEF(iemOp_movhps_Mq_Vq)
1950{
1951 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1952 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
1953 {
1954 IEMOP_MNEMONIC2(MR_MEM, MOVHPS, movhps, Mq_WO, VqHi, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1955
1956 IEM_MC_BEGIN(0, 2);
1957 IEM_MC_LOCAL(uint64_t, uSrc);
1958 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1959
1960 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1961 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1962 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
1963 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
1964
1965 IEM_MC_FETCH_XREG_HI_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
1966 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
1967
1968 IEM_MC_ADVANCE_RIP();
1969 IEM_MC_END();
1970 return VINF_SUCCESS;
1971 }
1972
1973 /**
1974 * @opdone
1975 * @opmnemonic ud0f17m3
1976 * @opcode 0x17
1977 * @opcodesub 11 mr/reg
1978 * @oppfx none
1979 * @opunused immediate
1980 * @opcpuid sse
1981 * @optest ->
1982 */
1983 return IEMOP_RAISE_INVALID_OPCODE();
1984}
1985
1986
1987/**
1988 * @opcode 0x17
1989 * @opcodesub !11 mr/reg
1990 * @oppfx 0x66
1991 * @opcpuid sse2
1992 * @opgroup og_sse2_pcksclr_datamove
1993 * @opxcpttype 5
1994 * @optest op1=1 op2=2 -> op1=2
1995 * @optest op1=0 op2=-42 -> op1=-42
1996 */
1997FNIEMOP_DEF(iemOp_movhpd_Mq_Vq)
1998{
1999 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2000 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
2001 {
2002 IEMOP_MNEMONIC2(MR_MEM, MOVHPD, movhpd, Mq_WO, VqHi, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2003
2004 IEM_MC_BEGIN(0, 2);
2005 IEM_MC_LOCAL(uint64_t, uSrc);
2006 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2007
2008 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2009 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2010 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
2011 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
2012
2013 IEM_MC_FETCH_XREG_HI_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2014 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
2015
2016 IEM_MC_ADVANCE_RIP();
2017 IEM_MC_END();
2018 return VINF_SUCCESS;
2019 }
2020
2021 /**
2022 * @opdone
2023 * @opmnemonic ud660f17m3
2024 * @opcode 0x17
2025 * @opcodesub 11 mr/reg
2026 * @oppfx 0x66
2027 * @opunused immediate
2028 * @opcpuid sse
2029 * @optest ->
2030 */
2031 return IEMOP_RAISE_INVALID_OPCODE();
2032}
2033
2034
2035/**
2036 * @opdone
2037 * @opmnemonic udf30f17
2038 * @opcode 0x17
2039 * @oppfx 0xf3
2040 * @opunused intel-modrm
2041 * @opcpuid sse
2042 * @optest ->
2043 * @opdone
2044 */
2045
2046/**
2047 * @opmnemonic udf20f17
2048 * @opcode 0x17
2049 * @oppfx 0xf2
2050 * @opunused intel-modrm
2051 * @opcpuid sse
2052 * @optest ->
2053 * @opdone
2054 */
2055
2056
2057/** Opcode 0x0f 0x18. */
2058FNIEMOP_DEF(iemOp_prefetch_Grp16)
2059{
2060 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2061 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
2062 {
2063 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
2064 {
2065 case 4: /* Aliased to /0 for the time being according to AMD. */
2066 case 5: /* Aliased to /0 for the time being according to AMD. */
2067 case 6: /* Aliased to /0 for the time being according to AMD. */
2068 case 7: /* Aliased to /0 for the time being according to AMD. */
2069 case 0: IEMOP_MNEMONIC(prefetchNTA, "prefetchNTA m8"); break;
2070 case 1: IEMOP_MNEMONIC(prefetchT0, "prefetchT0 m8"); break;
2071 case 2: IEMOP_MNEMONIC(prefetchT1, "prefetchT1 m8"); break;
2072 case 3: IEMOP_MNEMONIC(prefetchT2, "prefetchT2 m8"); break;
2073 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2074 }
2075
2076 IEM_MC_BEGIN(0, 1);
2077 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2078 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2079 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2080 /* Currently a NOP. */
2081 NOREF(GCPtrEffSrc);
2082 IEM_MC_ADVANCE_RIP();
2083 IEM_MC_END();
2084 return VINF_SUCCESS;
2085 }
2086
2087 return IEMOP_RAISE_INVALID_OPCODE();
2088}
2089
2090
2091/** Opcode 0x0f 0x19..0x1f. */
2092FNIEMOP_DEF(iemOp_nop_Ev)
2093{
2094 IEMOP_MNEMONIC(nop_Ev, "nop Ev");
2095 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2096 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2097 {
2098 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2099 IEM_MC_BEGIN(0, 0);
2100 IEM_MC_ADVANCE_RIP();
2101 IEM_MC_END();
2102 }
2103 else
2104 {
2105 IEM_MC_BEGIN(0, 1);
2106 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2107 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2108 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2109 /* Currently a NOP. */
2110 NOREF(GCPtrEffSrc);
2111 IEM_MC_ADVANCE_RIP();
2112 IEM_MC_END();
2113 }
2114 return VINF_SUCCESS;
2115}
2116
2117
2118/** Opcode 0x0f 0x20. */
2119FNIEMOP_DEF(iemOp_mov_Rd_Cd)
2120{
2121 /* mod is ignored, as is operand size overrides. */
2122 IEMOP_MNEMONIC(mov_Rd_Cd, "mov Rd,Cd");
2123 IEMOP_HLP_MIN_386();
2124 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
2125 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
2126 else
2127 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_32BIT;
2128
2129 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2130 uint8_t iCrReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg;
2131 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK)
2132 {
2133 /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
2134 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fMovCr8In32Bit)
2135 return IEMOP_RAISE_INVALID_OPCODE(); /* #UD takes precedence over #GP(), see test. */
2136 iCrReg |= 8;
2137 }
2138 switch (iCrReg)
2139 {
2140 case 0: case 2: case 3: case 4: case 8:
2141 break;
2142 default:
2143 return IEMOP_RAISE_INVALID_OPCODE();
2144 }
2145 IEMOP_HLP_DONE_DECODING();
2146
2147 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Rd_Cd, (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB, iCrReg);
2148}
2149
2150
2151/** Opcode 0x0f 0x21. */
2152FNIEMOP_DEF(iemOp_mov_Rd_Dd)
2153{
2154 IEMOP_MNEMONIC(mov_Rd_Dd, "mov Rd,Dd");
2155 IEMOP_HLP_MIN_386();
2156 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2157 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2158 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX_R)
2159 return IEMOP_RAISE_INVALID_OPCODE();
2160 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Rd_Dd,
2161 (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB,
2162 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK));
2163}
2164
2165
2166/** Opcode 0x0f 0x22. */
2167FNIEMOP_DEF(iemOp_mov_Cd_Rd)
2168{
2169 /* mod is ignored, as is operand size overrides. */
2170 IEMOP_MNEMONIC(mov_Cd_Rd, "mov Cd,Rd");
2171 IEMOP_HLP_MIN_386();
2172 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
2173 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
2174 else
2175 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_32BIT;
2176
2177 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2178 uint8_t iCrReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg;
2179 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK)
2180 {
2181 /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
2182 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fMovCr8In32Bit)
2183 return IEMOP_RAISE_INVALID_OPCODE(); /* #UD takes precedence over #GP(), see test. */
2184 iCrReg |= 8;
2185 }
2186 switch (iCrReg)
2187 {
2188 case 0: case 2: case 3: case 4: case 8:
2189 break;
2190 default:
2191 return IEMOP_RAISE_INVALID_OPCODE();
2192 }
2193 IEMOP_HLP_DONE_DECODING();
2194
2195 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Cd_Rd, iCrReg, (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB);
2196}
2197
2198
2199/** Opcode 0x0f 0x23. */
2200FNIEMOP_DEF(iemOp_mov_Dd_Rd)
2201{
2202 IEMOP_MNEMONIC(mov_Dd_Rd, "mov Dd,Rd");
2203 IEMOP_HLP_MIN_386();
2204 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2205 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2206 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX_R)
2207 return IEMOP_RAISE_INVALID_OPCODE();
2208 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Dd_Rd,
2209 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK),
2210 (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB);
2211}
2212
2213
2214/** Opcode 0x0f 0x24. */
2215FNIEMOP_DEF(iemOp_mov_Rd_Td)
2216{
2217 IEMOP_MNEMONIC(mov_Rd_Td, "mov Rd,Td");
2218 IEMOP_HLP_MIN_386();
2219 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2220 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2221 if (RT_LIKELY(IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_PENTIUM))
2222 return IEMOP_RAISE_INVALID_OPCODE();
2223 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Rd_Td,
2224 (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB,
2225 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK));
2226}
2227
2228
2229/** Opcode 0x0f 0x26. */
2230FNIEMOP_DEF(iemOp_mov_Td_Rd)
2231{
2232 IEMOP_MNEMONIC(mov_Td_Rd, "mov Td,Rd");
2233 IEMOP_HLP_MIN_386();
2234 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2235 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2236 if (RT_LIKELY(IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_PENTIUM))
2237 return IEMOP_RAISE_INVALID_OPCODE();
2238 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Td_Rd,
2239 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK),
2240 (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB);
2241}
2242
2243
2244/**
2245 * @opcode 0x28
2246 * @oppfx none
2247 * @opcpuid sse
2248 * @opgroup og_sse_simdfp_datamove
2249 * @opxcpttype 1
2250 * @optest op1=1 op2=2 -> op1=2
2251 * @optest op1=0 op2=-42 -> op1=-42
2252 */
2253FNIEMOP_DEF(iemOp_movaps_Vps_Wps)
2254{
2255 IEMOP_MNEMONIC2(RM, MOVAPS, movaps, Vps_WO, Wps, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2256 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2257 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2258 {
2259 /*
2260 * Register, register.
2261 */
2262 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2263 IEM_MC_BEGIN(0, 0);
2264 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
2265 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2266 IEM_MC_COPY_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg,
2267 (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2268 IEM_MC_ADVANCE_RIP();
2269 IEM_MC_END();
2270 }
2271 else
2272 {
2273 /*
2274 * Register, memory.
2275 */
2276 IEM_MC_BEGIN(0, 2);
2277 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
2278 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2279
2280 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2281 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2282 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
2283 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2284
2285 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
2286 IEM_MC_STORE_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
2287
2288 IEM_MC_ADVANCE_RIP();
2289 IEM_MC_END();
2290 }
2291 return VINF_SUCCESS;
2292}
2293
2294/**
2295 * @opcode 0x28
2296 * @oppfx 66
2297 * @opcpuid sse2
2298 * @opgroup og_sse2_pcksclr_datamove
2299 * @opxcpttype 1
2300 * @optest op1=1 op2=2 -> op1=2
2301 * @optest op1=0 op2=-42 -> op1=-42
2302 */
2303FNIEMOP_DEF(iemOp_movapd_Vpd_Wpd)
2304{
2305 IEMOP_MNEMONIC2(RM, MOVAPD, movapd, Vpd_WO, Wpd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2306 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2307 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2308 {
2309 /*
2310 * Register, register.
2311 */
2312 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2313 IEM_MC_BEGIN(0, 0);
2314 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
2315 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2316 IEM_MC_COPY_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg,
2317 (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2318 IEM_MC_ADVANCE_RIP();
2319 IEM_MC_END();
2320 }
2321 else
2322 {
2323 /*
2324 * Register, memory.
2325 */
2326 IEM_MC_BEGIN(0, 2);
2327 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
2328 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2329
2330 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2331 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2332 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
2333 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2334
2335 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
2336 IEM_MC_STORE_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
2337
2338 IEM_MC_ADVANCE_RIP();
2339 IEM_MC_END();
2340 }
2341 return VINF_SUCCESS;
2342}
2343
2344/* Opcode 0xf3 0x0f 0x28 - invalid */
2345/* Opcode 0xf2 0x0f 0x28 - invalid */
2346
2347/**
2348 * @opcode 0x29
2349 * @oppfx none
2350 * @opcpuid sse
2351 * @opgroup og_sse_simdfp_datamove
2352 * @opxcpttype 1
2353 * @optest op1=1 op2=2 -> op1=2
2354 * @optest op1=0 op2=-42 -> op1=-42
2355 */
2356FNIEMOP_DEF(iemOp_movaps_Wps_Vps)
2357{
2358 IEMOP_MNEMONIC2(MR, MOVAPS, movaps, Wps_WO, Vps, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2359 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2360 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2361 {
2362 /*
2363 * Register, register.
2364 */
2365 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2366 IEM_MC_BEGIN(0, 0);
2367 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
2368 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2369 IEM_MC_COPY_XREG_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB,
2370 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2371 IEM_MC_ADVANCE_RIP();
2372 IEM_MC_END();
2373 }
2374 else
2375 {
2376 /*
2377 * Memory, register.
2378 */
2379 IEM_MC_BEGIN(0, 2);
2380 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
2381 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2382
2383 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2384 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2385 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
2386 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
2387
2388 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2389 IEM_MC_STORE_MEM_U128_ALIGN_SSE(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
2390
2391 IEM_MC_ADVANCE_RIP();
2392 IEM_MC_END();
2393 }
2394 return VINF_SUCCESS;
2395}
2396
2397/**
2398 * @opcode 0x29
2399 * @oppfx 66
2400 * @opcpuid sse2
2401 * @opgroup og_sse2_pcksclr_datamove
2402 * @opxcpttype 1
2403 * @optest op1=1 op2=2 -> op1=2
2404 * @optest op1=0 op2=-42 -> op1=-42
2405 */
2406FNIEMOP_DEF(iemOp_movapd_Wpd_Vpd)
2407{
2408 IEMOP_MNEMONIC2(MR, MOVAPD, movapd, Wpd_WO, Vpd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2409 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2410 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2411 {
2412 /*
2413 * Register, register.
2414 */
2415 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2416 IEM_MC_BEGIN(0, 0);
2417 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
2418 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2419 IEM_MC_COPY_XREG_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB,
2420 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2421 IEM_MC_ADVANCE_RIP();
2422 IEM_MC_END();
2423 }
2424 else
2425 {
2426 /*
2427 * Memory, register.
2428 */
2429 IEM_MC_BEGIN(0, 2);
2430 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
2431 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2432
2433 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2434 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2435 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
2436 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
2437
2438 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2439 IEM_MC_STORE_MEM_U128_ALIGN_SSE(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
2440
2441 IEM_MC_ADVANCE_RIP();
2442 IEM_MC_END();
2443 }
2444 return VINF_SUCCESS;
2445}
2446
2447/* Opcode 0xf3 0x0f 0x29 - invalid */
2448/* Opcode 0xf2 0x0f 0x29 - invalid */
2449
2450
2451/** Opcode 0x0f 0x2a - cvtpi2ps Vps, Qpi */
2452FNIEMOP_STUB(iemOp_cvtpi2ps_Vps_Qpi); //NEXT
2453/** Opcode 0x66 0x0f 0x2a - cvtpi2pd Vpd, Qpi */
2454FNIEMOP_STUB(iemOp_cvtpi2pd_Vpd_Qpi); //NEXT
2455/** Opcode 0xf3 0x0f 0x2a - vcvtsi2ss Vss, Hss, Ey */
2456FNIEMOP_STUB(iemOp_cvtsi2ss_Vss_Ey); //NEXT
2457/** Opcode 0xf2 0x0f 0x2a - vcvtsi2sd Vsd, Hsd, Ey */
2458FNIEMOP_STUB(iemOp_cvtsi2sd_Vsd_Ey); //NEXT
2459
2460
2461/**
2462 * @opcode 0x2b
2463 * @opcodesub !11 mr/reg
2464 * @oppfx none
2465 * @opcpuid sse
2466 * @opgroup og_sse1_cachect
2467 * @opxcpttype 1
2468 * @optest op1=1 op2=2 -> op1=2
2469 * @optest op1=0 op2=-42 -> op1=-42
2470 */
2471FNIEMOP_DEF(iemOp_movntps_Mps_Vps)
2472{
2473 IEMOP_MNEMONIC2(MR_MEM, MOVNTPS, movntps, Mps_WO, Vps, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2474 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2475 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
2476 {
2477 /*
2478 * memory, register.
2479 */
2480 IEM_MC_BEGIN(0, 2);
2481 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
2482 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2483
2484 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2485 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2486 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
2487 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2488
2489 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2490 IEM_MC_STORE_MEM_U128_ALIGN_SSE(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
2491
2492 IEM_MC_ADVANCE_RIP();
2493 IEM_MC_END();
2494 }
2495 /* The register, register encoding is invalid. */
2496 else
2497 return IEMOP_RAISE_INVALID_OPCODE();
2498 return VINF_SUCCESS;
2499}
2500
2501/**
2502 * @opcode 0x2b
2503 * @opcodesub !11 mr/reg
2504 * @oppfx 0x66
2505 * @opcpuid sse2
2506 * @opgroup og_sse2_cachect
2507 * @opxcpttype 1
2508 * @optest op1=1 op2=2 -> op1=2
2509 * @optest op1=0 op2=-42 -> op1=-42
2510 */
2511FNIEMOP_DEF(iemOp_movntpd_Mpd_Vpd)
2512{
2513 IEMOP_MNEMONIC2(MR_MEM, MOVNTPD, movntpd, Mpd_WO, Vpd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
2514 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2515 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
2516 {
2517 /*
2518 * memory, register.
2519 */
2520 IEM_MC_BEGIN(0, 2);
2521 IEM_MC_LOCAL(RTUINT128U, uSrc); /** @todo optimize this one day... */
2522 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
2523
2524 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
2525 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2526 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
2527 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
2528
2529 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
2530 IEM_MC_STORE_MEM_U128_ALIGN_SSE(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
2531
2532 IEM_MC_ADVANCE_RIP();
2533 IEM_MC_END();
2534 }
2535 /* The register, register encoding is invalid. */
2536 else
2537 return IEMOP_RAISE_INVALID_OPCODE();
2538 return VINF_SUCCESS;
2539}
2540/* Opcode 0xf3 0x0f 0x2b - invalid */
2541/* Opcode 0xf2 0x0f 0x2b - invalid */
2542
2543
2544/** Opcode 0x0f 0x2c - cvttps2pi Ppi, Wps */
2545FNIEMOP_STUB(iemOp_cvttps2pi_Ppi_Wps);
2546/** Opcode 0x66 0x0f 0x2c - cvttpd2pi Ppi, Wpd */
2547FNIEMOP_STUB(iemOp_cvttpd2pi_Ppi_Wpd);
2548/** Opcode 0xf3 0x0f 0x2c - cvttss2si Gy, Wss */
2549FNIEMOP_STUB(iemOp_cvttss2si_Gy_Wss);
2550/** Opcode 0xf2 0x0f 0x2c - cvttsd2si Gy, Wsd */
2551FNIEMOP_STUB(iemOp_cvttsd2si_Gy_Wsd);
2552
2553/** Opcode 0x0f 0x2d - cvtps2pi Ppi, Wps */
2554FNIEMOP_STUB(iemOp_cvtps2pi_Ppi_Wps);
2555/** Opcode 0x66 0x0f 0x2d - cvtpd2pi Qpi, Wpd */
2556FNIEMOP_STUB(iemOp_cvtpd2pi_Qpi_Wpd);
2557/** Opcode 0xf3 0x0f 0x2d - cvtss2si Gy, Wss */
2558FNIEMOP_STUB(iemOp_cvtss2si_Gy_Wss);
2559/** Opcode 0xf2 0x0f 0x2d - cvtsd2si Gy, Wsd */
2560FNIEMOP_STUB(iemOp_cvtsd2si_Gy_Wsd);
2561
2562/** Opcode 0x0f 0x2e - ucomiss Vss, Wss */
2563FNIEMOP_STUB(iemOp_ucomiss_Vss_Wss); // NEXT
2564/** Opcode 0x66 0x0f 0x2e - ucomisd Vsd, Wsd */
2565FNIEMOP_STUB(iemOp_ucomisd_Vsd_Wsd); // NEXT
2566/* Opcode 0xf3 0x0f 0x2e - invalid */
2567/* Opcode 0xf2 0x0f 0x2e - invalid */
2568
2569/** Opcode 0x0f 0x2f - comiss Vss, Wss */
2570FNIEMOP_STUB(iemOp_comiss_Vss_Wss);
2571/** Opcode 0x66 0x0f 0x2f - comisd Vsd, Wsd */
2572FNIEMOP_STUB(iemOp_comisd_Vsd_Wsd);
2573/* Opcode 0xf3 0x0f 0x2f - invalid */
2574/* Opcode 0xf2 0x0f 0x2f - invalid */
2575
2576/** Opcode 0x0f 0x30. */
2577FNIEMOP_DEF(iemOp_wrmsr)
2578{
2579 IEMOP_MNEMONIC(wrmsr, "wrmsr");
2580 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2581 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_wrmsr);
2582}
2583
2584
2585/** Opcode 0x0f 0x31. */
2586FNIEMOP_DEF(iemOp_rdtsc)
2587{
2588 IEMOP_MNEMONIC(rdtsc, "rdtsc");
2589 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2590 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rdtsc);
2591}
2592
2593
2594/** Opcode 0x0f 0x33. */
2595FNIEMOP_DEF(iemOp_rdmsr)
2596{
2597 IEMOP_MNEMONIC(rdmsr, "rdmsr");
2598 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2599 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rdmsr);
2600}
2601
2602
2603/** Opcode 0x0f 0x34. */
2604FNIEMOP_DEF(iemOp_rdpmc)
2605{
2606 IEMOP_MNEMONIC(rdpmc, "rdpmc");
2607 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2608 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rdpmc);
2609}
2610
2611
2612/** Opcode 0x0f 0x34. */
2613FNIEMOP_DEF(iemOp_sysenter)
2614{
2615 IEMOP_MNEMONIC0(FIXED, SYSENTER, sysenter, DISOPTYPE_CONTROLFLOW | DISOPTYPE_UNCOND_CONTROLFLOW, 0);
2616 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2617 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_sysenter);
2618}
2619
2620/** Opcode 0x0f 0x35. */
2621FNIEMOP_DEF(iemOp_sysexit)
2622{
2623 IEMOP_MNEMONIC0(FIXED, SYSEXIT, sysexit, DISOPTYPE_CONTROLFLOW | DISOPTYPE_UNCOND_CONTROLFLOW, 0);
2624 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2625 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_sysexit, pVCpu->iem.s.enmEffOpSize);
2626}
2627
2628/** Opcode 0x0f 0x37. */
2629FNIEMOP_STUB(iemOp_getsec);
2630
2631
2632/** Opcode 0x0f 0x38. */
2633FNIEMOP_DEF(iemOp_3byte_Esc_0f_38)
2634{
2635#ifdef IEM_WITH_THREE_0F_38
2636 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2637 return FNIEMOP_CALL(g_apfnThreeByte0f38[(uintptr_t)b * 4 + pVCpu->iem.s.idxPrefix]);
2638#else
2639 IEMOP_BITCH_ABOUT_STUB();
2640 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
2641#endif
2642}
2643
2644
2645/** Opcode 0x0f 0x3a. */
2646FNIEMOP_DEF(iemOp_3byte_Esc_0f_3a)
2647{
2648#ifdef IEM_WITH_THREE_0F_3A
2649 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2650 return FNIEMOP_CALL(g_apfnThreeByte0f3a[(uintptr_t)b * 4 + pVCpu->iem.s.idxPrefix]);
2651#else
2652 IEMOP_BITCH_ABOUT_STUB();
2653 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
2654#endif
2655}
2656
2657
2658/**
2659 * Implements a conditional move.
2660 *
2661 * Wish there was an obvious way to do this where we could share and reduce
2662 * code bloat.
2663 *
2664 * @param a_Cnd The conditional "microcode" operation.
2665 */
2666#define CMOV_X(a_Cnd) \
2667 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
2668 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT)) \
2669 { \
2670 switch (pVCpu->iem.s.enmEffOpSize) \
2671 { \
2672 case IEMMODE_16BIT: \
2673 IEM_MC_BEGIN(0, 1); \
2674 IEM_MC_LOCAL(uint16_t, u16Tmp); \
2675 a_Cnd { \
2676 IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB); \
2677 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp); \
2678 } IEM_MC_ENDIF(); \
2679 IEM_MC_ADVANCE_RIP(); \
2680 IEM_MC_END(); \
2681 return VINF_SUCCESS; \
2682 \
2683 case IEMMODE_32BIT: \
2684 IEM_MC_BEGIN(0, 1); \
2685 IEM_MC_LOCAL(uint32_t, u32Tmp); \
2686 a_Cnd { \
2687 IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB); \
2688 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp); \
2689 } IEM_MC_ELSE() { \
2690 IEM_MC_CLEAR_HIGH_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg); \
2691 } IEM_MC_ENDIF(); \
2692 IEM_MC_ADVANCE_RIP(); \
2693 IEM_MC_END(); \
2694 return VINF_SUCCESS; \
2695 \
2696 case IEMMODE_64BIT: \
2697 IEM_MC_BEGIN(0, 1); \
2698 IEM_MC_LOCAL(uint64_t, u64Tmp); \
2699 a_Cnd { \
2700 IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB); \
2701 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp); \
2702 } IEM_MC_ENDIF(); \
2703 IEM_MC_ADVANCE_RIP(); \
2704 IEM_MC_END(); \
2705 return VINF_SUCCESS; \
2706 \
2707 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
2708 } \
2709 } \
2710 else \
2711 { \
2712 switch (pVCpu->iem.s.enmEffOpSize) \
2713 { \
2714 case IEMMODE_16BIT: \
2715 IEM_MC_BEGIN(0, 2); \
2716 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
2717 IEM_MC_LOCAL(uint16_t, u16Tmp); \
2718 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0); \
2719 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
2720 a_Cnd { \
2721 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp); \
2722 } IEM_MC_ENDIF(); \
2723 IEM_MC_ADVANCE_RIP(); \
2724 IEM_MC_END(); \
2725 return VINF_SUCCESS; \
2726 \
2727 case IEMMODE_32BIT: \
2728 IEM_MC_BEGIN(0, 2); \
2729 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
2730 IEM_MC_LOCAL(uint32_t, u32Tmp); \
2731 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0); \
2732 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
2733 a_Cnd { \
2734 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp); \
2735 } IEM_MC_ELSE() { \
2736 IEM_MC_CLEAR_HIGH_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg); \
2737 } IEM_MC_ENDIF(); \
2738 IEM_MC_ADVANCE_RIP(); \
2739 IEM_MC_END(); \
2740 return VINF_SUCCESS; \
2741 \
2742 case IEMMODE_64BIT: \
2743 IEM_MC_BEGIN(0, 2); \
2744 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); \
2745 IEM_MC_LOCAL(uint64_t, u64Tmp); \
2746 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0); \
2747 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
2748 a_Cnd { \
2749 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp); \
2750 } IEM_MC_ENDIF(); \
2751 IEM_MC_ADVANCE_RIP(); \
2752 IEM_MC_END(); \
2753 return VINF_SUCCESS; \
2754 \
2755 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
2756 } \
2757 } do {} while (0)
2758
2759
2760
2761/** Opcode 0x0f 0x40. */
2762FNIEMOP_DEF(iemOp_cmovo_Gv_Ev)
2763{
2764 IEMOP_MNEMONIC(cmovo_Gv_Ev, "cmovo Gv,Ev");
2765 CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF));
2766}
2767
2768
2769/** Opcode 0x0f 0x41. */
2770FNIEMOP_DEF(iemOp_cmovno_Gv_Ev)
2771{
2772 IEMOP_MNEMONIC(cmovno_Gv_Ev, "cmovno Gv,Ev");
2773 CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_OF));
2774}
2775
2776
2777/** Opcode 0x0f 0x42. */
2778FNIEMOP_DEF(iemOp_cmovc_Gv_Ev)
2779{
2780 IEMOP_MNEMONIC(cmovc_Gv_Ev, "cmovc Gv,Ev");
2781 CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF));
2782}
2783
2784
2785/** Opcode 0x0f 0x43. */
2786FNIEMOP_DEF(iemOp_cmovnc_Gv_Ev)
2787{
2788 IEMOP_MNEMONIC(cmovnc_Gv_Ev, "cmovnc Gv,Ev");
2789 CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_CF));
2790}
2791
2792
2793/** Opcode 0x0f 0x44. */
2794FNIEMOP_DEF(iemOp_cmove_Gv_Ev)
2795{
2796 IEMOP_MNEMONIC(cmove_Gv_Ev, "cmove Gv,Ev");
2797 CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF));
2798}
2799
2800
2801/** Opcode 0x0f 0x45. */
2802FNIEMOP_DEF(iemOp_cmovne_Gv_Ev)
2803{
2804 IEMOP_MNEMONIC(cmovne_Gv_Ev, "cmovne Gv,Ev");
2805 CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF));
2806}
2807
2808
2809/** Opcode 0x0f 0x46. */
2810FNIEMOP_DEF(iemOp_cmovbe_Gv_Ev)
2811{
2812 IEMOP_MNEMONIC(cmovbe_Gv_Ev, "cmovbe Gv,Ev");
2813 CMOV_X(IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF));
2814}
2815
2816
2817/** Opcode 0x0f 0x47. */
2818FNIEMOP_DEF(iemOp_cmovnbe_Gv_Ev)
2819{
2820 IEMOP_MNEMONIC(cmovnbe_Gv_Ev, "cmovnbe Gv,Ev");
2821 CMOV_X(IEM_MC_IF_EFL_NO_BITS_SET(X86_EFL_CF | X86_EFL_ZF));
2822}
2823
2824
2825/** Opcode 0x0f 0x48. */
2826FNIEMOP_DEF(iemOp_cmovs_Gv_Ev)
2827{
2828 IEMOP_MNEMONIC(cmovs_Gv_Ev, "cmovs Gv,Ev");
2829 CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF));
2830}
2831
2832
2833/** Opcode 0x0f 0x49. */
2834FNIEMOP_DEF(iemOp_cmovns_Gv_Ev)
2835{
2836 IEMOP_MNEMONIC(cmovns_Gv_Ev, "cmovns Gv,Ev");
2837 CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_SF));
2838}
2839
2840
2841/** Opcode 0x0f 0x4a. */
2842FNIEMOP_DEF(iemOp_cmovp_Gv_Ev)
2843{
2844 IEMOP_MNEMONIC(cmovp_Gv_Ev, "cmovp Gv,Ev");
2845 CMOV_X(IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF));
2846}
2847
2848
2849/** Opcode 0x0f 0x4b. */
2850FNIEMOP_DEF(iemOp_cmovnp_Gv_Ev)
2851{
2852 IEMOP_MNEMONIC(cmovnp_Gv_Ev, "cmovnp Gv,Ev");
2853 CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_PF));
2854}
2855
2856
2857/** Opcode 0x0f 0x4c. */
2858FNIEMOP_DEF(iemOp_cmovl_Gv_Ev)
2859{
2860 IEMOP_MNEMONIC(cmovl_Gv_Ev, "cmovl Gv,Ev");
2861 CMOV_X(IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF));
2862}
2863
2864
2865/** Opcode 0x0f 0x4d. */
2866FNIEMOP_DEF(iemOp_cmovnl_Gv_Ev)
2867{
2868 IEMOP_MNEMONIC(cmovnl_Gv_Ev, "cmovnl Gv,Ev");
2869 CMOV_X(IEM_MC_IF_EFL_BITS_EQ(X86_EFL_SF, X86_EFL_OF));
2870}
2871
2872
2873/** Opcode 0x0f 0x4e. */
2874FNIEMOP_DEF(iemOp_cmovle_Gv_Ev)
2875{
2876 IEMOP_MNEMONIC(cmovle_Gv_Ev, "cmovle Gv,Ev");
2877 CMOV_X(IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF));
2878}
2879
2880
2881/** Opcode 0x0f 0x4f. */
2882FNIEMOP_DEF(iemOp_cmovnle_Gv_Ev)
2883{
2884 IEMOP_MNEMONIC(cmovnle_Gv_Ev, "cmovnle Gv,Ev");
2885 CMOV_X(IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF));
2886}
2887
2888#undef CMOV_X
2889
2890/** Opcode 0x0f 0x50 - movmskps Gy, Ups */
2891FNIEMOP_STUB(iemOp_movmskps_Gy_Ups);
2892/** Opcode 0x66 0x0f 0x50 - movmskpd Gy, Upd */
2893FNIEMOP_STUB(iemOp_movmskpd_Gy_Upd);
2894/* Opcode 0xf3 0x0f 0x50 - invalid */
2895/* Opcode 0xf2 0x0f 0x50 - invalid */
2896
2897/** Opcode 0x0f 0x51 - sqrtps Vps, Wps */
2898FNIEMOP_STUB(iemOp_sqrtps_Vps_Wps);
2899/** Opcode 0x66 0x0f 0x51 - sqrtpd Vpd, Wpd */
2900FNIEMOP_STUB(iemOp_sqrtpd_Vpd_Wpd);
2901/** Opcode 0xf3 0x0f 0x51 - sqrtss Vss, Wss */
2902FNIEMOP_STUB(iemOp_sqrtss_Vss_Wss);
2903/** Opcode 0xf2 0x0f 0x51 - sqrtsd Vsd, Wsd */
2904FNIEMOP_STUB(iemOp_sqrtsd_Vsd_Wsd);
2905
2906/** Opcode 0x0f 0x52 - rsqrtps Vps, Wps */
2907FNIEMOP_STUB(iemOp_rsqrtps_Vps_Wps);
2908/* Opcode 0x66 0x0f 0x52 - invalid */
2909/** Opcode 0xf3 0x0f 0x52 - rsqrtss Vss, Wss */
2910FNIEMOP_STUB(iemOp_rsqrtss_Vss_Wss);
2911/* Opcode 0xf2 0x0f 0x52 - invalid */
2912
2913/** Opcode 0x0f 0x53 - rcpps Vps, Wps */
2914FNIEMOP_STUB(iemOp_rcpps_Vps_Wps);
2915/* Opcode 0x66 0x0f 0x53 - invalid */
2916/** Opcode 0xf3 0x0f 0x53 - rcpss Vss, Wss */
2917FNIEMOP_STUB(iemOp_rcpss_Vss_Wss);
2918/* Opcode 0xf2 0x0f 0x53 - invalid */
2919
2920/** Opcode 0x0f 0x54 - andps Vps, Wps */
2921FNIEMOP_STUB(iemOp_andps_Vps_Wps);
2922/** Opcode 0x66 0x0f 0x54 - andpd Vpd, Wpd */
2923FNIEMOP_STUB(iemOp_andpd_Vpd_Wpd);
2924/* Opcode 0xf3 0x0f 0x54 - invalid */
2925/* Opcode 0xf2 0x0f 0x54 - invalid */
2926
2927/** Opcode 0x0f 0x55 - andnps Vps, Wps */
2928FNIEMOP_STUB(iemOp_andnps_Vps_Wps);
2929/** Opcode 0x66 0x0f 0x55 - andnpd Vpd, Wpd */
2930FNIEMOP_STUB(iemOp_andnpd_Vpd_Wpd);
2931/* Opcode 0xf3 0x0f 0x55 - invalid */
2932/* Opcode 0xf2 0x0f 0x55 - invalid */
2933
2934/** Opcode 0x0f 0x56 - orps Vps, Wps */
2935FNIEMOP_STUB(iemOp_orps_Vps_Wps);
2936/** Opcode 0x66 0x0f 0x56 - orpd Vpd, Wpd */
2937FNIEMOP_STUB(iemOp_orpd_Vpd_Wpd);
2938/* Opcode 0xf3 0x0f 0x56 - invalid */
2939/* Opcode 0xf2 0x0f 0x56 - invalid */
2940
2941/** Opcode 0x0f 0x57 - xorps Vps, Wps */
2942FNIEMOP_STUB(iemOp_xorps_Vps_Wps);
2943/** Opcode 0x66 0x0f 0x57 - xorpd Vpd, Wpd */
2944FNIEMOP_STUB(iemOp_xorpd_Vpd_Wpd);
2945/* Opcode 0xf3 0x0f 0x57 - invalid */
2946/* Opcode 0xf2 0x0f 0x57 - invalid */
2947
2948/** Opcode 0x0f 0x58 - addps Vps, Wps */
2949FNIEMOP_STUB(iemOp_addps_Vps_Wps);
2950/** Opcode 0x66 0x0f 0x58 - addpd Vpd, Wpd */
2951FNIEMOP_STUB(iemOp_addpd_Vpd_Wpd);
2952/** Opcode 0xf3 0x0f 0x58 - addss Vss, Wss */
2953FNIEMOP_STUB(iemOp_addss_Vss_Wss);
2954/** Opcode 0xf2 0x0f 0x58 - addsd Vsd, Wsd */
2955FNIEMOP_STUB(iemOp_addsd_Vsd_Wsd);
2956
2957/** Opcode 0x0f 0x59 - mulps Vps, Wps */
2958FNIEMOP_STUB(iemOp_mulps_Vps_Wps);
2959/** Opcode 0x66 0x0f 0x59 - mulpd Vpd, Wpd */
2960FNIEMOP_STUB(iemOp_mulpd_Vpd_Wpd);
2961/** Opcode 0xf3 0x0f 0x59 - mulss Vss, Wss */
2962FNIEMOP_STUB(iemOp_mulss_Vss_Wss);
2963/** Opcode 0xf2 0x0f 0x59 - mulsd Vsd, Wsd */
2964FNIEMOP_STUB(iemOp_mulsd_Vsd_Wsd);
2965
2966/** Opcode 0x0f 0x5a - cvtps2pd Vpd, Wps */
2967FNIEMOP_STUB(iemOp_cvtps2pd_Vpd_Wps);
2968/** Opcode 0x66 0x0f 0x5a - cvtpd2ps Vps, Wpd */
2969FNIEMOP_STUB(iemOp_cvtpd2ps_Vps_Wpd);
2970/** Opcode 0xf3 0x0f 0x5a - cvtss2sd Vsd, Wss */
2971FNIEMOP_STUB(iemOp_cvtss2sd_Vsd_Wss);
2972/** Opcode 0xf2 0x0f 0x5a - cvtsd2ss Vss, Wsd */
2973FNIEMOP_STUB(iemOp_cvtsd2ss_Vss_Wsd);
2974
2975/** Opcode 0x0f 0x5b - cvtdq2ps Vps, Wdq */
2976FNIEMOP_STUB(iemOp_cvtdq2ps_Vps_Wdq);
2977/** Opcode 0x66 0x0f 0x5b - cvtps2dq Vdq, Wps */
2978FNIEMOP_STUB(iemOp_cvtps2dq_Vdq_Wps);
2979/** Opcode 0xf3 0x0f 0x5b - cvttps2dq Vdq, Wps */
2980FNIEMOP_STUB(iemOp_cvttps2dq_Vdq_Wps);
2981/* Opcode 0xf2 0x0f 0x5b - invalid */
2982
2983/** Opcode 0x0f 0x5c - subps Vps, Wps */
2984FNIEMOP_STUB(iemOp_subps_Vps_Wps);
2985/** Opcode 0x66 0x0f 0x5c - subpd Vpd, Wpd */
2986FNIEMOP_STUB(iemOp_subpd_Vpd_Wpd);
2987/** Opcode 0xf3 0x0f 0x5c - subss Vss, Wss */
2988FNIEMOP_STUB(iemOp_subss_Vss_Wss);
2989/** Opcode 0xf2 0x0f 0x5c - subsd Vsd, Wsd */
2990FNIEMOP_STUB(iemOp_subsd_Vsd_Wsd);
2991
2992/** Opcode 0x0f 0x5d - minps Vps, Wps */
2993FNIEMOP_STUB(iemOp_minps_Vps_Wps);
2994/** Opcode 0x66 0x0f 0x5d - minpd Vpd, Wpd */
2995FNIEMOP_STUB(iemOp_minpd_Vpd_Wpd);
2996/** Opcode 0xf3 0x0f 0x5d - minss Vss, Wss */
2997FNIEMOP_STUB(iemOp_minss_Vss_Wss);
2998/** Opcode 0xf2 0x0f 0x5d - minsd Vsd, Wsd */
2999FNIEMOP_STUB(iemOp_minsd_Vsd_Wsd);
3000
3001/** Opcode 0x0f 0x5e - divps Vps, Wps */
3002FNIEMOP_STUB(iemOp_divps_Vps_Wps);
3003/** Opcode 0x66 0x0f 0x5e - divpd Vpd, Wpd */
3004FNIEMOP_STUB(iemOp_divpd_Vpd_Wpd);
3005/** Opcode 0xf3 0x0f 0x5e - divss Vss, Wss */
3006FNIEMOP_STUB(iemOp_divss_Vss_Wss);
3007/** Opcode 0xf2 0x0f 0x5e - divsd Vsd, Wsd */
3008FNIEMOP_STUB(iemOp_divsd_Vsd_Wsd);
3009
3010/** Opcode 0x0f 0x5f - maxps Vps, Wps */
3011FNIEMOP_STUB(iemOp_maxps_Vps_Wps);
3012/** Opcode 0x66 0x0f 0x5f - maxpd Vpd, Wpd */
3013FNIEMOP_STUB(iemOp_maxpd_Vpd_Wpd);
3014/** Opcode 0xf3 0x0f 0x5f - maxss Vss, Wss */
3015FNIEMOP_STUB(iemOp_maxss_Vss_Wss);
3016/** Opcode 0xf2 0x0f 0x5f - maxsd Vsd, Wsd */
3017FNIEMOP_STUB(iemOp_maxsd_Vsd_Wsd);
3018
3019/**
3020 * Common worker for MMX instructions on the forms:
3021 * pxxxx mm1, mm2/mem32
3022 *
3023 * The 2nd operand is the first half of a register, which in the memory case
3024 * means a 32-bit memory access for MMX and 128-bit aligned 64-bit or 128-bit
3025 * memory accessed for MMX.
3026 *
3027 * Exceptions type 4.
3028 */
3029FNIEMOP_DEF_1(iemOpCommonMmx_LowLow_To_Full, PCIEMOPMEDIAF1L1, pImpl)
3030{
3031 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3032 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3033 {
3034 /*
3035 * Register, register.
3036 */
3037 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3038 IEM_MC_BEGIN(2, 0);
3039 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3040 IEM_MC_ARG(uint64_t const *, pSrc, 1);
3041 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3042 IEM_MC_PREPARE_SSE_USAGE();
3043 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3044 IEM_MC_REF_XREG_U64_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3045 IEM_MC_CALL_SSE_AIMPL_2(pImpl->pfnU128, pDst, pSrc);
3046 IEM_MC_ADVANCE_RIP();
3047 IEM_MC_END();
3048 }
3049 else
3050 {
3051 /*
3052 * Register, memory.
3053 */
3054 IEM_MC_BEGIN(2, 2);
3055 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3056 IEM_MC_LOCAL(uint64_t, uSrc);
3057 IEM_MC_ARG_LOCAL_REF(uint64_t const *, pSrc, uSrc, 1);
3058 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3059
3060 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3061 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3062 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3063 IEM_MC_FETCH_MEM_U64_ALIGN_U128(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3064
3065 IEM_MC_PREPARE_SSE_USAGE();
3066 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3067 IEM_MC_CALL_SSE_AIMPL_2(pImpl->pfnU128, pDst, pSrc);
3068
3069 IEM_MC_ADVANCE_RIP();
3070 IEM_MC_END();
3071 }
3072 return VINF_SUCCESS;
3073}
3074
3075
3076/**
3077 * Common worker for SSE2 instructions on the forms:
3078 * pxxxx xmm1, xmm2/mem128
3079 *
3080 * The 2nd operand is the first half of a register, which in the memory case
3081 * means a 32-bit memory access for MMX and 128-bit aligned 64-bit or 128-bit
3082 * memory accessed for MMX.
3083 *
3084 * Exceptions type 4.
3085 */
3086FNIEMOP_DEF_1(iemOpCommonSse_LowLow_To_Full, PCIEMOPMEDIAF1L1, pImpl)
3087{
3088 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3089 if (!pImpl->pfnU64)
3090 return IEMOP_RAISE_INVALID_OPCODE();
3091 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3092 {
3093 /*
3094 * Register, register.
3095 */
3096 /** @todo testcase: REX.B / REX.R and MMX register indexing. Ignored? */
3097 /** @todo testcase: REX.B / REX.R and segment register indexing. Ignored? */
3098 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3099 IEM_MC_BEGIN(2, 0);
3100 IEM_MC_ARG(uint64_t *, pDst, 0);
3101 IEM_MC_ARG(uint32_t const *, pSrc, 1);
3102 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3103 IEM_MC_PREPARE_FPU_USAGE();
3104 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
3105 IEM_MC_REF_MREG_U32_CONST(pSrc, bRm & X86_MODRM_RM_MASK);
3106 IEM_MC_CALL_MMX_AIMPL_2(pImpl->pfnU64, pDst, pSrc);
3107 IEM_MC_ADVANCE_RIP();
3108 IEM_MC_END();
3109 }
3110 else
3111 {
3112 /*
3113 * Register, memory.
3114 */
3115 IEM_MC_BEGIN(2, 2);
3116 IEM_MC_ARG(uint64_t *, pDst, 0);
3117 IEM_MC_LOCAL(uint32_t, uSrc);
3118 IEM_MC_ARG_LOCAL_REF(uint32_t const *, pSrc, uSrc, 1);
3119 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3120
3121 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3122 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3123 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3124 IEM_MC_FETCH_MEM_U32(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3125
3126 IEM_MC_PREPARE_FPU_USAGE();
3127 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
3128 IEM_MC_CALL_MMX_AIMPL_2(pImpl->pfnU64, pDst, pSrc);
3129
3130 IEM_MC_ADVANCE_RIP();
3131 IEM_MC_END();
3132 }
3133 return VINF_SUCCESS;
3134}
3135
3136
3137/** Opcode 0x0f 0x60 - punpcklbw Pq, Qd */
3138FNIEMOP_DEF(iemOp_punpcklbw_Pq_Qd)
3139{
3140 IEMOP_MNEMONIC(punpcklbw, "punpcklbw Pq, Qd");
3141 return FNIEMOP_CALL_1(iemOpCommonMmx_LowLow_To_Full, &g_iemAImpl_punpcklbw);
3142}
3143
3144/** Opcode 0x66 0x0f 0x60 - punpcklbw Vx, W */
3145FNIEMOP_DEF(iemOp_punpcklbw_Vx_Wx)
3146{
3147 IEMOP_MNEMONIC(vpunpcklbw_Vx_Wx, "vpunpcklbw Vx, Wx");
3148 return FNIEMOP_CALL_1(iemOpCommonSse_LowLow_To_Full, &g_iemAImpl_punpcklbw);
3149}
3150
3151/* Opcode 0xf3 0x0f 0x60 - invalid */
3152
3153
3154/** Opcode 0x0f 0x61 - punpcklwd Pq, Qd */
3155FNIEMOP_DEF(iemOp_punpcklwd_Pq_Qd)
3156{
3157 IEMOP_MNEMONIC(punpcklwd, "punpcklwd Pq, Qd"); /** @todo AMD mark the MMX version as 3DNow!. Intel says MMX CPUID req. */
3158 return FNIEMOP_CALL_1(iemOpCommonMmx_LowLow_To_Full, &g_iemAImpl_punpcklwd);
3159}
3160
3161/** Opcode 0x66 0x0f 0x61 - punpcklwd Vx, Wx */
3162FNIEMOP_DEF(iemOp_punpcklwd_Vx_Wx)
3163{
3164 IEMOP_MNEMONIC(vpunpcklwd_Vx_Wx, "punpcklwd Vx, Wx");
3165 return FNIEMOP_CALL_1(iemOpCommonSse_LowLow_To_Full, &g_iemAImpl_punpcklwd);
3166}
3167
3168/* Opcode 0xf3 0x0f 0x61 - invalid */
3169
3170
3171/** Opcode 0x0f 0x62 - punpckldq Pq, Qd */
3172FNIEMOP_DEF(iemOp_punpckldq_Pq_Qd)
3173{
3174 IEMOP_MNEMONIC(punpckldq, "punpckldq Pq, Qd");
3175 return FNIEMOP_CALL_1(iemOpCommonMmx_LowLow_To_Full, &g_iemAImpl_punpckldq);
3176}
3177
3178/** Opcode 0x66 0x0f 0x62 - punpckldq Vx, Wx */
3179FNIEMOP_DEF(iemOp_punpckldq_Vx_Wx)
3180{
3181 IEMOP_MNEMONIC(punpckldq_Vx_Wx, "punpckldq Vx, Wx");
3182 return FNIEMOP_CALL_1(iemOpCommonSse_LowLow_To_Full, &g_iemAImpl_punpckldq);
3183}
3184
3185/* Opcode 0xf3 0x0f 0x62 - invalid */
3186
3187
3188
3189/** Opcode 0x0f 0x63 - packsswb Pq, Qq */
3190FNIEMOP_STUB(iemOp_packsswb_Pq_Qq);
3191/** Opcode 0x66 0x0f 0x63 - packsswb Vx, Wx */
3192FNIEMOP_STUB(iemOp_packsswb_Vx_Wx);
3193/* Opcode 0xf3 0x0f 0x63 - invalid */
3194
3195/** Opcode 0x0f 0x64 - pcmpgtb Pq, Qq */
3196FNIEMOP_STUB(iemOp_pcmpgtb_Pq_Qq);
3197/** Opcode 0x66 0x0f 0x64 - pcmpgtb Vx, Wx */
3198FNIEMOP_STUB(iemOp_pcmpgtb_Vx_Wx);
3199/* Opcode 0xf3 0x0f 0x64 - invalid */
3200
3201/** Opcode 0x0f 0x65 - pcmpgtw Pq, Qq */
3202FNIEMOP_STUB(iemOp_pcmpgtw_Pq_Qq);
3203/** Opcode 0x66 0x0f 0x65 - pcmpgtw Vx, Wx */
3204FNIEMOP_STUB(iemOp_pcmpgtw_Vx_Wx);
3205/* Opcode 0xf3 0x0f 0x65 - invalid */
3206
3207/** Opcode 0x0f 0x66 - pcmpgtd Pq, Qq */
3208FNIEMOP_STUB(iemOp_pcmpgtd_Pq_Qq);
3209/** Opcode 0x66 0x0f 0x66 - pcmpgtd Vx, Wx */
3210FNIEMOP_STUB(iemOp_pcmpgtd_Vx_Wx);
3211/* Opcode 0xf3 0x0f 0x66 - invalid */
3212
3213/** Opcode 0x0f 0x67 - packuswb Pq, Qq */
3214FNIEMOP_STUB(iemOp_packuswb_Pq_Qq);
3215/** Opcode 0x66 0x0f 0x67 - packuswb Vx, W */
3216FNIEMOP_STUB(iemOp_packuswb_Vx_W);
3217/* Opcode 0xf3 0x0f 0x67 - invalid */
3218
3219
3220/**
3221 * Common worker for MMX instructions on the form:
3222 * pxxxx mm1, mm2/mem64
3223 *
3224 * The 2nd operand is the second half of a register, which in the memory case
3225 * means a 64-bit memory access for MMX, and for SSE a 128-bit aligned access
3226 * where it may read the full 128 bits or only the upper 64 bits.
3227 *
3228 * Exceptions type 4.
3229 */
3230FNIEMOP_DEF_1(iemOpCommonMmx_HighHigh_To_Full, PCIEMOPMEDIAF1H1, pImpl)
3231{
3232 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3233 AssertReturn(pImpl->pfnU64, IEMOP_RAISE_INVALID_OPCODE());
3234 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3235 {
3236 /*
3237 * Register, register.
3238 */
3239 /** @todo testcase: REX.B / REX.R and MMX register indexing. Ignored? */
3240 /** @todo testcase: REX.B / REX.R and segment register indexing. Ignored? */
3241 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3242 IEM_MC_BEGIN(2, 0);
3243 IEM_MC_ARG(uint64_t *, pDst, 0);
3244 IEM_MC_ARG(uint64_t const *, pSrc, 1);
3245 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3246 IEM_MC_PREPARE_FPU_USAGE();
3247 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
3248 IEM_MC_REF_MREG_U64_CONST(pSrc, bRm & X86_MODRM_RM_MASK);
3249 IEM_MC_CALL_MMX_AIMPL_2(pImpl->pfnU64, pDst, pSrc);
3250 IEM_MC_ADVANCE_RIP();
3251 IEM_MC_END();
3252 }
3253 else
3254 {
3255 /*
3256 * Register, memory.
3257 */
3258 IEM_MC_BEGIN(2, 2);
3259 IEM_MC_ARG(uint64_t *, pDst, 0);
3260 IEM_MC_LOCAL(uint64_t, uSrc);
3261 IEM_MC_ARG_LOCAL_REF(uint64_t const *, pSrc, uSrc, 1);
3262 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3263
3264 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3265 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3266 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3267 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3268
3269 IEM_MC_PREPARE_FPU_USAGE();
3270 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
3271 IEM_MC_CALL_MMX_AIMPL_2(pImpl->pfnU64, pDst, pSrc);
3272
3273 IEM_MC_ADVANCE_RIP();
3274 IEM_MC_END();
3275 }
3276 return VINF_SUCCESS;
3277}
3278
3279
3280/**
3281 * Common worker for SSE2 instructions on the form:
3282 * pxxxx xmm1, xmm2/mem128
3283 *
3284 * The 2nd operand is the second half of a register, which in the memory case
3285 * means a 64-bit memory access for MMX, and for SSE a 128-bit aligned access
3286 * where it may read the full 128 bits or only the upper 64 bits.
3287 *
3288 * Exceptions type 4.
3289 */
3290FNIEMOP_DEF_1(iemOpCommonSse_HighHigh_To_Full, PCIEMOPMEDIAF1H1, pImpl)
3291{
3292 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3293 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3294 {
3295 /*
3296 * Register, register.
3297 */
3298 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3299 IEM_MC_BEGIN(2, 0);
3300 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3301 IEM_MC_ARG(PCRTUINT128U, pSrc, 1);
3302 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3303 IEM_MC_PREPARE_SSE_USAGE();
3304 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3305 IEM_MC_REF_XREG_U128_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3306 IEM_MC_CALL_SSE_AIMPL_2(pImpl->pfnU128, pDst, pSrc);
3307 IEM_MC_ADVANCE_RIP();
3308 IEM_MC_END();
3309 }
3310 else
3311 {
3312 /*
3313 * Register, memory.
3314 */
3315 IEM_MC_BEGIN(2, 2);
3316 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3317 IEM_MC_LOCAL(RTUINT128U, uSrc);
3318 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, pSrc, uSrc, 1);
3319 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3320
3321 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3322 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3323 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3324 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); /* Most CPUs probably only right high qword */
3325
3326 IEM_MC_PREPARE_SSE_USAGE();
3327 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3328 IEM_MC_CALL_SSE_AIMPL_2(pImpl->pfnU128, pDst, pSrc);
3329
3330 IEM_MC_ADVANCE_RIP();
3331 IEM_MC_END();
3332 }
3333 return VINF_SUCCESS;
3334}
3335
3336
3337/** Opcode 0x0f 0x68 - punpckhbw Pq, Qd */
3338FNIEMOP_DEF(iemOp_punpckhbw_Pq_Qd)
3339{
3340 IEMOP_MNEMONIC(punpckhbw, "punpckhbw Pq, Qd");
3341 return FNIEMOP_CALL_1(iemOpCommonMmx_HighHigh_To_Full, &g_iemAImpl_punpckhbw);
3342}
3343
3344/** Opcode 0x66 0x0f 0x68 - punpckhbw Vx, Wx */
3345FNIEMOP_DEF(iemOp_punpckhbw_Vx_Wx)
3346{
3347 IEMOP_MNEMONIC(vpunpckhbw_Vx_Wx, "vpunpckhbw Vx, Wx");
3348 return FNIEMOP_CALL_1(iemOpCommonSse_HighHigh_To_Full, &g_iemAImpl_punpckhbw);
3349}
3350/* Opcode 0xf3 0x0f 0x68 - invalid */
3351
3352
3353/** Opcode 0x0f 0x69 - punpckhwd Pq, Qd */
3354FNIEMOP_DEF(iemOp_punpckhwd_Pq_Qd)
3355{
3356 IEMOP_MNEMONIC(punpckhwd, "punpckhwd Pq, Qd");
3357 return FNIEMOP_CALL_1(iemOpCommonMmx_HighHigh_To_Full, &g_iemAImpl_punpckhwd);
3358}
3359
3360/** Opcode 0x66 0x0f 0x69 - punpckhwd Vx, Hx, Wx */
3361FNIEMOP_DEF(iemOp_punpckhwd_Vx_Wx)
3362{
3363 IEMOP_MNEMONIC(punpckhwd_Vx_Wx, "punpckhwd Vx, Wx");
3364 return FNIEMOP_CALL_1(iemOpCommonSse_HighHigh_To_Full, &g_iemAImpl_punpckhwd);
3365
3366}
3367/* Opcode 0xf3 0x0f 0x69 - invalid */
3368
3369
3370/** Opcode 0x0f 0x6a - punpckhdq Pq, Qd */
3371FNIEMOP_DEF(iemOp_punpckhdq_Pq_Qd)
3372{
3373 IEMOP_MNEMONIC(punpckhdq, "punpckhdq Pq, Qd");
3374 return FNIEMOP_CALL_1(iemOpCommonMmx_HighHigh_To_Full, &g_iemAImpl_punpckhdq);
3375}
3376
3377/** Opcode 0x66 0x0f 0x6a - punpckhdq Vx, W */
3378FNIEMOP_DEF(iemOp_punpckhdq_Vx_W)
3379{
3380 IEMOP_MNEMONIC(punpckhdq_Vx_W, "punpckhdq Vx, W");
3381 return FNIEMOP_CALL_1(iemOpCommonSse_HighHigh_To_Full, &g_iemAImpl_punpckhdq);
3382}
3383/* Opcode 0xf3 0x0f 0x6a - invalid */
3384
3385
3386/** Opcode 0x0f 0x6b - packssdw Pq, Qd */
3387FNIEMOP_STUB(iemOp_packssdw_Pq_Qd);
3388/** Opcode 0x66 0x0f 0x6b - packssdw Vx, Wx */
3389FNIEMOP_STUB(iemOp_packssdw_Vx_Wx);
3390/* Opcode 0xf3 0x0f 0x6b - invalid */
3391
3392
3393/* Opcode 0x0f 0x6c - invalid */
3394
3395/** Opcode 0x66 0x0f 0x6c - punpcklqdq Vx, Wx */
3396FNIEMOP_DEF(iemOp_punpcklqdq_Vx_Wx)
3397{
3398 IEMOP_MNEMONIC(punpcklqdq, "punpcklqdq Vx, Wx");
3399 return FNIEMOP_CALL_1(iemOpCommonSse_LowLow_To_Full, &g_iemAImpl_punpcklqdq);
3400}
3401
3402/* Opcode 0xf3 0x0f 0x6c - invalid */
3403/* Opcode 0xf2 0x0f 0x6c - invalid */
3404
3405
3406/* Opcode 0x0f 0x6d - invalid */
3407
3408/** Opcode 0x66 0x0f 0x6d - punpckhqdq Vx, W */
3409FNIEMOP_DEF(iemOp_punpckhqdq_Vx_W)
3410{
3411 IEMOP_MNEMONIC(punpckhqdq_Vx_W, "punpckhqdq Vx,W");
3412 return FNIEMOP_CALL_1(iemOpCommonSse_HighHigh_To_Full, &g_iemAImpl_punpckhqdq);
3413}
3414
3415/* Opcode 0xf3 0x0f 0x6d - invalid */
3416
3417
3418FNIEMOP_DEF(iemOp_movd_q_Pd_Ey)
3419{
3420 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3421 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
3422 {
3423 /**
3424 * @opcode 0x6e
3425 * @opcodesub rex.w=1
3426 * @oppfx none
3427 * @opcpuid mmx
3428 * @opgroup og_mmx_datamove
3429 * @opxcpttype 5
3430 * @optest 64-bit / op1=1 op2=2 -> op1=2 ftw=0xff
3431 * @optest 64-bit / op1=0 op2=-42 -> op1=-42 ftw=0xff
3432 */
3433 IEMOP_MNEMONIC2(RM, MOVQ, movq, Pq_WO, Eq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
3434 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3435 {
3436 /* MMX, greg64 */
3437 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3438 IEM_MC_BEGIN(0, 1);
3439 IEM_MC_LOCAL(uint64_t, u64Tmp);
3440
3441 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3442 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
3443
3444 IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3445 IEM_MC_STORE_MREG_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, u64Tmp);
3446 IEM_MC_FPU_TO_MMX_MODE();
3447
3448 IEM_MC_ADVANCE_RIP();
3449 IEM_MC_END();
3450 }
3451 else
3452 {
3453 /* MMX, [mem64] */
3454 IEM_MC_BEGIN(0, 2);
3455 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3456 IEM_MC_LOCAL(uint64_t, u64Tmp);
3457
3458 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3459 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3460 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3461 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
3462
3463 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3464 IEM_MC_STORE_MREG_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, u64Tmp);
3465 IEM_MC_FPU_TO_MMX_MODE();
3466
3467 IEM_MC_ADVANCE_RIP();
3468 IEM_MC_END();
3469 }
3470 }
3471 else
3472 {
3473 /**
3474 * @opdone
3475 * @opcode 0x6e
3476 * @opcodesub rex.w=0
3477 * @oppfx none
3478 * @opcpuid mmx
3479 * @opgroup og_mmx_datamove
3480 * @opxcpttype 5
3481 * @opfunction iemOp_movd_q_Pd_Ey
3482 * @optest op1=1 op2=2 -> op1=2 ftw=0xff
3483 * @optest op1=0 op2=-42 -> op1=-42 ftw=0xff
3484 */
3485 IEMOP_MNEMONIC2(RM, MOVD, movd, PdZx_WO, Ed, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
3486 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3487 {
3488 /* MMX, greg */
3489 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3490 IEM_MC_BEGIN(0, 1);
3491 IEM_MC_LOCAL(uint64_t, u64Tmp);
3492
3493 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3494 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
3495
3496 IEM_MC_FETCH_GREG_U32_ZX_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3497 IEM_MC_STORE_MREG_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, u64Tmp);
3498 IEM_MC_FPU_TO_MMX_MODE();
3499
3500 IEM_MC_ADVANCE_RIP();
3501 IEM_MC_END();
3502 }
3503 else
3504 {
3505 /* MMX, [mem] */
3506 IEM_MC_BEGIN(0, 2);
3507 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3508 IEM_MC_LOCAL(uint32_t, u32Tmp);
3509
3510 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3511 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3512 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3513 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
3514
3515 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3516 IEM_MC_STORE_MREG_U32_ZX_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, u32Tmp);
3517 IEM_MC_FPU_TO_MMX_MODE();
3518
3519 IEM_MC_ADVANCE_RIP();
3520 IEM_MC_END();
3521 }
3522 }
3523 return VINF_SUCCESS;
3524}
3525
3526FNIEMOP_DEF(iemOp_movd_q_Vy_Ey)
3527{
3528 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3529 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
3530 {
3531 /**
3532 * @opcode 0x6e
3533 * @opcodesub rex.w=1
3534 * @oppfx 0x66
3535 * @opcpuid sse2
3536 * @opgroup og_sse2_simdint_datamove
3537 * @opxcpttype 5
3538 * @optest 64-bit / op1=1 op2=2 -> op1=2
3539 * @optest 64-bit / op1=0 op2=-42 -> op1=-42
3540 */
3541 IEMOP_MNEMONIC2(RM, MOVQ, movq, VqZx_WO, Eq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
3542 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3543 {
3544 /* XMM, greg64 */
3545 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3546 IEM_MC_BEGIN(0, 1);
3547 IEM_MC_LOCAL(uint64_t, u64Tmp);
3548
3549 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3550 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3551
3552 IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3553 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
3554
3555 IEM_MC_ADVANCE_RIP();
3556 IEM_MC_END();
3557 }
3558 else
3559 {
3560 /* XMM, [mem64] */
3561 IEM_MC_BEGIN(0, 2);
3562 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3563 IEM_MC_LOCAL(uint64_t, u64Tmp);
3564
3565 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3566 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3567 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3568 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3569
3570 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3571 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
3572
3573 IEM_MC_ADVANCE_RIP();
3574 IEM_MC_END();
3575 }
3576 }
3577 else
3578 {
3579 /**
3580 * @opdone
3581 * @opcode 0x6e
3582 * @opcodesub rex.w=0
3583 * @oppfx 0x66
3584 * @opcpuid sse2
3585 * @opgroup og_sse2_simdint_datamove
3586 * @opxcpttype 5
3587 * @opfunction iemOp_movd_q_Vy_Ey
3588 * @optest op1=1 op2=2 -> op1=2
3589 * @optest op1=0 op2=-42 -> op1=-42
3590 */
3591 IEMOP_MNEMONIC2(RM, MOVD, movd, VdZx_WO, Ed, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
3592 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3593 {
3594 /* XMM, greg32 */
3595 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3596 IEM_MC_BEGIN(0, 1);
3597 IEM_MC_LOCAL(uint32_t, u32Tmp);
3598
3599 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3600 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3601
3602 IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3603 IEM_MC_STORE_XREG_U32_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
3604
3605 IEM_MC_ADVANCE_RIP();
3606 IEM_MC_END();
3607 }
3608 else
3609 {
3610 /* XMM, [mem32] */
3611 IEM_MC_BEGIN(0, 2);
3612 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3613 IEM_MC_LOCAL(uint32_t, u32Tmp);
3614
3615 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3616 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3617 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3618 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3619
3620 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3621 IEM_MC_STORE_XREG_U32_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
3622
3623 IEM_MC_ADVANCE_RIP();
3624 IEM_MC_END();
3625 }
3626 }
3627 return VINF_SUCCESS;
3628}
3629
3630/* Opcode 0xf3 0x0f 0x6e - invalid */
3631
3632
3633/**
3634 * @opcode 0x6f
3635 * @oppfx none
3636 * @opcpuid mmx
3637 * @opgroup og_mmx_datamove
3638 * @opxcpttype 5
3639 * @optest op1=1 op2=2 -> op1=2 ftw=0xff
3640 * @optest op1=0 op2=-42 -> op1=-42 ftw=0xff
3641 */
3642FNIEMOP_DEF(iemOp_movq_Pq_Qq)
3643{
3644 IEMOP_MNEMONIC2(RM, MOVD, movd, Pq_WO, Qq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
3645 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3646 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3647 {
3648 /*
3649 * Register, register.
3650 */
3651 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3652 IEM_MC_BEGIN(0, 1);
3653 IEM_MC_LOCAL(uint64_t, u64Tmp);
3654
3655 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3656 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
3657
3658 IEM_MC_FETCH_MREG_U64(u64Tmp, bRm & X86_MODRM_RM_MASK);
3659 IEM_MC_STORE_MREG_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, u64Tmp);
3660 IEM_MC_FPU_TO_MMX_MODE();
3661
3662 IEM_MC_ADVANCE_RIP();
3663 IEM_MC_END();
3664 }
3665 else
3666 {
3667 /*
3668 * Register, memory.
3669 */
3670 IEM_MC_BEGIN(0, 2);
3671 IEM_MC_LOCAL(uint64_t, u64Tmp);
3672 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3673
3674 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3675 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3676 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
3677 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
3678
3679 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3680 IEM_MC_STORE_MREG_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, u64Tmp);
3681 IEM_MC_FPU_TO_MMX_MODE();
3682
3683 IEM_MC_ADVANCE_RIP();
3684 IEM_MC_END();
3685 }
3686 return VINF_SUCCESS;
3687}
3688
3689/**
3690 * @opcode 0x6f
3691 * @oppfx 0x66
3692 * @opcpuid sse2
3693 * @opgroup og_sse2_simdint_datamove
3694 * @opxcpttype 1
3695 * @optest op1=1 op2=2 -> op1=2
3696 * @optest op1=0 op2=-42 -> op1=-42
3697 */
3698FNIEMOP_DEF(iemOp_movdqa_Vdq_Wdq)
3699{
3700 IEMOP_MNEMONIC2(RM, MOVDQA, movdqa, Vdq_WO, Wdq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
3701 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3702 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3703 {
3704 /*
3705 * Register, register.
3706 */
3707 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3708 IEM_MC_BEGIN(0, 0);
3709
3710 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3711 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3712
3713 IEM_MC_COPY_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg,
3714 (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3715 IEM_MC_ADVANCE_RIP();
3716 IEM_MC_END();
3717 }
3718 else
3719 {
3720 /*
3721 * Register, memory.
3722 */
3723 IEM_MC_BEGIN(0, 2);
3724 IEM_MC_LOCAL(RTUINT128U, u128Tmp);
3725 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3726
3727 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3728 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3729 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3730 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3731
3732 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(u128Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3733 IEM_MC_STORE_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u128Tmp);
3734
3735 IEM_MC_ADVANCE_RIP();
3736 IEM_MC_END();
3737 }
3738 return VINF_SUCCESS;
3739}
3740
3741/**
3742 * @opcode 0x6f
3743 * @oppfx 0xf3
3744 * @opcpuid sse2
3745 * @opgroup og_sse2_simdint_datamove
3746 * @opxcpttype 4UA
3747 * @optest op1=1 op2=2 -> op1=2
3748 * @optest op1=0 op2=-42 -> op1=-42
3749 */
3750FNIEMOP_DEF(iemOp_movdqu_Vdq_Wdq)
3751{
3752 IEMOP_MNEMONIC2(RM, MOVDQU, movdqu, Vdq_WO, Wdq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
3753 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3754 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3755 {
3756 /*
3757 * Register, register.
3758 */
3759 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3760 IEM_MC_BEGIN(0, 0);
3761 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3762 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3763 IEM_MC_COPY_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg,
3764 (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3765 IEM_MC_ADVANCE_RIP();
3766 IEM_MC_END();
3767 }
3768 else
3769 {
3770 /*
3771 * Register, memory.
3772 */
3773 IEM_MC_BEGIN(0, 2);
3774 IEM_MC_LOCAL(RTUINT128U, u128Tmp);
3775 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3776
3777 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3778 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3779 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3780 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
3781 IEM_MC_FETCH_MEM_U128(u128Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3782 IEM_MC_STORE_XREG_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u128Tmp);
3783
3784 IEM_MC_ADVANCE_RIP();
3785 IEM_MC_END();
3786 }
3787 return VINF_SUCCESS;
3788}
3789
3790
3791/** Opcode 0x0f 0x70 - pshufw Pq, Qq, Ib */
3792FNIEMOP_DEF(iemOp_pshufw_Pq_Qq_Ib)
3793{
3794 IEMOP_MNEMONIC(pshufw_Pq_Qq, "pshufw Pq,Qq,Ib");
3795 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3796 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3797 {
3798 /*
3799 * Register, register.
3800 */
3801 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3802 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3803
3804 IEM_MC_BEGIN(3, 0);
3805 IEM_MC_ARG(uint64_t *, pDst, 0);
3806 IEM_MC_ARG(uint64_t const *, pSrc, 1);
3807 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3808 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT_CHECK_SSE_OR_MMXEXT();
3809 IEM_MC_PREPARE_FPU_USAGE();
3810 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
3811 IEM_MC_REF_MREG_U64_CONST(pSrc, bRm & X86_MODRM_RM_MASK);
3812 IEM_MC_CALL_MMX_AIMPL_3(iemAImpl_pshufw, pDst, pSrc, bEvilArg);
3813 IEM_MC_ADVANCE_RIP();
3814 IEM_MC_END();
3815 }
3816 else
3817 {
3818 /*
3819 * Register, memory.
3820 */
3821 IEM_MC_BEGIN(3, 2);
3822 IEM_MC_ARG(uint64_t *, pDst, 0);
3823 IEM_MC_LOCAL(uint64_t, uSrc);
3824 IEM_MC_ARG_LOCAL_REF(uint64_t const *, pSrc, uSrc, 1);
3825 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3826
3827 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3828 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3829 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3830 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3831 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT_CHECK_SSE_OR_MMXEXT();
3832
3833 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3834 IEM_MC_PREPARE_FPU_USAGE();
3835 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
3836 IEM_MC_CALL_MMX_AIMPL_3(iemAImpl_pshufw, pDst, pSrc, bEvilArg);
3837
3838 IEM_MC_ADVANCE_RIP();
3839 IEM_MC_END();
3840 }
3841 return VINF_SUCCESS;
3842}
3843
3844/** Opcode 0x66 0x0f 0x70 - pshufd Vx, Wx, Ib */
3845FNIEMOP_DEF(iemOp_pshufd_Vx_Wx_Ib)
3846{
3847 IEMOP_MNEMONIC(pshufd_Vx_Wx_Ib, "pshufd Vx,Wx,Ib");
3848 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3849 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3850 {
3851 /*
3852 * Register, register.
3853 */
3854 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3855 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3856
3857 IEM_MC_BEGIN(3, 0);
3858 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3859 IEM_MC_ARG(PCRTUINT128U, pSrc, 1);
3860 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3861 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3862 IEM_MC_PREPARE_SSE_USAGE();
3863 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3864 IEM_MC_REF_XREG_U128_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3865 IEM_MC_CALL_SSE_AIMPL_3(iemAImpl_pshufd, pDst, pSrc, bEvilArg);
3866 IEM_MC_ADVANCE_RIP();
3867 IEM_MC_END();
3868 }
3869 else
3870 {
3871 /*
3872 * Register, memory.
3873 */
3874 IEM_MC_BEGIN(3, 2);
3875 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3876 IEM_MC_LOCAL(RTUINT128U, uSrc);
3877 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, pSrc, uSrc, 1);
3878 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3879
3880 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3881 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3882 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3883 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3884 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3885
3886 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3887 IEM_MC_PREPARE_SSE_USAGE();
3888 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3889 IEM_MC_CALL_SSE_AIMPL_3(iemAImpl_pshufd, pDst, pSrc, bEvilArg);
3890
3891 IEM_MC_ADVANCE_RIP();
3892 IEM_MC_END();
3893 }
3894 return VINF_SUCCESS;
3895}
3896
3897/** Opcode 0xf3 0x0f 0x70 - pshufhw Vx, Wx, Ib */
3898FNIEMOP_DEF(iemOp_pshufhw_Vx_Wx_Ib)
3899{
3900 IEMOP_MNEMONIC(pshufhw_Vx_Wx_Ib, "pshufhw Vx,Wx,Ib");
3901 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3902 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3903 {
3904 /*
3905 * Register, register.
3906 */
3907 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3908 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3909
3910 IEM_MC_BEGIN(3, 0);
3911 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3912 IEM_MC_ARG(PCRTUINT128U, pSrc, 1);
3913 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3914 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3915 IEM_MC_PREPARE_SSE_USAGE();
3916 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3917 IEM_MC_REF_XREG_U128_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3918 IEM_MC_CALL_SSE_AIMPL_3(iemAImpl_pshufhw, pDst, pSrc, bEvilArg);
3919 IEM_MC_ADVANCE_RIP();
3920 IEM_MC_END();
3921 }
3922 else
3923 {
3924 /*
3925 * Register, memory.
3926 */
3927 IEM_MC_BEGIN(3, 2);
3928 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3929 IEM_MC_LOCAL(RTUINT128U, uSrc);
3930 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, pSrc, uSrc, 1);
3931 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3932
3933 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3934 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3935 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3936 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3937 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3938
3939 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3940 IEM_MC_PREPARE_SSE_USAGE();
3941 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3942 IEM_MC_CALL_SSE_AIMPL_3(iemAImpl_pshufhw, pDst, pSrc, bEvilArg);
3943
3944 IEM_MC_ADVANCE_RIP();
3945 IEM_MC_END();
3946 }
3947 return VINF_SUCCESS;
3948}
3949
3950/** Opcode 0xf2 0x0f 0x70 - pshuflw Vx, Wx, Ib */
3951FNIEMOP_DEF(iemOp_pshuflw_Vx_Wx_Ib)
3952{
3953 IEMOP_MNEMONIC(pshuflw_Vx_Wx_Ib, "pshuflw Vx,Wx,Ib");
3954 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3955 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3956 {
3957 /*
3958 * Register, register.
3959 */
3960 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3961 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3962
3963 IEM_MC_BEGIN(3, 0);
3964 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3965 IEM_MC_ARG(PCRTUINT128U, pSrc, 1);
3966 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3967 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3968 IEM_MC_PREPARE_SSE_USAGE();
3969 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3970 IEM_MC_REF_XREG_U128_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3971 IEM_MC_CALL_SSE_AIMPL_3(iemAImpl_pshuflw, pDst, pSrc, bEvilArg);
3972 IEM_MC_ADVANCE_RIP();
3973 IEM_MC_END();
3974 }
3975 else
3976 {
3977 /*
3978 * Register, memory.
3979 */
3980 IEM_MC_BEGIN(3, 2);
3981 IEM_MC_ARG(PRTUINT128U, pDst, 0);
3982 IEM_MC_LOCAL(RTUINT128U, uSrc);
3983 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, pSrc, uSrc, 1);
3984 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
3985
3986 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
3987 uint8_t bEvil; IEM_OPCODE_GET_NEXT_U8(&bEvil);
3988 IEM_MC_ARG_CONST(uint8_t, bEvilArg, /*=*/ bEvil, 2);
3989 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3990 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
3991
3992 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
3993 IEM_MC_PREPARE_SSE_USAGE();
3994 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3995 IEM_MC_CALL_SSE_AIMPL_3(iemAImpl_pshuflw, pDst, pSrc, bEvilArg);
3996
3997 IEM_MC_ADVANCE_RIP();
3998 IEM_MC_END();
3999 }
4000 return VINF_SUCCESS;
4001}
4002
4003
4004/** Opcode 0x0f 0x71 11/2. */
4005FNIEMOP_STUB_1(iemOp_Grp12_psrlw_Nq_Ib, uint8_t, bRm);
4006
4007/** Opcode 0x66 0x0f 0x71 11/2. */
4008FNIEMOP_STUB_1(iemOp_Grp12_psrlw_Ux_Ib, uint8_t, bRm);
4009
4010/** Opcode 0x0f 0x71 11/4. */
4011FNIEMOP_STUB_1(iemOp_Grp12_psraw_Nq_Ib, uint8_t, bRm);
4012
4013/** Opcode 0x66 0x0f 0x71 11/4. */
4014FNIEMOP_STUB_1(iemOp_Grp12_psraw_Ux_Ib, uint8_t, bRm);
4015
4016/** Opcode 0x0f 0x71 11/6. */
4017FNIEMOP_STUB_1(iemOp_Grp12_psllw_Nq_Ib, uint8_t, bRm);
4018
4019/** Opcode 0x66 0x0f 0x71 11/6. */
4020FNIEMOP_STUB_1(iemOp_Grp12_psllw_Ux_Ib, uint8_t, bRm);
4021
4022
4023/**
4024 * Group 12 jump table for register variant.
4025 */
4026IEM_STATIC const PFNIEMOPRM g_apfnGroup12RegReg[] =
4027{
4028 /* /0 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4029 /* /1 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4030 /* /2 */ iemOp_Grp12_psrlw_Nq_Ib, iemOp_Grp12_psrlw_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4031 /* /3 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4032 /* /4 */ iemOp_Grp12_psraw_Nq_Ib, iemOp_Grp12_psraw_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4033 /* /5 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4034 /* /6 */ iemOp_Grp12_psllw_Nq_Ib, iemOp_Grp12_psllw_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4035 /* /7 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8)
4036};
4037AssertCompile(RT_ELEMENTS(g_apfnGroup12RegReg) == 8*4);
4038
4039
4040/** Opcode 0x0f 0x71. */
4041FNIEMOP_DEF(iemOp_Grp12)
4042{
4043 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4044 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4045 /* register, register */
4046 return FNIEMOP_CALL_1(g_apfnGroup12RegReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
4047 + pVCpu->iem.s.idxPrefix], bRm);
4048 return FNIEMOP_CALL_1(iemOp_InvalidWithRMNeedImm8, bRm);
4049}
4050
4051
4052/** Opcode 0x0f 0x72 11/2. */
4053FNIEMOP_STUB_1(iemOp_Grp13_psrld_Nq_Ib, uint8_t, bRm);
4054
4055/** Opcode 0x66 0x0f 0x72 11/2. */
4056FNIEMOP_STUB_1(iemOp_Grp13_psrld_Ux_Ib, uint8_t, bRm);
4057
4058/** Opcode 0x0f 0x72 11/4. */
4059FNIEMOP_STUB_1(iemOp_Grp13_psrad_Nq_Ib, uint8_t, bRm);
4060
4061/** Opcode 0x66 0x0f 0x72 11/4. */
4062FNIEMOP_STUB_1(iemOp_Grp13_psrad_Ux_Ib, uint8_t, bRm);
4063
4064/** Opcode 0x0f 0x72 11/6. */
4065FNIEMOP_STUB_1(iemOp_Grp13_pslld_Nq_Ib, uint8_t, bRm);
4066
4067/** Opcode 0x66 0x0f 0x72 11/6. */
4068FNIEMOP_STUB_1(iemOp_Grp13_pslld_Ux_Ib, uint8_t, bRm);
4069
4070
4071/**
4072 * Group 13 jump table for register variant.
4073 */
4074IEM_STATIC const PFNIEMOPRM g_apfnGroup13RegReg[] =
4075{
4076 /* /0 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4077 /* /1 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4078 /* /2 */ iemOp_Grp13_psrld_Nq_Ib, iemOp_Grp13_psrld_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4079 /* /3 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4080 /* /4 */ iemOp_Grp13_psrad_Nq_Ib, iemOp_Grp13_psrad_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4081 /* /5 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4082 /* /6 */ iemOp_Grp13_pslld_Nq_Ib, iemOp_Grp13_pslld_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4083 /* /7 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8)
4084};
4085AssertCompile(RT_ELEMENTS(g_apfnGroup13RegReg) == 8*4);
4086
4087/** Opcode 0x0f 0x72. */
4088FNIEMOP_DEF(iemOp_Grp13)
4089{
4090 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4091 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4092 /* register, register */
4093 return FNIEMOP_CALL_1(g_apfnGroup13RegReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
4094 + pVCpu->iem.s.idxPrefix], bRm);
4095 return FNIEMOP_CALL_1(iemOp_InvalidWithRMNeedImm8, bRm);
4096}
4097
4098
4099/** Opcode 0x0f 0x73 11/2. */
4100FNIEMOP_STUB_1(iemOp_Grp14_psrlq_Nq_Ib, uint8_t, bRm);
4101
4102/** Opcode 0x66 0x0f 0x73 11/2. */
4103FNIEMOP_STUB_1(iemOp_Grp14_psrlq_Ux_Ib, uint8_t, bRm);
4104
4105/** Opcode 0x66 0x0f 0x73 11/3. */
4106FNIEMOP_STUB_1(iemOp_Grp14_psrldq_Ux_Ib, uint8_t, bRm); //NEXT
4107
4108/** Opcode 0x0f 0x73 11/6. */
4109FNIEMOP_STUB_1(iemOp_Grp14_psllq_Nq_Ib, uint8_t, bRm);
4110
4111/** Opcode 0x66 0x0f 0x73 11/6. */
4112FNIEMOP_STUB_1(iemOp_Grp14_psllq_Ux_Ib, uint8_t, bRm);
4113
4114/** Opcode 0x66 0x0f 0x73 11/7. */
4115FNIEMOP_STUB_1(iemOp_Grp14_pslldq_Ux_Ib, uint8_t, bRm); //NEXT
4116
4117/**
4118 * Group 14 jump table for register variant.
4119 */
4120IEM_STATIC const PFNIEMOPRM g_apfnGroup14RegReg[] =
4121{
4122 /* /0 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4123 /* /1 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4124 /* /2 */ iemOp_Grp14_psrlq_Nq_Ib, iemOp_Grp14_psrlq_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4125 /* /3 */ iemOp_InvalidWithRMNeedImm8, iemOp_Grp14_psrldq_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4126 /* /4 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4127 /* /5 */ IEMOP_X4(iemOp_InvalidWithRMNeedImm8),
4128 /* /6 */ iemOp_Grp14_psllq_Nq_Ib, iemOp_Grp14_psllq_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4129 /* /7 */ iemOp_InvalidWithRMNeedImm8, iemOp_Grp14_pslldq_Ux_Ib, iemOp_InvalidWithRMNeedImm8, iemOp_InvalidWithRMNeedImm8,
4130};
4131AssertCompile(RT_ELEMENTS(g_apfnGroup14RegReg) == 8*4);
4132
4133
4134/** Opcode 0x0f 0x73. */
4135FNIEMOP_DEF(iemOp_Grp14)
4136{
4137 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4138 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4139 /* register, register */
4140 return FNIEMOP_CALL_1(g_apfnGroup14RegReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
4141 + pVCpu->iem.s.idxPrefix], bRm);
4142 return FNIEMOP_CALL_1(iemOp_InvalidWithRMNeedImm8, bRm);
4143}
4144
4145
4146/**
4147 * Common worker for MMX instructions on the form:
4148 * pxxx mm1, mm2/mem64
4149 */
4150FNIEMOP_DEF_1(iemOpCommonMmx_FullFull_To_Full, PCIEMOPMEDIAF2, pImpl)
4151{
4152 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4153 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4154 {
4155 /*
4156 * Register, register.
4157 */
4158 /** @todo testcase: REX.B / REX.R and MMX register indexing. Ignored? */
4159 /** @todo testcase: REX.B / REX.R and segment register indexing. Ignored? */
4160 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4161 IEM_MC_BEGIN(2, 0);
4162 IEM_MC_ARG(uint64_t *, pDst, 0);
4163 IEM_MC_ARG(uint64_t const *, pSrc, 1);
4164 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4165 IEM_MC_PREPARE_FPU_USAGE();
4166 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4167 IEM_MC_REF_MREG_U64_CONST(pSrc, bRm & X86_MODRM_RM_MASK);
4168 IEM_MC_CALL_MMX_AIMPL_2(pImpl->pfnU64, pDst, pSrc);
4169 IEM_MC_ADVANCE_RIP();
4170 IEM_MC_END();
4171 }
4172 else
4173 {
4174 /*
4175 * Register, memory.
4176 */
4177 IEM_MC_BEGIN(2, 2);
4178 IEM_MC_ARG(uint64_t *, pDst, 0);
4179 IEM_MC_LOCAL(uint64_t, uSrc);
4180 IEM_MC_ARG_LOCAL_REF(uint64_t const *, pSrc, uSrc, 1);
4181 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4182
4183 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4184 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4185 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4186 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
4187
4188 IEM_MC_PREPARE_FPU_USAGE();
4189 IEM_MC_REF_MREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4190 IEM_MC_CALL_MMX_AIMPL_2(pImpl->pfnU64, pDst, pSrc);
4191
4192 IEM_MC_ADVANCE_RIP();
4193 IEM_MC_END();
4194 }
4195 return VINF_SUCCESS;
4196}
4197
4198
4199/**
4200 * Common worker for SSE2 instructions on the forms:
4201 * pxxx xmm1, xmm2/mem128
4202 *
4203 * Proper alignment of the 128-bit operand is enforced.
4204 * Exceptions type 4. SSE2 cpuid checks.
4205 */
4206FNIEMOP_DEF_1(iemOpCommonSse2_FullFull_To_Full, PCIEMOPMEDIAF2, pImpl)
4207{
4208 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4209 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4210 {
4211 /*
4212 * Register, register.
4213 */
4214 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4215 IEM_MC_BEGIN(2, 0);
4216 IEM_MC_ARG(PRTUINT128U, pDst, 0);
4217 IEM_MC_ARG(PCRTUINT128U, pSrc, 1);
4218 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4219 IEM_MC_PREPARE_SSE_USAGE();
4220 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4221 IEM_MC_REF_XREG_U128_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4222 IEM_MC_CALL_SSE_AIMPL_2(pImpl->pfnU128, pDst, pSrc);
4223 IEM_MC_ADVANCE_RIP();
4224 IEM_MC_END();
4225 }
4226 else
4227 {
4228 /*
4229 * Register, memory.
4230 */
4231 IEM_MC_BEGIN(2, 2);
4232 IEM_MC_ARG(PRTUINT128U, pDst, 0);
4233 IEM_MC_LOCAL(RTUINT128U, uSrc);
4234 IEM_MC_ARG_LOCAL_REF(PCRTUINT128U, pSrc, uSrc, 1);
4235 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4236
4237 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4238 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4239 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4240 IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
4241
4242 IEM_MC_PREPARE_SSE_USAGE();
4243 IEM_MC_REF_XREG_U128(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4244 IEM_MC_CALL_SSE_AIMPL_2(pImpl->pfnU128, pDst, pSrc);
4245
4246 IEM_MC_ADVANCE_RIP();
4247 IEM_MC_END();
4248 }
4249 return VINF_SUCCESS;
4250}
4251
4252
4253/** Opcode 0x0f 0x74 - pcmpeqb Pq, Qq */
4254FNIEMOP_DEF(iemOp_pcmpeqb_Pq_Qq)
4255{
4256 IEMOP_MNEMONIC(pcmpeqb, "pcmpeqb");
4257 return FNIEMOP_CALL_1(iemOpCommonMmx_FullFull_To_Full, &g_iemAImpl_pcmpeqb);
4258}
4259
4260/** Opcode 0x66 0x0f 0x74 - pcmpeqb Vx, Wx */
4261FNIEMOP_DEF(iemOp_pcmpeqb_Vx_Wx)
4262{
4263 IEMOP_MNEMONIC(vpcmpeqb_Vx_Wx, "pcmpeqb");
4264 return FNIEMOP_CALL_1(iemOpCommonSse2_FullFull_To_Full, &g_iemAImpl_pcmpeqb);
4265}
4266
4267/* Opcode 0xf3 0x0f 0x74 - invalid */
4268/* Opcode 0xf2 0x0f 0x74 - invalid */
4269
4270
4271/** Opcode 0x0f 0x75 - pcmpeqw Pq, Qq */
4272FNIEMOP_DEF(iemOp_pcmpeqw_Pq_Qq)
4273{
4274 IEMOP_MNEMONIC(pcmpeqw, "pcmpeqw");
4275 return FNIEMOP_CALL_1(iemOpCommonMmx_FullFull_To_Full, &g_iemAImpl_pcmpeqw);
4276}
4277
4278/** Opcode 0x66 0x0f 0x75 - pcmpeqw Vx, Wx */
4279FNIEMOP_DEF(iemOp_pcmpeqw_Vx_Wx)
4280{
4281 IEMOP_MNEMONIC(pcmpeqw_Vx_Wx, "pcmpeqw");
4282 return FNIEMOP_CALL_1(iemOpCommonSse2_FullFull_To_Full, &g_iemAImpl_pcmpeqw);
4283}
4284
4285/* Opcode 0xf3 0x0f 0x75 - invalid */
4286/* Opcode 0xf2 0x0f 0x75 - invalid */
4287
4288
4289/** Opcode 0x0f 0x76 - pcmpeqd Pq, Qq */
4290FNIEMOP_DEF(iemOp_pcmpeqd_Pq_Qq)
4291{
4292 IEMOP_MNEMONIC(pcmpeqd, "pcmpeqd");
4293 return FNIEMOP_CALL_1(iemOpCommonMmx_FullFull_To_Full, &g_iemAImpl_pcmpeqd);
4294}
4295
4296/** Opcode 0x66 0x0f 0x76 - pcmpeqd Vx, Wx */
4297FNIEMOP_DEF(iemOp_pcmpeqd_Vx_Wx)
4298{
4299 IEMOP_MNEMONIC(pcmpeqd_Vx_Wx, "vpcmpeqd");
4300 return FNIEMOP_CALL_1(iemOpCommonSse2_FullFull_To_Full, &g_iemAImpl_pcmpeqd);
4301}
4302
4303/* Opcode 0xf3 0x0f 0x76 - invalid */
4304/* Opcode 0xf2 0x0f 0x76 - invalid */
4305
4306
4307/** Opcode 0x0f 0x77 - emms (vex has vzeroall and vzeroupper here) */
4308FNIEMOP_DEF(iemOp_emms)
4309{
4310 IEMOP_MNEMONIC(emms, "emms");
4311 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4312
4313 IEM_MC_BEGIN(0,0);
4314 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
4315 IEM_MC_MAYBE_RAISE_FPU_XCPT();
4316 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
4317 IEM_MC_FPU_FROM_MMX_MODE();
4318 IEM_MC_ADVANCE_RIP();
4319 IEM_MC_END();
4320 return VINF_SUCCESS;
4321}
4322
4323/* Opcode 0x66 0x0f 0x77 - invalid */
4324/* Opcode 0xf3 0x0f 0x77 - invalid */
4325/* Opcode 0xf2 0x0f 0x77 - invalid */
4326
4327/** Opcode 0x0f 0x78 - VMREAD Ey, Gy */
4328#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
4329FNIEMOP_DEF(iemOp_vmread_Ey_Gy)
4330{
4331 IEMOP_MNEMONIC(vmread, "vmread Ey,Gy");
4332 IEMOP_HLP_IN_VMX_OPERATION("vmread", kVmxVDiag_Vmread);
4333 IEMOP_HLP_VMX_INSTR("vmread", kVmxVDiag_Vmread);
4334 IEMMODE const enmEffOpSize = pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT ? IEMMODE_64BIT : IEMMODE_32BIT;
4335
4336 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4337 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4338 {
4339 /*
4340 * Register, register.
4341 */
4342 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
4343 if (enmEffOpSize == IEMMODE_64BIT)
4344 {
4345 IEM_MC_BEGIN(2, 0);
4346 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
4347 IEM_MC_ARG(uint64_t, u64Enc, 1);
4348 IEM_MC_FETCH_GREG_U64(u64Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4349 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4350 IEM_MC_CALL_CIMPL_2(iemCImpl_vmread_reg64, pu64Dst, u64Enc);
4351 IEM_MC_END();
4352 }
4353 else
4354 {
4355 IEM_MC_BEGIN(2, 0);
4356 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
4357 IEM_MC_ARG(uint32_t, u32Enc, 1);
4358 IEM_MC_FETCH_GREG_U32(u32Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4359 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4360 IEM_MC_CALL_CIMPL_2(iemCImpl_vmread_reg32, pu32Dst, u32Enc);
4361 IEM_MC_END();
4362 }
4363 }
4364 else
4365 {
4366 /*
4367 * Memory, register.
4368 */
4369 if (enmEffOpSize == IEMMODE_64BIT)
4370 {
4371 IEM_MC_BEGIN(3, 0);
4372 IEM_MC_ARG(uint8_t, iEffSeg, 0);
4373 IEM_MC_ARG(RTGCPTR, GCPtrVal, 1);
4374 IEM_MC_ARG(uint64_t, u64Enc, 2);
4375 IEM_MC_CALC_RM_EFF_ADDR(GCPtrVal, bRm, 0);
4376 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
4377 IEM_MC_FETCH_GREG_U64(u64Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4378 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
4379 IEM_MC_CALL_CIMPL_3(iemCImpl_vmread_mem_reg64, iEffSeg, GCPtrVal, u64Enc);
4380 IEM_MC_END();
4381 }
4382 else
4383 {
4384 IEM_MC_BEGIN(3, 0);
4385 IEM_MC_ARG(uint8_t, iEffSeg, 0);
4386 IEM_MC_ARG(RTGCPTR, GCPtrVal, 1);
4387 IEM_MC_ARG(uint32_t, u32Enc, 2);
4388 IEM_MC_CALC_RM_EFF_ADDR(GCPtrVal, bRm, 0);
4389 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
4390 IEM_MC_FETCH_GREG_U32(u32Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4391 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
4392 IEM_MC_CALL_CIMPL_3(iemCImpl_vmread_mem_reg32, iEffSeg, GCPtrVal, u32Enc);
4393 IEM_MC_END();
4394 }
4395 }
4396 return VINF_SUCCESS;
4397}
4398#else
4399FNIEMOP_STUB(iemOp_vmread_Ey_Gy);
4400#endif
4401
4402/* Opcode 0x66 0x0f 0x78 - AMD Group 17 */
4403FNIEMOP_STUB(iemOp_AmdGrp17);
4404/* Opcode 0xf3 0x0f 0x78 - invalid */
4405/* Opcode 0xf2 0x0f 0x78 - invalid */
4406
4407/** Opcode 0x0f 0x79 - VMWRITE Gy, Ey */
4408#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
4409FNIEMOP_DEF(iemOp_vmwrite_Gy_Ey)
4410{
4411 IEMOP_MNEMONIC(vmwrite, "vmwrite Gy,Ey");
4412 IEMOP_HLP_IN_VMX_OPERATION("vmwrite", kVmxVDiag_Vmwrite);
4413 IEMOP_HLP_VMX_INSTR("vmwrite", kVmxVDiag_Vmwrite);
4414 IEMMODE const enmEffOpSize = pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT ? IEMMODE_64BIT : IEMMODE_32BIT;
4415
4416 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4417 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4418 {
4419 /*
4420 * Register, register.
4421 */
4422 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
4423 if (enmEffOpSize == IEMMODE_64BIT)
4424 {
4425 IEM_MC_BEGIN(2, 0);
4426 IEM_MC_ARG(uint64_t, u64Val, 0);
4427 IEM_MC_ARG(uint64_t, u64Enc, 1);
4428 IEM_MC_FETCH_GREG_U64(u64Val, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4429 IEM_MC_FETCH_GREG_U64(u64Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4430 IEM_MC_CALL_CIMPL_2(iemCImpl_vmwrite_reg, u64Val, u64Enc);
4431 IEM_MC_END();
4432 }
4433 else
4434 {
4435 IEM_MC_BEGIN(2, 0);
4436 IEM_MC_ARG(uint32_t, u32Val, 0);
4437 IEM_MC_ARG(uint32_t, u32Enc, 1);
4438 IEM_MC_FETCH_GREG_U32(u32Val, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4439 IEM_MC_FETCH_GREG_U32(u32Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4440 IEM_MC_CALL_CIMPL_2(iemCImpl_vmwrite_reg, u32Val, u32Enc);
4441 IEM_MC_END();
4442 }
4443 }
4444 else
4445 {
4446 /*
4447 * Register, memory.
4448 */
4449 if (enmEffOpSize == IEMMODE_64BIT)
4450 {
4451 IEM_MC_BEGIN(3, 0);
4452 IEM_MC_ARG(uint8_t, iEffSeg, 0);
4453 IEM_MC_ARG(RTGCPTR, GCPtrVal, 1);
4454 IEM_MC_ARG(uint64_t, u64Enc, 2);
4455 IEM_MC_CALC_RM_EFF_ADDR(GCPtrVal, bRm, 0);
4456 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
4457 IEM_MC_FETCH_GREG_U64(u64Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4458 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
4459 IEM_MC_CALL_CIMPL_3(iemCImpl_vmwrite_mem, iEffSeg, GCPtrVal, u64Enc);
4460 IEM_MC_END();
4461 }
4462 else
4463 {
4464 IEM_MC_BEGIN(3, 0);
4465 IEM_MC_ARG(uint8_t, iEffSeg, 0);
4466 IEM_MC_ARG(RTGCPTR, GCPtrVal, 1);
4467 IEM_MC_ARG(uint32_t, u32Enc, 2);
4468 IEM_MC_CALC_RM_EFF_ADDR(GCPtrVal, bRm, 0);
4469 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
4470 IEM_MC_FETCH_GREG_U32(u32Enc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4471 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
4472 IEM_MC_CALL_CIMPL_3(iemCImpl_vmwrite_mem, iEffSeg, GCPtrVal, u32Enc);
4473 IEM_MC_END();
4474 }
4475 }
4476 return VINF_SUCCESS;
4477}
4478#else
4479FNIEMOP_STUB(iemOp_vmwrite_Gy_Ey);
4480#endif
4481/* Opcode 0x66 0x0f 0x79 - invalid */
4482/* Opcode 0xf3 0x0f 0x79 - invalid */
4483/* Opcode 0xf2 0x0f 0x79 - invalid */
4484
4485/* Opcode 0x0f 0x7a - invalid */
4486/* Opcode 0x66 0x0f 0x7a - invalid */
4487/* Opcode 0xf3 0x0f 0x7a - invalid */
4488/* Opcode 0xf2 0x0f 0x7a - invalid */
4489
4490/* Opcode 0x0f 0x7b - invalid */
4491/* Opcode 0x66 0x0f 0x7b - invalid */
4492/* Opcode 0xf3 0x0f 0x7b - invalid */
4493/* Opcode 0xf2 0x0f 0x7b - invalid */
4494
4495/* Opcode 0x0f 0x7c - invalid */
4496/** Opcode 0x66 0x0f 0x7c - haddpd Vpd, Wpd */
4497FNIEMOP_STUB(iemOp_haddpd_Vpd_Wpd);
4498/* Opcode 0xf3 0x0f 0x7c - invalid */
4499/** Opcode 0xf2 0x0f 0x7c - haddps Vps, Wps */
4500FNIEMOP_STUB(iemOp_haddps_Vps_Wps);
4501
4502/* Opcode 0x0f 0x7d - invalid */
4503/** Opcode 0x66 0x0f 0x7d - hsubpd Vpd, Wpd */
4504FNIEMOP_STUB(iemOp_hsubpd_Vpd_Wpd);
4505/* Opcode 0xf3 0x0f 0x7d - invalid */
4506/** Opcode 0xf2 0x0f 0x7d - hsubps Vps, Wps */
4507FNIEMOP_STUB(iemOp_hsubps_Vps_Wps);
4508
4509
4510/** Opcode 0x0f 0x7e - movd_q Ey, Pd */
4511FNIEMOP_DEF(iemOp_movd_q_Ey_Pd)
4512{
4513 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4514 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
4515 {
4516 /**
4517 * @opcode 0x7e
4518 * @opcodesub rex.w=1
4519 * @oppfx none
4520 * @opcpuid mmx
4521 * @opgroup og_mmx_datamove
4522 * @opxcpttype 5
4523 * @optest 64-bit / op1=1 op2=2 -> op1=2 ftw=0xff
4524 * @optest 64-bit / op1=0 op2=-42 -> op1=-42 ftw=0xff
4525 */
4526 IEMOP_MNEMONIC2(MR, MOVQ, movq, Eq_WO, Pq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
4527 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4528 {
4529 /* greg64, MMX */
4530 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4531 IEM_MC_BEGIN(0, 1);
4532 IEM_MC_LOCAL(uint64_t, u64Tmp);
4533
4534 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4535 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
4536
4537 IEM_MC_FETCH_MREG_U64(u64Tmp, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4538 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Tmp);
4539 IEM_MC_FPU_TO_MMX_MODE();
4540
4541 IEM_MC_ADVANCE_RIP();
4542 IEM_MC_END();
4543 }
4544 else
4545 {
4546 /* [mem64], MMX */
4547 IEM_MC_BEGIN(0, 2);
4548 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4549 IEM_MC_LOCAL(uint64_t, u64Tmp);
4550
4551 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4552 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4553 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4554 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
4555
4556 IEM_MC_FETCH_MREG_U64(u64Tmp, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4557 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u64Tmp);
4558 IEM_MC_FPU_TO_MMX_MODE();
4559
4560 IEM_MC_ADVANCE_RIP();
4561 IEM_MC_END();
4562 }
4563 }
4564 else
4565 {
4566 /**
4567 * @opdone
4568 * @opcode 0x7e
4569 * @opcodesub rex.w=0
4570 * @oppfx none
4571 * @opcpuid mmx
4572 * @opgroup og_mmx_datamove
4573 * @opxcpttype 5
4574 * @opfunction iemOp_movd_q_Pd_Ey
4575 * @optest op1=1 op2=2 -> op1=2 ftw=0xff
4576 * @optest op1=0 op2=-42 -> op1=-42 ftw=0xff
4577 */
4578 IEMOP_MNEMONIC2(MR, MOVD, movd, Ed_WO, Pd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
4579 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4580 {
4581 /* greg32, MMX */
4582 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4583 IEM_MC_BEGIN(0, 1);
4584 IEM_MC_LOCAL(uint32_t, u32Tmp);
4585
4586 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4587 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
4588
4589 IEM_MC_FETCH_MREG_U32(u32Tmp, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4590 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Tmp);
4591 IEM_MC_FPU_TO_MMX_MODE();
4592
4593 IEM_MC_ADVANCE_RIP();
4594 IEM_MC_END();
4595 }
4596 else
4597 {
4598 /* [mem32], MMX */
4599 IEM_MC_BEGIN(0, 2);
4600 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4601 IEM_MC_LOCAL(uint32_t, u32Tmp);
4602
4603 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4604 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4605 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4606 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
4607
4608 IEM_MC_FETCH_MREG_U32(u32Tmp, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4609 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u32Tmp);
4610 IEM_MC_FPU_TO_MMX_MODE();
4611
4612 IEM_MC_ADVANCE_RIP();
4613 IEM_MC_END();
4614 }
4615 }
4616 return VINF_SUCCESS;
4617
4618}
4619
4620
4621FNIEMOP_DEF(iemOp_movd_q_Ey_Vy)
4622{
4623 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4624 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
4625 {
4626 /**
4627 * @opcode 0x7e
4628 * @opcodesub rex.w=1
4629 * @oppfx 0x66
4630 * @opcpuid sse2
4631 * @opgroup og_sse2_simdint_datamove
4632 * @opxcpttype 5
4633 * @optest 64-bit / op1=1 op2=2 -> op1=2
4634 * @optest 64-bit / op1=0 op2=-42 -> op1=-42
4635 */
4636 IEMOP_MNEMONIC2(MR, MOVQ, movq, Eq_WO, Vq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
4637 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4638 {
4639 /* greg64, XMM */
4640 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4641 IEM_MC_BEGIN(0, 1);
4642 IEM_MC_LOCAL(uint64_t, u64Tmp);
4643
4644 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4645 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
4646
4647 IEM_MC_FETCH_XREG_U64(u64Tmp, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4648 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Tmp);
4649
4650 IEM_MC_ADVANCE_RIP();
4651 IEM_MC_END();
4652 }
4653 else
4654 {
4655 /* [mem64], XMM */
4656 IEM_MC_BEGIN(0, 2);
4657 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4658 IEM_MC_LOCAL(uint64_t, u64Tmp);
4659
4660 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4661 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4662 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4663 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
4664
4665 IEM_MC_FETCH_XREG_U64(u64Tmp, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4666 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u64Tmp);
4667
4668 IEM_MC_ADVANCE_RIP();
4669 IEM_MC_END();
4670 }
4671 }
4672 else
4673 {
4674 /**
4675 * @opdone
4676 * @opcode 0x7e
4677 * @opcodesub rex.w=0
4678 * @oppfx 0x66
4679 * @opcpuid sse2
4680 * @opgroup og_sse2_simdint_datamove
4681 * @opxcpttype 5
4682 * @opfunction iemOp_movd_q_Vy_Ey
4683 * @optest op1=1 op2=2 -> op1=2
4684 * @optest op1=0 op2=-42 -> op1=-42
4685 */
4686 IEMOP_MNEMONIC2(MR, MOVD, movd, Ed_WO, Vd, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OZ_PFX);
4687 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4688 {
4689 /* greg32, XMM */
4690 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4691 IEM_MC_BEGIN(0, 1);
4692 IEM_MC_LOCAL(uint32_t, u32Tmp);
4693
4694 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4695 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
4696
4697 IEM_MC_FETCH_XREG_U32(u32Tmp, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4698 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Tmp);
4699
4700 IEM_MC_ADVANCE_RIP();
4701 IEM_MC_END();
4702 }
4703 else
4704 {
4705 /* [mem32], XMM */
4706 IEM_MC_BEGIN(0, 2);
4707 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4708 IEM_MC_LOCAL(uint32_t, u32Tmp);
4709
4710 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4711 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4712 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4713 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
4714
4715 IEM_MC_FETCH_XREG_U32(u32Tmp, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4716 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u32Tmp);
4717
4718 IEM_MC_ADVANCE_RIP();
4719 IEM_MC_END();
4720 }
4721 }
4722 return VINF_SUCCESS;
4723
4724}
4725
4726/**
4727 * @opcode 0x7e
4728 * @oppfx 0xf3
4729 * @opcpuid sse2
4730 * @opgroup og_sse2_pcksclr_datamove
4731 * @opxcpttype none
4732 * @optest op1=1 op2=2 -> op1=2
4733 * @optest op1=0 op2=-42 -> op1=-42
4734 */
4735FNIEMOP_DEF(iemOp_movq_Vq_Wq)
4736{
4737 IEMOP_MNEMONIC2(RM, MOVQ, movq, VqZx_WO, Wq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
4738 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4739 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4740 {
4741 /*
4742 * Register, register.
4743 */
4744 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4745 IEM_MC_BEGIN(0, 2);
4746 IEM_MC_LOCAL(uint64_t, uSrc);
4747
4748 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4749 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
4750
4751 IEM_MC_FETCH_XREG_U64(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4752 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
4753
4754 IEM_MC_ADVANCE_RIP();
4755 IEM_MC_END();
4756 }
4757 else
4758 {
4759 /*
4760 * Memory, register.
4761 */
4762 IEM_MC_BEGIN(0, 2);
4763 IEM_MC_LOCAL(uint64_t, uSrc);
4764 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4765
4766 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4767 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4768 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4769 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
4770
4771 IEM_MC_FETCH_MEM_U64(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
4772 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
4773
4774 IEM_MC_ADVANCE_RIP();
4775 IEM_MC_END();
4776 }
4777 return VINF_SUCCESS;
4778}
4779
4780/* Opcode 0xf2 0x0f 0x7e - invalid */
4781
4782
4783/** Opcode 0x0f 0x7f - movq Qq, Pq */
4784FNIEMOP_DEF(iemOp_movq_Qq_Pq)
4785{
4786 IEMOP_MNEMONIC(movq_Qq_Pq, "movq Qq,Pq");
4787 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4788 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4789 {
4790 /*
4791 * Register, register.
4792 */
4793 /** @todo testcase: REX.B / REX.R and MMX register indexing. Ignored? */
4794 /** @todo testcase: REX.B / REX.R and segment register indexing. Ignored? */
4795 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4796 IEM_MC_BEGIN(0, 1);
4797 IEM_MC_LOCAL(uint64_t, u64Tmp);
4798 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4799 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
4800 IEM_MC_FETCH_MREG_U64(u64Tmp, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4801 IEM_MC_STORE_MREG_U64(bRm & X86_MODRM_RM_MASK, u64Tmp);
4802 IEM_MC_ADVANCE_RIP();
4803 IEM_MC_END();
4804 }
4805 else
4806 {
4807 /*
4808 * Register, memory.
4809 */
4810 IEM_MC_BEGIN(0, 2);
4811 IEM_MC_LOCAL(uint64_t, u64Tmp);
4812 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4813
4814 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4815 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4816 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
4817 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
4818
4819 IEM_MC_FETCH_MREG_U64(u64Tmp, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4820 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u64Tmp);
4821
4822 IEM_MC_ADVANCE_RIP();
4823 IEM_MC_END();
4824 }
4825 return VINF_SUCCESS;
4826}
4827
4828/** Opcode 0x66 0x0f 0x7f - movdqa Wx,Vx */
4829FNIEMOP_DEF(iemOp_movdqa_Wx_Vx)
4830{
4831 IEMOP_MNEMONIC(movdqa_Wdq_Vdq, "movdqa Wx,Vx");
4832 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4833 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4834 {
4835 /*
4836 * Register, register.
4837 */
4838 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4839 IEM_MC_BEGIN(0, 0);
4840 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4841 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
4842 IEM_MC_COPY_XREG_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB,
4843 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4844 IEM_MC_ADVANCE_RIP();
4845 IEM_MC_END();
4846 }
4847 else
4848 {
4849 /*
4850 * Register, memory.
4851 */
4852 IEM_MC_BEGIN(0, 2);
4853 IEM_MC_LOCAL(RTUINT128U, u128Tmp);
4854 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4855
4856 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4857 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4858 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4859 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
4860
4861 IEM_MC_FETCH_XREG_U128(u128Tmp, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4862 IEM_MC_STORE_MEM_U128_ALIGN_SSE(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u128Tmp);
4863
4864 IEM_MC_ADVANCE_RIP();
4865 IEM_MC_END();
4866 }
4867 return VINF_SUCCESS;
4868}
4869
4870/** Opcode 0xf3 0x0f 0x7f - movdqu Wx,Vx */
4871FNIEMOP_DEF(iemOp_movdqu_Wx_Vx)
4872{
4873 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4874 IEMOP_MNEMONIC(movdqu_Wdq_Vdq, "movdqu Wx,Vx");
4875 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4876 {
4877 /*
4878 * Register, register.
4879 */
4880 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4881 IEM_MC_BEGIN(0, 0);
4882 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4883 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
4884 IEM_MC_COPY_XREG_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB,
4885 ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4886 IEM_MC_ADVANCE_RIP();
4887 IEM_MC_END();
4888 }
4889 else
4890 {
4891 /*
4892 * Register, memory.
4893 */
4894 IEM_MC_BEGIN(0, 2);
4895 IEM_MC_LOCAL(RTUINT128U, u128Tmp);
4896 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4897
4898 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4899 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4900 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
4901 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
4902
4903 IEM_MC_FETCH_XREG_U128(u128Tmp, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
4904 IEM_MC_STORE_MEM_U128(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, u128Tmp);
4905
4906 IEM_MC_ADVANCE_RIP();
4907 IEM_MC_END();
4908 }
4909 return VINF_SUCCESS;
4910}
4911
4912/* Opcode 0xf2 0x0f 0x7f - invalid */
4913
4914
4915
4916/** Opcode 0x0f 0x80. */
4917FNIEMOP_DEF(iemOp_jo_Jv)
4918{
4919 IEMOP_MNEMONIC(jo_Jv, "jo Jv");
4920 IEMOP_HLP_MIN_386();
4921 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
4922 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
4923 {
4924 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
4925 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4926
4927 IEM_MC_BEGIN(0, 0);
4928 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
4929 IEM_MC_REL_JMP_S16(i16Imm);
4930 } IEM_MC_ELSE() {
4931 IEM_MC_ADVANCE_RIP();
4932 } IEM_MC_ENDIF();
4933 IEM_MC_END();
4934 }
4935 else
4936 {
4937 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
4938 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4939
4940 IEM_MC_BEGIN(0, 0);
4941 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
4942 IEM_MC_REL_JMP_S32(i32Imm);
4943 } IEM_MC_ELSE() {
4944 IEM_MC_ADVANCE_RIP();
4945 } IEM_MC_ENDIF();
4946 IEM_MC_END();
4947 }
4948 return VINF_SUCCESS;
4949}
4950
4951
4952/** Opcode 0x0f 0x81. */
4953FNIEMOP_DEF(iemOp_jno_Jv)
4954{
4955 IEMOP_MNEMONIC(jno_Jv, "jno Jv");
4956 IEMOP_HLP_MIN_386();
4957 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
4958 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
4959 {
4960 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
4961 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4962
4963 IEM_MC_BEGIN(0, 0);
4964 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
4965 IEM_MC_ADVANCE_RIP();
4966 } IEM_MC_ELSE() {
4967 IEM_MC_REL_JMP_S16(i16Imm);
4968 } IEM_MC_ENDIF();
4969 IEM_MC_END();
4970 }
4971 else
4972 {
4973 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
4974 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4975
4976 IEM_MC_BEGIN(0, 0);
4977 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
4978 IEM_MC_ADVANCE_RIP();
4979 } IEM_MC_ELSE() {
4980 IEM_MC_REL_JMP_S32(i32Imm);
4981 } IEM_MC_ENDIF();
4982 IEM_MC_END();
4983 }
4984 return VINF_SUCCESS;
4985}
4986
4987
4988/** Opcode 0x0f 0x82. */
4989FNIEMOP_DEF(iemOp_jc_Jv)
4990{
4991 IEMOP_MNEMONIC(jc_Jv, "jc/jb/jnae Jv");
4992 IEMOP_HLP_MIN_386();
4993 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
4994 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
4995 {
4996 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
4997 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4998
4999 IEM_MC_BEGIN(0, 0);
5000 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5001 IEM_MC_REL_JMP_S16(i16Imm);
5002 } IEM_MC_ELSE() {
5003 IEM_MC_ADVANCE_RIP();
5004 } IEM_MC_ENDIF();
5005 IEM_MC_END();
5006 }
5007 else
5008 {
5009 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5010 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5011
5012 IEM_MC_BEGIN(0, 0);
5013 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5014 IEM_MC_REL_JMP_S32(i32Imm);
5015 } IEM_MC_ELSE() {
5016 IEM_MC_ADVANCE_RIP();
5017 } IEM_MC_ENDIF();
5018 IEM_MC_END();
5019 }
5020 return VINF_SUCCESS;
5021}
5022
5023
5024/** Opcode 0x0f 0x83. */
5025FNIEMOP_DEF(iemOp_jnc_Jv)
5026{
5027 IEMOP_MNEMONIC(jnc_Jv, "jnc/jnb/jae Jv");
5028 IEMOP_HLP_MIN_386();
5029 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5030 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5031 {
5032 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5033 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5034
5035 IEM_MC_BEGIN(0, 0);
5036 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5037 IEM_MC_ADVANCE_RIP();
5038 } IEM_MC_ELSE() {
5039 IEM_MC_REL_JMP_S16(i16Imm);
5040 } IEM_MC_ENDIF();
5041 IEM_MC_END();
5042 }
5043 else
5044 {
5045 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5046 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5047
5048 IEM_MC_BEGIN(0, 0);
5049 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5050 IEM_MC_ADVANCE_RIP();
5051 } IEM_MC_ELSE() {
5052 IEM_MC_REL_JMP_S32(i32Imm);
5053 } IEM_MC_ENDIF();
5054 IEM_MC_END();
5055 }
5056 return VINF_SUCCESS;
5057}
5058
5059
5060/** Opcode 0x0f 0x84. */
5061FNIEMOP_DEF(iemOp_je_Jv)
5062{
5063 IEMOP_MNEMONIC(je_Jv, "je/jz Jv");
5064 IEMOP_HLP_MIN_386();
5065 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5066 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5067 {
5068 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5069 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5070
5071 IEM_MC_BEGIN(0, 0);
5072 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5073 IEM_MC_REL_JMP_S16(i16Imm);
5074 } IEM_MC_ELSE() {
5075 IEM_MC_ADVANCE_RIP();
5076 } IEM_MC_ENDIF();
5077 IEM_MC_END();
5078 }
5079 else
5080 {
5081 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5082 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5083
5084 IEM_MC_BEGIN(0, 0);
5085 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5086 IEM_MC_REL_JMP_S32(i32Imm);
5087 } IEM_MC_ELSE() {
5088 IEM_MC_ADVANCE_RIP();
5089 } IEM_MC_ENDIF();
5090 IEM_MC_END();
5091 }
5092 return VINF_SUCCESS;
5093}
5094
5095
5096/** Opcode 0x0f 0x85. */
5097FNIEMOP_DEF(iemOp_jne_Jv)
5098{
5099 IEMOP_MNEMONIC(jne_Jv, "jne/jnz Jv");
5100 IEMOP_HLP_MIN_386();
5101 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5102 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5103 {
5104 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5105 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5106
5107 IEM_MC_BEGIN(0, 0);
5108 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5109 IEM_MC_ADVANCE_RIP();
5110 } IEM_MC_ELSE() {
5111 IEM_MC_REL_JMP_S16(i16Imm);
5112 } IEM_MC_ENDIF();
5113 IEM_MC_END();
5114 }
5115 else
5116 {
5117 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5118 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5119
5120 IEM_MC_BEGIN(0, 0);
5121 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5122 IEM_MC_ADVANCE_RIP();
5123 } IEM_MC_ELSE() {
5124 IEM_MC_REL_JMP_S32(i32Imm);
5125 } IEM_MC_ENDIF();
5126 IEM_MC_END();
5127 }
5128 return VINF_SUCCESS;
5129}
5130
5131
5132/** Opcode 0x0f 0x86. */
5133FNIEMOP_DEF(iemOp_jbe_Jv)
5134{
5135 IEMOP_MNEMONIC(jbe_Jv, "jbe/jna Jv");
5136 IEMOP_HLP_MIN_386();
5137 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5138 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5139 {
5140 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5141 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5142
5143 IEM_MC_BEGIN(0, 0);
5144 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5145 IEM_MC_REL_JMP_S16(i16Imm);
5146 } IEM_MC_ELSE() {
5147 IEM_MC_ADVANCE_RIP();
5148 } IEM_MC_ENDIF();
5149 IEM_MC_END();
5150 }
5151 else
5152 {
5153 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5154 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5155
5156 IEM_MC_BEGIN(0, 0);
5157 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5158 IEM_MC_REL_JMP_S32(i32Imm);
5159 } IEM_MC_ELSE() {
5160 IEM_MC_ADVANCE_RIP();
5161 } IEM_MC_ENDIF();
5162 IEM_MC_END();
5163 }
5164 return VINF_SUCCESS;
5165}
5166
5167
5168/** Opcode 0x0f 0x87. */
5169FNIEMOP_DEF(iemOp_jnbe_Jv)
5170{
5171 IEMOP_MNEMONIC(ja_Jv, "jnbe/ja Jv");
5172 IEMOP_HLP_MIN_386();
5173 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5174 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5175 {
5176 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5177 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5178
5179 IEM_MC_BEGIN(0, 0);
5180 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5181 IEM_MC_ADVANCE_RIP();
5182 } IEM_MC_ELSE() {
5183 IEM_MC_REL_JMP_S16(i16Imm);
5184 } IEM_MC_ENDIF();
5185 IEM_MC_END();
5186 }
5187 else
5188 {
5189 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5190 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5191
5192 IEM_MC_BEGIN(0, 0);
5193 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5194 IEM_MC_ADVANCE_RIP();
5195 } IEM_MC_ELSE() {
5196 IEM_MC_REL_JMP_S32(i32Imm);
5197 } IEM_MC_ENDIF();
5198 IEM_MC_END();
5199 }
5200 return VINF_SUCCESS;
5201}
5202
5203
5204/** Opcode 0x0f 0x88. */
5205FNIEMOP_DEF(iemOp_js_Jv)
5206{
5207 IEMOP_MNEMONIC(js_Jv, "js Jv");
5208 IEMOP_HLP_MIN_386();
5209 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5210 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5211 {
5212 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5213 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5214
5215 IEM_MC_BEGIN(0, 0);
5216 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5217 IEM_MC_REL_JMP_S16(i16Imm);
5218 } IEM_MC_ELSE() {
5219 IEM_MC_ADVANCE_RIP();
5220 } IEM_MC_ENDIF();
5221 IEM_MC_END();
5222 }
5223 else
5224 {
5225 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5226 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5227
5228 IEM_MC_BEGIN(0, 0);
5229 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5230 IEM_MC_REL_JMP_S32(i32Imm);
5231 } IEM_MC_ELSE() {
5232 IEM_MC_ADVANCE_RIP();
5233 } IEM_MC_ENDIF();
5234 IEM_MC_END();
5235 }
5236 return VINF_SUCCESS;
5237}
5238
5239
5240/** Opcode 0x0f 0x89. */
5241FNIEMOP_DEF(iemOp_jns_Jv)
5242{
5243 IEMOP_MNEMONIC(jns_Jv, "jns Jv");
5244 IEMOP_HLP_MIN_386();
5245 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5246 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5247 {
5248 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5249 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5250
5251 IEM_MC_BEGIN(0, 0);
5252 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5253 IEM_MC_ADVANCE_RIP();
5254 } IEM_MC_ELSE() {
5255 IEM_MC_REL_JMP_S16(i16Imm);
5256 } IEM_MC_ENDIF();
5257 IEM_MC_END();
5258 }
5259 else
5260 {
5261 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5262 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5263
5264 IEM_MC_BEGIN(0, 0);
5265 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5266 IEM_MC_ADVANCE_RIP();
5267 } IEM_MC_ELSE() {
5268 IEM_MC_REL_JMP_S32(i32Imm);
5269 } IEM_MC_ENDIF();
5270 IEM_MC_END();
5271 }
5272 return VINF_SUCCESS;
5273}
5274
5275
5276/** Opcode 0x0f 0x8a. */
5277FNIEMOP_DEF(iemOp_jp_Jv)
5278{
5279 IEMOP_MNEMONIC(jp_Jv, "jp Jv");
5280 IEMOP_HLP_MIN_386();
5281 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5282 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5283 {
5284 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5285 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5286
5287 IEM_MC_BEGIN(0, 0);
5288 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5289 IEM_MC_REL_JMP_S16(i16Imm);
5290 } IEM_MC_ELSE() {
5291 IEM_MC_ADVANCE_RIP();
5292 } IEM_MC_ENDIF();
5293 IEM_MC_END();
5294 }
5295 else
5296 {
5297 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5298 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5299
5300 IEM_MC_BEGIN(0, 0);
5301 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5302 IEM_MC_REL_JMP_S32(i32Imm);
5303 } IEM_MC_ELSE() {
5304 IEM_MC_ADVANCE_RIP();
5305 } IEM_MC_ENDIF();
5306 IEM_MC_END();
5307 }
5308 return VINF_SUCCESS;
5309}
5310
5311
5312/** Opcode 0x0f 0x8b. */
5313FNIEMOP_DEF(iemOp_jnp_Jv)
5314{
5315 IEMOP_MNEMONIC(jnp_Jv, "jnp Jv");
5316 IEMOP_HLP_MIN_386();
5317 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5318 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5319 {
5320 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5321 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5322
5323 IEM_MC_BEGIN(0, 0);
5324 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5325 IEM_MC_ADVANCE_RIP();
5326 } IEM_MC_ELSE() {
5327 IEM_MC_REL_JMP_S16(i16Imm);
5328 } IEM_MC_ENDIF();
5329 IEM_MC_END();
5330 }
5331 else
5332 {
5333 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5334 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5335
5336 IEM_MC_BEGIN(0, 0);
5337 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5338 IEM_MC_ADVANCE_RIP();
5339 } IEM_MC_ELSE() {
5340 IEM_MC_REL_JMP_S32(i32Imm);
5341 } IEM_MC_ENDIF();
5342 IEM_MC_END();
5343 }
5344 return VINF_SUCCESS;
5345}
5346
5347
5348/** Opcode 0x0f 0x8c. */
5349FNIEMOP_DEF(iemOp_jl_Jv)
5350{
5351 IEMOP_MNEMONIC(jl_Jv, "jl/jnge Jv");
5352 IEMOP_HLP_MIN_386();
5353 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5354 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5355 {
5356 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5357 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5358
5359 IEM_MC_BEGIN(0, 0);
5360 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
5361 IEM_MC_REL_JMP_S16(i16Imm);
5362 } IEM_MC_ELSE() {
5363 IEM_MC_ADVANCE_RIP();
5364 } IEM_MC_ENDIF();
5365 IEM_MC_END();
5366 }
5367 else
5368 {
5369 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5370 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5371
5372 IEM_MC_BEGIN(0, 0);
5373 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
5374 IEM_MC_REL_JMP_S32(i32Imm);
5375 } IEM_MC_ELSE() {
5376 IEM_MC_ADVANCE_RIP();
5377 } IEM_MC_ENDIF();
5378 IEM_MC_END();
5379 }
5380 return VINF_SUCCESS;
5381}
5382
5383
5384/** Opcode 0x0f 0x8d. */
5385FNIEMOP_DEF(iemOp_jnl_Jv)
5386{
5387 IEMOP_MNEMONIC(jge_Jv, "jnl/jge Jv");
5388 IEMOP_HLP_MIN_386();
5389 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5390 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5391 {
5392 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5393 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5394
5395 IEM_MC_BEGIN(0, 0);
5396 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
5397 IEM_MC_ADVANCE_RIP();
5398 } IEM_MC_ELSE() {
5399 IEM_MC_REL_JMP_S16(i16Imm);
5400 } IEM_MC_ENDIF();
5401 IEM_MC_END();
5402 }
5403 else
5404 {
5405 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5406 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5407
5408 IEM_MC_BEGIN(0, 0);
5409 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
5410 IEM_MC_ADVANCE_RIP();
5411 } IEM_MC_ELSE() {
5412 IEM_MC_REL_JMP_S32(i32Imm);
5413 } IEM_MC_ENDIF();
5414 IEM_MC_END();
5415 }
5416 return VINF_SUCCESS;
5417}
5418
5419
5420/** Opcode 0x0f 0x8e. */
5421FNIEMOP_DEF(iemOp_jle_Jv)
5422{
5423 IEMOP_MNEMONIC(jle_Jv, "jle/jng Jv");
5424 IEMOP_HLP_MIN_386();
5425 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5426 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5427 {
5428 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5429 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5430
5431 IEM_MC_BEGIN(0, 0);
5432 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
5433 IEM_MC_REL_JMP_S16(i16Imm);
5434 } IEM_MC_ELSE() {
5435 IEM_MC_ADVANCE_RIP();
5436 } IEM_MC_ENDIF();
5437 IEM_MC_END();
5438 }
5439 else
5440 {
5441 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5442 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5443
5444 IEM_MC_BEGIN(0, 0);
5445 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
5446 IEM_MC_REL_JMP_S32(i32Imm);
5447 } IEM_MC_ELSE() {
5448 IEM_MC_ADVANCE_RIP();
5449 } IEM_MC_ENDIF();
5450 IEM_MC_END();
5451 }
5452 return VINF_SUCCESS;
5453}
5454
5455
5456/** Opcode 0x0f 0x8f. */
5457FNIEMOP_DEF(iemOp_jnle_Jv)
5458{
5459 IEMOP_MNEMONIC(jg_Jv, "jnle/jg Jv");
5460 IEMOP_HLP_MIN_386();
5461 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
5462 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
5463 {
5464 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
5465 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5466
5467 IEM_MC_BEGIN(0, 0);
5468 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
5469 IEM_MC_ADVANCE_RIP();
5470 } IEM_MC_ELSE() {
5471 IEM_MC_REL_JMP_S16(i16Imm);
5472 } IEM_MC_ENDIF();
5473 IEM_MC_END();
5474 }
5475 else
5476 {
5477 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
5478 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5479
5480 IEM_MC_BEGIN(0, 0);
5481 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
5482 IEM_MC_ADVANCE_RIP();
5483 } IEM_MC_ELSE() {
5484 IEM_MC_REL_JMP_S32(i32Imm);
5485 } IEM_MC_ENDIF();
5486 IEM_MC_END();
5487 }
5488 return VINF_SUCCESS;
5489}
5490
5491
5492/** Opcode 0x0f 0x90. */
5493FNIEMOP_DEF(iemOp_seto_Eb)
5494{
5495 IEMOP_MNEMONIC(seto_Eb, "seto Eb");
5496 IEMOP_HLP_MIN_386();
5497 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5498
5499 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5500 * any way. AMD says it's "unused", whatever that means. We're
5501 * ignoring for now. */
5502 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5503 {
5504 /* register target */
5505 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5506 IEM_MC_BEGIN(0, 0);
5507 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
5508 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5509 } IEM_MC_ELSE() {
5510 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5511 } IEM_MC_ENDIF();
5512 IEM_MC_ADVANCE_RIP();
5513 IEM_MC_END();
5514 }
5515 else
5516 {
5517 /* memory target */
5518 IEM_MC_BEGIN(0, 1);
5519 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5520 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5521 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5522 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
5523 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5524 } IEM_MC_ELSE() {
5525 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5526 } IEM_MC_ENDIF();
5527 IEM_MC_ADVANCE_RIP();
5528 IEM_MC_END();
5529 }
5530 return VINF_SUCCESS;
5531}
5532
5533
5534/** Opcode 0x0f 0x91. */
5535FNIEMOP_DEF(iemOp_setno_Eb)
5536{
5537 IEMOP_MNEMONIC(setno_Eb, "setno Eb");
5538 IEMOP_HLP_MIN_386();
5539 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5540
5541 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5542 * any way. AMD says it's "unused", whatever that means. We're
5543 * ignoring for now. */
5544 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5545 {
5546 /* register target */
5547 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5548 IEM_MC_BEGIN(0, 0);
5549 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
5550 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5551 } IEM_MC_ELSE() {
5552 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5553 } IEM_MC_ENDIF();
5554 IEM_MC_ADVANCE_RIP();
5555 IEM_MC_END();
5556 }
5557 else
5558 {
5559 /* memory target */
5560 IEM_MC_BEGIN(0, 1);
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_IF_EFL_BIT_SET(X86_EFL_OF) {
5565 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5566 } IEM_MC_ELSE() {
5567 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5568 } IEM_MC_ENDIF();
5569 IEM_MC_ADVANCE_RIP();
5570 IEM_MC_END();
5571 }
5572 return VINF_SUCCESS;
5573}
5574
5575
5576/** Opcode 0x0f 0x92. */
5577FNIEMOP_DEF(iemOp_setc_Eb)
5578{
5579 IEMOP_MNEMONIC(setc_Eb, "setc Eb");
5580 IEMOP_HLP_MIN_386();
5581 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5582
5583 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5584 * any way. AMD says it's "unused", whatever that means. We're
5585 * ignoring for now. */
5586 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5587 {
5588 /* register target */
5589 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5590 IEM_MC_BEGIN(0, 0);
5591 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5592 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5593 } IEM_MC_ELSE() {
5594 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5595 } IEM_MC_ENDIF();
5596 IEM_MC_ADVANCE_RIP();
5597 IEM_MC_END();
5598 }
5599 else
5600 {
5601 /* memory target */
5602 IEM_MC_BEGIN(0, 1);
5603 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5604 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5605 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5606 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5607 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5608 } IEM_MC_ELSE() {
5609 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5610 } IEM_MC_ENDIF();
5611 IEM_MC_ADVANCE_RIP();
5612 IEM_MC_END();
5613 }
5614 return VINF_SUCCESS;
5615}
5616
5617
5618/** Opcode 0x0f 0x93. */
5619FNIEMOP_DEF(iemOp_setnc_Eb)
5620{
5621 IEMOP_MNEMONIC(setnc_Eb, "setnc Eb");
5622 IEMOP_HLP_MIN_386();
5623 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5624
5625 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5626 * any way. AMD says it's "unused", whatever that means. We're
5627 * ignoring for now. */
5628 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5629 {
5630 /* register target */
5631 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5632 IEM_MC_BEGIN(0, 0);
5633 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5634 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5635 } IEM_MC_ELSE() {
5636 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5637 } IEM_MC_ENDIF();
5638 IEM_MC_ADVANCE_RIP();
5639 IEM_MC_END();
5640 }
5641 else
5642 {
5643 /* memory target */
5644 IEM_MC_BEGIN(0, 1);
5645 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5646 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5647 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5648 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
5649 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5650 } IEM_MC_ELSE() {
5651 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5652 } IEM_MC_ENDIF();
5653 IEM_MC_ADVANCE_RIP();
5654 IEM_MC_END();
5655 }
5656 return VINF_SUCCESS;
5657}
5658
5659
5660/** Opcode 0x0f 0x94. */
5661FNIEMOP_DEF(iemOp_sete_Eb)
5662{
5663 IEMOP_MNEMONIC(sete_Eb, "sete Eb");
5664 IEMOP_HLP_MIN_386();
5665 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5666
5667 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5668 * any way. AMD says it's "unused", whatever that means. We're
5669 * ignoring for now. */
5670 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5671 {
5672 /* register target */
5673 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5674 IEM_MC_BEGIN(0, 0);
5675 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5676 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5677 } IEM_MC_ELSE() {
5678 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5679 } IEM_MC_ENDIF();
5680 IEM_MC_ADVANCE_RIP();
5681 IEM_MC_END();
5682 }
5683 else
5684 {
5685 /* memory target */
5686 IEM_MC_BEGIN(0, 1);
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_IF_EFL_BIT_SET(X86_EFL_ZF) {
5691 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5692 } IEM_MC_ELSE() {
5693 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5694 } IEM_MC_ENDIF();
5695 IEM_MC_ADVANCE_RIP();
5696 IEM_MC_END();
5697 }
5698 return VINF_SUCCESS;
5699}
5700
5701
5702/** Opcode 0x0f 0x95. */
5703FNIEMOP_DEF(iemOp_setne_Eb)
5704{
5705 IEMOP_MNEMONIC(setne_Eb, "setne Eb");
5706 IEMOP_HLP_MIN_386();
5707 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5708
5709 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5710 * any way. AMD says it's "unused", whatever that means. We're
5711 * ignoring for now. */
5712 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5713 {
5714 /* register target */
5715 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5716 IEM_MC_BEGIN(0, 0);
5717 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5718 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5719 } IEM_MC_ELSE() {
5720 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5721 } IEM_MC_ENDIF();
5722 IEM_MC_ADVANCE_RIP();
5723 IEM_MC_END();
5724 }
5725 else
5726 {
5727 /* memory target */
5728 IEM_MC_BEGIN(0, 1);
5729 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5730 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5731 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5732 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
5733 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5734 } IEM_MC_ELSE() {
5735 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5736 } IEM_MC_ENDIF();
5737 IEM_MC_ADVANCE_RIP();
5738 IEM_MC_END();
5739 }
5740 return VINF_SUCCESS;
5741}
5742
5743
5744/** Opcode 0x0f 0x96. */
5745FNIEMOP_DEF(iemOp_setbe_Eb)
5746{
5747 IEMOP_MNEMONIC(setbe_Eb, "setbe Eb");
5748 IEMOP_HLP_MIN_386();
5749 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5750
5751 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5752 * any way. AMD says it's "unused", whatever that means. We're
5753 * ignoring for now. */
5754 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5755 {
5756 /* register target */
5757 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5758 IEM_MC_BEGIN(0, 0);
5759 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5760 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5761 } IEM_MC_ELSE() {
5762 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5763 } IEM_MC_ENDIF();
5764 IEM_MC_ADVANCE_RIP();
5765 IEM_MC_END();
5766 }
5767 else
5768 {
5769 /* memory target */
5770 IEM_MC_BEGIN(0, 1);
5771 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5772 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5773 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5774 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5775 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5776 } IEM_MC_ELSE() {
5777 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5778 } IEM_MC_ENDIF();
5779 IEM_MC_ADVANCE_RIP();
5780 IEM_MC_END();
5781 }
5782 return VINF_SUCCESS;
5783}
5784
5785
5786/** Opcode 0x0f 0x97. */
5787FNIEMOP_DEF(iemOp_setnbe_Eb)
5788{
5789 IEMOP_MNEMONIC(setnbe_Eb, "setnbe Eb");
5790 IEMOP_HLP_MIN_386();
5791 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5792
5793 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5794 * any way. AMD says it's "unused", whatever that means. We're
5795 * ignoring for now. */
5796 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5797 {
5798 /* register target */
5799 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5800 IEM_MC_BEGIN(0, 0);
5801 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5802 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5803 } IEM_MC_ELSE() {
5804 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5805 } IEM_MC_ENDIF();
5806 IEM_MC_ADVANCE_RIP();
5807 IEM_MC_END();
5808 }
5809 else
5810 {
5811 /* memory target */
5812 IEM_MC_BEGIN(0, 1);
5813 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5814 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5815 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5816 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
5817 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5818 } IEM_MC_ELSE() {
5819 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5820 } IEM_MC_ENDIF();
5821 IEM_MC_ADVANCE_RIP();
5822 IEM_MC_END();
5823 }
5824 return VINF_SUCCESS;
5825}
5826
5827
5828/** Opcode 0x0f 0x98. */
5829FNIEMOP_DEF(iemOp_sets_Eb)
5830{
5831 IEMOP_MNEMONIC(sets_Eb, "sets Eb");
5832 IEMOP_HLP_MIN_386();
5833 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5834
5835 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5836 * any way. AMD says it's "unused", whatever that means. We're
5837 * ignoring for now. */
5838 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5839 {
5840 /* register target */
5841 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5842 IEM_MC_BEGIN(0, 0);
5843 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5844 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5845 } IEM_MC_ELSE() {
5846 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5847 } IEM_MC_ENDIF();
5848 IEM_MC_ADVANCE_RIP();
5849 IEM_MC_END();
5850 }
5851 else
5852 {
5853 /* memory target */
5854 IEM_MC_BEGIN(0, 1);
5855 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5856 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5857 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5858 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5859 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5860 } IEM_MC_ELSE() {
5861 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5862 } IEM_MC_ENDIF();
5863 IEM_MC_ADVANCE_RIP();
5864 IEM_MC_END();
5865 }
5866 return VINF_SUCCESS;
5867}
5868
5869
5870/** Opcode 0x0f 0x99. */
5871FNIEMOP_DEF(iemOp_setns_Eb)
5872{
5873 IEMOP_MNEMONIC(setns_Eb, "setns Eb");
5874 IEMOP_HLP_MIN_386();
5875 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5876
5877 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5878 * any way. AMD says it's "unused", whatever that means. We're
5879 * ignoring for now. */
5880 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5881 {
5882 /* register target */
5883 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5884 IEM_MC_BEGIN(0, 0);
5885 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5886 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5887 } IEM_MC_ELSE() {
5888 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5889 } IEM_MC_ENDIF();
5890 IEM_MC_ADVANCE_RIP();
5891 IEM_MC_END();
5892 }
5893 else
5894 {
5895 /* memory target */
5896 IEM_MC_BEGIN(0, 1);
5897 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5898 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5899 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5900 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
5901 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5902 } IEM_MC_ELSE() {
5903 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5904 } IEM_MC_ENDIF();
5905 IEM_MC_ADVANCE_RIP();
5906 IEM_MC_END();
5907 }
5908 return VINF_SUCCESS;
5909}
5910
5911
5912/** Opcode 0x0f 0x9a. */
5913FNIEMOP_DEF(iemOp_setp_Eb)
5914{
5915 IEMOP_MNEMONIC(setp_Eb, "setp Eb");
5916 IEMOP_HLP_MIN_386();
5917 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5918
5919 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5920 * any way. AMD says it's "unused", whatever that means. We're
5921 * ignoring for now. */
5922 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5923 {
5924 /* register target */
5925 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5926 IEM_MC_BEGIN(0, 0);
5927 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5928 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5929 } IEM_MC_ELSE() {
5930 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5931 } IEM_MC_ENDIF();
5932 IEM_MC_ADVANCE_RIP();
5933 IEM_MC_END();
5934 }
5935 else
5936 {
5937 /* memory target */
5938 IEM_MC_BEGIN(0, 1);
5939 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5940 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5941 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5942 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5943 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5944 } IEM_MC_ELSE() {
5945 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5946 } IEM_MC_ENDIF();
5947 IEM_MC_ADVANCE_RIP();
5948 IEM_MC_END();
5949 }
5950 return VINF_SUCCESS;
5951}
5952
5953
5954/** Opcode 0x0f 0x9b. */
5955FNIEMOP_DEF(iemOp_setnp_Eb)
5956{
5957 IEMOP_MNEMONIC(setnp_Eb, "setnp Eb");
5958 IEMOP_HLP_MIN_386();
5959 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
5960
5961 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
5962 * any way. AMD says it's "unused", whatever that means. We're
5963 * ignoring for now. */
5964 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
5965 {
5966 /* register target */
5967 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5968 IEM_MC_BEGIN(0, 0);
5969 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5970 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
5971 } IEM_MC_ELSE() {
5972 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
5973 } IEM_MC_ENDIF();
5974 IEM_MC_ADVANCE_RIP();
5975 IEM_MC_END();
5976 }
5977 else
5978 {
5979 /* memory target */
5980 IEM_MC_BEGIN(0, 1);
5981 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
5982 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
5983 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5984 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
5985 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
5986 } IEM_MC_ELSE() {
5987 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
5988 } IEM_MC_ENDIF();
5989 IEM_MC_ADVANCE_RIP();
5990 IEM_MC_END();
5991 }
5992 return VINF_SUCCESS;
5993}
5994
5995
5996/** Opcode 0x0f 0x9c. */
5997FNIEMOP_DEF(iemOp_setl_Eb)
5998{
5999 IEMOP_MNEMONIC(setl_Eb, "setl Eb");
6000 IEMOP_HLP_MIN_386();
6001 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6002
6003 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
6004 * any way. AMD says it's "unused", whatever that means. We're
6005 * ignoring for now. */
6006 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6007 {
6008 /* register target */
6009 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6010 IEM_MC_BEGIN(0, 0);
6011 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
6012 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
6013 } IEM_MC_ELSE() {
6014 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
6015 } IEM_MC_ENDIF();
6016 IEM_MC_ADVANCE_RIP();
6017 IEM_MC_END();
6018 }
6019 else
6020 {
6021 /* memory target */
6022 IEM_MC_BEGIN(0, 1);
6023 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6024 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6025 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6026 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
6027 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
6028 } IEM_MC_ELSE() {
6029 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6030 } IEM_MC_ENDIF();
6031 IEM_MC_ADVANCE_RIP();
6032 IEM_MC_END();
6033 }
6034 return VINF_SUCCESS;
6035}
6036
6037
6038/** Opcode 0x0f 0x9d. */
6039FNIEMOP_DEF(iemOp_setnl_Eb)
6040{
6041 IEMOP_MNEMONIC(setnl_Eb, "setnl Eb");
6042 IEMOP_HLP_MIN_386();
6043 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6044
6045 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
6046 * any way. AMD says it's "unused", whatever that means. We're
6047 * ignoring for now. */
6048 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6049 {
6050 /* register target */
6051 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6052 IEM_MC_BEGIN(0, 0);
6053 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
6054 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
6055 } IEM_MC_ELSE() {
6056 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
6057 } IEM_MC_ENDIF();
6058 IEM_MC_ADVANCE_RIP();
6059 IEM_MC_END();
6060 }
6061 else
6062 {
6063 /* memory target */
6064 IEM_MC_BEGIN(0, 1);
6065 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6066 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6067 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6068 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
6069 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6070 } IEM_MC_ELSE() {
6071 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
6072 } IEM_MC_ENDIF();
6073 IEM_MC_ADVANCE_RIP();
6074 IEM_MC_END();
6075 }
6076 return VINF_SUCCESS;
6077}
6078
6079
6080/** Opcode 0x0f 0x9e. */
6081FNIEMOP_DEF(iemOp_setle_Eb)
6082{
6083 IEMOP_MNEMONIC(setle_Eb, "setle Eb");
6084 IEMOP_HLP_MIN_386();
6085 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6086
6087 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
6088 * any way. AMD says it's "unused", whatever that means. We're
6089 * ignoring for now. */
6090 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6091 {
6092 /* register target */
6093 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6094 IEM_MC_BEGIN(0, 0);
6095 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
6096 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
6097 } IEM_MC_ELSE() {
6098 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
6099 } IEM_MC_ENDIF();
6100 IEM_MC_ADVANCE_RIP();
6101 IEM_MC_END();
6102 }
6103 else
6104 {
6105 /* memory target */
6106 IEM_MC_BEGIN(0, 1);
6107 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6108 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6109 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6110 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
6111 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
6112 } IEM_MC_ELSE() {
6113 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6114 } IEM_MC_ENDIF();
6115 IEM_MC_ADVANCE_RIP();
6116 IEM_MC_END();
6117 }
6118 return VINF_SUCCESS;
6119}
6120
6121
6122/** Opcode 0x0f 0x9f. */
6123FNIEMOP_DEF(iemOp_setnle_Eb)
6124{
6125 IEMOP_MNEMONIC(setnle_Eb, "setnle Eb");
6126 IEMOP_HLP_MIN_386();
6127 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6128
6129 /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
6130 * any way. AMD says it's "unused", whatever that means. We're
6131 * ignoring for now. */
6132 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6133 {
6134 /* register target */
6135 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6136 IEM_MC_BEGIN(0, 0);
6137 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
6138 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 0);
6139 } IEM_MC_ELSE() {
6140 IEM_MC_STORE_GREG_U8_CONST((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, 1);
6141 } IEM_MC_ENDIF();
6142 IEM_MC_ADVANCE_RIP();
6143 IEM_MC_END();
6144 }
6145 else
6146 {
6147 /* memory target */
6148 IEM_MC_BEGIN(0, 1);
6149 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6150 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6151 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6152 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
6153 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6154 } IEM_MC_ELSE() {
6155 IEM_MC_STORE_MEM_U8_CONST(pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1);
6156 } IEM_MC_ENDIF();
6157 IEM_MC_ADVANCE_RIP();
6158 IEM_MC_END();
6159 }
6160 return VINF_SUCCESS;
6161}
6162
6163
6164/**
6165 * Common 'push segment-register' helper.
6166 */
6167FNIEMOP_DEF_1(iemOpCommonPushSReg, uint8_t, iReg)
6168{
6169 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6170 Assert(iReg < X86_SREG_FS || pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT);
6171 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6172
6173 switch (pVCpu->iem.s.enmEffOpSize)
6174 {
6175 case IEMMODE_16BIT:
6176 IEM_MC_BEGIN(0, 1);
6177 IEM_MC_LOCAL(uint16_t, u16Value);
6178 IEM_MC_FETCH_SREG_U16(u16Value, iReg);
6179 IEM_MC_PUSH_U16(u16Value);
6180 IEM_MC_ADVANCE_RIP();
6181 IEM_MC_END();
6182 break;
6183
6184 case IEMMODE_32BIT:
6185 IEM_MC_BEGIN(0, 1);
6186 IEM_MC_LOCAL(uint32_t, u32Value);
6187 IEM_MC_FETCH_SREG_ZX_U32(u32Value, iReg);
6188 IEM_MC_PUSH_U32_SREG(u32Value);
6189 IEM_MC_ADVANCE_RIP();
6190 IEM_MC_END();
6191 break;
6192
6193 case IEMMODE_64BIT:
6194 IEM_MC_BEGIN(0, 1);
6195 IEM_MC_LOCAL(uint64_t, u64Value);
6196 IEM_MC_FETCH_SREG_ZX_U64(u64Value, iReg);
6197 IEM_MC_PUSH_U64(u64Value);
6198 IEM_MC_ADVANCE_RIP();
6199 IEM_MC_END();
6200 break;
6201 }
6202
6203 return VINF_SUCCESS;
6204}
6205
6206
6207/** Opcode 0x0f 0xa0. */
6208FNIEMOP_DEF(iemOp_push_fs)
6209{
6210 IEMOP_MNEMONIC(push_fs, "push fs");
6211 IEMOP_HLP_MIN_386();
6212 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6213 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_FS);
6214}
6215
6216
6217/** Opcode 0x0f 0xa1. */
6218FNIEMOP_DEF(iemOp_pop_fs)
6219{
6220 IEMOP_MNEMONIC(pop_fs, "pop fs");
6221 IEMOP_HLP_MIN_386();
6222 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6223 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_FS, pVCpu->iem.s.enmEffOpSize);
6224}
6225
6226
6227/** Opcode 0x0f 0xa2. */
6228FNIEMOP_DEF(iemOp_cpuid)
6229{
6230 IEMOP_MNEMONIC(cpuid, "cpuid");
6231 IEMOP_HLP_MIN_486(); /* not all 486es. */
6232 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6233 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_cpuid);
6234}
6235
6236
6237/**
6238 * Common worker for iemOp_bt_Ev_Gv, iemOp_btc_Ev_Gv, iemOp_btr_Ev_Gv and
6239 * iemOp_bts_Ev_Gv.
6240 */
6241FNIEMOP_DEF_1(iemOpCommonBit_Ev_Gv, PCIEMOPBINSIZES, pImpl)
6242{
6243 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6244 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
6245
6246 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6247 {
6248 /* register destination. */
6249 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6250 switch (pVCpu->iem.s.enmEffOpSize)
6251 {
6252 case IEMMODE_16BIT:
6253 IEM_MC_BEGIN(3, 0);
6254 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6255 IEM_MC_ARG(uint16_t, u16Src, 1);
6256 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6257
6258 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6259 IEM_MC_AND_LOCAL_U16(u16Src, 0xf);
6260 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6261 IEM_MC_REF_EFLAGS(pEFlags);
6262 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
6263
6264 IEM_MC_ADVANCE_RIP();
6265 IEM_MC_END();
6266 return VINF_SUCCESS;
6267
6268 case IEMMODE_32BIT:
6269 IEM_MC_BEGIN(3, 0);
6270 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6271 IEM_MC_ARG(uint32_t, u32Src, 1);
6272 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6273
6274 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6275 IEM_MC_AND_LOCAL_U32(u32Src, 0x1f);
6276 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6277 IEM_MC_REF_EFLAGS(pEFlags);
6278 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
6279
6280 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
6281 IEM_MC_ADVANCE_RIP();
6282 IEM_MC_END();
6283 return VINF_SUCCESS;
6284
6285 case IEMMODE_64BIT:
6286 IEM_MC_BEGIN(3, 0);
6287 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6288 IEM_MC_ARG(uint64_t, u64Src, 1);
6289 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6290
6291 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6292 IEM_MC_AND_LOCAL_U64(u64Src, 0x3f);
6293 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6294 IEM_MC_REF_EFLAGS(pEFlags);
6295 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
6296
6297 IEM_MC_ADVANCE_RIP();
6298 IEM_MC_END();
6299 return VINF_SUCCESS;
6300
6301 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6302 }
6303 }
6304 else
6305 {
6306 /* memory destination. */
6307
6308 uint32_t fAccess;
6309 if (pImpl->pfnLockedU16)
6310 fAccess = IEM_ACCESS_DATA_RW;
6311 else /* BT */
6312 fAccess = IEM_ACCESS_DATA_R;
6313
6314 /** @todo test negative bit offsets! */
6315 switch (pVCpu->iem.s.enmEffOpSize)
6316 {
6317 case IEMMODE_16BIT:
6318 IEM_MC_BEGIN(3, 2);
6319 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6320 IEM_MC_ARG(uint16_t, u16Src, 1);
6321 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
6322 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6323 IEM_MC_LOCAL(int16_t, i16AddrAdj);
6324
6325 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6326 if (pImpl->pfnLockedU16)
6327 IEMOP_HLP_DONE_DECODING();
6328 else
6329 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6330 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6331 IEM_MC_ASSIGN(i16AddrAdj, u16Src);
6332 IEM_MC_AND_ARG_U16(u16Src, 0x0f);
6333 IEM_MC_SAR_LOCAL_S16(i16AddrAdj, 4);
6334 IEM_MC_SHL_LOCAL_S16(i16AddrAdj, 1);
6335 IEM_MC_ADD_LOCAL_S16_TO_EFF_ADDR(GCPtrEffDst, i16AddrAdj);
6336 IEM_MC_FETCH_EFLAGS(EFlags);
6337
6338 IEM_MC_MEM_MAP(pu16Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6339 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
6340 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
6341 else
6342 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
6343 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
6344
6345 IEM_MC_COMMIT_EFLAGS(EFlags);
6346 IEM_MC_ADVANCE_RIP();
6347 IEM_MC_END();
6348 return VINF_SUCCESS;
6349
6350 case IEMMODE_32BIT:
6351 IEM_MC_BEGIN(3, 2);
6352 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6353 IEM_MC_ARG(uint32_t, u32Src, 1);
6354 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
6355 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6356 IEM_MC_LOCAL(int32_t, i32AddrAdj);
6357
6358 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6359 if (pImpl->pfnLockedU16)
6360 IEMOP_HLP_DONE_DECODING();
6361 else
6362 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6363 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6364 IEM_MC_ASSIGN(i32AddrAdj, u32Src);
6365 IEM_MC_AND_ARG_U32(u32Src, 0x1f);
6366 IEM_MC_SAR_LOCAL_S32(i32AddrAdj, 5);
6367 IEM_MC_SHL_LOCAL_S32(i32AddrAdj, 2);
6368 IEM_MC_ADD_LOCAL_S32_TO_EFF_ADDR(GCPtrEffDst, i32AddrAdj);
6369 IEM_MC_FETCH_EFLAGS(EFlags);
6370
6371 IEM_MC_MEM_MAP(pu32Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6372 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
6373 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
6374 else
6375 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
6376 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
6377
6378 IEM_MC_COMMIT_EFLAGS(EFlags);
6379 IEM_MC_ADVANCE_RIP();
6380 IEM_MC_END();
6381 return VINF_SUCCESS;
6382
6383 case IEMMODE_64BIT:
6384 IEM_MC_BEGIN(3, 2);
6385 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6386 IEM_MC_ARG(uint64_t, u64Src, 1);
6387 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
6388 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6389 IEM_MC_LOCAL(int64_t, i64AddrAdj);
6390
6391 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6392 if (pImpl->pfnLockedU16)
6393 IEMOP_HLP_DONE_DECODING();
6394 else
6395 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6396 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6397 IEM_MC_ASSIGN(i64AddrAdj, u64Src);
6398 IEM_MC_AND_ARG_U64(u64Src, 0x3f);
6399 IEM_MC_SAR_LOCAL_S64(i64AddrAdj, 6);
6400 IEM_MC_SHL_LOCAL_S64(i64AddrAdj, 3);
6401 IEM_MC_ADD_LOCAL_S64_TO_EFF_ADDR(GCPtrEffDst, i64AddrAdj);
6402 IEM_MC_FETCH_EFLAGS(EFlags);
6403
6404 IEM_MC_MEM_MAP(pu64Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6405 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
6406 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
6407 else
6408 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
6409 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
6410
6411 IEM_MC_COMMIT_EFLAGS(EFlags);
6412 IEM_MC_ADVANCE_RIP();
6413 IEM_MC_END();
6414 return VINF_SUCCESS;
6415
6416 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6417 }
6418 }
6419}
6420
6421
6422/** Opcode 0x0f 0xa3. */
6423FNIEMOP_DEF(iemOp_bt_Ev_Gv)
6424{
6425 IEMOP_MNEMONIC(bt_Ev_Gv, "bt Ev,Gv");
6426 IEMOP_HLP_MIN_386();
6427 return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_bt);
6428}
6429
6430
6431/**
6432 * Common worker for iemOp_shrd_Ev_Gv_Ib and iemOp_shld_Ev_Gv_Ib.
6433 */
6434FNIEMOP_DEF_1(iemOpCommonShldShrd_Ib, PCIEMOPSHIFTDBLSIZES, pImpl)
6435{
6436 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6437 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF | X86_EFL_OF);
6438
6439 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6440 {
6441 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6442 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6443
6444 switch (pVCpu->iem.s.enmEffOpSize)
6445 {
6446 case IEMMODE_16BIT:
6447 IEM_MC_BEGIN(4, 0);
6448 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6449 IEM_MC_ARG(uint16_t, u16Src, 1);
6450 IEM_MC_ARG_CONST(uint8_t, cShiftArg, /*=*/cShift, 2);
6451 IEM_MC_ARG(uint32_t *, pEFlags, 3);
6452
6453 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6454 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6455 IEM_MC_REF_EFLAGS(pEFlags);
6456 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
6457
6458 IEM_MC_ADVANCE_RIP();
6459 IEM_MC_END();
6460 return VINF_SUCCESS;
6461
6462 case IEMMODE_32BIT:
6463 IEM_MC_BEGIN(4, 0);
6464 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6465 IEM_MC_ARG(uint32_t, u32Src, 1);
6466 IEM_MC_ARG_CONST(uint8_t, cShiftArg, /*=*/cShift, 2);
6467 IEM_MC_ARG(uint32_t *, pEFlags, 3);
6468
6469 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6470 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6471 IEM_MC_REF_EFLAGS(pEFlags);
6472 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
6473
6474 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
6475 IEM_MC_ADVANCE_RIP();
6476 IEM_MC_END();
6477 return VINF_SUCCESS;
6478
6479 case IEMMODE_64BIT:
6480 IEM_MC_BEGIN(4, 0);
6481 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6482 IEM_MC_ARG(uint64_t, u64Src, 1);
6483 IEM_MC_ARG_CONST(uint8_t, cShiftArg, /*=*/cShift, 2);
6484 IEM_MC_ARG(uint32_t *, pEFlags, 3);
6485
6486 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6487 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6488 IEM_MC_REF_EFLAGS(pEFlags);
6489 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
6490
6491 IEM_MC_ADVANCE_RIP();
6492 IEM_MC_END();
6493 return VINF_SUCCESS;
6494
6495 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6496 }
6497 }
6498 else
6499 {
6500 switch (pVCpu->iem.s.enmEffOpSize)
6501 {
6502 case IEMMODE_16BIT:
6503 IEM_MC_BEGIN(4, 2);
6504 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6505 IEM_MC_ARG(uint16_t, u16Src, 1);
6506 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6507 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
6508 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6509
6510 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6511 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6512 IEM_MC_ASSIGN(cShiftArg, cShift);
6513 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6514 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6515 IEM_MC_FETCH_EFLAGS(EFlags);
6516 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6517 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
6518
6519 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
6520 IEM_MC_COMMIT_EFLAGS(EFlags);
6521 IEM_MC_ADVANCE_RIP();
6522 IEM_MC_END();
6523 return VINF_SUCCESS;
6524
6525 case IEMMODE_32BIT:
6526 IEM_MC_BEGIN(4, 2);
6527 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6528 IEM_MC_ARG(uint32_t, u32Src, 1);
6529 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6530 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
6531 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6532
6533 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6534 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6535 IEM_MC_ASSIGN(cShiftArg, cShift);
6536 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6537 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6538 IEM_MC_FETCH_EFLAGS(EFlags);
6539 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6540 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
6541
6542 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
6543 IEM_MC_COMMIT_EFLAGS(EFlags);
6544 IEM_MC_ADVANCE_RIP();
6545 IEM_MC_END();
6546 return VINF_SUCCESS;
6547
6548 case IEMMODE_64BIT:
6549 IEM_MC_BEGIN(4, 2);
6550 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6551 IEM_MC_ARG(uint64_t, u64Src, 1);
6552 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6553 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
6554 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6555
6556 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6557 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6558 IEM_MC_ASSIGN(cShiftArg, cShift);
6559 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6560 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6561 IEM_MC_FETCH_EFLAGS(EFlags);
6562 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6563 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
6564
6565 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
6566 IEM_MC_COMMIT_EFLAGS(EFlags);
6567 IEM_MC_ADVANCE_RIP();
6568 IEM_MC_END();
6569 return VINF_SUCCESS;
6570
6571 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6572 }
6573 }
6574}
6575
6576
6577/**
6578 * Common worker for iemOp_shrd_Ev_Gv_CL and iemOp_shld_Ev_Gv_CL.
6579 */
6580FNIEMOP_DEF_1(iemOpCommonShldShrd_CL, PCIEMOPSHIFTDBLSIZES, pImpl)
6581{
6582 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6583 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF | X86_EFL_OF);
6584
6585 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6586 {
6587 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6588
6589 switch (pVCpu->iem.s.enmEffOpSize)
6590 {
6591 case IEMMODE_16BIT:
6592 IEM_MC_BEGIN(4, 0);
6593 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6594 IEM_MC_ARG(uint16_t, u16Src, 1);
6595 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6596 IEM_MC_ARG(uint32_t *, pEFlags, 3);
6597
6598 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6599 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6600 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6601 IEM_MC_REF_EFLAGS(pEFlags);
6602 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
6603
6604 IEM_MC_ADVANCE_RIP();
6605 IEM_MC_END();
6606 return VINF_SUCCESS;
6607
6608 case IEMMODE_32BIT:
6609 IEM_MC_BEGIN(4, 0);
6610 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6611 IEM_MC_ARG(uint32_t, u32Src, 1);
6612 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6613 IEM_MC_ARG(uint32_t *, pEFlags, 3);
6614
6615 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6616 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6617 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6618 IEM_MC_REF_EFLAGS(pEFlags);
6619 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
6620
6621 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
6622 IEM_MC_ADVANCE_RIP();
6623 IEM_MC_END();
6624 return VINF_SUCCESS;
6625
6626 case IEMMODE_64BIT:
6627 IEM_MC_BEGIN(4, 0);
6628 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6629 IEM_MC_ARG(uint64_t, u64Src, 1);
6630 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6631 IEM_MC_ARG(uint32_t *, pEFlags, 3);
6632
6633 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6634 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6635 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6636 IEM_MC_REF_EFLAGS(pEFlags);
6637 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
6638
6639 IEM_MC_ADVANCE_RIP();
6640 IEM_MC_END();
6641 return VINF_SUCCESS;
6642
6643 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6644 }
6645 }
6646 else
6647 {
6648 switch (pVCpu->iem.s.enmEffOpSize)
6649 {
6650 case IEMMODE_16BIT:
6651 IEM_MC_BEGIN(4, 2);
6652 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6653 IEM_MC_ARG(uint16_t, u16Src, 1);
6654 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6655 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
6656 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6657
6658 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6659 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6660 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6661 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6662 IEM_MC_FETCH_EFLAGS(EFlags);
6663 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6664 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU16, pu16Dst, u16Src, cShiftArg, pEFlags);
6665
6666 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
6667 IEM_MC_COMMIT_EFLAGS(EFlags);
6668 IEM_MC_ADVANCE_RIP();
6669 IEM_MC_END();
6670 return VINF_SUCCESS;
6671
6672 case IEMMODE_32BIT:
6673 IEM_MC_BEGIN(4, 2);
6674 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6675 IEM_MC_ARG(uint32_t, u32Src, 1);
6676 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6677 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
6678 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6679
6680 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6681 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6682 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6683 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6684 IEM_MC_FETCH_EFLAGS(EFlags);
6685 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6686 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU32, pu32Dst, u32Src, cShiftArg, pEFlags);
6687
6688 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
6689 IEM_MC_COMMIT_EFLAGS(EFlags);
6690 IEM_MC_ADVANCE_RIP();
6691 IEM_MC_END();
6692 return VINF_SUCCESS;
6693
6694 case IEMMODE_64BIT:
6695 IEM_MC_BEGIN(4, 2);
6696 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6697 IEM_MC_ARG(uint64_t, u64Src, 1);
6698 IEM_MC_ARG(uint8_t, cShiftArg, 2);
6699 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
6700 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6701
6702 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6703 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6704 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
6705 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6706 IEM_MC_FETCH_EFLAGS(EFlags);
6707 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
6708 IEM_MC_CALL_VOID_AIMPL_4(pImpl->pfnNormalU64, pu64Dst, u64Src, cShiftArg, pEFlags);
6709
6710 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
6711 IEM_MC_COMMIT_EFLAGS(EFlags);
6712 IEM_MC_ADVANCE_RIP();
6713 IEM_MC_END();
6714 return VINF_SUCCESS;
6715
6716 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6717 }
6718 }
6719}
6720
6721
6722
6723/** Opcode 0x0f 0xa4. */
6724FNIEMOP_DEF(iemOp_shld_Ev_Gv_Ib)
6725{
6726 IEMOP_MNEMONIC(shld_Ev_Gv_Ib, "shld Ev,Gv,Ib");
6727 IEMOP_HLP_MIN_386();
6728 return FNIEMOP_CALL_1(iemOpCommonShldShrd_Ib, &g_iemAImpl_shld);
6729}
6730
6731
6732/** Opcode 0x0f 0xa5. */
6733FNIEMOP_DEF(iemOp_shld_Ev_Gv_CL)
6734{
6735 IEMOP_MNEMONIC(shld_Ev_Gv_CL, "shld Ev,Gv,CL");
6736 IEMOP_HLP_MIN_386();
6737 return FNIEMOP_CALL_1(iemOpCommonShldShrd_CL, &g_iemAImpl_shld);
6738}
6739
6740
6741/** Opcode 0x0f 0xa8. */
6742FNIEMOP_DEF(iemOp_push_gs)
6743{
6744 IEMOP_MNEMONIC(push_gs, "push gs");
6745 IEMOP_HLP_MIN_386();
6746 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6747 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_GS);
6748}
6749
6750
6751/** Opcode 0x0f 0xa9. */
6752FNIEMOP_DEF(iemOp_pop_gs)
6753{
6754 IEMOP_MNEMONIC(pop_gs, "pop gs");
6755 IEMOP_HLP_MIN_386();
6756 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6757 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_GS, pVCpu->iem.s.enmEffOpSize);
6758}
6759
6760
6761/** Opcode 0x0f 0xaa. */
6762FNIEMOP_DEF(iemOp_rsm)
6763{
6764 IEMOP_MNEMONIC0(FIXED, RSM, rsm, DISOPTYPE_HARMLESS, 0);
6765 IEMOP_HLP_MIN_386(); /* 386SL and later. */
6766 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6767 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rsm);
6768}
6769
6770
6771
6772/** Opcode 0x0f 0xab. */
6773FNIEMOP_DEF(iemOp_bts_Ev_Gv)
6774{
6775 IEMOP_MNEMONIC(bts_Ev_Gv, "bts Ev,Gv");
6776 IEMOP_HLP_MIN_386();
6777 return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_bts);
6778}
6779
6780
6781/** Opcode 0x0f 0xac. */
6782FNIEMOP_DEF(iemOp_shrd_Ev_Gv_Ib)
6783{
6784 IEMOP_MNEMONIC(shrd_Ev_Gv_Ib, "shrd Ev,Gv,Ib");
6785 IEMOP_HLP_MIN_386();
6786 return FNIEMOP_CALL_1(iemOpCommonShldShrd_Ib, &g_iemAImpl_shrd);
6787}
6788
6789
6790/** Opcode 0x0f 0xad. */
6791FNIEMOP_DEF(iemOp_shrd_Ev_Gv_CL)
6792{
6793 IEMOP_MNEMONIC(shrd_Ev_Gv_CL, "shrd Ev,Gv,CL");
6794 IEMOP_HLP_MIN_386();
6795 return FNIEMOP_CALL_1(iemOpCommonShldShrd_CL, &g_iemAImpl_shrd);
6796}
6797
6798
6799/** Opcode 0x0f 0xae mem/0. */
6800FNIEMOP_DEF_1(iemOp_Grp15_fxsave, uint8_t, bRm)
6801{
6802 IEMOP_MNEMONIC(fxsave, "fxsave m512");
6803 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fFxSaveRstor)
6804 return IEMOP_RAISE_INVALID_OPCODE();
6805
6806 IEM_MC_BEGIN(3, 1);
6807 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6808 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6809 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 2);
6810 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6811 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6812 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
6813 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6814 IEM_MC_CALL_CIMPL_3(iemCImpl_fxsave, iEffSeg, GCPtrEff, enmEffOpSize);
6815 IEM_MC_END();
6816 return VINF_SUCCESS;
6817}
6818
6819
6820/** Opcode 0x0f 0xae mem/1. */
6821FNIEMOP_DEF_1(iemOp_Grp15_fxrstor, uint8_t, bRm)
6822{
6823 IEMOP_MNEMONIC(fxrstor, "fxrstor m512");
6824 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fFxSaveRstor)
6825 return IEMOP_RAISE_INVALID_OPCODE();
6826
6827 IEM_MC_BEGIN(3, 1);
6828 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6829 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6830 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 2);
6831 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6832 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6833 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
6834 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6835 IEM_MC_CALL_CIMPL_3(iemCImpl_fxrstor, iEffSeg, GCPtrEff, enmEffOpSize);
6836 IEM_MC_END();
6837 return VINF_SUCCESS;
6838}
6839
6840
6841/**
6842 * @opmaps grp15
6843 * @opcode !11/2
6844 * @oppfx none
6845 * @opcpuid sse
6846 * @opgroup og_sse_mxcsrsm
6847 * @opxcpttype 5
6848 * @optest op1=0 -> mxcsr=0
6849 * @optest op1=0x2083 -> mxcsr=0x2083
6850 * @optest op1=0xfffffffe -> value.xcpt=0xd
6851 * @optest op1=0x2083 cr0|=ts -> value.xcpt=0x7
6852 * @optest op1=0x2083 cr0|=em -> value.xcpt=0x6
6853 * @optest op1=0x2083 cr0|=mp -> mxcsr=0x2083
6854 * @optest op1=0x2083 cr4&~=osfxsr -> value.xcpt=0x6
6855 * @optest op1=0x2083 cr0|=ts,em -> value.xcpt=0x6
6856 * @optest op1=0x2083 cr0|=em cr4&~=osfxsr -> value.xcpt=0x6
6857 * @optest op1=0x2083 cr0|=ts,em cr4&~=osfxsr -> value.xcpt=0x6
6858 * @optest op1=0x2083 cr0|=ts,em,mp cr4&~=osfxsr -> value.xcpt=0x6
6859 */
6860FNIEMOP_DEF_1(iemOp_Grp15_ldmxcsr, uint8_t, bRm)
6861{
6862 IEMOP_MNEMONIC1(M_MEM, LDMXCSR, ldmxcsr, Md_RO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
6863 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse)
6864 return IEMOP_RAISE_INVALID_OPCODE();
6865
6866 IEM_MC_BEGIN(2, 0);
6867 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6868 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6869 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6870 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6871 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
6872 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6873 IEM_MC_CALL_CIMPL_2(iemCImpl_ldmxcsr, iEffSeg, GCPtrEff);
6874 IEM_MC_END();
6875 return VINF_SUCCESS;
6876}
6877
6878
6879/**
6880 * @opmaps grp15
6881 * @opcode !11/3
6882 * @oppfx none
6883 * @opcpuid sse
6884 * @opgroup og_sse_mxcsrsm
6885 * @opxcpttype 5
6886 * @optest mxcsr=0 -> op1=0
6887 * @optest mxcsr=0x2083 -> op1=0x2083
6888 * @optest mxcsr=0x2084 cr0|=ts -> value.xcpt=0x7
6889 * @optest mxcsr=0x2085 cr0|=em -> value.xcpt=0x6
6890 * @optest mxcsr=0x2086 cr0|=mp -> op1=0x2086
6891 * @optest mxcsr=0x2087 cr4&~=osfxsr -> value.xcpt=0x6
6892 * @optest mxcsr=0x2088 cr0|=ts,em -> value.xcpt=0x6
6893 * @optest mxcsr=0x2089 cr0|=em cr4&~=osfxsr -> value.xcpt=0x6
6894 * @optest mxcsr=0x208a cr0|=ts,em cr4&~=osfxsr -> value.xcpt=0x6
6895 * @optest mxcsr=0x208b cr0|=ts,em,mp cr4&~=osfxsr -> value.xcpt=0x6
6896 */
6897FNIEMOP_DEF_1(iemOp_Grp15_stmxcsr, uint8_t, bRm)
6898{
6899 IEMOP_MNEMONIC1(M_MEM, STMXCSR, stmxcsr, Md_WO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
6900 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse)
6901 return IEMOP_RAISE_INVALID_OPCODE();
6902
6903 IEM_MC_BEGIN(2, 0);
6904 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6905 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6906 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6907 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6908 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
6909 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6910 IEM_MC_CALL_CIMPL_2(iemCImpl_stmxcsr, iEffSeg, GCPtrEff);
6911 IEM_MC_END();
6912 return VINF_SUCCESS;
6913}
6914
6915
6916/**
6917 * @opmaps grp15
6918 * @opcode !11/4
6919 * @oppfx none
6920 * @opcpuid xsave
6921 * @opgroup og_system
6922 * @opxcpttype none
6923 */
6924FNIEMOP_DEF_1(iemOp_Grp15_xsave, uint8_t, bRm)
6925{
6926 IEMOP_MNEMONIC1(M_MEM, XSAVE, xsave, M_RW, DISOPTYPE_HARMLESS, 0);
6927 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fXSaveRstor)
6928 return IEMOP_RAISE_INVALID_OPCODE();
6929
6930 IEM_MC_BEGIN(3, 0);
6931 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6932 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6933 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 2);
6934 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6935 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6936 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
6937 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6938 IEM_MC_CALL_CIMPL_3(iemCImpl_xsave, iEffSeg, GCPtrEff, enmEffOpSize);
6939 IEM_MC_END();
6940 return VINF_SUCCESS;
6941}
6942
6943
6944/**
6945 * @opmaps grp15
6946 * @opcode !11/5
6947 * @oppfx none
6948 * @opcpuid xsave
6949 * @opgroup og_system
6950 * @opxcpttype none
6951 */
6952FNIEMOP_DEF_1(iemOp_Grp15_xrstor, uint8_t, bRm)
6953{
6954 IEMOP_MNEMONIC1(M_MEM, XRSTOR, xrstor, M_RO, DISOPTYPE_HARMLESS, 0);
6955 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fXSaveRstor)
6956 return IEMOP_RAISE_INVALID_OPCODE();
6957
6958 IEM_MC_BEGIN(3, 0);
6959 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6960 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6961 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 2);
6962 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6963 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6964 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
6965 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6966 IEM_MC_CALL_CIMPL_3(iemCImpl_xrstor, iEffSeg, GCPtrEff, enmEffOpSize);
6967 IEM_MC_END();
6968 return VINF_SUCCESS;
6969}
6970
6971/** Opcode 0x0f 0xae mem/6. */
6972FNIEMOP_UD_STUB_1(iemOp_Grp15_xsaveopt, uint8_t, bRm);
6973
6974/**
6975 * @opmaps grp15
6976 * @opcode !11/7
6977 * @oppfx none
6978 * @opcpuid clfsh
6979 * @opgroup og_cachectl
6980 * @optest op1=1 ->
6981 */
6982FNIEMOP_DEF_1(iemOp_Grp15_clflush, uint8_t, bRm)
6983{
6984 IEMOP_MNEMONIC1(M_MEM, CLFLUSH, clflush, Mb_RO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
6985 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fClFlush)
6986 return FNIEMOP_CALL_1(iemOp_InvalidWithRMAllNeeded, bRm);
6987
6988 IEM_MC_BEGIN(2, 0);
6989 IEM_MC_ARG(uint8_t, iEffSeg, 0);
6990 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
6991 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
6992 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6993 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
6994 IEM_MC_CALL_CIMPL_2(iemCImpl_clflush_clflushopt, iEffSeg, GCPtrEff);
6995 IEM_MC_END();
6996 return VINF_SUCCESS;
6997}
6998
6999/**
7000 * @opmaps grp15
7001 * @opcode !11/7
7002 * @oppfx 0x66
7003 * @opcpuid clflushopt
7004 * @opgroup og_cachectl
7005 * @optest op1=1 ->
7006 */
7007FNIEMOP_DEF_1(iemOp_Grp15_clflushopt, uint8_t, bRm)
7008{
7009 IEMOP_MNEMONIC1(M_MEM, CLFLUSHOPT, clflushopt, Mb_RO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
7010 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fClFlushOpt)
7011 return FNIEMOP_CALL_1(iemOp_InvalidWithRMAllNeeded, bRm);
7012
7013 IEM_MC_BEGIN(2, 0);
7014 IEM_MC_ARG(uint8_t, iEffSeg, 0);
7015 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1);
7016 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
7017 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7018 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
7019 IEM_MC_CALL_CIMPL_2(iemCImpl_clflush_clflushopt, iEffSeg, GCPtrEff);
7020 IEM_MC_END();
7021 return VINF_SUCCESS;
7022}
7023
7024
7025/** Opcode 0x0f 0xae 11b/5. */
7026FNIEMOP_DEF_1(iemOp_Grp15_lfence, uint8_t, bRm)
7027{
7028 RT_NOREF_PV(bRm);
7029 IEMOP_MNEMONIC(lfence, "lfence");
7030 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7031 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2)
7032 return IEMOP_RAISE_INVALID_OPCODE();
7033
7034 IEM_MC_BEGIN(0, 0);
7035 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2)
7036 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence);
7037 else
7038 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
7039 IEM_MC_ADVANCE_RIP();
7040 IEM_MC_END();
7041 return VINF_SUCCESS;
7042}
7043
7044
7045/** Opcode 0x0f 0xae 11b/6. */
7046FNIEMOP_DEF_1(iemOp_Grp15_mfence, uint8_t, bRm)
7047{
7048 RT_NOREF_PV(bRm);
7049 IEMOP_MNEMONIC(mfence, "mfence");
7050 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7051 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2)
7052 return IEMOP_RAISE_INVALID_OPCODE();
7053
7054 IEM_MC_BEGIN(0, 0);
7055 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2)
7056 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence);
7057 else
7058 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
7059 IEM_MC_ADVANCE_RIP();
7060 IEM_MC_END();
7061 return VINF_SUCCESS;
7062}
7063
7064
7065/** Opcode 0x0f 0xae 11b/7. */
7066FNIEMOP_DEF_1(iemOp_Grp15_sfence, uint8_t, bRm)
7067{
7068 RT_NOREF_PV(bRm);
7069 IEMOP_MNEMONIC(sfence, "sfence");
7070 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7071 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2)
7072 return IEMOP_RAISE_INVALID_OPCODE();
7073
7074 IEM_MC_BEGIN(0, 0);
7075 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2)
7076 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence);
7077 else
7078 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
7079 IEM_MC_ADVANCE_RIP();
7080 IEM_MC_END();
7081 return VINF_SUCCESS;
7082}
7083
7084
7085/** Opcode 0xf3 0x0f 0xae 11b/0. */
7086FNIEMOP_DEF_1(iemOp_Grp15_rdfsbase, uint8_t, bRm)
7087{
7088 IEMOP_MNEMONIC(rdfsbase, "rdfsbase Ry");
7089 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7090 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_64BIT)
7091 {
7092 IEM_MC_BEGIN(1, 0);
7093 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7094 IEM_MC_ARG(uint64_t, u64Dst, 0);
7095 IEM_MC_FETCH_SREG_BASE_U64(u64Dst, X86_SREG_FS);
7096 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Dst);
7097 IEM_MC_ADVANCE_RIP();
7098 IEM_MC_END();
7099 }
7100 else
7101 {
7102 IEM_MC_BEGIN(1, 0);
7103 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7104 IEM_MC_ARG(uint32_t, u32Dst, 0);
7105 IEM_MC_FETCH_SREG_BASE_U32(u32Dst, X86_SREG_FS);
7106 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Dst);
7107 IEM_MC_ADVANCE_RIP();
7108 IEM_MC_END();
7109 }
7110 return VINF_SUCCESS;
7111}
7112
7113
7114/** Opcode 0xf3 0x0f 0xae 11b/1. */
7115FNIEMOP_DEF_1(iemOp_Grp15_rdgsbase, uint8_t, bRm)
7116{
7117 IEMOP_MNEMONIC(rdgsbase, "rdgsbase Ry");
7118 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7119 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_64BIT)
7120 {
7121 IEM_MC_BEGIN(1, 0);
7122 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7123 IEM_MC_ARG(uint64_t, u64Dst, 0);
7124 IEM_MC_FETCH_SREG_BASE_U64(u64Dst, X86_SREG_GS);
7125 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Dst);
7126 IEM_MC_ADVANCE_RIP();
7127 IEM_MC_END();
7128 }
7129 else
7130 {
7131 IEM_MC_BEGIN(1, 0);
7132 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7133 IEM_MC_ARG(uint32_t, u32Dst, 0);
7134 IEM_MC_FETCH_SREG_BASE_U32(u32Dst, X86_SREG_GS);
7135 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Dst);
7136 IEM_MC_ADVANCE_RIP();
7137 IEM_MC_END();
7138 }
7139 return VINF_SUCCESS;
7140}
7141
7142
7143/** Opcode 0xf3 0x0f 0xae 11b/2. */
7144FNIEMOP_DEF_1(iemOp_Grp15_wrfsbase, uint8_t, bRm)
7145{
7146 IEMOP_MNEMONIC(wrfsbase, "wrfsbase Ry");
7147 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7148 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_64BIT)
7149 {
7150 IEM_MC_BEGIN(1, 0);
7151 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7152 IEM_MC_ARG(uint64_t, u64Dst, 0);
7153 IEM_MC_FETCH_GREG_U64(u64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7154 IEM_MC_MAYBE_RAISE_NON_CANONICAL_ADDR_GP0(u64Dst);
7155 IEM_MC_STORE_SREG_BASE_U64(X86_SREG_FS, u64Dst);
7156 IEM_MC_ADVANCE_RIP();
7157 IEM_MC_END();
7158 }
7159 else
7160 {
7161 IEM_MC_BEGIN(1, 0);
7162 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7163 IEM_MC_ARG(uint32_t, u32Dst, 0);
7164 IEM_MC_FETCH_GREG_U32(u32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7165 IEM_MC_STORE_SREG_BASE_U64(X86_SREG_FS, u32Dst);
7166 IEM_MC_ADVANCE_RIP();
7167 IEM_MC_END();
7168 }
7169 return VINF_SUCCESS;
7170}
7171
7172
7173/** Opcode 0xf3 0x0f 0xae 11b/3. */
7174FNIEMOP_DEF_1(iemOp_Grp15_wrgsbase, uint8_t, bRm)
7175{
7176 IEMOP_MNEMONIC(wrgsbase, "wrgsbase Ry");
7177 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7178 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_64BIT)
7179 {
7180 IEM_MC_BEGIN(1, 0);
7181 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7182 IEM_MC_ARG(uint64_t, u64Dst, 0);
7183 IEM_MC_FETCH_GREG_U64(u64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7184 IEM_MC_MAYBE_RAISE_NON_CANONICAL_ADDR_GP0(u64Dst);
7185 IEM_MC_STORE_SREG_BASE_U64(X86_SREG_GS, u64Dst);
7186 IEM_MC_ADVANCE_RIP();
7187 IEM_MC_END();
7188 }
7189 else
7190 {
7191 IEM_MC_BEGIN(1, 0);
7192 IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT();
7193 IEM_MC_ARG(uint32_t, u32Dst, 0);
7194 IEM_MC_FETCH_GREG_U32(u32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7195 IEM_MC_STORE_SREG_BASE_U64(X86_SREG_GS, u32Dst);
7196 IEM_MC_ADVANCE_RIP();
7197 IEM_MC_END();
7198 }
7199 return VINF_SUCCESS;
7200}
7201
7202
7203/**
7204 * Group 15 jump table for register variant.
7205 */
7206IEM_STATIC const PFNIEMOPRM g_apfnGroup15RegReg[] =
7207{ /* pfx: none, 066h, 0f3h, 0f2h */
7208 /* /0 */ iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_Grp15_rdfsbase, iemOp_InvalidWithRM,
7209 /* /1 */ iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_Grp15_rdgsbase, iemOp_InvalidWithRM,
7210 /* /2 */ iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_Grp15_wrfsbase, iemOp_InvalidWithRM,
7211 /* /3 */ iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_Grp15_wrgsbase, iemOp_InvalidWithRM,
7212 /* /4 */ IEMOP_X4(iemOp_InvalidWithRM),
7213 /* /5 */ iemOp_Grp15_lfence, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7214 /* /6 */ iemOp_Grp15_mfence, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7215 /* /7 */ iemOp_Grp15_sfence, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7216};
7217AssertCompile(RT_ELEMENTS(g_apfnGroup15RegReg) == 8*4);
7218
7219
7220/**
7221 * Group 15 jump table for memory variant.
7222 */
7223IEM_STATIC const PFNIEMOPRM g_apfnGroup15MemReg[] =
7224{ /* pfx: none, 066h, 0f3h, 0f2h */
7225 /* /0 */ iemOp_Grp15_fxsave, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7226 /* /1 */ iemOp_Grp15_fxrstor, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7227 /* /2 */ iemOp_Grp15_ldmxcsr, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7228 /* /3 */ iemOp_Grp15_stmxcsr, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7229 /* /4 */ iemOp_Grp15_xsave, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7230 /* /5 */ iemOp_Grp15_xrstor, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7231 /* /6 */ iemOp_Grp15_xsaveopt, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7232 /* /7 */ iemOp_Grp15_clflush, iemOp_Grp15_clflushopt, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
7233};
7234AssertCompile(RT_ELEMENTS(g_apfnGroup15MemReg) == 8*4);
7235
7236
7237/** Opcode 0x0f 0xae. */
7238FNIEMOP_DEF(iemOp_Grp15)
7239{
7240 IEMOP_HLP_MIN_586(); /* Not entirely accurate nor needed, but useful for debugging 286 code. */
7241 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7242 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7243 /* register, register */
7244 return FNIEMOP_CALL_1(g_apfnGroup15RegReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
7245 + pVCpu->iem.s.idxPrefix], bRm);
7246 /* memory, register */
7247 return FNIEMOP_CALL_1(g_apfnGroup15MemReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
7248 + pVCpu->iem.s.idxPrefix], bRm);
7249}
7250
7251
7252/** Opcode 0x0f 0xaf. */
7253FNIEMOP_DEF(iemOp_imul_Gv_Ev)
7254{
7255 IEMOP_MNEMONIC(imul_Gv_Ev, "imul Gv,Ev");
7256 IEMOP_HLP_MIN_386();
7257 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
7258 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_imul_two);
7259}
7260
7261
7262/** Opcode 0x0f 0xb0. */
7263FNIEMOP_DEF(iemOp_cmpxchg_Eb_Gb)
7264{
7265 IEMOP_MNEMONIC(cmpxchg_Eb_Gb, "cmpxchg Eb,Gb");
7266 IEMOP_HLP_MIN_486();
7267 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7268
7269 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7270 {
7271 IEMOP_HLP_DONE_DECODING();
7272 IEM_MC_BEGIN(4, 0);
7273 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
7274 IEM_MC_ARG(uint8_t *, pu8Al, 1);
7275 IEM_MC_ARG(uint8_t, u8Src, 2);
7276 IEM_MC_ARG(uint32_t *, pEFlags, 3);
7277
7278 IEM_MC_FETCH_GREG_U8(u8Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7279 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7280 IEM_MC_REF_GREG_U8(pu8Al, X86_GREG_xAX);
7281 IEM_MC_REF_EFLAGS(pEFlags);
7282 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7283 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u8, pu8Dst, pu8Al, u8Src, pEFlags);
7284 else
7285 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u8_locked, pu8Dst, pu8Al, u8Src, pEFlags);
7286
7287 IEM_MC_ADVANCE_RIP();
7288 IEM_MC_END();
7289 }
7290 else
7291 {
7292 IEM_MC_BEGIN(4, 3);
7293 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
7294 IEM_MC_ARG(uint8_t *, pu8Al, 1);
7295 IEM_MC_ARG(uint8_t, u8Src, 2);
7296 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
7297 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7298 IEM_MC_LOCAL(uint8_t, u8Al);
7299
7300 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7301 IEMOP_HLP_DONE_DECODING();
7302 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7303 IEM_MC_FETCH_GREG_U8(u8Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7304 IEM_MC_FETCH_GREG_U8(u8Al, X86_GREG_xAX);
7305 IEM_MC_FETCH_EFLAGS(EFlags);
7306 IEM_MC_REF_LOCAL(pu8Al, u8Al);
7307 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7308 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u8, pu8Dst, pu8Al, u8Src, pEFlags);
7309 else
7310 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u8_locked, pu8Dst, pu8Al, u8Src, pEFlags);
7311
7312 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
7313 IEM_MC_COMMIT_EFLAGS(EFlags);
7314 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Al);
7315 IEM_MC_ADVANCE_RIP();
7316 IEM_MC_END();
7317 }
7318 return VINF_SUCCESS;
7319}
7320
7321/** Opcode 0x0f 0xb1. */
7322FNIEMOP_DEF(iemOp_cmpxchg_Ev_Gv)
7323{
7324 IEMOP_MNEMONIC(cmpxchg_Ev_Gv, "cmpxchg Ev,Gv");
7325 IEMOP_HLP_MIN_486();
7326 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7327
7328 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7329 {
7330 IEMOP_HLP_DONE_DECODING();
7331 switch (pVCpu->iem.s.enmEffOpSize)
7332 {
7333 case IEMMODE_16BIT:
7334 IEM_MC_BEGIN(4, 0);
7335 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
7336 IEM_MC_ARG(uint16_t *, pu16Ax, 1);
7337 IEM_MC_ARG(uint16_t, u16Src, 2);
7338 IEM_MC_ARG(uint32_t *, pEFlags, 3);
7339
7340 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7341 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7342 IEM_MC_REF_GREG_U16(pu16Ax, X86_GREG_xAX);
7343 IEM_MC_REF_EFLAGS(pEFlags);
7344 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7345 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u16, pu16Dst, pu16Ax, u16Src, pEFlags);
7346 else
7347 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u16_locked, pu16Dst, pu16Ax, u16Src, pEFlags);
7348
7349 IEM_MC_ADVANCE_RIP();
7350 IEM_MC_END();
7351 return VINF_SUCCESS;
7352
7353 case IEMMODE_32BIT:
7354 IEM_MC_BEGIN(4, 0);
7355 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
7356 IEM_MC_ARG(uint32_t *, pu32Eax, 1);
7357 IEM_MC_ARG(uint32_t, u32Src, 2);
7358 IEM_MC_ARG(uint32_t *, pEFlags, 3);
7359
7360 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7361 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7362 IEM_MC_REF_GREG_U32(pu32Eax, X86_GREG_xAX);
7363 IEM_MC_REF_EFLAGS(pEFlags);
7364 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7365 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u32, pu32Dst, pu32Eax, u32Src, pEFlags);
7366 else
7367 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u32_locked, pu32Dst, pu32Eax, u32Src, pEFlags);
7368
7369 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Eax);
7370 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
7371 IEM_MC_ADVANCE_RIP();
7372 IEM_MC_END();
7373 return VINF_SUCCESS;
7374
7375 case IEMMODE_64BIT:
7376 IEM_MC_BEGIN(4, 0);
7377 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
7378 IEM_MC_ARG(uint64_t *, pu64Rax, 1);
7379#ifdef RT_ARCH_X86
7380 IEM_MC_ARG(uint64_t *, pu64Src, 2);
7381#else
7382 IEM_MC_ARG(uint64_t, u64Src, 2);
7383#endif
7384 IEM_MC_ARG(uint32_t *, pEFlags, 3);
7385
7386 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7387 IEM_MC_REF_GREG_U64(pu64Rax, X86_GREG_xAX);
7388 IEM_MC_REF_EFLAGS(pEFlags);
7389#ifdef RT_ARCH_X86
7390 IEM_MC_REF_GREG_U64(pu64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7391 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7392 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64, pu64Dst, pu64Rax, pu64Src, pEFlags);
7393 else
7394 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64_locked, pu64Dst, pu64Rax, pu64Src, pEFlags);
7395#else
7396 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7397 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7398 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64, pu64Dst, pu64Rax, u64Src, pEFlags);
7399 else
7400 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64_locked, pu64Dst, pu64Rax, u64Src, pEFlags);
7401#endif
7402
7403 IEM_MC_ADVANCE_RIP();
7404 IEM_MC_END();
7405 return VINF_SUCCESS;
7406
7407 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7408 }
7409 }
7410 else
7411 {
7412 switch (pVCpu->iem.s.enmEffOpSize)
7413 {
7414 case IEMMODE_16BIT:
7415 IEM_MC_BEGIN(4, 3);
7416 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
7417 IEM_MC_ARG(uint16_t *, pu16Ax, 1);
7418 IEM_MC_ARG(uint16_t, u16Src, 2);
7419 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
7420 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7421 IEM_MC_LOCAL(uint16_t, u16Ax);
7422
7423 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7424 IEMOP_HLP_DONE_DECODING();
7425 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7426 IEM_MC_FETCH_GREG_U16(u16Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7427 IEM_MC_FETCH_GREG_U16(u16Ax, X86_GREG_xAX);
7428 IEM_MC_FETCH_EFLAGS(EFlags);
7429 IEM_MC_REF_LOCAL(pu16Ax, u16Ax);
7430 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7431 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u16, pu16Dst, pu16Ax, u16Src, pEFlags);
7432 else
7433 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u16_locked, pu16Dst, pu16Ax, u16Src, pEFlags);
7434
7435 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
7436 IEM_MC_COMMIT_EFLAGS(EFlags);
7437 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Ax);
7438 IEM_MC_ADVANCE_RIP();
7439 IEM_MC_END();
7440 return VINF_SUCCESS;
7441
7442 case IEMMODE_32BIT:
7443 IEM_MC_BEGIN(4, 3);
7444 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
7445 IEM_MC_ARG(uint32_t *, pu32Eax, 1);
7446 IEM_MC_ARG(uint32_t, u32Src, 2);
7447 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
7448 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7449 IEM_MC_LOCAL(uint32_t, u32Eax);
7450
7451 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7452 IEMOP_HLP_DONE_DECODING();
7453 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7454 IEM_MC_FETCH_GREG_U32(u32Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7455 IEM_MC_FETCH_GREG_U32(u32Eax, X86_GREG_xAX);
7456 IEM_MC_FETCH_EFLAGS(EFlags);
7457 IEM_MC_REF_LOCAL(pu32Eax, u32Eax);
7458 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7459 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u32, pu32Dst, pu32Eax, u32Src, pEFlags);
7460 else
7461 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u32_locked, pu32Dst, pu32Eax, u32Src, pEFlags);
7462
7463 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
7464 IEM_MC_COMMIT_EFLAGS(EFlags);
7465 IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Eax);
7466 IEM_MC_ADVANCE_RIP();
7467 IEM_MC_END();
7468 return VINF_SUCCESS;
7469
7470 case IEMMODE_64BIT:
7471 IEM_MC_BEGIN(4, 3);
7472 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
7473 IEM_MC_ARG(uint64_t *, pu64Rax, 1);
7474#ifdef RT_ARCH_X86
7475 IEM_MC_ARG(uint64_t *, pu64Src, 2);
7476#else
7477 IEM_MC_ARG(uint64_t, u64Src, 2);
7478#endif
7479 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 3);
7480 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7481 IEM_MC_LOCAL(uint64_t, u64Rax);
7482
7483 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7484 IEMOP_HLP_DONE_DECODING();
7485 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7486 IEM_MC_FETCH_GREG_U64(u64Rax, X86_GREG_xAX);
7487 IEM_MC_FETCH_EFLAGS(EFlags);
7488 IEM_MC_REF_LOCAL(pu64Rax, u64Rax);
7489#ifdef RT_ARCH_X86
7490 IEM_MC_REF_GREG_U64(pu64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7491 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7492 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64, pu64Dst, pu64Rax, pu64Src, pEFlags);
7493 else
7494 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64_locked, pu64Dst, pu64Rax, pu64Src, pEFlags);
7495#else
7496 IEM_MC_FETCH_GREG_U64(u64Src, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
7497 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7498 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64, pu64Dst, pu64Rax, u64Src, pEFlags);
7499 else
7500 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg_u64_locked, pu64Dst, pu64Rax, u64Src, pEFlags);
7501#endif
7502
7503 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
7504 IEM_MC_COMMIT_EFLAGS(EFlags);
7505 IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Rax);
7506 IEM_MC_ADVANCE_RIP();
7507 IEM_MC_END();
7508 return VINF_SUCCESS;
7509
7510 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7511 }
7512 }
7513}
7514
7515
7516FNIEMOP_DEF_2(iemOpCommonLoadSRegAndGreg, uint8_t, iSegReg, uint8_t, bRm)
7517{
7518 Assert((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT)); /* Caller checks this */
7519 uint8_t const iGReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg;
7520
7521 switch (pVCpu->iem.s.enmEffOpSize)
7522 {
7523 case IEMMODE_16BIT:
7524 IEM_MC_BEGIN(5, 1);
7525 IEM_MC_ARG(uint16_t, uSel, 0);
7526 IEM_MC_ARG(uint16_t, offSeg, 1);
7527 IEM_MC_ARG_CONST(uint8_t, iSegRegArg,/*=*/iSegReg, 2);
7528 IEM_MC_ARG_CONST(uint8_t, iGRegArg, /*=*/iGReg, 3);
7529 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 4);
7530 IEM_MC_LOCAL(RTGCPTR, GCPtrEff);
7531 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
7532 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7533 IEM_MC_FETCH_MEM_U16(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEff);
7534 IEM_MC_FETCH_MEM_U16_DISP(uSel, pVCpu->iem.s.iEffSeg, GCPtrEff, 2);
7535 IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
7536 IEM_MC_END();
7537 return VINF_SUCCESS;
7538
7539 case IEMMODE_32BIT:
7540 IEM_MC_BEGIN(5, 1);
7541 IEM_MC_ARG(uint16_t, uSel, 0);
7542 IEM_MC_ARG(uint32_t, offSeg, 1);
7543 IEM_MC_ARG_CONST(uint8_t, iSegRegArg,/*=*/iSegReg, 2);
7544 IEM_MC_ARG_CONST(uint8_t, iGRegArg, /*=*/iGReg, 3);
7545 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 4);
7546 IEM_MC_LOCAL(RTGCPTR, GCPtrEff);
7547 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
7548 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7549 IEM_MC_FETCH_MEM_U32(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEff);
7550 IEM_MC_FETCH_MEM_U16_DISP(uSel, pVCpu->iem.s.iEffSeg, GCPtrEff, 4);
7551 IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
7552 IEM_MC_END();
7553 return VINF_SUCCESS;
7554
7555 case IEMMODE_64BIT:
7556 IEM_MC_BEGIN(5, 1);
7557 IEM_MC_ARG(uint16_t, uSel, 0);
7558 IEM_MC_ARG(uint64_t, offSeg, 1);
7559 IEM_MC_ARG_CONST(uint8_t, iSegRegArg,/*=*/iSegReg, 2);
7560 IEM_MC_ARG_CONST(uint8_t, iGRegArg, /*=*/iGReg, 3);
7561 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize, 4);
7562 IEM_MC_LOCAL(RTGCPTR, GCPtrEff);
7563 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
7564 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7565 if (IEM_IS_GUEST_CPU_AMD(pVCpu)) /** @todo testcase: rev 3.15 of the amd manuals claims it only loads a 32-bit greg. */
7566 IEM_MC_FETCH_MEM_U32_SX_U64(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEff);
7567 else
7568 IEM_MC_FETCH_MEM_U64(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEff);
7569 IEM_MC_FETCH_MEM_U16_DISP(uSel, pVCpu->iem.s.iEffSeg, GCPtrEff, 8);
7570 IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
7571 IEM_MC_END();
7572 return VINF_SUCCESS;
7573
7574 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7575 }
7576}
7577
7578
7579/** Opcode 0x0f 0xb2. */
7580FNIEMOP_DEF(iemOp_lss_Gv_Mp)
7581{
7582 IEMOP_MNEMONIC(lss_Gv_Mp, "lss Gv,Mp");
7583 IEMOP_HLP_MIN_386();
7584 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7585 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7586 return IEMOP_RAISE_INVALID_OPCODE();
7587 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_SS, bRm);
7588}
7589
7590
7591/** Opcode 0x0f 0xb3. */
7592FNIEMOP_DEF(iemOp_btr_Ev_Gv)
7593{
7594 IEMOP_MNEMONIC(btr_Ev_Gv, "btr Ev,Gv");
7595 IEMOP_HLP_MIN_386();
7596 return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_btr);
7597}
7598
7599
7600/** Opcode 0x0f 0xb4. */
7601FNIEMOP_DEF(iemOp_lfs_Gv_Mp)
7602{
7603 IEMOP_MNEMONIC(lfs_Gv_Mp, "lfs Gv,Mp");
7604 IEMOP_HLP_MIN_386();
7605 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7606 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7607 return IEMOP_RAISE_INVALID_OPCODE();
7608 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_FS, bRm);
7609}
7610
7611
7612/** Opcode 0x0f 0xb5. */
7613FNIEMOP_DEF(iemOp_lgs_Gv_Mp)
7614{
7615 IEMOP_MNEMONIC(lgs_Gv_Mp, "lgs Gv,Mp");
7616 IEMOP_HLP_MIN_386();
7617 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7618 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7619 return IEMOP_RAISE_INVALID_OPCODE();
7620 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_GS, bRm);
7621}
7622
7623
7624/** Opcode 0x0f 0xb6. */
7625FNIEMOP_DEF(iemOp_movzx_Gv_Eb)
7626{
7627 IEMOP_MNEMONIC(movzx_Gv_Eb, "movzx Gv,Eb");
7628 IEMOP_HLP_MIN_386();
7629
7630 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7631
7632 /*
7633 * If rm is denoting a register, no more instruction bytes.
7634 */
7635 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7636 {
7637 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7638 switch (pVCpu->iem.s.enmEffOpSize)
7639 {
7640 case IEMMODE_16BIT:
7641 IEM_MC_BEGIN(0, 1);
7642 IEM_MC_LOCAL(uint16_t, u16Value);
7643 IEM_MC_FETCH_GREG_U8_ZX_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7644 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Value);
7645 IEM_MC_ADVANCE_RIP();
7646 IEM_MC_END();
7647 return VINF_SUCCESS;
7648
7649 case IEMMODE_32BIT:
7650 IEM_MC_BEGIN(0, 1);
7651 IEM_MC_LOCAL(uint32_t, u32Value);
7652 IEM_MC_FETCH_GREG_U8_ZX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7653 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
7654 IEM_MC_ADVANCE_RIP();
7655 IEM_MC_END();
7656 return VINF_SUCCESS;
7657
7658 case IEMMODE_64BIT:
7659 IEM_MC_BEGIN(0, 1);
7660 IEM_MC_LOCAL(uint64_t, u64Value);
7661 IEM_MC_FETCH_GREG_U8_ZX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7662 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
7663 IEM_MC_ADVANCE_RIP();
7664 IEM_MC_END();
7665 return VINF_SUCCESS;
7666
7667 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7668 }
7669 }
7670 else
7671 {
7672 /*
7673 * We're loading a register from memory.
7674 */
7675 switch (pVCpu->iem.s.enmEffOpSize)
7676 {
7677 case IEMMODE_16BIT:
7678 IEM_MC_BEGIN(0, 2);
7679 IEM_MC_LOCAL(uint16_t, u16Value);
7680 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7681 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7682 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7683 IEM_MC_FETCH_MEM_U8_ZX_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7684 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Value);
7685 IEM_MC_ADVANCE_RIP();
7686 IEM_MC_END();
7687 return VINF_SUCCESS;
7688
7689 case IEMMODE_32BIT:
7690 IEM_MC_BEGIN(0, 2);
7691 IEM_MC_LOCAL(uint32_t, u32Value);
7692 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7693 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7694 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7695 IEM_MC_FETCH_MEM_U8_ZX_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7696 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
7697 IEM_MC_ADVANCE_RIP();
7698 IEM_MC_END();
7699 return VINF_SUCCESS;
7700
7701 case IEMMODE_64BIT:
7702 IEM_MC_BEGIN(0, 2);
7703 IEM_MC_LOCAL(uint64_t, u64Value);
7704 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7705 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7706 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7707 IEM_MC_FETCH_MEM_U8_ZX_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7708 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
7709 IEM_MC_ADVANCE_RIP();
7710 IEM_MC_END();
7711 return VINF_SUCCESS;
7712
7713 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7714 }
7715 }
7716}
7717
7718
7719/** Opcode 0x0f 0xb7. */
7720FNIEMOP_DEF(iemOp_movzx_Gv_Ew)
7721{
7722 IEMOP_MNEMONIC(movzx_Gv_Ew, "movzx Gv,Ew");
7723 IEMOP_HLP_MIN_386();
7724
7725 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7726
7727 /** @todo Not entirely sure how the operand size prefix is handled here,
7728 * assuming that it will be ignored. Would be nice to have a few
7729 * test for this. */
7730 /*
7731 * If rm is denoting a register, no more instruction bytes.
7732 */
7733 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7734 {
7735 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7736 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT)
7737 {
7738 IEM_MC_BEGIN(0, 1);
7739 IEM_MC_LOCAL(uint32_t, u32Value);
7740 IEM_MC_FETCH_GREG_U16_ZX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7741 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
7742 IEM_MC_ADVANCE_RIP();
7743 IEM_MC_END();
7744 }
7745 else
7746 {
7747 IEM_MC_BEGIN(0, 1);
7748 IEM_MC_LOCAL(uint64_t, u64Value);
7749 IEM_MC_FETCH_GREG_U16_ZX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7750 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
7751 IEM_MC_ADVANCE_RIP();
7752 IEM_MC_END();
7753 }
7754 }
7755 else
7756 {
7757 /*
7758 * We're loading a register from memory.
7759 */
7760 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT)
7761 {
7762 IEM_MC_BEGIN(0, 2);
7763 IEM_MC_LOCAL(uint32_t, u32Value);
7764 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7765 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7766 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7767 IEM_MC_FETCH_MEM_U16_ZX_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7768 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
7769 IEM_MC_ADVANCE_RIP();
7770 IEM_MC_END();
7771 }
7772 else
7773 {
7774 IEM_MC_BEGIN(0, 2);
7775 IEM_MC_LOCAL(uint64_t, u64Value);
7776 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7777 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7778 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7779 IEM_MC_FETCH_MEM_U16_ZX_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7780 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
7781 IEM_MC_ADVANCE_RIP();
7782 IEM_MC_END();
7783 }
7784 }
7785 return VINF_SUCCESS;
7786}
7787
7788
7789/** Opcode 0x0f 0xb8 - JMPE (reserved for emulator on IPF) */
7790FNIEMOP_UD_STUB(iemOp_jmpe);
7791/** Opcode 0xf3 0x0f 0xb8 - POPCNT Gv, Ev */
7792FNIEMOP_STUB(iemOp_popcnt_Gv_Ev);
7793
7794
7795/**
7796 * @opcode 0xb9
7797 * @opinvalid intel-modrm
7798 * @optest ->
7799 */
7800FNIEMOP_DEF(iemOp_Grp10)
7801{
7802 /*
7803 * AMD does not decode beyond the 0xb9 whereas intel does the modr/m bit
7804 * too. See bs3-cpu-decoder-1.c32. So, we can forward to iemOp_InvalidNeedRM.
7805 */
7806 Log(("iemOp_Grp10 aka UD1 -> #UD\n"));
7807 IEMOP_MNEMONIC2EX(ud1, "ud1", RM, UD1, ud1, Gb, Eb, DISOPTYPE_INVALID, IEMOPHINT_IGNORES_OP_SIZES); /* just picked Gb,Eb here. */
7808 return FNIEMOP_CALL(iemOp_InvalidNeedRM);
7809}
7810
7811
7812/** Opcode 0x0f 0xba. */
7813FNIEMOP_DEF(iemOp_Grp8)
7814{
7815 IEMOP_HLP_MIN_386();
7816 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7817 PCIEMOPBINSIZES pImpl;
7818 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
7819 {
7820 case 0: case 1: case 2: case 3:
7821 /* Both AMD and Intel want full modr/m decoding and imm8. */
7822 return FNIEMOP_CALL_1(iemOp_InvalidWithRMAllNeedImm8, bRm);
7823 case 4: pImpl = &g_iemAImpl_bt; IEMOP_MNEMONIC(bt_Ev_Ib, "bt Ev,Ib"); break;
7824 case 5: pImpl = &g_iemAImpl_bts; IEMOP_MNEMONIC(bts_Ev_Ib, "bts Ev,Ib"); break;
7825 case 6: pImpl = &g_iemAImpl_btr; IEMOP_MNEMONIC(btr_Ev_Ib, "btr Ev,Ib"); break;
7826 case 7: pImpl = &g_iemAImpl_btc; IEMOP_MNEMONIC(btc_Ev_Ib, "btc Ev,Ib"); break;
7827 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7828 }
7829 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
7830
7831 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7832 {
7833 /* register destination. */
7834 uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
7835 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7836
7837 switch (pVCpu->iem.s.enmEffOpSize)
7838 {
7839 case IEMMODE_16BIT:
7840 IEM_MC_BEGIN(3, 0);
7841 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
7842 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ u8Bit & 0x0f, 1);
7843 IEM_MC_ARG(uint32_t *, pEFlags, 2);
7844
7845 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7846 IEM_MC_REF_EFLAGS(pEFlags);
7847 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
7848
7849 IEM_MC_ADVANCE_RIP();
7850 IEM_MC_END();
7851 return VINF_SUCCESS;
7852
7853 case IEMMODE_32BIT:
7854 IEM_MC_BEGIN(3, 0);
7855 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
7856 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ u8Bit & 0x1f, 1);
7857 IEM_MC_ARG(uint32_t *, pEFlags, 2);
7858
7859 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7860 IEM_MC_REF_EFLAGS(pEFlags);
7861 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
7862
7863 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
7864 IEM_MC_ADVANCE_RIP();
7865 IEM_MC_END();
7866 return VINF_SUCCESS;
7867
7868 case IEMMODE_64BIT:
7869 IEM_MC_BEGIN(3, 0);
7870 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
7871 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ u8Bit & 0x3f, 1);
7872 IEM_MC_ARG(uint32_t *, pEFlags, 2);
7873
7874 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
7875 IEM_MC_REF_EFLAGS(pEFlags);
7876 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
7877
7878 IEM_MC_ADVANCE_RIP();
7879 IEM_MC_END();
7880 return VINF_SUCCESS;
7881
7882 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7883 }
7884 }
7885 else
7886 {
7887 /* memory destination. */
7888
7889 uint32_t fAccess;
7890 if (pImpl->pfnLockedU16)
7891 fAccess = IEM_ACCESS_DATA_RW;
7892 else /* BT */
7893 fAccess = IEM_ACCESS_DATA_R;
7894
7895 /** @todo test negative bit offsets! */
7896 switch (pVCpu->iem.s.enmEffOpSize)
7897 {
7898 case IEMMODE_16BIT:
7899 IEM_MC_BEGIN(3, 1);
7900 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
7901 IEM_MC_ARG(uint16_t, u16Src, 1);
7902 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
7903 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7904
7905 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
7906 uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
7907 IEM_MC_ASSIGN(u16Src, u8Bit & 0x0f);
7908 if (pImpl->pfnLockedU16)
7909 IEMOP_HLP_DONE_DECODING();
7910 else
7911 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7912 IEM_MC_FETCH_EFLAGS(EFlags);
7913 IEM_MC_MEM_MAP(pu16Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7914 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7915 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
7916 else
7917 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
7918 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
7919
7920 IEM_MC_COMMIT_EFLAGS(EFlags);
7921 IEM_MC_ADVANCE_RIP();
7922 IEM_MC_END();
7923 return VINF_SUCCESS;
7924
7925 case IEMMODE_32BIT:
7926 IEM_MC_BEGIN(3, 1);
7927 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
7928 IEM_MC_ARG(uint32_t, u32Src, 1);
7929 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
7930 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7931
7932 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
7933 uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
7934 IEM_MC_ASSIGN(u32Src, u8Bit & 0x1f);
7935 if (pImpl->pfnLockedU16)
7936 IEMOP_HLP_DONE_DECODING();
7937 else
7938 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7939 IEM_MC_FETCH_EFLAGS(EFlags);
7940 IEM_MC_MEM_MAP(pu32Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7941 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7942 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
7943 else
7944 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
7945 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
7946
7947 IEM_MC_COMMIT_EFLAGS(EFlags);
7948 IEM_MC_ADVANCE_RIP();
7949 IEM_MC_END();
7950 return VINF_SUCCESS;
7951
7952 case IEMMODE_64BIT:
7953 IEM_MC_BEGIN(3, 1);
7954 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
7955 IEM_MC_ARG(uint64_t, u64Src, 1);
7956 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
7957 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7958
7959 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
7960 uint8_t u8Bit; IEM_OPCODE_GET_NEXT_U8(&u8Bit);
7961 IEM_MC_ASSIGN(u64Src, u8Bit & 0x3f);
7962 if (pImpl->pfnLockedU16)
7963 IEMOP_HLP_DONE_DECODING();
7964 else
7965 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7966 IEM_MC_FETCH_EFLAGS(EFlags);
7967 IEM_MC_MEM_MAP(pu64Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0);
7968 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
7969 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
7970 else
7971 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
7972 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
7973
7974 IEM_MC_COMMIT_EFLAGS(EFlags);
7975 IEM_MC_ADVANCE_RIP();
7976 IEM_MC_END();
7977 return VINF_SUCCESS;
7978
7979 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7980 }
7981 }
7982}
7983
7984
7985/** Opcode 0x0f 0xbb. */
7986FNIEMOP_DEF(iemOp_btc_Ev_Gv)
7987{
7988 IEMOP_MNEMONIC(btc_Ev_Gv, "btc Ev,Gv");
7989 IEMOP_HLP_MIN_386();
7990 return FNIEMOP_CALL_1(iemOpCommonBit_Ev_Gv, &g_iemAImpl_btc);
7991}
7992
7993
7994/** Opcode 0x0f 0xbc. */
7995FNIEMOP_DEF(iemOp_bsf_Gv_Ev)
7996{
7997 IEMOP_MNEMONIC(bsf_Gv_Ev, "bsf Gv,Ev");
7998 IEMOP_HLP_MIN_386();
7999 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
8000 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_bsf);
8001}
8002
8003
8004/** Opcode 0xf3 0x0f 0xbc - TZCNT Gv, Ev */
8005FNIEMOP_STUB(iemOp_tzcnt_Gv_Ev);
8006
8007
8008/** Opcode 0x0f 0xbd. */
8009FNIEMOP_DEF(iemOp_bsr_Gv_Ev)
8010{
8011 IEMOP_MNEMONIC(bsr_Gv_Ev, "bsr Gv,Ev");
8012 IEMOP_HLP_MIN_386();
8013 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
8014 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_bsr);
8015}
8016
8017
8018/** Opcode 0xf3 0x0f 0xbd - LZCNT Gv, Ev */
8019FNIEMOP_STUB(iemOp_lzcnt_Gv_Ev);
8020
8021
8022/** Opcode 0x0f 0xbe. */
8023FNIEMOP_DEF(iemOp_movsx_Gv_Eb)
8024{
8025 IEMOP_MNEMONIC(movsx_Gv_Eb, "movsx Gv,Eb");
8026 IEMOP_HLP_MIN_386();
8027
8028 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8029
8030 /*
8031 * If rm is denoting a register, no more instruction bytes.
8032 */
8033 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8034 {
8035 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8036 switch (pVCpu->iem.s.enmEffOpSize)
8037 {
8038 case IEMMODE_16BIT:
8039 IEM_MC_BEGIN(0, 1);
8040 IEM_MC_LOCAL(uint16_t, u16Value);
8041 IEM_MC_FETCH_GREG_U8_SX_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8042 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Value);
8043 IEM_MC_ADVANCE_RIP();
8044 IEM_MC_END();
8045 return VINF_SUCCESS;
8046
8047 case IEMMODE_32BIT:
8048 IEM_MC_BEGIN(0, 1);
8049 IEM_MC_LOCAL(uint32_t, u32Value);
8050 IEM_MC_FETCH_GREG_U8_SX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8051 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
8052 IEM_MC_ADVANCE_RIP();
8053 IEM_MC_END();
8054 return VINF_SUCCESS;
8055
8056 case IEMMODE_64BIT:
8057 IEM_MC_BEGIN(0, 1);
8058 IEM_MC_LOCAL(uint64_t, u64Value);
8059 IEM_MC_FETCH_GREG_U8_SX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8060 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
8061 IEM_MC_ADVANCE_RIP();
8062 IEM_MC_END();
8063 return VINF_SUCCESS;
8064
8065 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8066 }
8067 }
8068 else
8069 {
8070 /*
8071 * We're loading a register from memory.
8072 */
8073 switch (pVCpu->iem.s.enmEffOpSize)
8074 {
8075 case IEMMODE_16BIT:
8076 IEM_MC_BEGIN(0, 2);
8077 IEM_MC_LOCAL(uint16_t, u16Value);
8078 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8079 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8080 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8081 IEM_MC_FETCH_MEM_U8_SX_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8082 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Value);
8083 IEM_MC_ADVANCE_RIP();
8084 IEM_MC_END();
8085 return VINF_SUCCESS;
8086
8087 case IEMMODE_32BIT:
8088 IEM_MC_BEGIN(0, 2);
8089 IEM_MC_LOCAL(uint32_t, u32Value);
8090 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8091 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8092 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8093 IEM_MC_FETCH_MEM_U8_SX_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8094 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
8095 IEM_MC_ADVANCE_RIP();
8096 IEM_MC_END();
8097 return VINF_SUCCESS;
8098
8099 case IEMMODE_64BIT:
8100 IEM_MC_BEGIN(0, 2);
8101 IEM_MC_LOCAL(uint64_t, u64Value);
8102 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8103 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8104 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8105 IEM_MC_FETCH_MEM_U8_SX_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8106 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
8107 IEM_MC_ADVANCE_RIP();
8108 IEM_MC_END();
8109 return VINF_SUCCESS;
8110
8111 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8112 }
8113 }
8114}
8115
8116
8117/** Opcode 0x0f 0xbf. */
8118FNIEMOP_DEF(iemOp_movsx_Gv_Ew)
8119{
8120 IEMOP_MNEMONIC(movsx_Gv_Ew, "movsx Gv,Ew");
8121 IEMOP_HLP_MIN_386();
8122
8123 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8124
8125 /** @todo Not entirely sure how the operand size prefix is handled here,
8126 * assuming that it will be ignored. Would be nice to have a few
8127 * test for this. */
8128 /*
8129 * If rm is denoting a register, no more instruction bytes.
8130 */
8131 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8132 {
8133 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8134 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT)
8135 {
8136 IEM_MC_BEGIN(0, 1);
8137 IEM_MC_LOCAL(uint32_t, u32Value);
8138 IEM_MC_FETCH_GREG_U16_SX_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8139 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
8140 IEM_MC_ADVANCE_RIP();
8141 IEM_MC_END();
8142 }
8143 else
8144 {
8145 IEM_MC_BEGIN(0, 1);
8146 IEM_MC_LOCAL(uint64_t, u64Value);
8147 IEM_MC_FETCH_GREG_U16_SX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8148 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
8149 IEM_MC_ADVANCE_RIP();
8150 IEM_MC_END();
8151 }
8152 }
8153 else
8154 {
8155 /*
8156 * We're loading a register from memory.
8157 */
8158 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT)
8159 {
8160 IEM_MC_BEGIN(0, 2);
8161 IEM_MC_LOCAL(uint32_t, u32Value);
8162 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8163 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8164 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8165 IEM_MC_FETCH_MEM_U16_SX_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8166 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
8167 IEM_MC_ADVANCE_RIP();
8168 IEM_MC_END();
8169 }
8170 else
8171 {
8172 IEM_MC_BEGIN(0, 2);
8173 IEM_MC_LOCAL(uint64_t, u64Value);
8174 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8175 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8176 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8177 IEM_MC_FETCH_MEM_U16_SX_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8178 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
8179 IEM_MC_ADVANCE_RIP();
8180 IEM_MC_END();
8181 }
8182 }
8183 return VINF_SUCCESS;
8184}
8185
8186
8187/** Opcode 0x0f 0xc0. */
8188FNIEMOP_DEF(iemOp_xadd_Eb_Gb)
8189{
8190 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8191 IEMOP_HLP_MIN_486();
8192 IEMOP_MNEMONIC(xadd_Eb_Gb, "xadd Eb,Gb");
8193
8194 /*
8195 * If rm is denoting a register, no more instruction bytes.
8196 */
8197 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8198 {
8199 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8200
8201 IEM_MC_BEGIN(3, 0);
8202 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
8203 IEM_MC_ARG(uint8_t *, pu8Reg, 1);
8204 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8205
8206 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8207 IEM_MC_REF_GREG_U8(pu8Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8208 IEM_MC_REF_EFLAGS(pEFlags);
8209 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u8, pu8Dst, pu8Reg, pEFlags);
8210
8211 IEM_MC_ADVANCE_RIP();
8212 IEM_MC_END();
8213 }
8214 else
8215 {
8216 /*
8217 * We're accessing memory.
8218 */
8219 IEM_MC_BEGIN(3, 3);
8220 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
8221 IEM_MC_ARG(uint8_t *, pu8Reg, 1);
8222 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8223 IEM_MC_LOCAL(uint8_t, u8RegCopy);
8224 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8225
8226 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8227 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
8228 IEM_MC_FETCH_GREG_U8(u8RegCopy, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8229 IEM_MC_REF_LOCAL(pu8Reg, u8RegCopy);
8230 IEM_MC_FETCH_EFLAGS(EFlags);
8231 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
8232 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u8, pu8Dst, pu8Reg, pEFlags);
8233 else
8234 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u8_locked, pu8Dst, pu8Reg, pEFlags);
8235
8236 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
8237 IEM_MC_COMMIT_EFLAGS(EFlags);
8238 IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u8RegCopy);
8239 IEM_MC_ADVANCE_RIP();
8240 IEM_MC_END();
8241 return VINF_SUCCESS;
8242 }
8243 return VINF_SUCCESS;
8244}
8245
8246
8247/** Opcode 0x0f 0xc1. */
8248FNIEMOP_DEF(iemOp_xadd_Ev_Gv)
8249{
8250 IEMOP_MNEMONIC(xadd_Ev_Gv, "xadd Ev,Gv");
8251 IEMOP_HLP_MIN_486();
8252 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8253
8254 /*
8255 * If rm is denoting a register, no more instruction bytes.
8256 */
8257 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8258 {
8259 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8260
8261 switch (pVCpu->iem.s.enmEffOpSize)
8262 {
8263 case IEMMODE_16BIT:
8264 IEM_MC_BEGIN(3, 0);
8265 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
8266 IEM_MC_ARG(uint16_t *, pu16Reg, 1);
8267 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8268
8269 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8270 IEM_MC_REF_GREG_U16(pu16Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8271 IEM_MC_REF_EFLAGS(pEFlags);
8272 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u16, pu16Dst, pu16Reg, pEFlags);
8273
8274 IEM_MC_ADVANCE_RIP();
8275 IEM_MC_END();
8276 return VINF_SUCCESS;
8277
8278 case IEMMODE_32BIT:
8279 IEM_MC_BEGIN(3, 0);
8280 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8281 IEM_MC_ARG(uint32_t *, pu32Reg, 1);
8282 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8283
8284 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8285 IEM_MC_REF_GREG_U32(pu32Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8286 IEM_MC_REF_EFLAGS(pEFlags);
8287 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u32, pu32Dst, pu32Reg, pEFlags);
8288
8289 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
8290 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Reg);
8291 IEM_MC_ADVANCE_RIP();
8292 IEM_MC_END();
8293 return VINF_SUCCESS;
8294
8295 case IEMMODE_64BIT:
8296 IEM_MC_BEGIN(3, 0);
8297 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8298 IEM_MC_ARG(uint64_t *, pu64Reg, 1);
8299 IEM_MC_ARG(uint32_t *, pEFlags, 2);
8300
8301 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
8302 IEM_MC_REF_GREG_U64(pu64Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8303 IEM_MC_REF_EFLAGS(pEFlags);
8304 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u64, pu64Dst, pu64Reg, pEFlags);
8305
8306 IEM_MC_ADVANCE_RIP();
8307 IEM_MC_END();
8308 return VINF_SUCCESS;
8309
8310 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8311 }
8312 }
8313 else
8314 {
8315 /*
8316 * We're accessing memory.
8317 */
8318 switch (pVCpu->iem.s.enmEffOpSize)
8319 {
8320 case IEMMODE_16BIT:
8321 IEM_MC_BEGIN(3, 3);
8322 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
8323 IEM_MC_ARG(uint16_t *, pu16Reg, 1);
8324 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8325 IEM_MC_LOCAL(uint16_t, u16RegCopy);
8326 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8327
8328 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8329 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
8330 IEM_MC_FETCH_GREG_U16(u16RegCopy, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8331 IEM_MC_REF_LOCAL(pu16Reg, u16RegCopy);
8332 IEM_MC_FETCH_EFLAGS(EFlags);
8333 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
8334 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u16, pu16Dst, pu16Reg, pEFlags);
8335 else
8336 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u16_locked, pu16Dst, pu16Reg, pEFlags);
8337
8338 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
8339 IEM_MC_COMMIT_EFLAGS(EFlags);
8340 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16RegCopy);
8341 IEM_MC_ADVANCE_RIP();
8342 IEM_MC_END();
8343 return VINF_SUCCESS;
8344
8345 case IEMMODE_32BIT:
8346 IEM_MC_BEGIN(3, 3);
8347 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8348 IEM_MC_ARG(uint32_t *, pu32Reg, 1);
8349 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8350 IEM_MC_LOCAL(uint32_t, u32RegCopy);
8351 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8352
8353 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8354 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
8355 IEM_MC_FETCH_GREG_U32(u32RegCopy, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8356 IEM_MC_REF_LOCAL(pu32Reg, u32RegCopy);
8357 IEM_MC_FETCH_EFLAGS(EFlags);
8358 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
8359 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u32, pu32Dst, pu32Reg, pEFlags);
8360 else
8361 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u32_locked, pu32Dst, pu32Reg, pEFlags);
8362
8363 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
8364 IEM_MC_COMMIT_EFLAGS(EFlags);
8365 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32RegCopy);
8366 IEM_MC_ADVANCE_RIP();
8367 IEM_MC_END();
8368 return VINF_SUCCESS;
8369
8370 case IEMMODE_64BIT:
8371 IEM_MC_BEGIN(3, 3);
8372 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8373 IEM_MC_ARG(uint64_t *, pu64Reg, 1);
8374 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
8375 IEM_MC_LOCAL(uint64_t, u64RegCopy);
8376 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8377
8378 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8379 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
8380 IEM_MC_FETCH_GREG_U64(u64RegCopy, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8381 IEM_MC_REF_LOCAL(pu64Reg, u64RegCopy);
8382 IEM_MC_FETCH_EFLAGS(EFlags);
8383 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
8384 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u64, pu64Dst, pu64Reg, pEFlags);
8385 else
8386 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_xadd_u64_locked, pu64Dst, pu64Reg, pEFlags);
8387
8388 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
8389 IEM_MC_COMMIT_EFLAGS(EFlags);
8390 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64RegCopy);
8391 IEM_MC_ADVANCE_RIP();
8392 IEM_MC_END();
8393 return VINF_SUCCESS;
8394
8395 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8396 }
8397 }
8398}
8399
8400
8401/** Opcode 0x0f 0xc2 - cmpps Vps,Wps,Ib */
8402FNIEMOP_STUB(iemOp_cmpps_Vps_Wps_Ib);
8403/** Opcode 0x66 0x0f 0xc2 - cmppd Vpd,Wpd,Ib */
8404FNIEMOP_STUB(iemOp_cmppd_Vpd_Wpd_Ib);
8405/** Opcode 0xf3 0x0f 0xc2 - cmpss Vss,Wss,Ib */
8406FNIEMOP_STUB(iemOp_cmpss_Vss_Wss_Ib);
8407/** Opcode 0xf2 0x0f 0xc2 - cmpsd Vsd,Wsd,Ib */
8408FNIEMOP_STUB(iemOp_cmpsd_Vsd_Wsd_Ib);
8409
8410
8411/** Opcode 0x0f 0xc3. */
8412FNIEMOP_DEF(iemOp_movnti_My_Gy)
8413{
8414 IEMOP_MNEMONIC(movnti_My_Gy, "movnti My,Gy");
8415
8416 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8417
8418 /* Only the register -> memory form makes sense, assuming #UD for the other form. */
8419 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
8420 {
8421 switch (pVCpu->iem.s.enmEffOpSize)
8422 {
8423 case IEMMODE_32BIT:
8424 IEM_MC_BEGIN(0, 2);
8425 IEM_MC_LOCAL(uint32_t, u32Value);
8426 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8427
8428 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8429 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8430 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2)
8431 return IEMOP_RAISE_INVALID_OPCODE();
8432
8433 IEM_MC_FETCH_GREG_U32(u32Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8434 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u32Value);
8435 IEM_MC_ADVANCE_RIP();
8436 IEM_MC_END();
8437 break;
8438
8439 case IEMMODE_64BIT:
8440 IEM_MC_BEGIN(0, 2);
8441 IEM_MC_LOCAL(uint64_t, u64Value);
8442 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8443
8444 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8445 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8446 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2)
8447 return IEMOP_RAISE_INVALID_OPCODE();
8448
8449 IEM_MC_FETCH_GREG_U64(u64Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8450 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u64Value);
8451 IEM_MC_ADVANCE_RIP();
8452 IEM_MC_END();
8453 break;
8454
8455 case IEMMODE_16BIT:
8456 /** @todo check this form. */
8457 return IEMOP_RAISE_INVALID_OPCODE();
8458 }
8459 }
8460 else
8461 return IEMOP_RAISE_INVALID_OPCODE();
8462 return VINF_SUCCESS;
8463}
8464/* Opcode 0x66 0x0f 0xc3 - invalid */
8465/* Opcode 0xf3 0x0f 0xc3 - invalid */
8466/* Opcode 0xf2 0x0f 0xc3 - invalid */
8467
8468/** Opcode 0x0f 0xc4 - pinsrw Pq, Ry/Mw,Ib */
8469FNIEMOP_STUB(iemOp_pinsrw_Pq_RyMw_Ib);
8470/** Opcode 0x66 0x0f 0xc4 - pinsrw Vdq, Ry/Mw,Ib */
8471FNIEMOP_STUB(iemOp_pinsrw_Vdq_RyMw_Ib);
8472/* Opcode 0xf3 0x0f 0xc4 - invalid */
8473/* Opcode 0xf2 0x0f 0xc4 - invalid */
8474
8475/** Opcode 0x0f 0xc5 - pextrw Gd, Nq, Ib */
8476FNIEMOP_STUB(iemOp_pextrw_Gd_Nq_Ib);
8477/** Opcode 0x66 0x0f 0xc5 - pextrw Gd, Udq, Ib */
8478FNIEMOP_STUB(iemOp_pextrw_Gd_Udq_Ib);
8479/* Opcode 0xf3 0x0f 0xc5 - invalid */
8480/* Opcode 0xf2 0x0f 0xc5 - invalid */
8481
8482/** Opcode 0x0f 0xc6 - shufps Vps, Wps, Ib */
8483FNIEMOP_STUB(iemOp_shufps_Vps_Wps_Ib);
8484/** Opcode 0x66 0x0f 0xc6 - shufpd Vpd, Wpd, Ib */
8485FNIEMOP_STUB(iemOp_shufpd_Vpd_Wpd_Ib);
8486/* Opcode 0xf3 0x0f 0xc6 - invalid */
8487/* Opcode 0xf2 0x0f 0xc6 - invalid */
8488
8489
8490/** Opcode 0x0f 0xc7 !11/1. */
8491FNIEMOP_DEF_1(iemOp_Grp9_cmpxchg8b_Mq, uint8_t, bRm)
8492{
8493 IEMOP_MNEMONIC(cmpxchg8b, "cmpxchg8b Mq");
8494
8495 IEM_MC_BEGIN(4, 3);
8496 IEM_MC_ARG(uint64_t *, pu64MemDst, 0);
8497 IEM_MC_ARG(PRTUINT64U, pu64EaxEdx, 1);
8498 IEM_MC_ARG(PRTUINT64U, pu64EbxEcx, 2);
8499 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 3);
8500 IEM_MC_LOCAL(RTUINT64U, u64EaxEdx);
8501 IEM_MC_LOCAL(RTUINT64U, u64EbxEcx);
8502 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8503
8504 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8505 IEMOP_HLP_DONE_DECODING();
8506 IEM_MC_MEM_MAP(pu64MemDst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
8507
8508 IEM_MC_FETCH_GREG_U32(u64EaxEdx.s.Lo, X86_GREG_xAX);
8509 IEM_MC_FETCH_GREG_U32(u64EaxEdx.s.Hi, X86_GREG_xDX);
8510 IEM_MC_REF_LOCAL(pu64EaxEdx, u64EaxEdx);
8511
8512 IEM_MC_FETCH_GREG_U32(u64EbxEcx.s.Lo, X86_GREG_xBX);
8513 IEM_MC_FETCH_GREG_U32(u64EbxEcx.s.Hi, X86_GREG_xCX);
8514 IEM_MC_REF_LOCAL(pu64EbxEcx, u64EbxEcx);
8515
8516 IEM_MC_FETCH_EFLAGS(EFlags);
8517 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
8518 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg8b, pu64MemDst, pu64EaxEdx, pu64EbxEcx, pEFlags);
8519 else
8520 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg8b_locked, pu64MemDst, pu64EaxEdx, pu64EbxEcx, pEFlags);
8521
8522 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64MemDst, IEM_ACCESS_DATA_RW);
8523 IEM_MC_COMMIT_EFLAGS(EFlags);
8524 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF)
8525 /** @todo Testcase: Check effect of cmpxchg8b on bits 63:32 in rax and rdx. */
8526 IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u64EaxEdx.s.Lo);
8527 IEM_MC_STORE_GREG_U32(X86_GREG_xDX, u64EaxEdx.s.Hi);
8528 IEM_MC_ENDIF();
8529 IEM_MC_ADVANCE_RIP();
8530
8531 IEM_MC_END();
8532 return VINF_SUCCESS;
8533}
8534
8535
8536/** Opcode REX.W 0x0f 0xc7 !11/1. */
8537FNIEMOP_DEF_1(iemOp_Grp9_cmpxchg16b_Mdq, uint8_t, bRm)
8538{
8539 IEMOP_MNEMONIC(cmpxchg16b, "cmpxchg16b Mdq");
8540 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fMovCmpXchg16b)
8541 {
8542#if 0
8543 RT_NOREF(bRm);
8544 IEMOP_BITCH_ABOUT_STUB();
8545 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
8546#else
8547 IEM_MC_BEGIN(4, 3);
8548 IEM_MC_ARG(PRTUINT128U, pu128MemDst, 0);
8549 IEM_MC_ARG(PRTUINT128U, pu128RaxRdx, 1);
8550 IEM_MC_ARG(PRTUINT128U, pu128RbxRcx, 2);
8551 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 3);
8552 IEM_MC_LOCAL(RTUINT128U, u128RaxRdx);
8553 IEM_MC_LOCAL(RTUINT128U, u128RbxRcx);
8554 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8555
8556 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8557 IEMOP_HLP_DONE_DECODING();
8558 IEM_MC_RAISE_GP0_IF_EFF_ADDR_UNALIGNED(GCPtrEffDst, 16);
8559 IEM_MC_MEM_MAP(pu128MemDst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
8560
8561 IEM_MC_FETCH_GREG_U64(u128RaxRdx.s.Lo, X86_GREG_xAX);
8562 IEM_MC_FETCH_GREG_U64(u128RaxRdx.s.Hi, X86_GREG_xDX);
8563 IEM_MC_REF_LOCAL(pu128RaxRdx, u128RaxRdx);
8564
8565 IEM_MC_FETCH_GREG_U64(u128RbxRcx.s.Lo, X86_GREG_xBX);
8566 IEM_MC_FETCH_GREG_U64(u128RbxRcx.s.Hi, X86_GREG_xCX);
8567 IEM_MC_REF_LOCAL(pu128RbxRcx, u128RbxRcx);
8568
8569 IEM_MC_FETCH_EFLAGS(EFlags);
8570# ifdef RT_ARCH_AMD64
8571 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fMovCmpXchg16b)
8572 {
8573 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
8574 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
8575 else
8576 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_locked, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
8577 }
8578 else
8579# endif
8580 {
8581 /* Note! The fallback for 32-bit systems and systems without CX16 is multiple
8582 accesses and not all all atomic, which works fine on in UNI CPU guest
8583 configuration (ignoring DMA). If guest SMP is active we have no choice
8584 but to use a rendezvous callback here. Sigh. */
8585 if (pVCpu->CTX_SUFF(pVM)->cCpus == 1)
8586 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_fallback, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
8587 else
8588 {
8589 IEM_MC_CALL_CIMPL_4(iemCImpl_cmpxchg16b_fallback_rendezvous, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
8590 /* Does not get here, tail code is duplicated in iemCImpl_cmpxchg16b_fallback_rendezvous. */
8591 }
8592 }
8593
8594 IEM_MC_MEM_COMMIT_AND_UNMAP(pu128MemDst, IEM_ACCESS_DATA_RW);
8595 IEM_MC_COMMIT_EFLAGS(EFlags);
8596 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF)
8597 IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u128RaxRdx.s.Lo);
8598 IEM_MC_STORE_GREG_U64(X86_GREG_xDX, u128RaxRdx.s.Hi);
8599 IEM_MC_ENDIF();
8600 IEM_MC_ADVANCE_RIP();
8601
8602 IEM_MC_END();
8603 return VINF_SUCCESS;
8604#endif
8605 }
8606 Log(("cmpxchg16b -> #UD\n"));
8607 return IEMOP_RAISE_INVALID_OPCODE();
8608}
8609
8610FNIEMOP_DEF_1(iemOp_Grp9_cmpxchg8bOr16b, uint8_t, bRm)
8611{
8612 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
8613 return FNIEMOP_CALL_1(iemOp_Grp9_cmpxchg16b_Mdq, bRm);
8614 return FNIEMOP_CALL_1(iemOp_Grp9_cmpxchg8b_Mq, bRm);
8615}
8616
8617/** Opcode 0x0f 0xc7 11/6. */
8618FNIEMOP_UD_STUB_1(iemOp_Grp9_rdrand_Rv, uint8_t, bRm);
8619
8620/** Opcode 0x0f 0xc7 !11/6. */
8621#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
8622FNIEMOP_DEF_1(iemOp_Grp9_vmptrld_Mq, uint8_t, bRm)
8623{
8624 IEMOP_MNEMONIC(vmptrld, "vmptrld");
8625 IEMOP_HLP_IN_VMX_OPERATION("vmptrld", kVmxVDiag_Vmptrld);
8626 IEMOP_HLP_VMX_INSTR("vmptrld", kVmxVDiag_Vmptrld);
8627 IEM_MC_BEGIN(2, 0);
8628 IEM_MC_ARG(uint8_t, iEffSeg, 0);
8629 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
8630 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8631 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
8632 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
8633 IEM_MC_CALL_CIMPL_2(iemCImpl_vmptrld, iEffSeg, GCPtrEffSrc);
8634 IEM_MC_END();
8635 return VINF_SUCCESS;
8636}
8637#else
8638FNIEMOP_UD_STUB_1(iemOp_Grp9_vmptrld_Mq, uint8_t, bRm);
8639#endif
8640
8641/** Opcode 0x66 0x0f 0xc7 !11/6. */
8642#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
8643FNIEMOP_DEF_1(iemOp_Grp9_vmclear_Mq, uint8_t, bRm)
8644{
8645 IEMOP_MNEMONIC(vmclear, "vmclear");
8646 IEMOP_HLP_IN_VMX_OPERATION("vmclear", kVmxVDiag_Vmclear);
8647 IEMOP_HLP_VMX_INSTR("vmclear", kVmxVDiag_Vmclear);
8648 IEM_MC_BEGIN(2, 0);
8649 IEM_MC_ARG(uint8_t, iEffSeg, 0);
8650 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
8651 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8652 IEMOP_HLP_DONE_DECODING();
8653 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
8654 IEM_MC_CALL_CIMPL_2(iemCImpl_vmclear, iEffSeg, GCPtrEffDst);
8655 IEM_MC_END();
8656 return VINF_SUCCESS;
8657}
8658#else
8659FNIEMOP_UD_STUB_1(iemOp_Grp9_vmclear_Mq, uint8_t, bRm);
8660#endif
8661
8662/** Opcode 0xf3 0x0f 0xc7 !11/6. */
8663#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
8664FNIEMOP_DEF_1(iemOp_Grp9_vmxon_Mq, uint8_t, bRm)
8665{
8666 IEMOP_MNEMONIC(vmxon, "vmxon");
8667 IEMOP_HLP_VMX_INSTR("vmxon", kVmxVDiag_Vmxon);
8668 IEM_MC_BEGIN(2, 0);
8669 IEM_MC_ARG(uint8_t, iEffSeg, 0);
8670 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 1);
8671 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8672 IEMOP_HLP_DONE_DECODING();
8673 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
8674 IEM_MC_CALL_CIMPL_2(iemCImpl_vmxon, iEffSeg, GCPtrEffSrc);
8675 IEM_MC_END();
8676 return VINF_SUCCESS;
8677}
8678#else
8679FNIEMOP_UD_STUB_1(iemOp_Grp9_vmxon_Mq, uint8_t, bRm);
8680#endif
8681
8682/** Opcode [0xf3] 0x0f 0xc7 !11/7. */
8683#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
8684FNIEMOP_DEF_1(iemOp_Grp9_vmptrst_Mq, uint8_t, bRm)
8685{
8686 IEMOP_MNEMONIC(vmptrst, "vmptrst");
8687 IEMOP_HLP_IN_VMX_OPERATION("vmptrst", kVmxVDiag_Vmptrst);
8688 IEMOP_HLP_VMX_INSTR("vmptrst", kVmxVDiag_Vmptrst);
8689 IEM_MC_BEGIN(2, 0);
8690 IEM_MC_ARG(uint8_t, iEffSeg, 0);
8691 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 1);
8692 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8693 IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES();
8694 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
8695 IEM_MC_CALL_CIMPL_2(iemCImpl_vmptrst, iEffSeg, GCPtrEffDst);
8696 IEM_MC_END();
8697 return VINF_SUCCESS;
8698}
8699#else
8700FNIEMOP_UD_STUB_1(iemOp_Grp9_vmptrst_Mq, uint8_t, bRm);
8701#endif
8702
8703/** Opcode 0x0f 0xc7 11/7. */
8704FNIEMOP_UD_STUB_1(iemOp_Grp9_rdseed_Rv, uint8_t, bRm);
8705
8706
8707/**
8708 * Group 9 jump table for register variant.
8709 */
8710IEM_STATIC const PFNIEMOPRM g_apfnGroup9RegReg[] =
8711{ /* pfx: none, 066h, 0f3h, 0f2h */
8712 /* /0 */ IEMOP_X4(iemOp_InvalidWithRM),
8713 /* /1 */ IEMOP_X4(iemOp_InvalidWithRM),
8714 /* /2 */ IEMOP_X4(iemOp_InvalidWithRM),
8715 /* /3 */ IEMOP_X4(iemOp_InvalidWithRM),
8716 /* /4 */ IEMOP_X4(iemOp_InvalidWithRM),
8717 /* /5 */ IEMOP_X4(iemOp_InvalidWithRM),
8718 /* /6 */ iemOp_Grp9_rdrand_Rv, iemOp_Grp9_rdrand_Rv, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
8719 /* /7 */ iemOp_Grp9_rdseed_Rv, iemOp_Grp9_rdseed_Rv, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
8720};
8721AssertCompile(RT_ELEMENTS(g_apfnGroup9RegReg) == 8*4);
8722
8723
8724/**
8725 * Group 9 jump table for memory variant.
8726 */
8727IEM_STATIC const PFNIEMOPRM g_apfnGroup9MemReg[] =
8728{ /* pfx: none, 066h, 0f3h, 0f2h */
8729 /* /0 */ IEMOP_X4(iemOp_InvalidWithRM),
8730 /* /1 */ iemOp_Grp9_cmpxchg8bOr16b, iemOp_Grp9_cmpxchg8bOr16b, iemOp_Grp9_cmpxchg8bOr16b, iemOp_Grp9_cmpxchg8bOr16b, /* see bs3-cpu-decoding-1 */
8731 /* /2 */ IEMOP_X4(iemOp_InvalidWithRM),
8732 /* /3 */ IEMOP_X4(iemOp_InvalidWithRM),
8733 /* /4 */ IEMOP_X4(iemOp_InvalidWithRM),
8734 /* /5 */ IEMOP_X4(iemOp_InvalidWithRM),
8735 /* /6 */ iemOp_Grp9_vmptrld_Mq, iemOp_Grp9_vmclear_Mq, iemOp_Grp9_vmxon_Mq, iemOp_InvalidWithRM,
8736 /* /7 */ iemOp_Grp9_vmptrst_Mq, iemOp_InvalidWithRM, iemOp_InvalidWithRM, iemOp_InvalidWithRM,
8737};
8738AssertCompile(RT_ELEMENTS(g_apfnGroup9MemReg) == 8*4);
8739
8740
8741/** Opcode 0x0f 0xc7. */
8742FNIEMOP_DEF(iemOp_Grp9)
8743{
8744 uint8_t bRm; IEM_OPCODE_GET_NEXT_RM(&bRm);
8745 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8746 /* register, register */
8747 return FNIEMOP_CALL_1(g_apfnGroup9RegReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
8748 + pVCpu->iem.s.idxPrefix], bRm);
8749 /* memory, register */
8750 return FNIEMOP_CALL_1(g_apfnGroup9MemReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
8751 + pVCpu->iem.s.idxPrefix], bRm);
8752}
8753
8754
8755/**
8756 * Common 'bswap register' helper.
8757 */
8758FNIEMOP_DEF_1(iemOpCommonBswapGReg, uint8_t, iReg)
8759{
8760 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8761 switch (pVCpu->iem.s.enmEffOpSize)
8762 {
8763 case IEMMODE_16BIT:
8764 IEM_MC_BEGIN(1, 0);
8765 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8766 IEM_MC_REF_GREG_U32(pu32Dst, iReg); /* Don't clear the high dword! */
8767 IEM_MC_CALL_VOID_AIMPL_1(iemAImpl_bswap_u16, pu32Dst);
8768 IEM_MC_ADVANCE_RIP();
8769 IEM_MC_END();
8770 return VINF_SUCCESS;
8771
8772 case IEMMODE_32BIT:
8773 IEM_MC_BEGIN(1, 0);
8774 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
8775 IEM_MC_REF_GREG_U32(pu32Dst, iReg);
8776 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
8777 IEM_MC_CALL_VOID_AIMPL_1(iemAImpl_bswap_u32, pu32Dst);
8778 IEM_MC_ADVANCE_RIP();
8779 IEM_MC_END();
8780 return VINF_SUCCESS;
8781
8782 case IEMMODE_64BIT:
8783 IEM_MC_BEGIN(1, 0);
8784 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
8785 IEM_MC_REF_GREG_U64(pu64Dst, iReg);
8786 IEM_MC_CALL_VOID_AIMPL_1(iemAImpl_bswap_u64, pu64Dst);
8787 IEM_MC_ADVANCE_RIP();
8788 IEM_MC_END();
8789 return VINF_SUCCESS;
8790
8791 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8792 }
8793}
8794
8795
8796/** Opcode 0x0f 0xc8. */
8797FNIEMOP_DEF(iemOp_bswap_rAX_r8)
8798{
8799 IEMOP_MNEMONIC(bswap_rAX_r8, "bswap rAX/r8");
8800 /* Note! Intel manuals states that R8-R15 can be accessed by using a REX.X
8801 prefix. REX.B is the correct prefix it appears. For a parallel
8802 case, see iemOp_mov_AL_Ib and iemOp_mov_eAX_Iv. */
8803 IEMOP_HLP_MIN_486();
8804 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xAX | pVCpu->iem.s.uRexB);
8805}
8806
8807
8808/** Opcode 0x0f 0xc9. */
8809FNIEMOP_DEF(iemOp_bswap_rCX_r9)
8810{
8811 IEMOP_MNEMONIC(bswap_rCX_r9, "bswap rCX/r9");
8812 IEMOP_HLP_MIN_486();
8813 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xCX | pVCpu->iem.s.uRexB);
8814}
8815
8816
8817/** Opcode 0x0f 0xca. */
8818FNIEMOP_DEF(iemOp_bswap_rDX_r10)
8819{
8820 IEMOP_MNEMONIC(bswap_rDX_r9, "bswap rDX/r9");
8821 IEMOP_HLP_MIN_486();
8822 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xDX | pVCpu->iem.s.uRexB);
8823}
8824
8825
8826/** Opcode 0x0f 0xcb. */
8827FNIEMOP_DEF(iemOp_bswap_rBX_r11)
8828{
8829 IEMOP_MNEMONIC(bswap_rBX_r9, "bswap rBX/r9");
8830 IEMOP_HLP_MIN_486();
8831 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xBX | pVCpu->iem.s.uRexB);
8832}
8833
8834
8835/** Opcode 0x0f 0xcc. */
8836FNIEMOP_DEF(iemOp_bswap_rSP_r12)
8837{
8838 IEMOP_MNEMONIC(bswap_rSP_r12, "bswap rSP/r12");
8839 IEMOP_HLP_MIN_486();
8840 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xSP | pVCpu->iem.s.uRexB);
8841}
8842
8843
8844/** Opcode 0x0f 0xcd. */
8845FNIEMOP_DEF(iemOp_bswap_rBP_r13)
8846{
8847 IEMOP_MNEMONIC(bswap_rBP_r13, "bswap rBP/r13");
8848 IEMOP_HLP_MIN_486();
8849 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xBP | pVCpu->iem.s.uRexB);
8850}
8851
8852
8853/** Opcode 0x0f 0xce. */
8854FNIEMOP_DEF(iemOp_bswap_rSI_r14)
8855{
8856 IEMOP_MNEMONIC(bswap_rSI_r14, "bswap rSI/r14");
8857 IEMOP_HLP_MIN_486();
8858 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xSI | pVCpu->iem.s.uRexB);
8859}
8860
8861
8862/** Opcode 0x0f 0xcf. */
8863FNIEMOP_DEF(iemOp_bswap_rDI_r15)
8864{
8865 IEMOP_MNEMONIC(bswap_rDI_r15, "bswap rDI/r15");
8866 IEMOP_HLP_MIN_486();
8867 return FNIEMOP_CALL_1(iemOpCommonBswapGReg, X86_GREG_xDI | pVCpu->iem.s.uRexB);
8868}
8869
8870
8871/* Opcode 0x0f 0xd0 - invalid */
8872/** Opcode 0x66 0x0f 0xd0 - addsubpd Vpd, Wpd */
8873FNIEMOP_STUB(iemOp_addsubpd_Vpd_Wpd);
8874/* Opcode 0xf3 0x0f 0xd0 - invalid */
8875/** Opcode 0xf2 0x0f 0xd0 - addsubps Vps, Wps */
8876FNIEMOP_STUB(iemOp_addsubps_Vps_Wps);
8877
8878/** Opcode 0x0f 0xd1 - psrlw Pq, Qq */
8879FNIEMOP_STUB(iemOp_psrlw_Pq_Qq);
8880/** Opcode 0x66 0x0f 0xd1 - psrlw Vx, W */
8881FNIEMOP_STUB(iemOp_psrlw_Vx_W);
8882/* Opcode 0xf3 0x0f 0xd1 - invalid */
8883/* Opcode 0xf2 0x0f 0xd1 - invalid */
8884
8885/** Opcode 0x0f 0xd2 - psrld Pq, Qq */
8886FNIEMOP_STUB(iemOp_psrld_Pq_Qq);
8887/** Opcode 0x66 0x0f 0xd2 - psrld Vx, Wx */
8888FNIEMOP_STUB(iemOp_psrld_Vx_Wx);
8889/* Opcode 0xf3 0x0f 0xd2 - invalid */
8890/* Opcode 0xf2 0x0f 0xd2 - invalid */
8891
8892/** Opcode 0x0f 0xd3 - psrlq Pq, Qq */
8893FNIEMOP_STUB(iemOp_psrlq_Pq_Qq);
8894/** Opcode 0x66 0x0f 0xd3 - psrlq Vx, Wx */
8895FNIEMOP_STUB(iemOp_psrlq_Vx_Wx);
8896/* Opcode 0xf3 0x0f 0xd3 - invalid */
8897/* Opcode 0xf2 0x0f 0xd3 - invalid */
8898
8899/** Opcode 0x0f 0xd4 - paddq Pq, Qq */
8900FNIEMOP_STUB(iemOp_paddq_Pq_Qq);
8901/** Opcode 0x66 0x0f 0xd4 - paddq Vx, W */
8902FNIEMOP_STUB(iemOp_paddq_Vx_W);
8903/* Opcode 0xf3 0x0f 0xd4 - invalid */
8904/* Opcode 0xf2 0x0f 0xd4 - invalid */
8905
8906/** Opcode 0x0f 0xd5 - pmullw Pq, Qq */
8907FNIEMOP_STUB(iemOp_pmullw_Pq_Qq);
8908/** Opcode 0x66 0x0f 0xd5 - pmullw Vx, Wx */
8909FNIEMOP_STUB(iemOp_pmullw_Vx_Wx);
8910/* Opcode 0xf3 0x0f 0xd5 - invalid */
8911/* Opcode 0xf2 0x0f 0xd5 - invalid */
8912
8913/* Opcode 0x0f 0xd6 - invalid */
8914
8915/**
8916 * @opcode 0xd6
8917 * @oppfx 0x66
8918 * @opcpuid sse2
8919 * @opgroup og_sse2_pcksclr_datamove
8920 * @opxcpttype none
8921 * @optest op1=-1 op2=2 -> op1=2
8922 * @optest op1=0 op2=-42 -> op1=-42
8923 */
8924FNIEMOP_DEF(iemOp_movq_Wq_Vq)
8925{
8926 IEMOP_MNEMONIC2(MR, MOVQ, movq, WqZxReg_WO, Vq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
8927 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8928 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8929 {
8930 /*
8931 * Register, register.
8932 */
8933 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8934 IEM_MC_BEGIN(0, 2);
8935 IEM_MC_LOCAL(uint64_t, uSrc);
8936
8937 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
8938 IEM_MC_ACTUALIZE_SSE_STATE_FOR_CHANGE();
8939
8940 IEM_MC_FETCH_XREG_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8941 IEM_MC_STORE_XREG_U64_ZX_U128((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uSrc);
8942
8943 IEM_MC_ADVANCE_RIP();
8944 IEM_MC_END();
8945 }
8946 else
8947 {
8948 /*
8949 * Memory, register.
8950 */
8951 IEM_MC_BEGIN(0, 2);
8952 IEM_MC_LOCAL(uint64_t, uSrc);
8953 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
8954
8955 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8956 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8957 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
8958 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
8959
8960 IEM_MC_FETCH_XREG_U64(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
8961 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
8962
8963 IEM_MC_ADVANCE_RIP();
8964 IEM_MC_END();
8965 }
8966 return VINF_SUCCESS;
8967}
8968
8969
8970/**
8971 * @opcode 0xd6
8972 * @opcodesub 11 mr/reg
8973 * @oppfx f3
8974 * @opcpuid sse2
8975 * @opgroup og_sse2_simdint_datamove
8976 * @optest op1=1 op2=2 -> op1=2 ftw=0xff
8977 * @optest op1=0 op2=-42 -> op1=-42 ftw=0xff
8978 */
8979FNIEMOP_DEF(iemOp_movq2dq_Vdq_Nq)
8980{
8981 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8982 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8983 {
8984 /*
8985 * Register, register.
8986 */
8987 IEMOP_MNEMONIC2(RM_REG, MOVQ2DQ, movq2dq, VqZx_WO, Nq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
8988 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8989 IEM_MC_BEGIN(0, 1);
8990 IEM_MC_LOCAL(uint64_t, uSrc);
8991
8992 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
8993 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
8994
8995 IEM_MC_FETCH_MREG_U64(uSrc, bRm & X86_MODRM_RM_MASK);
8996 IEM_MC_STORE_XREG_U64_ZX_U128(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uSrc);
8997 IEM_MC_FPU_TO_MMX_MODE();
8998
8999 IEM_MC_ADVANCE_RIP();
9000 IEM_MC_END();
9001 return VINF_SUCCESS;
9002 }
9003
9004 /**
9005 * @opdone
9006 * @opmnemonic udf30fd6mem
9007 * @opcode 0xd6
9008 * @opcodesub !11 mr/reg
9009 * @oppfx f3
9010 * @opunused intel-modrm
9011 * @opcpuid sse
9012 * @optest ->
9013 */
9014 return FNIEMOP_CALL_1(iemOp_InvalidWithRMNeedDecode, bRm);
9015}
9016
9017
9018/**
9019 * @opcode 0xd6
9020 * @opcodesub 11 mr/reg
9021 * @oppfx f2
9022 * @opcpuid sse2
9023 * @opgroup og_sse2_simdint_datamove
9024 * @optest op1=1 op2=2 -> op1=2 ftw=0xff
9025 * @optest op1=0 op2=-42 -> op1=-42 ftw=0xff
9026 * @optest op1=0 op2=0x1123456789abcdef -> op1=0x1123456789abcdef ftw=0xff
9027 * @optest op1=0 op2=0xfedcba9876543210 -> op1=0xfedcba9876543210 ftw=0xff
9028 * @optest op1=-42 op2=0xfedcba9876543210
9029 * -> op1=0xfedcba9876543210 ftw=0xff
9030 */
9031FNIEMOP_DEF(iemOp_movdq2q_Pq_Uq)
9032{
9033 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9034 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
9035 {
9036 /*
9037 * Register, register.
9038 */
9039 IEMOP_MNEMONIC2(RM_REG, MOVDQ2Q, movdq2q, Pq_WO, Uq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
9040 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9041 IEM_MC_BEGIN(0, 1);
9042 IEM_MC_LOCAL(uint64_t, uSrc);
9043
9044 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
9045 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9046
9047 IEM_MC_FETCH_XREG_U64(uSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
9048 IEM_MC_STORE_MREG_U64((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK, uSrc);
9049 IEM_MC_FPU_TO_MMX_MODE();
9050
9051 IEM_MC_ADVANCE_RIP();
9052 IEM_MC_END();
9053 return VINF_SUCCESS;
9054 }
9055
9056 /**
9057 * @opdone
9058 * @opmnemonic udf20fd6mem
9059 * @opcode 0xd6
9060 * @opcodesub !11 mr/reg
9061 * @oppfx f2
9062 * @opunused intel-modrm
9063 * @opcpuid sse
9064 * @optest ->
9065 */
9066 return FNIEMOP_CALL_1(iemOp_InvalidWithRMNeedDecode, bRm);
9067}
9068
9069/** Opcode 0x0f 0xd7 - pmovmskb Gd, Nq */
9070FNIEMOP_DEF(iemOp_pmovmskb_Gd_Nq)
9071{
9072 /* Note! Taking the lazy approch here wrt the high 32-bits of the GREG. */
9073 /** @todo testcase: Check that the instruction implicitly clears the high
9074 * bits in 64-bit mode. The REX.W is first necessary when VLMAX > 256
9075 * and opcode modifications are made to work with the whole width (not
9076 * just 128). */
9077 IEMOP_MNEMONIC(pmovmskb_Gd_Udq, "pmovmskb Gd,Nq");
9078 /* Docs says register only. */
9079 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9080 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT)) /** @todo test that this is registers only. */
9081 {
9082 IEMOP_HLP_DECODED_NL_2(OP_PMOVMSKB, IEMOPFORM_RM_REG, OP_PARM_Gd, OP_PARM_Vdq, DISOPTYPE_MMX | DISOPTYPE_HARMLESS);
9083 IEM_MC_BEGIN(2, 0);
9084 IEM_MC_ARG(uint64_t *, pDst, 0);
9085 IEM_MC_ARG(uint64_t const *, pSrc, 1);
9086 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT_CHECK_SSE_OR_MMXEXT();
9087 IEM_MC_PREPARE_FPU_USAGE();
9088 IEM_MC_REF_GREG_U64(pDst, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
9089 IEM_MC_REF_MREG_U64_CONST(pSrc, bRm & X86_MODRM_RM_MASK);
9090 IEM_MC_CALL_MMX_AIMPL_2(iemAImpl_pmovmskb_u64, pDst, pSrc);
9091 IEM_MC_ADVANCE_RIP();
9092 IEM_MC_END();
9093 return VINF_SUCCESS;
9094 }
9095 return IEMOP_RAISE_INVALID_OPCODE();
9096}
9097
9098/** Opcode 0x66 0x0f 0xd7 - */
9099FNIEMOP_DEF(iemOp_pmovmskb_Gd_Ux)
9100{
9101 /* Note! Taking the lazy approch here wrt the high 32-bits of the GREG. */
9102 /** @todo testcase: Check that the instruction implicitly clears the high
9103 * bits in 64-bit mode. The REX.W is first necessary when VLMAX > 256
9104 * and opcode modifications are made to work with the whole width (not
9105 * just 128). */
9106 IEMOP_MNEMONIC(pmovmskb_Gd_Nq, "vpmovmskb Gd, Ux");
9107 /* Docs says register only. */
9108 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9109 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT)) /** @todo test that this is registers only. */
9110 {
9111 IEMOP_HLP_DECODED_NL_2(OP_PMOVMSKB, IEMOPFORM_RM_REG, OP_PARM_Gd, OP_PARM_Vdq, DISOPTYPE_SSE | DISOPTYPE_HARMLESS);
9112 IEM_MC_BEGIN(2, 0);
9113 IEM_MC_ARG(uint64_t *, pDst, 0);
9114 IEM_MC_ARG(PCRTUINT128U, pSrc, 1);
9115 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
9116 IEM_MC_PREPARE_SSE_USAGE();
9117 IEM_MC_REF_GREG_U64(pDst, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
9118 IEM_MC_REF_XREG_U128_CONST(pSrc, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
9119 IEM_MC_CALL_SSE_AIMPL_2(iemAImpl_pmovmskb_u128, pDst, pSrc);
9120 IEM_MC_ADVANCE_RIP();
9121 IEM_MC_END();
9122 return VINF_SUCCESS;
9123 }
9124 return IEMOP_RAISE_INVALID_OPCODE();
9125}
9126
9127/* Opcode 0xf3 0x0f 0xd7 - invalid */
9128/* Opcode 0xf2 0x0f 0xd7 - invalid */
9129
9130
9131/** Opcode 0x0f 0xd8 - psubusb Pq, Qq */
9132FNIEMOP_STUB(iemOp_psubusb_Pq_Qq);
9133/** Opcode 0x66 0x0f 0xd8 - psubusb Vx, W */
9134FNIEMOP_STUB(iemOp_psubusb_Vx_W);
9135/* Opcode 0xf3 0x0f 0xd8 - invalid */
9136/* Opcode 0xf2 0x0f 0xd8 - invalid */
9137
9138/** Opcode 0x0f 0xd9 - psubusw Pq, Qq */
9139FNIEMOP_STUB(iemOp_psubusw_Pq_Qq);
9140/** Opcode 0x66 0x0f 0xd9 - psubusw Vx, Wx */
9141FNIEMOP_STUB(iemOp_psubusw_Vx_Wx);
9142/* Opcode 0xf3 0x0f 0xd9 - invalid */
9143/* Opcode 0xf2 0x0f 0xd9 - invalid */
9144
9145/** Opcode 0x0f 0xda - pminub Pq, Qq */
9146FNIEMOP_STUB(iemOp_pminub_Pq_Qq);
9147/** Opcode 0x66 0x0f 0xda - pminub Vx, Wx */
9148FNIEMOP_STUB(iemOp_pminub_Vx_Wx);
9149/* Opcode 0xf3 0x0f 0xda - invalid */
9150/* Opcode 0xf2 0x0f 0xda - invalid */
9151
9152/** Opcode 0x0f 0xdb - pand Pq, Qq */
9153FNIEMOP_STUB(iemOp_pand_Pq_Qq);
9154/** Opcode 0x66 0x0f 0xdb - pand Vx, W */
9155FNIEMOP_STUB(iemOp_pand_Vx_W);
9156/* Opcode 0xf3 0x0f 0xdb - invalid */
9157/* Opcode 0xf2 0x0f 0xdb - invalid */
9158
9159/** Opcode 0x0f 0xdc - paddusb Pq, Qq */
9160FNIEMOP_STUB(iemOp_paddusb_Pq_Qq);
9161/** Opcode 0x66 0x0f 0xdc - paddusb Vx, Wx */
9162FNIEMOP_STUB(iemOp_paddusb_Vx_Wx);
9163/* Opcode 0xf3 0x0f 0xdc - invalid */
9164/* Opcode 0xf2 0x0f 0xdc - invalid */
9165
9166/** Opcode 0x0f 0xdd - paddusw Pq, Qq */
9167FNIEMOP_STUB(iemOp_paddusw_Pq_Qq);
9168/** Opcode 0x66 0x0f 0xdd - paddusw Vx, Wx */
9169FNIEMOP_STUB(iemOp_paddusw_Vx_Wx);
9170/* Opcode 0xf3 0x0f 0xdd - invalid */
9171/* Opcode 0xf2 0x0f 0xdd - invalid */
9172
9173/** Opcode 0x0f 0xde - pmaxub Pq, Qq */
9174FNIEMOP_STUB(iemOp_pmaxub_Pq_Qq);
9175/** Opcode 0x66 0x0f 0xde - pmaxub Vx, W */
9176FNIEMOP_STUB(iemOp_pmaxub_Vx_W);
9177/* Opcode 0xf3 0x0f 0xde - invalid */
9178/* Opcode 0xf2 0x0f 0xde - invalid */
9179
9180/** Opcode 0x0f 0xdf - pandn Pq, Qq */
9181FNIEMOP_STUB(iemOp_pandn_Pq_Qq);
9182/** Opcode 0x66 0x0f 0xdf - pandn Vx, Wx */
9183FNIEMOP_STUB(iemOp_pandn_Vx_Wx);
9184/* Opcode 0xf3 0x0f 0xdf - invalid */
9185/* Opcode 0xf2 0x0f 0xdf - invalid */
9186
9187/** Opcode 0x0f 0xe0 - pavgb Pq, Qq */
9188FNIEMOP_STUB(iemOp_pavgb_Pq_Qq);
9189/** Opcode 0x66 0x0f 0xe0 - pavgb Vx, Wx */
9190FNIEMOP_STUB(iemOp_pavgb_Vx_Wx);
9191/* Opcode 0xf3 0x0f 0xe0 - invalid */
9192/* Opcode 0xf2 0x0f 0xe0 - invalid */
9193
9194/** Opcode 0x0f 0xe1 - psraw Pq, Qq */
9195FNIEMOP_STUB(iemOp_psraw_Pq_Qq);
9196/** Opcode 0x66 0x0f 0xe1 - psraw Vx, W */
9197FNIEMOP_STUB(iemOp_psraw_Vx_W);
9198/* Opcode 0xf3 0x0f 0xe1 - invalid */
9199/* Opcode 0xf2 0x0f 0xe1 - invalid */
9200
9201/** Opcode 0x0f 0xe2 - psrad Pq, Qq */
9202FNIEMOP_STUB(iemOp_psrad_Pq_Qq);
9203/** Opcode 0x66 0x0f 0xe2 - psrad Vx, Wx */
9204FNIEMOP_STUB(iemOp_psrad_Vx_Wx);
9205/* Opcode 0xf3 0x0f 0xe2 - invalid */
9206/* Opcode 0xf2 0x0f 0xe2 - invalid */
9207
9208/** Opcode 0x0f 0xe3 - pavgw Pq, Qq */
9209FNIEMOP_STUB(iemOp_pavgw_Pq_Qq);
9210/** Opcode 0x66 0x0f 0xe3 - pavgw Vx, Wx */
9211FNIEMOP_STUB(iemOp_pavgw_Vx_Wx);
9212/* Opcode 0xf3 0x0f 0xe3 - invalid */
9213/* Opcode 0xf2 0x0f 0xe3 - invalid */
9214
9215/** Opcode 0x0f 0xe4 - pmulhuw Pq, Qq */
9216FNIEMOP_STUB(iemOp_pmulhuw_Pq_Qq);
9217/** Opcode 0x66 0x0f 0xe4 - pmulhuw Vx, W */
9218FNIEMOP_STUB(iemOp_pmulhuw_Vx_W);
9219/* Opcode 0xf3 0x0f 0xe4 - invalid */
9220/* Opcode 0xf2 0x0f 0xe4 - invalid */
9221
9222/** Opcode 0x0f 0xe5 - pmulhw Pq, Qq */
9223FNIEMOP_STUB(iemOp_pmulhw_Pq_Qq);
9224/** Opcode 0x66 0x0f 0xe5 - pmulhw Vx, Wx */
9225FNIEMOP_STUB(iemOp_pmulhw_Vx_Wx);
9226/* Opcode 0xf3 0x0f 0xe5 - invalid */
9227/* Opcode 0xf2 0x0f 0xe5 - invalid */
9228
9229/* Opcode 0x0f 0xe6 - invalid */
9230/** Opcode 0x66 0x0f 0xe6 - cvttpd2dq Vx, Wpd */
9231FNIEMOP_STUB(iemOp_cvttpd2dq_Vx_Wpd);
9232/** Opcode 0xf3 0x0f 0xe6 - cvtdq2pd Vx, Wpd */
9233FNIEMOP_STUB(iemOp_cvtdq2pd_Vx_Wpd);
9234/** Opcode 0xf2 0x0f 0xe6 - cvtpd2dq Vx, Wpd */
9235FNIEMOP_STUB(iemOp_cvtpd2dq_Vx_Wpd);
9236
9237
9238/**
9239 * @opcode 0xe7
9240 * @opcodesub !11 mr/reg
9241 * @oppfx none
9242 * @opcpuid sse
9243 * @opgroup og_sse1_cachect
9244 * @opxcpttype none
9245 * @optest op1=-1 op2=2 -> op1=2 ftw=0xff
9246 * @optest op1=0 op2=-42 -> op1=-42 ftw=0xff
9247 */
9248FNIEMOP_DEF(iemOp_movntq_Mq_Pq)
9249{
9250 IEMOP_MNEMONIC2(MR_MEM, MOVNTQ, movntq, Mq_WO, Pq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
9251 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9252 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
9253 {
9254 /* Register, memory. */
9255 IEM_MC_BEGIN(0, 2);
9256 IEM_MC_LOCAL(uint64_t, uSrc);
9257 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9258
9259 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9260 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9261 IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT();
9262 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9263
9264 IEM_MC_FETCH_MREG_U64(uSrc, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
9265 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
9266 IEM_MC_FPU_TO_MMX_MODE();
9267
9268 IEM_MC_ADVANCE_RIP();
9269 IEM_MC_END();
9270 return VINF_SUCCESS;
9271 }
9272 /**
9273 * @opdone
9274 * @opmnemonic ud0fe7reg
9275 * @opcode 0xe7
9276 * @opcodesub 11 mr/reg
9277 * @oppfx none
9278 * @opunused immediate
9279 * @opcpuid sse
9280 * @optest ->
9281 */
9282 return IEMOP_RAISE_INVALID_OPCODE();
9283}
9284
9285/**
9286 * @opcode 0xe7
9287 * @opcodesub !11 mr/reg
9288 * @oppfx 0x66
9289 * @opcpuid sse2
9290 * @opgroup og_sse2_cachect
9291 * @opxcpttype 1
9292 * @optest op1=-1 op2=2 -> op1=2
9293 * @optest op1=0 op2=-42 -> op1=-42
9294 */
9295FNIEMOP_DEF(iemOp_movntdq_Mdq_Vdq)
9296{
9297 IEMOP_MNEMONIC2(MR_MEM, MOVNTDQ, movntdq, Mdq_WO, Vdq, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
9298 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9299 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
9300 {
9301 /* Register, memory. */
9302 IEM_MC_BEGIN(0, 2);
9303 IEM_MC_LOCAL(RTUINT128U, uSrc);
9304 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9305
9306 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9307 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9308 IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
9309 IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ();
9310
9311 IEM_MC_FETCH_XREG_U128(uSrc, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
9312 IEM_MC_STORE_MEM_U128_ALIGN_SSE(pVCpu->iem.s.iEffSeg, GCPtrEffSrc, uSrc);
9313
9314 IEM_MC_ADVANCE_RIP();
9315 IEM_MC_END();
9316 return VINF_SUCCESS;
9317 }
9318
9319 /**
9320 * @opdone
9321 * @opmnemonic ud660fe7reg
9322 * @opcode 0xe7
9323 * @opcodesub 11 mr/reg
9324 * @oppfx 0x66
9325 * @opunused immediate
9326 * @opcpuid sse
9327 * @optest ->
9328 */
9329 return IEMOP_RAISE_INVALID_OPCODE();
9330}
9331
9332/* Opcode 0xf3 0x0f 0xe7 - invalid */
9333/* Opcode 0xf2 0x0f 0xe7 - invalid */
9334
9335
9336/** Opcode 0x0f 0xe8 - psubsb Pq, Qq */
9337FNIEMOP_STUB(iemOp_psubsb_Pq_Qq);
9338/** Opcode 0x66 0x0f 0xe8 - psubsb Vx, W */
9339FNIEMOP_STUB(iemOp_psubsb_Vx_W);
9340/* Opcode 0xf3 0x0f 0xe8 - invalid */
9341/* Opcode 0xf2 0x0f 0xe8 - invalid */
9342
9343/** Opcode 0x0f 0xe9 - psubsw Pq, Qq */
9344FNIEMOP_STUB(iemOp_psubsw_Pq_Qq);
9345/** Opcode 0x66 0x0f 0xe9 - psubsw Vx, Wx */
9346FNIEMOP_STUB(iemOp_psubsw_Vx_Wx);
9347/* Opcode 0xf3 0x0f 0xe9 - invalid */
9348/* Opcode 0xf2 0x0f 0xe9 - invalid */
9349
9350/** Opcode 0x0f 0xea - pminsw Pq, Qq */
9351FNIEMOP_STUB(iemOp_pminsw_Pq_Qq);
9352/** Opcode 0x66 0x0f 0xea - pminsw Vx, Wx */
9353FNIEMOP_STUB(iemOp_pminsw_Vx_Wx);
9354/* Opcode 0xf3 0x0f 0xea - invalid */
9355/* Opcode 0xf2 0x0f 0xea - invalid */
9356
9357/** Opcode 0x0f 0xeb - por Pq, Qq */
9358FNIEMOP_STUB(iemOp_por_Pq_Qq);
9359/** Opcode 0x66 0x0f 0xeb - por Vx, W */
9360FNIEMOP_STUB(iemOp_por_Vx_W);
9361/* Opcode 0xf3 0x0f 0xeb - invalid */
9362/* Opcode 0xf2 0x0f 0xeb - invalid */
9363
9364/** Opcode 0x0f 0xec - paddsb Pq, Qq */
9365FNIEMOP_STUB(iemOp_paddsb_Pq_Qq);
9366/** Opcode 0x66 0x0f 0xec - paddsb Vx, Wx */
9367FNIEMOP_STUB(iemOp_paddsb_Vx_Wx);
9368/* Opcode 0xf3 0x0f 0xec - invalid */
9369/* Opcode 0xf2 0x0f 0xec - invalid */
9370
9371/** Opcode 0x0f 0xed - paddsw Pq, Qq */
9372FNIEMOP_STUB(iemOp_paddsw_Pq_Qq);
9373/** Opcode 0x66 0x0f 0xed - paddsw Vx, Wx */
9374FNIEMOP_STUB(iemOp_paddsw_Vx_Wx);
9375/* Opcode 0xf3 0x0f 0xed - invalid */
9376/* Opcode 0xf2 0x0f 0xed - invalid */
9377
9378/** Opcode 0x0f 0xee - pmaxsw Pq, Qq */
9379FNIEMOP_STUB(iemOp_pmaxsw_Pq_Qq);
9380/** Opcode 0x66 0x0f 0xee - pmaxsw Vx, W */
9381FNIEMOP_STUB(iemOp_pmaxsw_Vx_W);
9382/* Opcode 0xf3 0x0f 0xee - invalid */
9383/* Opcode 0xf2 0x0f 0xee - invalid */
9384
9385
9386/** Opcode 0x0f 0xef - pxor Pq, Qq */
9387FNIEMOP_DEF(iemOp_pxor_Pq_Qq)
9388{
9389 IEMOP_MNEMONIC(pxor, "pxor");
9390 return FNIEMOP_CALL_1(iemOpCommonMmx_FullFull_To_Full, &g_iemAImpl_pxor);
9391}
9392
9393/** Opcode 0x66 0x0f 0xef - pxor Vx, Wx */
9394FNIEMOP_DEF(iemOp_pxor_Vx_Wx)
9395{
9396 IEMOP_MNEMONIC(pxor_Vx_Wx, "pxor");
9397 return FNIEMOP_CALL_1(iemOpCommonSse2_FullFull_To_Full, &g_iemAImpl_pxor);
9398}
9399
9400/* Opcode 0xf3 0x0f 0xef - invalid */
9401/* Opcode 0xf2 0x0f 0xef - invalid */
9402
9403/* Opcode 0x0f 0xf0 - invalid */
9404/* Opcode 0x66 0x0f 0xf0 - invalid */
9405/** Opcode 0xf2 0x0f 0xf0 - lddqu Vx, Mx */
9406FNIEMOP_STUB(iemOp_lddqu_Vx_Mx);
9407
9408/** Opcode 0x0f 0xf1 - psllw Pq, Qq */
9409FNIEMOP_STUB(iemOp_psllw_Pq_Qq);
9410/** Opcode 0x66 0x0f 0xf1 - psllw Vx, W */
9411FNIEMOP_STUB(iemOp_psllw_Vx_W);
9412/* Opcode 0xf2 0x0f 0xf1 - invalid */
9413
9414/** Opcode 0x0f 0xf2 - pslld Pq, Qq */
9415FNIEMOP_STUB(iemOp_pslld_Pq_Qq);
9416/** Opcode 0x66 0x0f 0xf2 - pslld Vx, Wx */
9417FNIEMOP_STUB(iemOp_pslld_Vx_Wx);
9418/* Opcode 0xf2 0x0f 0xf2 - invalid */
9419
9420/** Opcode 0x0f 0xf3 - psllq Pq, Qq */
9421FNIEMOP_STUB(iemOp_psllq_Pq_Qq);
9422/** Opcode 0x66 0x0f 0xf3 - psllq Vx, Wx */
9423FNIEMOP_STUB(iemOp_psllq_Vx_Wx);
9424/* Opcode 0xf2 0x0f 0xf3 - invalid */
9425
9426/** Opcode 0x0f 0xf4 - pmuludq Pq, Qq */
9427FNIEMOP_STUB(iemOp_pmuludq_Pq_Qq);
9428/** Opcode 0x66 0x0f 0xf4 - pmuludq Vx, W */
9429FNIEMOP_STUB(iemOp_pmuludq_Vx_W);
9430/* Opcode 0xf2 0x0f 0xf4 - invalid */
9431
9432/** Opcode 0x0f 0xf5 - pmaddwd Pq, Qq */
9433FNIEMOP_STUB(iemOp_pmaddwd_Pq_Qq);
9434/** Opcode 0x66 0x0f 0xf5 - pmaddwd Vx, Wx */
9435FNIEMOP_STUB(iemOp_pmaddwd_Vx_Wx);
9436/* Opcode 0xf2 0x0f 0xf5 - invalid */
9437
9438/** Opcode 0x0f 0xf6 - psadbw Pq, Qq */
9439FNIEMOP_STUB(iemOp_psadbw_Pq_Qq);
9440/** Opcode 0x66 0x0f 0xf6 - psadbw Vx, Wx */
9441FNIEMOP_STUB(iemOp_psadbw_Vx_Wx);
9442/* Opcode 0xf2 0x0f 0xf6 - invalid */
9443
9444/** Opcode 0x0f 0xf7 - maskmovq Pq, Nq */
9445FNIEMOP_STUB(iemOp_maskmovq_Pq_Nq);
9446/** Opcode 0x66 0x0f 0xf7 - maskmovdqu Vdq, Udq */
9447FNIEMOP_STUB(iemOp_maskmovdqu_Vdq_Udq);
9448/* Opcode 0xf2 0x0f 0xf7 - invalid */
9449
9450/** Opcode 0x0f 0xf8 - psubb Pq, Qq */
9451FNIEMOP_STUB(iemOp_psubb_Pq_Qq);
9452/** Opcode 0x66 0x0f 0xf8 - psubb Vx, W */
9453FNIEMOP_STUB(iemOp_psubb_Vx_W);
9454/* Opcode 0xf2 0x0f 0xf8 - invalid */
9455
9456/** Opcode 0x0f 0xf9 - psubw Pq, Qq */
9457FNIEMOP_STUB(iemOp_psubw_Pq_Qq);
9458/** Opcode 0x66 0x0f 0xf9 - psubw Vx, Wx */
9459FNIEMOP_STUB(iemOp_psubw_Vx_Wx);
9460/* Opcode 0xf2 0x0f 0xf9 - invalid */
9461
9462/** Opcode 0x0f 0xfa - psubd Pq, Qq */
9463FNIEMOP_STUB(iemOp_psubd_Pq_Qq);
9464/** Opcode 0x66 0x0f 0xfa - psubd Vx, Wx */
9465FNIEMOP_STUB(iemOp_psubd_Vx_Wx);
9466/* Opcode 0xf2 0x0f 0xfa - invalid */
9467
9468/** Opcode 0x0f 0xfb - psubq Pq, Qq */
9469FNIEMOP_STUB(iemOp_psubq_Pq_Qq);
9470/** Opcode 0x66 0x0f 0xfb - psubq Vx, W */
9471FNIEMOP_STUB(iemOp_psubq_Vx_W);
9472/* Opcode 0xf2 0x0f 0xfb - invalid */
9473
9474/** Opcode 0x0f 0xfc - paddb Pq, Qq */
9475FNIEMOP_STUB(iemOp_paddb_Pq_Qq);
9476/** Opcode 0x66 0x0f 0xfc - paddb Vx, Wx */
9477FNIEMOP_STUB(iemOp_paddb_Vx_Wx);
9478/* Opcode 0xf2 0x0f 0xfc - invalid */
9479
9480/** Opcode 0x0f 0xfd - paddw Pq, Qq */
9481FNIEMOP_STUB(iemOp_paddw_Pq_Qq);
9482/** Opcode 0x66 0x0f 0xfd - paddw Vx, Wx */
9483FNIEMOP_STUB(iemOp_paddw_Vx_Wx);
9484/* Opcode 0xf2 0x0f 0xfd - invalid */
9485
9486/** Opcode 0x0f 0xfe - paddd Pq, Qq */
9487FNIEMOP_STUB(iemOp_paddd_Pq_Qq);
9488/** Opcode 0x66 0x0f 0xfe - paddd Vx, W */
9489FNIEMOP_STUB(iemOp_paddd_Vx_W);
9490/* Opcode 0xf2 0x0f 0xfe - invalid */
9491
9492
9493/** Opcode **** 0x0f 0xff - UD0 */
9494FNIEMOP_DEF(iemOp_ud0)
9495{
9496 IEMOP_MNEMONIC(ud0, "ud0");
9497 if (pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
9498 {
9499 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); RT_NOREF(bRm);
9500#ifndef TST_IEM_CHECK_MC
9501 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
9502 {
9503 RTGCPTR GCPtrEff;
9504 VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff);
9505 if (rcStrict != VINF_SUCCESS)
9506 return rcStrict;
9507 }
9508#endif
9509 IEMOP_HLP_DONE_DECODING();
9510 }
9511 return IEMOP_RAISE_INVALID_OPCODE();
9512}
9513
9514
9515
9516/**
9517 * Two byte opcode map, first byte 0x0f.
9518 *
9519 * @remarks The g_apfnVexMap1 table is currently a subset of this one, so please
9520 * check if it needs updating as well when making changes.
9521 */
9522IEM_STATIC const PFNIEMOP g_apfnTwoByteMap[] =
9523{
9524 /* no prefix, 066h prefix f3h prefix, f2h prefix */
9525 /* 0x00 */ IEMOP_X4(iemOp_Grp6),
9526 /* 0x01 */ IEMOP_X4(iemOp_Grp7),
9527 /* 0x02 */ IEMOP_X4(iemOp_lar_Gv_Ew),
9528 /* 0x03 */ IEMOP_X4(iemOp_lsl_Gv_Ew),
9529 /* 0x04 */ IEMOP_X4(iemOp_Invalid),
9530 /* 0x05 */ IEMOP_X4(iemOp_syscall),
9531 /* 0x06 */ IEMOP_X4(iemOp_clts),
9532 /* 0x07 */ IEMOP_X4(iemOp_sysret),
9533 /* 0x08 */ IEMOP_X4(iemOp_invd),
9534 /* 0x09 */ IEMOP_X4(iemOp_wbinvd),
9535 /* 0x0a */ IEMOP_X4(iemOp_Invalid),
9536 /* 0x0b */ IEMOP_X4(iemOp_ud2),
9537 /* 0x0c */ IEMOP_X4(iemOp_Invalid),
9538 /* 0x0d */ IEMOP_X4(iemOp_nop_Ev_GrpP),
9539 /* 0x0e */ IEMOP_X4(iemOp_femms),
9540 /* 0x0f */ IEMOP_X4(iemOp_3Dnow),
9541
9542 /* 0x10 */ iemOp_movups_Vps_Wps, iemOp_movupd_Vpd_Wpd, iemOp_movss_Vss_Wss, iemOp_movsd_Vsd_Wsd,
9543 /* 0x11 */ iemOp_movups_Wps_Vps, iemOp_movupd_Wpd_Vpd, iemOp_movss_Wss_Vss, iemOp_movsd_Wsd_Vsd,
9544 /* 0x12 */ iemOp_movlps_Vq_Mq__movhlps, iemOp_movlpd_Vq_Mq, iemOp_movsldup_Vdq_Wdq, iemOp_movddup_Vdq_Wdq,
9545 /* 0x13 */ iemOp_movlps_Mq_Vq, iemOp_movlpd_Mq_Vq, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9546 /* 0x14 */ iemOp_unpcklps_Vx_Wx, iemOp_unpcklpd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9547 /* 0x15 */ iemOp_unpckhps_Vx_Wx, iemOp_unpckhpd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9548 /* 0x16 */ iemOp_movhps_Vdq_Mq__movlhps_Vdq_Uq, iemOp_movhpd_Vdq_Mq, iemOp_movshdup_Vdq_Wdq, iemOp_InvalidNeedRM,
9549 /* 0x17 */ iemOp_movhps_Mq_Vq, iemOp_movhpd_Mq_Vq, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9550 /* 0x18 */ IEMOP_X4(iemOp_prefetch_Grp16),
9551 /* 0x19 */ IEMOP_X4(iemOp_nop_Ev),
9552 /* 0x1a */ IEMOP_X4(iemOp_nop_Ev),
9553 /* 0x1b */ IEMOP_X4(iemOp_nop_Ev),
9554 /* 0x1c */ IEMOP_X4(iemOp_nop_Ev),
9555 /* 0x1d */ IEMOP_X4(iemOp_nop_Ev),
9556 /* 0x1e */ IEMOP_X4(iemOp_nop_Ev),
9557 /* 0x1f */ IEMOP_X4(iemOp_nop_Ev),
9558
9559 /* 0x20 */ iemOp_mov_Rd_Cd, iemOp_mov_Rd_Cd, iemOp_mov_Rd_Cd, iemOp_mov_Rd_Cd,
9560 /* 0x21 */ iemOp_mov_Rd_Dd, iemOp_mov_Rd_Dd, iemOp_mov_Rd_Dd, iemOp_mov_Rd_Dd,
9561 /* 0x22 */ iemOp_mov_Cd_Rd, iemOp_mov_Cd_Rd, iemOp_mov_Cd_Rd, iemOp_mov_Cd_Rd,
9562 /* 0x23 */ iemOp_mov_Dd_Rd, iemOp_mov_Dd_Rd, iemOp_mov_Dd_Rd, iemOp_mov_Dd_Rd,
9563 /* 0x24 */ iemOp_mov_Rd_Td, iemOp_mov_Rd_Td, iemOp_mov_Rd_Td, iemOp_mov_Rd_Td,
9564 /* 0x25 */ iemOp_Invalid, iemOp_Invalid, iemOp_Invalid, iemOp_Invalid,
9565 /* 0x26 */ iemOp_mov_Td_Rd, iemOp_mov_Td_Rd, iemOp_mov_Td_Rd, iemOp_mov_Td_Rd,
9566 /* 0x27 */ iemOp_Invalid, iemOp_Invalid, iemOp_Invalid, iemOp_Invalid,
9567 /* 0x28 */ iemOp_movaps_Vps_Wps, iemOp_movapd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9568 /* 0x29 */ iemOp_movaps_Wps_Vps, iemOp_movapd_Wpd_Vpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9569 /* 0x2a */ iemOp_cvtpi2ps_Vps_Qpi, iemOp_cvtpi2pd_Vpd_Qpi, iemOp_cvtsi2ss_Vss_Ey, iemOp_cvtsi2sd_Vsd_Ey,
9570 /* 0x2b */ iemOp_movntps_Mps_Vps, iemOp_movntpd_Mpd_Vpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9571 /* 0x2c */ iemOp_cvttps2pi_Ppi_Wps, iemOp_cvttpd2pi_Ppi_Wpd, iemOp_cvttss2si_Gy_Wss, iemOp_cvttsd2si_Gy_Wsd,
9572 /* 0x2d */ iemOp_cvtps2pi_Ppi_Wps, iemOp_cvtpd2pi_Qpi_Wpd, iemOp_cvtss2si_Gy_Wss, iemOp_cvtsd2si_Gy_Wsd,
9573 /* 0x2e */ iemOp_ucomiss_Vss_Wss, iemOp_ucomisd_Vsd_Wsd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9574 /* 0x2f */ iemOp_comiss_Vss_Wss, iemOp_comisd_Vsd_Wsd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9575
9576 /* 0x30 */ IEMOP_X4(iemOp_wrmsr),
9577 /* 0x31 */ IEMOP_X4(iemOp_rdtsc),
9578 /* 0x32 */ IEMOP_X4(iemOp_rdmsr),
9579 /* 0x33 */ IEMOP_X4(iemOp_rdpmc),
9580 /* 0x34 */ IEMOP_X4(iemOp_sysenter),
9581 /* 0x35 */ IEMOP_X4(iemOp_sysexit),
9582 /* 0x36 */ IEMOP_X4(iemOp_Invalid),
9583 /* 0x37 */ IEMOP_X4(iemOp_getsec),
9584 /* 0x38 */ IEMOP_X4(iemOp_3byte_Esc_0f_38),
9585 /* 0x39 */ IEMOP_X4(iemOp_InvalidNeed3ByteEscRM),
9586 /* 0x3a */ IEMOP_X4(iemOp_3byte_Esc_0f_3a),
9587 /* 0x3b */ IEMOP_X4(iemOp_InvalidNeed3ByteEscRMImm8),
9588 /* 0x3c */ IEMOP_X4(iemOp_InvalidNeed3ByteEscRM),
9589 /* 0x3d */ IEMOP_X4(iemOp_InvalidNeed3ByteEscRM),
9590 /* 0x3e */ IEMOP_X4(iemOp_InvalidNeed3ByteEscRMImm8),
9591 /* 0x3f */ IEMOP_X4(iemOp_InvalidNeed3ByteEscRMImm8),
9592
9593 /* 0x40 */ IEMOP_X4(iemOp_cmovo_Gv_Ev),
9594 /* 0x41 */ IEMOP_X4(iemOp_cmovno_Gv_Ev),
9595 /* 0x42 */ IEMOP_X4(iemOp_cmovc_Gv_Ev),
9596 /* 0x43 */ IEMOP_X4(iemOp_cmovnc_Gv_Ev),
9597 /* 0x44 */ IEMOP_X4(iemOp_cmove_Gv_Ev),
9598 /* 0x45 */ IEMOP_X4(iemOp_cmovne_Gv_Ev),
9599 /* 0x46 */ IEMOP_X4(iemOp_cmovbe_Gv_Ev),
9600 /* 0x47 */ IEMOP_X4(iemOp_cmovnbe_Gv_Ev),
9601 /* 0x48 */ IEMOP_X4(iemOp_cmovs_Gv_Ev),
9602 /* 0x49 */ IEMOP_X4(iemOp_cmovns_Gv_Ev),
9603 /* 0x4a */ IEMOP_X4(iemOp_cmovp_Gv_Ev),
9604 /* 0x4b */ IEMOP_X4(iemOp_cmovnp_Gv_Ev),
9605 /* 0x4c */ IEMOP_X4(iemOp_cmovl_Gv_Ev),
9606 /* 0x4d */ IEMOP_X4(iemOp_cmovnl_Gv_Ev),
9607 /* 0x4e */ IEMOP_X4(iemOp_cmovle_Gv_Ev),
9608 /* 0x4f */ IEMOP_X4(iemOp_cmovnle_Gv_Ev),
9609
9610 /* 0x50 */ iemOp_movmskps_Gy_Ups, iemOp_movmskpd_Gy_Upd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9611 /* 0x51 */ iemOp_sqrtps_Vps_Wps, iemOp_sqrtpd_Vpd_Wpd, iemOp_sqrtss_Vss_Wss, iemOp_sqrtsd_Vsd_Wsd,
9612 /* 0x52 */ iemOp_rsqrtps_Vps_Wps, iemOp_InvalidNeedRM, iemOp_rsqrtss_Vss_Wss, iemOp_InvalidNeedRM,
9613 /* 0x53 */ iemOp_rcpps_Vps_Wps, iemOp_InvalidNeedRM, iemOp_rcpss_Vss_Wss, iemOp_InvalidNeedRM,
9614 /* 0x54 */ iemOp_andps_Vps_Wps, iemOp_andpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9615 /* 0x55 */ iemOp_andnps_Vps_Wps, iemOp_andnpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9616 /* 0x56 */ iemOp_orps_Vps_Wps, iemOp_orpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9617 /* 0x57 */ iemOp_xorps_Vps_Wps, iemOp_xorpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9618 /* 0x58 */ iemOp_addps_Vps_Wps, iemOp_addpd_Vpd_Wpd, iemOp_addss_Vss_Wss, iemOp_addsd_Vsd_Wsd,
9619 /* 0x59 */ iemOp_mulps_Vps_Wps, iemOp_mulpd_Vpd_Wpd, iemOp_mulss_Vss_Wss, iemOp_mulsd_Vsd_Wsd,
9620 /* 0x5a */ iemOp_cvtps2pd_Vpd_Wps, iemOp_cvtpd2ps_Vps_Wpd, iemOp_cvtss2sd_Vsd_Wss, iemOp_cvtsd2ss_Vss_Wsd,
9621 /* 0x5b */ iemOp_cvtdq2ps_Vps_Wdq, iemOp_cvtps2dq_Vdq_Wps, iemOp_cvttps2dq_Vdq_Wps, iemOp_InvalidNeedRM,
9622 /* 0x5c */ iemOp_subps_Vps_Wps, iemOp_subpd_Vpd_Wpd, iemOp_subss_Vss_Wss, iemOp_subsd_Vsd_Wsd,
9623 /* 0x5d */ iemOp_minps_Vps_Wps, iemOp_minpd_Vpd_Wpd, iemOp_minss_Vss_Wss, iemOp_minsd_Vsd_Wsd,
9624 /* 0x5e */ iemOp_divps_Vps_Wps, iemOp_divpd_Vpd_Wpd, iemOp_divss_Vss_Wss, iemOp_divsd_Vsd_Wsd,
9625 /* 0x5f */ iemOp_maxps_Vps_Wps, iemOp_maxpd_Vpd_Wpd, iemOp_maxss_Vss_Wss, iemOp_maxsd_Vsd_Wsd,
9626
9627 /* 0x60 */ iemOp_punpcklbw_Pq_Qd, iemOp_punpcklbw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9628 /* 0x61 */ iemOp_punpcklwd_Pq_Qd, iemOp_punpcklwd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9629 /* 0x62 */ iemOp_punpckldq_Pq_Qd, iemOp_punpckldq_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9630 /* 0x63 */ iemOp_packsswb_Pq_Qq, iemOp_packsswb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9631 /* 0x64 */ iemOp_pcmpgtb_Pq_Qq, iemOp_pcmpgtb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9632 /* 0x65 */ iemOp_pcmpgtw_Pq_Qq, iemOp_pcmpgtw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9633 /* 0x66 */ iemOp_pcmpgtd_Pq_Qq, iemOp_pcmpgtd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9634 /* 0x67 */ iemOp_packuswb_Pq_Qq, iemOp_packuswb_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9635 /* 0x68 */ iemOp_punpckhbw_Pq_Qd, iemOp_punpckhbw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9636 /* 0x69 */ iemOp_punpckhwd_Pq_Qd, iemOp_punpckhwd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9637 /* 0x6a */ iemOp_punpckhdq_Pq_Qd, iemOp_punpckhdq_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9638 /* 0x6b */ iemOp_packssdw_Pq_Qd, iemOp_packssdw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9639 /* 0x6c */ iemOp_InvalidNeedRM, iemOp_punpcklqdq_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9640 /* 0x6d */ iemOp_InvalidNeedRM, iemOp_punpckhqdq_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9641 /* 0x6e */ iemOp_movd_q_Pd_Ey, iemOp_movd_q_Vy_Ey, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9642 /* 0x6f */ iemOp_movq_Pq_Qq, iemOp_movdqa_Vdq_Wdq, iemOp_movdqu_Vdq_Wdq, iemOp_InvalidNeedRM,
9643
9644 /* 0x70 */ iemOp_pshufw_Pq_Qq_Ib, iemOp_pshufd_Vx_Wx_Ib, iemOp_pshufhw_Vx_Wx_Ib, iemOp_pshuflw_Vx_Wx_Ib,
9645 /* 0x71 */ IEMOP_X4(iemOp_Grp12),
9646 /* 0x72 */ IEMOP_X4(iemOp_Grp13),
9647 /* 0x73 */ IEMOP_X4(iemOp_Grp14),
9648 /* 0x74 */ iemOp_pcmpeqb_Pq_Qq, iemOp_pcmpeqb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9649 /* 0x75 */ iemOp_pcmpeqw_Pq_Qq, iemOp_pcmpeqw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9650 /* 0x76 */ iemOp_pcmpeqd_Pq_Qq, iemOp_pcmpeqd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9651 /* 0x77 */ iemOp_emms, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9652
9653 /* 0x78 */ iemOp_vmread_Ey_Gy, iemOp_AmdGrp17, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9654 /* 0x79 */ iemOp_vmwrite_Gy_Ey, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9655 /* 0x7a */ iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9656 /* 0x7b */ iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9657 /* 0x7c */ iemOp_InvalidNeedRM, iemOp_haddpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_haddps_Vps_Wps,
9658 /* 0x7d */ iemOp_InvalidNeedRM, iemOp_hsubpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_hsubps_Vps_Wps,
9659 /* 0x7e */ iemOp_movd_q_Ey_Pd, iemOp_movd_q_Ey_Vy, iemOp_movq_Vq_Wq, iemOp_InvalidNeedRM,
9660 /* 0x7f */ iemOp_movq_Qq_Pq, iemOp_movdqa_Wx_Vx, iemOp_movdqu_Wx_Vx, iemOp_InvalidNeedRM,
9661
9662 /* 0x80 */ IEMOP_X4(iemOp_jo_Jv),
9663 /* 0x81 */ IEMOP_X4(iemOp_jno_Jv),
9664 /* 0x82 */ IEMOP_X4(iemOp_jc_Jv),
9665 /* 0x83 */ IEMOP_X4(iemOp_jnc_Jv),
9666 /* 0x84 */ IEMOP_X4(iemOp_je_Jv),
9667 /* 0x85 */ IEMOP_X4(iemOp_jne_Jv),
9668 /* 0x86 */ IEMOP_X4(iemOp_jbe_Jv),
9669 /* 0x87 */ IEMOP_X4(iemOp_jnbe_Jv),
9670 /* 0x88 */ IEMOP_X4(iemOp_js_Jv),
9671 /* 0x89 */ IEMOP_X4(iemOp_jns_Jv),
9672 /* 0x8a */ IEMOP_X4(iemOp_jp_Jv),
9673 /* 0x8b */ IEMOP_X4(iemOp_jnp_Jv),
9674 /* 0x8c */ IEMOP_X4(iemOp_jl_Jv),
9675 /* 0x8d */ IEMOP_X4(iemOp_jnl_Jv),
9676 /* 0x8e */ IEMOP_X4(iemOp_jle_Jv),
9677 /* 0x8f */ IEMOP_X4(iemOp_jnle_Jv),
9678
9679 /* 0x90 */ IEMOP_X4(iemOp_seto_Eb),
9680 /* 0x91 */ IEMOP_X4(iemOp_setno_Eb),
9681 /* 0x92 */ IEMOP_X4(iemOp_setc_Eb),
9682 /* 0x93 */ IEMOP_X4(iemOp_setnc_Eb),
9683 /* 0x94 */ IEMOP_X4(iemOp_sete_Eb),
9684 /* 0x95 */ IEMOP_X4(iemOp_setne_Eb),
9685 /* 0x96 */ IEMOP_X4(iemOp_setbe_Eb),
9686 /* 0x97 */ IEMOP_X4(iemOp_setnbe_Eb),
9687 /* 0x98 */ IEMOP_X4(iemOp_sets_Eb),
9688 /* 0x99 */ IEMOP_X4(iemOp_setns_Eb),
9689 /* 0x9a */ IEMOP_X4(iemOp_setp_Eb),
9690 /* 0x9b */ IEMOP_X4(iemOp_setnp_Eb),
9691 /* 0x9c */ IEMOP_X4(iemOp_setl_Eb),
9692 /* 0x9d */ IEMOP_X4(iemOp_setnl_Eb),
9693 /* 0x9e */ IEMOP_X4(iemOp_setle_Eb),
9694 /* 0x9f */ IEMOP_X4(iemOp_setnle_Eb),
9695
9696 /* 0xa0 */ IEMOP_X4(iemOp_push_fs),
9697 /* 0xa1 */ IEMOP_X4(iemOp_pop_fs),
9698 /* 0xa2 */ IEMOP_X4(iemOp_cpuid),
9699 /* 0xa3 */ IEMOP_X4(iemOp_bt_Ev_Gv),
9700 /* 0xa4 */ IEMOP_X4(iemOp_shld_Ev_Gv_Ib),
9701 /* 0xa5 */ IEMOP_X4(iemOp_shld_Ev_Gv_CL),
9702 /* 0xa6 */ IEMOP_X4(iemOp_InvalidNeedRM),
9703 /* 0xa7 */ IEMOP_X4(iemOp_InvalidNeedRM),
9704 /* 0xa8 */ IEMOP_X4(iemOp_push_gs),
9705 /* 0xa9 */ IEMOP_X4(iemOp_pop_gs),
9706 /* 0xaa */ IEMOP_X4(iemOp_rsm),
9707 /* 0xab */ IEMOP_X4(iemOp_bts_Ev_Gv),
9708 /* 0xac */ IEMOP_X4(iemOp_shrd_Ev_Gv_Ib),
9709 /* 0xad */ IEMOP_X4(iemOp_shrd_Ev_Gv_CL),
9710 /* 0xae */ IEMOP_X4(iemOp_Grp15),
9711 /* 0xaf */ IEMOP_X4(iemOp_imul_Gv_Ev),
9712
9713 /* 0xb0 */ IEMOP_X4(iemOp_cmpxchg_Eb_Gb),
9714 /* 0xb1 */ IEMOP_X4(iemOp_cmpxchg_Ev_Gv),
9715 /* 0xb2 */ IEMOP_X4(iemOp_lss_Gv_Mp),
9716 /* 0xb3 */ IEMOP_X4(iemOp_btr_Ev_Gv),
9717 /* 0xb4 */ IEMOP_X4(iemOp_lfs_Gv_Mp),
9718 /* 0xb5 */ IEMOP_X4(iemOp_lgs_Gv_Mp),
9719 /* 0xb6 */ IEMOP_X4(iemOp_movzx_Gv_Eb),
9720 /* 0xb7 */ IEMOP_X4(iemOp_movzx_Gv_Ew),
9721 /* 0xb8 */ iemOp_jmpe, iemOp_InvalidNeedRM, iemOp_popcnt_Gv_Ev, iemOp_InvalidNeedRM,
9722 /* 0xb9 */ IEMOP_X4(iemOp_Grp10),
9723 /* 0xba */ IEMOP_X4(iemOp_Grp8),
9724 /* 0xbb */ IEMOP_X4(iemOp_btc_Ev_Gv), // 0xf3?
9725 /* 0xbc */ iemOp_bsf_Gv_Ev, iemOp_bsf_Gv_Ev, iemOp_tzcnt_Gv_Ev, iemOp_bsf_Gv_Ev,
9726 /* 0xbd */ iemOp_bsr_Gv_Ev, iemOp_bsr_Gv_Ev, iemOp_lzcnt_Gv_Ev, iemOp_bsr_Gv_Ev,
9727 /* 0xbe */ IEMOP_X4(iemOp_movsx_Gv_Eb),
9728 /* 0xbf */ IEMOP_X4(iemOp_movsx_Gv_Ew),
9729
9730 /* 0xc0 */ IEMOP_X4(iemOp_xadd_Eb_Gb),
9731 /* 0xc1 */ IEMOP_X4(iemOp_xadd_Ev_Gv),
9732 /* 0xc2 */ iemOp_cmpps_Vps_Wps_Ib, iemOp_cmppd_Vpd_Wpd_Ib, iemOp_cmpss_Vss_Wss_Ib, iemOp_cmpsd_Vsd_Wsd_Ib,
9733 /* 0xc3 */ iemOp_movnti_My_Gy, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9734 /* 0xc4 */ iemOp_pinsrw_Pq_RyMw_Ib, iemOp_pinsrw_Vdq_RyMw_Ib, iemOp_InvalidNeedRMImm8, iemOp_InvalidNeedRMImm8,
9735 /* 0xc5 */ iemOp_pextrw_Gd_Nq_Ib, iemOp_pextrw_Gd_Udq_Ib, iemOp_InvalidNeedRMImm8, iemOp_InvalidNeedRMImm8,
9736 /* 0xc6 */ iemOp_shufps_Vps_Wps_Ib, iemOp_shufpd_Vpd_Wpd_Ib, iemOp_InvalidNeedRMImm8, iemOp_InvalidNeedRMImm8,
9737 /* 0xc7 */ IEMOP_X4(iemOp_Grp9),
9738 /* 0xc8 */ IEMOP_X4(iemOp_bswap_rAX_r8),
9739 /* 0xc9 */ IEMOP_X4(iemOp_bswap_rCX_r9),
9740 /* 0xca */ IEMOP_X4(iemOp_bswap_rDX_r10),
9741 /* 0xcb */ IEMOP_X4(iemOp_bswap_rBX_r11),
9742 /* 0xcc */ IEMOP_X4(iemOp_bswap_rSP_r12),
9743 /* 0xcd */ IEMOP_X4(iemOp_bswap_rBP_r13),
9744 /* 0xce */ IEMOP_X4(iemOp_bswap_rSI_r14),
9745 /* 0xcf */ IEMOP_X4(iemOp_bswap_rDI_r15),
9746
9747 /* 0xd0 */ iemOp_InvalidNeedRM, iemOp_addsubpd_Vpd_Wpd, iemOp_InvalidNeedRM, iemOp_addsubps_Vps_Wps,
9748 /* 0xd1 */ iemOp_psrlw_Pq_Qq, iemOp_psrlw_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9749 /* 0xd2 */ iemOp_psrld_Pq_Qq, iemOp_psrld_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9750 /* 0xd3 */ iemOp_psrlq_Pq_Qq, iemOp_psrlq_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9751 /* 0xd4 */ iemOp_paddq_Pq_Qq, iemOp_paddq_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9752 /* 0xd5 */ iemOp_pmullw_Pq_Qq, iemOp_pmullw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9753 /* 0xd6 */ iemOp_InvalidNeedRM, iemOp_movq_Wq_Vq, iemOp_movq2dq_Vdq_Nq, iemOp_movdq2q_Pq_Uq,
9754 /* 0xd7 */ iemOp_pmovmskb_Gd_Nq, iemOp_pmovmskb_Gd_Ux, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9755 /* 0xd8 */ iemOp_psubusb_Pq_Qq, iemOp_psubusb_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9756 /* 0xd9 */ iemOp_psubusw_Pq_Qq, iemOp_psubusw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9757 /* 0xda */ iemOp_pminub_Pq_Qq, iemOp_pminub_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9758 /* 0xdb */ iemOp_pand_Pq_Qq, iemOp_pand_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9759 /* 0xdc */ iemOp_paddusb_Pq_Qq, iemOp_paddusb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9760 /* 0xdd */ iemOp_paddusw_Pq_Qq, iemOp_paddusw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9761 /* 0xde */ iemOp_pmaxub_Pq_Qq, iemOp_pmaxub_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9762 /* 0xdf */ iemOp_pandn_Pq_Qq, iemOp_pandn_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9763
9764 /* 0xe0 */ iemOp_pavgb_Pq_Qq, iemOp_pavgb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9765 /* 0xe1 */ iemOp_psraw_Pq_Qq, iemOp_psraw_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9766 /* 0xe2 */ iemOp_psrad_Pq_Qq, iemOp_psrad_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9767 /* 0xe3 */ iemOp_pavgw_Pq_Qq, iemOp_pavgw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9768 /* 0xe4 */ iemOp_pmulhuw_Pq_Qq, iemOp_pmulhuw_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9769 /* 0xe5 */ iemOp_pmulhw_Pq_Qq, iemOp_pmulhw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9770 /* 0xe6 */ iemOp_InvalidNeedRM, iemOp_cvttpd2dq_Vx_Wpd, iemOp_cvtdq2pd_Vx_Wpd, iemOp_cvtpd2dq_Vx_Wpd,
9771 /* 0xe7 */ iemOp_movntq_Mq_Pq, iemOp_movntdq_Mdq_Vdq, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9772 /* 0xe8 */ iemOp_psubsb_Pq_Qq, iemOp_psubsb_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9773 /* 0xe9 */ iemOp_psubsw_Pq_Qq, iemOp_psubsw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9774 /* 0xea */ iemOp_pminsw_Pq_Qq, iemOp_pminsw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9775 /* 0xeb */ iemOp_por_Pq_Qq, iemOp_por_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9776 /* 0xec */ iemOp_paddsb_Pq_Qq, iemOp_paddsb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9777 /* 0xed */ iemOp_paddsw_Pq_Qq, iemOp_paddsw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9778 /* 0xee */ iemOp_pmaxsw_Pq_Qq, iemOp_pmaxsw_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9779 /* 0xef */ iemOp_pxor_Pq_Qq, iemOp_pxor_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9780
9781 /* 0xf0 */ iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM, iemOp_lddqu_Vx_Mx,
9782 /* 0xf1 */ iemOp_psllw_Pq_Qq, iemOp_psllw_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9783 /* 0xf2 */ iemOp_pslld_Pq_Qq, iemOp_pslld_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9784 /* 0xf3 */ iemOp_psllq_Pq_Qq, iemOp_psllq_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9785 /* 0xf4 */ iemOp_pmuludq_Pq_Qq, iemOp_pmuludq_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9786 /* 0xf5 */ iemOp_pmaddwd_Pq_Qq, iemOp_pmaddwd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9787 /* 0xf6 */ iemOp_psadbw_Pq_Qq, iemOp_psadbw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9788 /* 0xf7 */ iemOp_maskmovq_Pq_Nq, iemOp_maskmovdqu_Vdq_Udq, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9789 /* 0xf8 */ iemOp_psubb_Pq_Qq, iemOp_psubb_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9790 /* 0xf9 */ iemOp_psubw_Pq_Qq, iemOp_psubw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9791 /* 0xfa */ iemOp_psubd_Pq_Qq, iemOp_psubd_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9792 /* 0xfb */ iemOp_psubq_Pq_Qq, iemOp_psubq_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9793 /* 0xfc */ iemOp_paddb_Pq_Qq, iemOp_paddb_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9794 /* 0xfd */ iemOp_paddw_Pq_Qq, iemOp_paddw_Vx_Wx, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9795 /* 0xfe */ iemOp_paddd_Pq_Qq, iemOp_paddd_Vx_W, iemOp_InvalidNeedRM, iemOp_InvalidNeedRM,
9796 /* 0xff */ IEMOP_X4(iemOp_ud0),
9797};
9798AssertCompile(RT_ELEMENTS(g_apfnTwoByteMap) == 1024);
9799
9800/** @} */
9801
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