VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h@ 93906

Last change on this file since 93906 was 93906, checked in by vboxsync, 3 years ago

IEM: Implemented fbstp instruction (used by OLE and indirectly MS Word 6.0 and similar).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 395.7 KB
Line 
1/* $Id: IEMAllInstructionsOneByte.cpp.h 93906 2022-02-24 10:28:32Z vboxsync $ */
2/** @file
3 * IEM - Instruction Decoding and Emulation.
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Global Variables *
21*******************************************************************************/
22extern const PFNIEMOP g_apfnOneByteMap[256]; /* not static since we need to forward declare it. */
23
24/* Instruction group definitions: */
25
26/** @defgroup og_gen General
27 * @{ */
28 /** @defgroup og_gen_arith Arithmetic
29 * @{ */
30 /** @defgroup og_gen_arith_bin Binary numbers */
31 /** @defgroup og_gen_arith_dec Decimal numbers */
32 /** @} */
33/** @} */
34
35/** @defgroup og_stack Stack
36 * @{ */
37 /** @defgroup og_stack_sreg Segment registers */
38/** @} */
39
40/** @defgroup og_prefix Prefixes */
41/** @defgroup og_escapes Escape bytes */
42
43
44
45/** @name One byte opcodes.
46 * @{
47 */
48
49/* Instruction specification format - work in progress: */
50
51/**
52 * @opcode 0x00
53 * @opmnemonic add
54 * @op1 rm:Eb
55 * @op2 reg:Gb
56 * @opmaps one
57 * @openc ModR/M
58 * @opflmodify cf,pf,af,zf,sf,of
59 * @ophints harmless ignores_op_sizes
60 * @opstats add_Eb_Gb
61 * @opgroup og_gen_arith_bin
62 * @optest op1=1 op2=1 -> op1=2 efl&|=nc,pe,na,nz,pl,nv
63 * @optest efl|=cf op1=1 op2=2 -> op1=3 efl&|=nc,po,na,nz,pl,nv
64 * @optest op1=254 op2=1 -> op1=255 efl&|=nc,po,na,nz,ng,nv
65 * @optest op1=128 op2=128 -> op1=0 efl&|=ov,pl,zf,na,po,cf
66 */
67FNIEMOP_DEF(iemOp_add_Eb_Gb)
68{
69 IEMOP_MNEMONIC2(MR, ADD, add, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
70 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_add);
71}
72
73
74/**
75 * @opcode 0x01
76 * @opgroup og_gen_arith_bin
77 * @opflmodify cf,pf,af,zf,sf,of
78 * @optest op1=1 op2=1 -> op1=2 efl&|=nc,pe,na,nz,pl,nv
79 * @optest efl|=cf op1=2 op2=2 -> op1=4 efl&|=nc,pe,na,nz,pl,nv
80 * @optest efl&~=cf op1=-1 op2=1 -> op1=0 efl&|=cf,po,af,zf,pl,nv
81 * @optest op1=-1 op2=-1 -> op1=-2 efl&|=cf,pe,af,nz,ng,nv
82 */
83FNIEMOP_DEF(iemOp_add_Ev_Gv)
84{
85 IEMOP_MNEMONIC2(MR, ADD, add, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
86 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_add);
87}
88
89
90/**
91 * @opcode 0x02
92 * @opgroup og_gen_arith_bin
93 * @opflmodify cf,pf,af,zf,sf,of
94 * @opcopytests iemOp_add_Eb_Gb
95 */
96FNIEMOP_DEF(iemOp_add_Gb_Eb)
97{
98 IEMOP_MNEMONIC2(RM, ADD, add, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
99 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_add);
100}
101
102
103/**
104 * @opcode 0x03
105 * @opgroup og_gen_arith_bin
106 * @opflmodify cf,pf,af,zf,sf,of
107 * @opcopytests iemOp_add_Ev_Gv
108 */
109FNIEMOP_DEF(iemOp_add_Gv_Ev)
110{
111 IEMOP_MNEMONIC2(RM, ADD, add, Gv, Ev, DISOPTYPE_HARMLESS, 0);
112 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_add);
113}
114
115
116/**
117 * @opcode 0x04
118 * @opgroup og_gen_arith_bin
119 * @opflmodify cf,pf,af,zf,sf,of
120 * @opcopytests iemOp_add_Eb_Gb
121 */
122FNIEMOP_DEF(iemOp_add_Al_Ib)
123{
124 IEMOP_MNEMONIC2(FIXED, ADD, add, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
125 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_add);
126}
127
128
129/**
130 * @opcode 0x05
131 * @opgroup og_gen_arith_bin
132 * @opflmodify cf,pf,af,zf,sf,of
133 * @optest op1=1 op2=1 -> op1=2 efl&|=nv,pl,nz,na,pe
134 * @optest efl|=cf op1=2 op2=2 -> op1=4 efl&|=nc,pe,na,nz,pl,nv
135 * @optest efl&~=cf op1=-1 op2=1 -> op1=0 efl&|=cf,po,af,zf,pl,nv
136 * @optest op1=-1 op2=-1 -> op1=-2 efl&|=cf,pe,af,nz,ng,nv
137 */
138FNIEMOP_DEF(iemOp_add_eAX_Iz)
139{
140 IEMOP_MNEMONIC2(FIXED, ADD, add, rAX, Iz, DISOPTYPE_HARMLESS, 0);
141 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_add);
142}
143
144
145/**
146 * @opcode 0x06
147 * @opgroup og_stack_sreg
148 */
149FNIEMOP_DEF(iemOp_push_ES)
150{
151 IEMOP_MNEMONIC1(FIXED, PUSH, push, ES, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0);
152 IEMOP_HLP_NO_64BIT();
153 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_ES);
154}
155
156
157/**
158 * @opcode 0x07
159 * @opgroup og_stack_sreg
160 */
161FNIEMOP_DEF(iemOp_pop_ES)
162{
163 IEMOP_MNEMONIC1(FIXED, POP, pop, ES, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0);
164 IEMOP_HLP_NO_64BIT();
165 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
166 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_ES, pVCpu->iem.s.enmEffOpSize);
167}
168
169
170/**
171 * @opcode 0x08
172 * @opgroup og_gen_arith_bin
173 * @opflmodify cf,pf,af,zf,sf,of
174 * @opflundef af
175 * @opflclear of,cf
176 * @optest op1=7 op2=12 -> op1=15 efl&|=nc,po,na,nz,pl,nv
177 * @optest efl|=of,cf op1=0 op2=0 -> op1=0 efl&|=nc,po,na,zf,pl,nv
178 * @optest op1=0xee op2=0x11 -> op1=0xff efl&|=nc,po,na,nz,ng,nv
179 * @optest op1=0xff op2=0xff -> op1=0xff efl&|=nc,po,na,nz,ng,nv
180 */
181FNIEMOP_DEF(iemOp_or_Eb_Gb)
182{
183 IEMOP_MNEMONIC2(MR, OR, or, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
184 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
185 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_or);
186}
187
188
189/*
190 * @opcode 0x09
191 * @opgroup og_gen_arith_bin
192 * @opflmodify cf,pf,af,zf,sf,of
193 * @opflundef af
194 * @opflclear of,cf
195 * @optest efl|=of,cf op1=12 op2=7 -> op1=15 efl&|=nc,po,na,nz,pl,nv
196 * @optest efl|=of,cf op1=0 op2=0 -> op1=0 efl&|=nc,po,na,zf,pl,nv
197 * @optest op1=-2 op2=1 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
198 * @optest o16 / op1=0x5a5a op2=0xa5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
199 * @optest o32 / op1=0x5a5a5a5a op2=0xa5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
200 * @optest o64 / op1=0x5a5a5a5a5a5a5a5a op2=0xa5a5a5a5a5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
201 */
202FNIEMOP_DEF(iemOp_or_Ev_Gv)
203{
204 IEMOP_MNEMONIC2(MR, OR, or, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
205 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
206 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_or);
207}
208
209
210/**
211 * @opcode 0x0a
212 * @opgroup og_gen_arith_bin
213 * @opflmodify cf,pf,af,zf,sf,of
214 * @opflundef af
215 * @opflclear of,cf
216 * @opcopytests iemOp_or_Eb_Gb
217 */
218FNIEMOP_DEF(iemOp_or_Gb_Eb)
219{
220 IEMOP_MNEMONIC2(RM, OR, or, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
221 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
222 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_or);
223}
224
225
226/**
227 * @opcode 0x0b
228 * @opgroup og_gen_arith_bin
229 * @opflmodify cf,pf,af,zf,sf,of
230 * @opflundef af
231 * @opflclear of,cf
232 * @opcopytests iemOp_or_Ev_Gv
233 */
234FNIEMOP_DEF(iemOp_or_Gv_Ev)
235{
236 IEMOP_MNEMONIC2(RM, OR, or, Gv, Ev, DISOPTYPE_HARMLESS, 0);
237 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
238 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_or);
239}
240
241
242/**
243 * @opcode 0x0c
244 * @opgroup og_gen_arith_bin
245 * @opflmodify cf,pf,af,zf,sf,of
246 * @opflundef af
247 * @opflclear of,cf
248 * @opcopytests iemOp_or_Eb_Gb
249 */
250FNIEMOP_DEF(iemOp_or_Al_Ib)
251{
252 IEMOP_MNEMONIC2(FIXED, OR, or, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
253 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
254 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_or);
255}
256
257
258/**
259 * @opcode 0x0d
260 * @opgroup og_gen_arith_bin
261 * @opflmodify cf,pf,af,zf,sf,of
262 * @opflundef af
263 * @opflclear of,cf
264 * @optest efl|=of,cf op1=12 op2=7 -> op1=15 efl&|=nc,po,na,nz,pl,nv
265 * @optest efl|=of,cf op1=0 op2=0 -> op1=0 efl&|=nc,po,na,zf,pl,nv
266 * @optest op1=-2 op2=1 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
267 * @optest o16 / op1=0x5a5a op2=0xa5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
268 * @optest o32 / op1=0x5a5a5a5a op2=0xa5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
269 * @optest o64 / op1=0x5a5a5a5a5a5a5a5a op2=0xa5a5a5a5 -> op1=-1 efl&|=nc,po,na,nz,ng,nv
270 * @optest o64 / op1=0x5a5a5a5aa5a5a5a5 op2=0x5a5a5a5a -> op1=0x5a5a5a5affffffff efl&|=nc,po,na,nz,pl,nv
271 */
272FNIEMOP_DEF(iemOp_or_eAX_Iz)
273{
274 IEMOP_MNEMONIC2(FIXED, OR, or, rAX, Iz, DISOPTYPE_HARMLESS, 0);
275 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
276 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_or);
277}
278
279
280/**
281 * @opcode 0x0e
282 * @opgroup og_stack_sreg
283 */
284FNIEMOP_DEF(iemOp_push_CS)
285{
286 IEMOP_MNEMONIC1(FIXED, PUSH, push, CS, DISOPTYPE_HARMLESS | DISOPTYPE_POTENTIALLY_DANGEROUS | DISOPTYPE_INVALID_64, 0);
287 IEMOP_HLP_NO_64BIT();
288 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_CS);
289}
290
291
292/**
293 * @opcode 0x0f
294 * @opmnemonic EscTwo0f
295 * @openc two0f
296 * @opdisenum OP_2B_ESC
297 * @ophints harmless
298 * @opgroup og_escapes
299 */
300FNIEMOP_DEF(iemOp_2byteEscape)
301{
302#ifdef VBOX_STRICT
303 /* Sanity check the table the first time around. */
304 static bool s_fTested = false;
305 if (RT_LIKELY(s_fTested)) { /* likely */ }
306 else
307 {
308 s_fTested = true;
309 Assert(g_apfnTwoByteMap[0xbc * 4 + 0] == iemOp_bsf_Gv_Ev);
310 Assert(g_apfnTwoByteMap[0xbc * 4 + 1] == iemOp_bsf_Gv_Ev);
311 Assert(g_apfnTwoByteMap[0xbc * 4 + 2] == iemOp_tzcnt_Gv_Ev);
312 Assert(g_apfnTwoByteMap[0xbc * 4 + 3] == iemOp_bsf_Gv_Ev);
313 }
314#endif
315
316 if (RT_LIKELY(IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_286))
317 {
318 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
319 IEMOP_HLP_MIN_286();
320 return FNIEMOP_CALL(g_apfnTwoByteMap[(uintptr_t)b * 4 + pVCpu->iem.s.idxPrefix]);
321 }
322 /* @opdone */
323
324 /*
325 * On the 8086 this is a POP CS instruction.
326 * For the time being we don't specify this this.
327 */
328 IEMOP_MNEMONIC1(FIXED, POP, pop, CS, DISOPTYPE_HARMLESS | DISOPTYPE_POTENTIALLY_DANGEROUS | DISOPTYPE_INVALID_64, IEMOPHINT_SKIP_PYTHON);
329 IEMOP_HLP_NO_64BIT();
330 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
331 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_ES, pVCpu->iem.s.enmEffOpSize);
332}
333
334/**
335 * @opcode 0x10
336 * @opgroup og_gen_arith_bin
337 * @opfltest cf
338 * @opflmodify cf,pf,af,zf,sf,of
339 * @optest op1=1 op2=1 efl&~=cf -> op1=2 efl&|=nc,pe,na,nz,pl,nv
340 * @optest op1=1 op2=1 efl|=cf -> op1=3 efl&|=nc,po,na,nz,pl,nv
341 * @optest op1=0xff op2=0 efl|=cf -> op1=0 efl&|=cf,po,af,zf,pl,nv
342 * @optest op1=0 op2=0 efl|=cf -> op1=1 efl&|=nc,pe,na,nz,pl,nv
343 * @optest op1=0 op2=0 efl&~=cf -> op1=0 efl&|=nc,po,na,zf,pl,nv
344 */
345FNIEMOP_DEF(iemOp_adc_Eb_Gb)
346{
347 IEMOP_MNEMONIC2(MR, ADC, adc, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
348 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_adc);
349}
350
351
352/**
353 * @opcode 0x11
354 * @opgroup og_gen_arith_bin
355 * @opfltest cf
356 * @opflmodify cf,pf,af,zf,sf,of
357 * @optest op1=1 op2=1 efl&~=cf -> op1=2 efl&|=nc,pe,na,nz,pl,nv
358 * @optest op1=1 op2=1 efl|=cf -> op1=3 efl&|=nc,po,na,nz,pl,nv
359 * @optest op1=-1 op2=0 efl|=cf -> op1=0 efl&|=cf,po,af,zf,pl,nv
360 * @optest op1=0 op2=0 efl|=cf -> op1=1 efl&|=nc,pe,na,nz,pl,nv
361 * @optest op1=0 op2=0 efl&~=cf -> op1=0 efl&|=nc,po,na,zf,pl,nv
362 */
363FNIEMOP_DEF(iemOp_adc_Ev_Gv)
364{
365 IEMOP_MNEMONIC2(MR, ADC, adc, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
366 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_adc);
367}
368
369
370/**
371 * @opcode 0x12
372 * @opgroup og_gen_arith_bin
373 * @opfltest cf
374 * @opflmodify cf,pf,af,zf,sf,of
375 * @opcopytests iemOp_adc_Eb_Gb
376 */
377FNIEMOP_DEF(iemOp_adc_Gb_Eb)
378{
379 IEMOP_MNEMONIC2(RM, ADC, adc, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
380 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_adc);
381}
382
383
384/**
385 * @opcode 0x13
386 * @opgroup og_gen_arith_bin
387 * @opfltest cf
388 * @opflmodify cf,pf,af,zf,sf,of
389 * @opcopytests iemOp_adc_Ev_Gv
390 */
391FNIEMOP_DEF(iemOp_adc_Gv_Ev)
392{
393 IEMOP_MNEMONIC2(RM, ADC, adc, Gv, Ev, DISOPTYPE_HARMLESS, 0);
394 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_adc);
395}
396
397
398/**
399 * @opcode 0x14
400 * @opgroup og_gen_arith_bin
401 * @opfltest cf
402 * @opflmodify cf,pf,af,zf,sf,of
403 * @opcopytests iemOp_adc_Eb_Gb
404 */
405FNIEMOP_DEF(iemOp_adc_Al_Ib)
406{
407 IEMOP_MNEMONIC2(FIXED, ADC, adc, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
408 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_adc);
409}
410
411
412/**
413 * @opcode 0x15
414 * @opgroup og_gen_arith_bin
415 * @opfltest cf
416 * @opflmodify cf,pf,af,zf,sf,of
417 * @opcopytests iemOp_adc_Ev_Gv
418 */
419FNIEMOP_DEF(iemOp_adc_eAX_Iz)
420{
421 IEMOP_MNEMONIC2(FIXED, ADC, adc, rAX, Iz, DISOPTYPE_HARMLESS, 0);
422 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_adc);
423}
424
425
426/**
427 * @opcode 0x16
428 */
429FNIEMOP_DEF(iemOp_push_SS)
430{
431 IEMOP_MNEMONIC1(FIXED, PUSH, push, SS, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64 | DISOPTYPE_RRM_DANGEROUS, 0);
432 IEMOP_HLP_NO_64BIT();
433 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_SS);
434}
435
436
437/**
438 * @opcode 0x17
439 * @opgroup og_gen_arith_bin
440 * @opfltest cf
441 * @opflmodify cf,pf,af,zf,sf,of
442 */
443FNIEMOP_DEF(iemOp_pop_SS)
444{
445 IEMOP_MNEMONIC1(FIXED, POP, pop, SS, DISOPTYPE_HARMLESS | DISOPTYPE_INHIBIT_IRQS | DISOPTYPE_INVALID_64 | DISOPTYPE_RRM_DANGEROUS , 0);
446 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
447 IEMOP_HLP_NO_64BIT();
448 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_SS, pVCpu->iem.s.enmEffOpSize);
449}
450
451
452/**
453 * @opcode 0x18
454 * @opgroup og_gen_arith_bin
455 * @opfltest cf
456 * @opflmodify cf,pf,af,zf,sf,of
457 */
458FNIEMOP_DEF(iemOp_sbb_Eb_Gb)
459{
460 IEMOP_MNEMONIC2(MR, SBB, sbb, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
461 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_sbb);
462}
463
464
465/**
466 * @opcode 0x19
467 * @opgroup og_gen_arith_bin
468 * @opfltest cf
469 * @opflmodify cf,pf,af,zf,sf,of
470 */
471FNIEMOP_DEF(iemOp_sbb_Ev_Gv)
472{
473 IEMOP_MNEMONIC2(MR, SBB, sbb, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
474 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_sbb);
475}
476
477
478/**
479 * @opcode 0x1a
480 * @opgroup og_gen_arith_bin
481 * @opfltest cf
482 * @opflmodify cf,pf,af,zf,sf,of
483 */
484FNIEMOP_DEF(iemOp_sbb_Gb_Eb)
485{
486 IEMOP_MNEMONIC2(RM, SBB, sbb, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
487 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_sbb);
488}
489
490
491/**
492 * @opcode 0x1b
493 * @opgroup og_gen_arith_bin
494 * @opfltest cf
495 * @opflmodify cf,pf,af,zf,sf,of
496 */
497FNIEMOP_DEF(iemOp_sbb_Gv_Ev)
498{
499 IEMOP_MNEMONIC2(RM, SBB, sbb, Gv, Ev, DISOPTYPE_HARMLESS, 0);
500 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_sbb);
501}
502
503
504/**
505 * @opcode 0x1c
506 * @opgroup og_gen_arith_bin
507 * @opfltest cf
508 * @opflmodify cf,pf,af,zf,sf,of
509 */
510FNIEMOP_DEF(iemOp_sbb_Al_Ib)
511{
512 IEMOP_MNEMONIC2(FIXED, SBB, sbb, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
513 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_sbb);
514}
515
516
517/**
518 * @opcode 0x1d
519 * @opgroup og_gen_arith_bin
520 * @opfltest cf
521 * @opflmodify cf,pf,af,zf,sf,of
522 */
523FNIEMOP_DEF(iemOp_sbb_eAX_Iz)
524{
525 IEMOP_MNEMONIC2(FIXED, SBB, sbb, rAX, Iz, DISOPTYPE_HARMLESS, 0);
526 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_sbb);
527}
528
529
530/**
531 * @opcode 0x1e
532 * @opgroup og_stack_sreg
533 */
534FNIEMOP_DEF(iemOp_push_DS)
535{
536 IEMOP_MNEMONIC1(FIXED, PUSH, push, DS, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0);
537 IEMOP_HLP_NO_64BIT();
538 return FNIEMOP_CALL_1(iemOpCommonPushSReg, X86_SREG_DS);
539}
540
541
542/**
543 * @opcode 0x1f
544 * @opgroup og_stack_sreg
545 */
546FNIEMOP_DEF(iemOp_pop_DS)
547{
548 IEMOP_MNEMONIC1(FIXED, POP, pop, DS, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64 | DISOPTYPE_RRM_DANGEROUS, 0);
549 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
550 IEMOP_HLP_NO_64BIT();
551 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_pop_Sreg, X86_SREG_DS, pVCpu->iem.s.enmEffOpSize);
552}
553
554
555/**
556 * @opcode 0x20
557 * @opgroup og_gen_arith_bin
558 * @opflmodify cf,pf,af,zf,sf,of
559 * @opflundef af
560 * @opflclear of,cf
561 */
562FNIEMOP_DEF(iemOp_and_Eb_Gb)
563{
564 IEMOP_MNEMONIC2(MR, AND, and, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
565 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
566 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_and);
567}
568
569
570/**
571 * @opcode 0x21
572 * @opgroup og_gen_arith_bin
573 * @opflmodify cf,pf,af,zf,sf,of
574 * @opflundef af
575 * @opflclear of,cf
576 */
577FNIEMOP_DEF(iemOp_and_Ev_Gv)
578{
579 IEMOP_MNEMONIC2(MR, AND, and, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
580 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
581 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_and);
582}
583
584
585/**
586 * @opcode 0x22
587 * @opgroup og_gen_arith_bin
588 * @opflmodify cf,pf,af,zf,sf,of
589 * @opflundef af
590 * @opflclear of,cf
591 */
592FNIEMOP_DEF(iemOp_and_Gb_Eb)
593{
594 IEMOP_MNEMONIC2(RM, AND, and, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
595 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
596 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_and);
597}
598
599
600/**
601 * @opcode 0x23
602 * @opgroup og_gen_arith_bin
603 * @opflmodify cf,pf,af,zf,sf,of
604 * @opflundef af
605 * @opflclear of,cf
606 */
607FNIEMOP_DEF(iemOp_and_Gv_Ev)
608{
609 IEMOP_MNEMONIC2(RM, AND, and, Gv, Ev, DISOPTYPE_HARMLESS, 0);
610 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
611 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_and);
612}
613
614
615/**
616 * @opcode 0x24
617 * @opgroup og_gen_arith_bin
618 * @opflmodify cf,pf,af,zf,sf,of
619 * @opflundef af
620 * @opflclear of,cf
621 */
622FNIEMOP_DEF(iemOp_and_Al_Ib)
623{
624 IEMOP_MNEMONIC2(FIXED, AND, and, AL, Ib, DISOPTYPE_HARMLESS, 0);
625 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
626 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_and);
627}
628
629
630/**
631 * @opcode 0x25
632 * @opgroup og_gen_arith_bin
633 * @opflmodify cf,pf,af,zf,sf,of
634 * @opflundef af
635 * @opflclear of,cf
636 */
637FNIEMOP_DEF(iemOp_and_eAX_Iz)
638{
639 IEMOP_MNEMONIC2(FIXED, AND, and, rAX, Iz, DISOPTYPE_HARMLESS, 0);
640 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
641 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_and);
642}
643
644
645/**
646 * @opcode 0x26
647 * @opmnemonic SEG
648 * @op1 ES
649 * @opgroup og_prefix
650 * @openc prefix
651 * @opdisenum OP_SEG
652 * @ophints harmless
653 */
654FNIEMOP_DEF(iemOp_seg_ES)
655{
656 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg es");
657 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_ES;
658 pVCpu->iem.s.iEffSeg = X86_SREG_ES;
659
660 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
661 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
662}
663
664
665/**
666 * @opcode 0x27
667 * @opfltest af,cf
668 * @opflmodify cf,pf,af,zf,sf,of
669 * @opflundef of
670 */
671FNIEMOP_DEF(iemOp_daa)
672{
673 IEMOP_MNEMONIC0(FIXED, DAA, daa, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0); /* express implicit AL register use */
674 IEMOP_HLP_NO_64BIT();
675 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
676 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
677 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_daa);
678}
679
680
681/**
682 * @opcode 0x28
683 * @opgroup og_gen_arith_bin
684 * @opflmodify cf,pf,af,zf,sf,of
685 */
686FNIEMOP_DEF(iemOp_sub_Eb_Gb)
687{
688 IEMOP_MNEMONIC2(MR, SUB, sub, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
689 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_sub);
690}
691
692
693/**
694 * @opcode 0x29
695 * @opgroup og_gen_arith_bin
696 * @opflmodify cf,pf,af,zf,sf,of
697 */
698FNIEMOP_DEF(iemOp_sub_Ev_Gv)
699{
700 IEMOP_MNEMONIC2(MR, SUB, sub, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
701 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_sub);
702}
703
704
705/**
706 * @opcode 0x2a
707 * @opgroup og_gen_arith_bin
708 * @opflmodify cf,pf,af,zf,sf,of
709 */
710FNIEMOP_DEF(iemOp_sub_Gb_Eb)
711{
712 IEMOP_MNEMONIC2(RM, SUB, sub, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
713 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_sub);
714}
715
716
717/**
718 * @opcode 0x2b
719 * @opgroup og_gen_arith_bin
720 * @opflmodify cf,pf,af,zf,sf,of
721 */
722FNIEMOP_DEF(iemOp_sub_Gv_Ev)
723{
724 IEMOP_MNEMONIC2(RM, SUB, sub, Gv, Ev, DISOPTYPE_HARMLESS, 0);
725 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_sub);
726}
727
728
729/**
730 * @opcode 0x2c
731 * @opgroup og_gen_arith_bin
732 * @opflmodify cf,pf,af,zf,sf,of
733 */
734FNIEMOP_DEF(iemOp_sub_Al_Ib)
735{
736 IEMOP_MNEMONIC2(FIXED, SUB, sub, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
737 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_sub);
738}
739
740
741/**
742 * @opcode 0x2d
743 * @opgroup og_gen_arith_bin
744 * @opflmodify cf,pf,af,zf,sf,of
745 */
746FNIEMOP_DEF(iemOp_sub_eAX_Iz)
747{
748 IEMOP_MNEMONIC2(FIXED, SUB, sub, rAX, Iz, DISOPTYPE_HARMLESS, 0);
749 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_sub);
750}
751
752
753/**
754 * @opcode 0x2e
755 * @opmnemonic SEG
756 * @op1 CS
757 * @opgroup og_prefix
758 * @openc prefix
759 * @opdisenum OP_SEG
760 * @ophints harmless
761 */
762FNIEMOP_DEF(iemOp_seg_CS)
763{
764 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg cs");
765 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_CS;
766 pVCpu->iem.s.iEffSeg = X86_SREG_CS;
767
768 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
769 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
770}
771
772
773/**
774 * @opcode 0x2f
775 * @opfltest af,cf
776 * @opflmodify cf,pf,af,zf,sf,of
777 * @opflundef of
778 */
779FNIEMOP_DEF(iemOp_das)
780{
781 IEMOP_MNEMONIC0(FIXED, DAS, das, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0); /* express implicit AL register use */
782 IEMOP_HLP_NO_64BIT();
783 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
784 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
785 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_das);
786}
787
788
789/**
790 * @opcode 0x30
791 * @opgroup og_gen_arith_bin
792 * @opflmodify cf,pf,af,zf,sf,of
793 * @opflundef af
794 * @opflclear of,cf
795 */
796FNIEMOP_DEF(iemOp_xor_Eb_Gb)
797{
798 IEMOP_MNEMONIC2(MR, XOR, xor, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
799 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
800 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_xor);
801}
802
803
804/**
805 * @opcode 0x31
806 * @opgroup og_gen_arith_bin
807 * @opflmodify cf,pf,af,zf,sf,of
808 * @opflundef af
809 * @opflclear of,cf
810 */
811FNIEMOP_DEF(iemOp_xor_Ev_Gv)
812{
813 IEMOP_MNEMONIC2(MR, XOR, xor, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
814 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
815 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_xor);
816}
817
818
819/**
820 * @opcode 0x32
821 * @opgroup og_gen_arith_bin
822 * @opflmodify cf,pf,af,zf,sf,of
823 * @opflundef af
824 * @opflclear of,cf
825 */
826FNIEMOP_DEF(iemOp_xor_Gb_Eb)
827{
828 IEMOP_MNEMONIC2(RM, XOR, xor, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
829 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
830 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_xor);
831}
832
833
834/**
835 * @opcode 0x33
836 * @opgroup og_gen_arith_bin
837 * @opflmodify cf,pf,af,zf,sf,of
838 * @opflundef af
839 * @opflclear of,cf
840 */
841FNIEMOP_DEF(iemOp_xor_Gv_Ev)
842{
843 IEMOP_MNEMONIC2(RM, XOR, xor, Gv, Ev, DISOPTYPE_HARMLESS, 0);
844 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
845 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_xor);
846}
847
848
849/**
850 * @opcode 0x34
851 * @opgroup og_gen_arith_bin
852 * @opflmodify cf,pf,af,zf,sf,of
853 * @opflundef af
854 * @opflclear of,cf
855 */
856FNIEMOP_DEF(iemOp_xor_Al_Ib)
857{
858 IEMOP_MNEMONIC2(FIXED, XOR, xor, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
859 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
860 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_xor);
861}
862
863
864/**
865 * @opcode 0x35
866 * @opgroup og_gen_arith_bin
867 * @opflmodify cf,pf,af,zf,sf,of
868 * @opflundef af
869 * @opflclear of,cf
870 */
871FNIEMOP_DEF(iemOp_xor_eAX_Iz)
872{
873 IEMOP_MNEMONIC2(FIXED, XOR, xor, rAX, Iz, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
874 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
875 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_xor);
876}
877
878
879/**
880 * @opcode 0x36
881 * @opmnemonic SEG
882 * @op1 SS
883 * @opgroup og_prefix
884 * @openc prefix
885 * @opdisenum OP_SEG
886 * @ophints harmless
887 */
888FNIEMOP_DEF(iemOp_seg_SS)
889{
890 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg ss");
891 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_SS;
892 pVCpu->iem.s.iEffSeg = X86_SREG_SS;
893
894 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
895 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
896}
897
898
899/**
900 * @opcode 0x37
901 * @opfltest af,cf
902 * @opflmodify cf,pf,af,zf,sf,of
903 * @opflundef pf,zf,sf,of
904 * @opgroup og_gen_arith_dec
905 * @optest efl&~=af ax=9 -> efl&|=nc,po,na,nz,pl,nv
906 * @optest efl&~=af ax=0 -> efl&|=nc,po,na,zf,pl,nv
907 * @optest intel / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,zf,pl,nv
908 * @optest amd / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,nz,pl,nv
909 * @optest efl&~=af ax=0x00f9 -> ax=0x0009 efl&|=nc,po,na,nz,pl,nv
910 * @optest efl|=af ax=0 -> ax=0x0106 efl&|=cf,po,af,nz,pl,nv
911 * @optest efl|=af ax=0x0100 -> ax=0x0206 efl&|=cf,po,af,nz,pl,nv
912 * @optest intel / efl|=af ax=0x000a -> ax=0x0100 efl&|=cf,po,af,zf,pl,nv
913 * @optest amd / efl|=af ax=0x000a -> ax=0x0100 efl&|=cf,pe,af,nz,pl,nv
914 * @optest intel / efl|=af ax=0x010a -> ax=0x0200 efl&|=cf,po,af,zf,pl,nv
915 * @optest amd / efl|=af ax=0x010a -> ax=0x0200 efl&|=cf,pe,af,nz,pl,nv
916 * @optest intel / efl|=af ax=0x0f0a -> ax=0x1000 efl&|=cf,po,af,zf,pl,nv
917 * @optest amd / efl|=af ax=0x0f0a -> ax=0x1000 efl&|=cf,pe,af,nz,pl,nv
918 * @optest intel / efl|=af ax=0x7f0a -> ax=0x8000 efl&|=cf,po,af,zf,pl,nv
919 * @optest amd / efl|=af ax=0x7f0a -> ax=0x8000 efl&|=cf,pe,af,nz,ng,ov
920 * @optest intel / efl|=af ax=0xff0a -> ax=0x0000 efl&|=cf,po,af,zf,pl,nv
921 * @optest amd / efl|=af ax=0xff0a -> ax=0x0000 efl&|=cf,pe,af,nz,pl,nv
922 * @optest intel / efl&~=af ax=0xff0a -> ax=0x0000 efl&|=cf,po,af,zf,pl,nv
923 * @optest amd / efl&~=af ax=0xff0a -> ax=0x0000 efl&|=cf,pe,af,nz,pl,nv
924 * @optest intel / efl&~=af ax=0x000b -> ax=0x0101 efl&|=cf,pe,af,nz,pl,nv
925 * @optest amd / efl&~=af ax=0x000b -> ax=0x0101 efl&|=cf,po,af,nz,pl,nv
926 * @optest intel / efl&~=af ax=0x000c -> ax=0x0102 efl&|=cf,pe,af,nz,pl,nv
927 * @optest amd / efl&~=af ax=0x000c -> ax=0x0102 efl&|=cf,po,af,nz,pl,nv
928 * @optest intel / efl&~=af ax=0x000d -> ax=0x0103 efl&|=cf,po,af,nz,pl,nv
929 * @optest amd / efl&~=af ax=0x000d -> ax=0x0103 efl&|=cf,pe,af,nz,pl,nv
930 * @optest intel / efl&~=af ax=0x000e -> ax=0x0104 efl&|=cf,pe,af,nz,pl,nv
931 * @optest amd / efl&~=af ax=0x000e -> ax=0x0104 efl&|=cf,po,af,nz,pl,nv
932 * @optest intel / efl&~=af ax=0x000f -> ax=0x0105 efl&|=cf,po,af,nz,pl,nv
933 * @optest amd / efl&~=af ax=0x000f -> ax=0x0105 efl&|=cf,pe,af,nz,pl,nv
934 * @optest intel / efl&~=af ax=0x020f -> ax=0x0305 efl&|=cf,po,af,nz,pl,nv
935 * @optest amd / efl&~=af ax=0x020f -> ax=0x0305 efl&|=cf,pe,af,nz,pl,nv
936 */
937FNIEMOP_DEF(iemOp_aaa)
938{
939 IEMOP_MNEMONIC0(FIXED, AAA, aaa, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0); /* express implicit AL/AX register use */
940 IEMOP_HLP_NO_64BIT();
941 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
942 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
943
944 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_aaa);
945}
946
947
948/**
949 * @opcode 0x38
950 */
951FNIEMOP_DEF(iemOp_cmp_Eb_Gb)
952{
953 IEMOP_MNEMONIC(cmp_Eb_Gb, "cmp Eb,Gb");
954 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_cmp);
955}
956
957
958/**
959 * @opcode 0x39
960 */
961FNIEMOP_DEF(iemOp_cmp_Ev_Gv)
962{
963 IEMOP_MNEMONIC(cmp_Ev_Gv, "cmp Ev,Gv");
964 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_cmp);
965}
966
967
968/**
969 * @opcode 0x3a
970 */
971FNIEMOP_DEF(iemOp_cmp_Gb_Eb)
972{
973 IEMOP_MNEMONIC(cmp_Gb_Eb, "cmp Gb,Eb");
974 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_r8_rm, &g_iemAImpl_cmp);
975}
976
977
978/**
979 * @opcode 0x3b
980 */
981FNIEMOP_DEF(iemOp_cmp_Gv_Ev)
982{
983 IEMOP_MNEMONIC(cmp_Gv_Ev, "cmp Gv,Ev");
984 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_cmp);
985}
986
987
988/**
989 * @opcode 0x3c
990 */
991FNIEMOP_DEF(iemOp_cmp_Al_Ib)
992{
993 IEMOP_MNEMONIC(cmp_al_Ib, "cmp al,Ib");
994 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_cmp);
995}
996
997
998/**
999 * @opcode 0x3d
1000 */
1001FNIEMOP_DEF(iemOp_cmp_eAX_Iz)
1002{
1003 IEMOP_MNEMONIC(cmp_rAX_Iz, "cmp rAX,Iz");
1004 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_cmp);
1005}
1006
1007
1008/**
1009 * @opcode 0x3e
1010 */
1011FNIEMOP_DEF(iemOp_seg_DS)
1012{
1013 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg ds");
1014 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_DS;
1015 pVCpu->iem.s.iEffSeg = X86_SREG_DS;
1016
1017 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1018 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1019}
1020
1021
1022/**
1023 * @opcode 0x3f
1024 * @opfltest af,cf
1025 * @opflmodify cf,pf,af,zf,sf,of
1026 * @opflundef pf,zf,sf,of
1027 * @opgroup og_gen_arith_dec
1028 * @optest / efl&~=af ax=0x0009 -> efl&|=nc,po,na,nz,pl,nv
1029 * @optest / efl&~=af ax=0x0000 -> efl&|=nc,po,na,zf,pl,nv
1030 * @optest intel / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,zf,pl,nv
1031 * @optest amd / efl&~=af ax=0x00f0 -> ax=0x0000 efl&|=nc,po,na,nz,pl,nv
1032 * @optest / efl&~=af ax=0x00f9 -> ax=0x0009 efl&|=nc,po,na,nz,pl,nv
1033 * @optest intel / efl|=af ax=0x0000 -> ax=0xfe0a efl&|=cf,po,af,nz,pl,nv
1034 * @optest amd / efl|=af ax=0x0000 -> ax=0xfe0a efl&|=cf,po,af,nz,ng,nv
1035 * @optest intel / efl|=af ax=0x0100 -> ax=0xff0a efl&|=cf,po,af,nz,pl,nv
1036 * @optest8 amd / efl|=af ax=0x0100 -> ax=0xff0a efl&|=cf,po,af,nz,ng,nv
1037 * @optest intel / efl|=af ax=0x000a -> ax=0xff04 efl&|=cf,pe,af,nz,pl,nv
1038 * @optest10 amd / efl|=af ax=0x000a -> ax=0xff04 efl&|=cf,pe,af,nz,ng,nv
1039 * @optest / efl|=af ax=0x010a -> ax=0x0004 efl&|=cf,pe,af,nz,pl,nv
1040 * @optest / efl|=af ax=0x020a -> ax=0x0104 efl&|=cf,pe,af,nz,pl,nv
1041 * @optest / efl|=af ax=0x0f0a -> ax=0x0e04 efl&|=cf,pe,af,nz,pl,nv
1042 * @optest / efl|=af ax=0x7f0a -> ax=0x7e04 efl&|=cf,pe,af,nz,pl,nv
1043 * @optest intel / efl|=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,pl,nv
1044 * @optest amd / efl|=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,ng,nv
1045 * @optest intel / efl&~=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,pl,nv
1046 * @optest amd / efl&~=af ax=0xff0a -> ax=0xfe04 efl&|=cf,pe,af,nz,ng,nv
1047 * @optest intel / efl&~=af ax=0xff09 -> ax=0xff09 efl&|=nc,po,na,nz,pl,nv
1048 * @optest amd / efl&~=af ax=0xff09 -> ax=0xff09 efl&|=nc,po,na,nz,ng,nv
1049 * @optest intel / efl&~=af ax=0x000b -> ax=0xff05 efl&|=cf,po,af,nz,pl,nv
1050 * @optest22 amd / efl&~=af ax=0x000b -> ax=0xff05 efl&|=cf,po,af,nz,ng,nv
1051 * @optest intel / efl&~=af ax=0x000c -> ax=0xff06 efl&|=cf,po,af,nz,pl,nv
1052 * @optest24 amd / efl&~=af ax=0x000c -> ax=0xff06 efl&|=cf,po,af,nz,ng,nv
1053 * @optest intel / efl&~=af ax=0x000d -> ax=0xff07 efl&|=cf,pe,af,nz,pl,nv
1054 * @optest26 amd / efl&~=af ax=0x000d -> ax=0xff07 efl&|=cf,pe,af,nz,ng,nv
1055 * @optest intel / efl&~=af ax=0x000e -> ax=0xff08 efl&|=cf,pe,af,nz,pl,nv
1056 * @optest28 amd / efl&~=af ax=0x000e -> ax=0xff08 efl&|=cf,pe,af,nz,ng,nv
1057 * @optest intel / efl&~=af ax=0x000f -> ax=0xff09 efl&|=cf,po,af,nz,pl,nv
1058 * @optest30 amd / efl&~=af ax=0x000f -> ax=0xff09 efl&|=cf,po,af,nz,ng,nv
1059 * @optest31 intel / efl&~=af ax=0x00fa -> ax=0xff04 efl&|=cf,pe,af,nz,pl,nv
1060 * @optest32 amd / efl&~=af ax=0x00fa -> ax=0xff04 efl&|=cf,pe,af,nz,ng,nv
1061 * @optest33 intel / efl&~=af ax=0xfffa -> ax=0xfe04 efl&|=cf,pe,af,nz,pl,nv
1062 * @optest34 amd / efl&~=af ax=0xfffa -> ax=0xfe04 efl&|=cf,pe,af,nz,ng,nv
1063 */
1064FNIEMOP_DEF(iemOp_aas)
1065{
1066 IEMOP_MNEMONIC0(FIXED, AAS, aas, DISOPTYPE_HARMLESS | DISOPTYPE_INVALID_64, 0); /* express implicit AL/AX register use */
1067 IEMOP_HLP_NO_64BIT();
1068 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1069 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_OF);
1070
1071 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_aas);
1072}
1073
1074
1075/**
1076 * Common 'inc/dec/not/neg register' helper.
1077 */
1078FNIEMOP_DEF_2(iemOpCommonUnaryGReg, PCIEMOPUNARYSIZES, pImpl, uint8_t, iReg)
1079{
1080 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1081 switch (pVCpu->iem.s.enmEffOpSize)
1082 {
1083 case IEMMODE_16BIT:
1084 IEM_MC_BEGIN(2, 0);
1085 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
1086 IEM_MC_ARG(uint32_t *, pEFlags, 1);
1087 IEM_MC_REF_GREG_U16(pu16Dst, iReg);
1088 IEM_MC_REF_EFLAGS(pEFlags);
1089 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU16, pu16Dst, pEFlags);
1090 IEM_MC_ADVANCE_RIP();
1091 IEM_MC_END();
1092 return VINF_SUCCESS;
1093
1094 case IEMMODE_32BIT:
1095 IEM_MC_BEGIN(2, 0);
1096 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
1097 IEM_MC_ARG(uint32_t *, pEFlags, 1);
1098 IEM_MC_REF_GREG_U32(pu32Dst, iReg);
1099 IEM_MC_REF_EFLAGS(pEFlags);
1100 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU32, pu32Dst, pEFlags);
1101 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
1102 IEM_MC_ADVANCE_RIP();
1103 IEM_MC_END();
1104 return VINF_SUCCESS;
1105
1106 case IEMMODE_64BIT:
1107 IEM_MC_BEGIN(2, 0);
1108 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
1109 IEM_MC_ARG(uint32_t *, pEFlags, 1);
1110 IEM_MC_REF_GREG_U64(pu64Dst, iReg);
1111 IEM_MC_REF_EFLAGS(pEFlags);
1112 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU64, pu64Dst, pEFlags);
1113 IEM_MC_ADVANCE_RIP();
1114 IEM_MC_END();
1115 return VINF_SUCCESS;
1116 }
1117 return VINF_SUCCESS;
1118}
1119
1120
1121/**
1122 * @opcode 0x40
1123 */
1124FNIEMOP_DEF(iemOp_inc_eAX)
1125{
1126 /*
1127 * This is a REX prefix in 64-bit mode.
1128 */
1129 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1130 {
1131 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex");
1132 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX;
1133
1134 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1135 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1136 }
1137
1138 IEMOP_MNEMONIC(inc_eAX, "inc eAX");
1139 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xAX);
1140}
1141
1142
1143/**
1144 * @opcode 0x41
1145 */
1146FNIEMOP_DEF(iemOp_inc_eCX)
1147{
1148 /*
1149 * This is a REX prefix in 64-bit mode.
1150 */
1151 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1152 {
1153 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.b");
1154 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B;
1155 pVCpu->iem.s.uRexB = 1 << 3;
1156
1157 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1158 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1159 }
1160
1161 IEMOP_MNEMONIC(inc_eCX, "inc eCX");
1162 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xCX);
1163}
1164
1165
1166/**
1167 * @opcode 0x42
1168 */
1169FNIEMOP_DEF(iemOp_inc_eDX)
1170{
1171 /*
1172 * This is a REX prefix in 64-bit mode.
1173 */
1174 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1175 {
1176 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.x");
1177 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_X;
1178 pVCpu->iem.s.uRexIndex = 1 << 3;
1179
1180 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1181 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1182 }
1183
1184 IEMOP_MNEMONIC(inc_eDX, "inc eDX");
1185 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xDX);
1186}
1187
1188
1189
1190/**
1191 * @opcode 0x43
1192 */
1193FNIEMOP_DEF(iemOp_inc_eBX)
1194{
1195 /*
1196 * This is a REX prefix in 64-bit mode.
1197 */
1198 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1199 {
1200 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.bx");
1201 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X;
1202 pVCpu->iem.s.uRexB = 1 << 3;
1203 pVCpu->iem.s.uRexIndex = 1 << 3;
1204
1205 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1206 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1207 }
1208
1209 IEMOP_MNEMONIC(inc_eBX, "inc eBX");
1210 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xBX);
1211}
1212
1213
1214/**
1215 * @opcode 0x44
1216 */
1217FNIEMOP_DEF(iemOp_inc_eSP)
1218{
1219 /*
1220 * This is a REX prefix in 64-bit mode.
1221 */
1222 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1223 {
1224 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.r");
1225 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R;
1226 pVCpu->iem.s.uRexReg = 1 << 3;
1227
1228 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1229 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1230 }
1231
1232 IEMOP_MNEMONIC(inc_eSP, "inc eSP");
1233 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xSP);
1234}
1235
1236
1237/**
1238 * @opcode 0x45
1239 */
1240FNIEMOP_DEF(iemOp_inc_eBP)
1241{
1242 /*
1243 * This is a REX prefix in 64-bit mode.
1244 */
1245 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1246 {
1247 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rb");
1248 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B;
1249 pVCpu->iem.s.uRexReg = 1 << 3;
1250 pVCpu->iem.s.uRexB = 1 << 3;
1251
1252 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1253 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1254 }
1255
1256 IEMOP_MNEMONIC(inc_eBP, "inc eBP");
1257 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xBP);
1258}
1259
1260
1261/**
1262 * @opcode 0x46
1263 */
1264FNIEMOP_DEF(iemOp_inc_eSI)
1265{
1266 /*
1267 * This is a REX prefix in 64-bit mode.
1268 */
1269 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1270 {
1271 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rx");
1272 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_X;
1273 pVCpu->iem.s.uRexReg = 1 << 3;
1274 pVCpu->iem.s.uRexIndex = 1 << 3;
1275
1276 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1277 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1278 }
1279
1280 IEMOP_MNEMONIC(inc_eSI, "inc eSI");
1281 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xSI);
1282}
1283
1284
1285/**
1286 * @opcode 0x47
1287 */
1288FNIEMOP_DEF(iemOp_inc_eDI)
1289{
1290 /*
1291 * This is a REX prefix in 64-bit mode.
1292 */
1293 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1294 {
1295 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rbx");
1296 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X;
1297 pVCpu->iem.s.uRexReg = 1 << 3;
1298 pVCpu->iem.s.uRexB = 1 << 3;
1299 pVCpu->iem.s.uRexIndex = 1 << 3;
1300
1301 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1302 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1303 }
1304
1305 IEMOP_MNEMONIC(inc_eDI, "inc eDI");
1306 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_inc, X86_GREG_xDI);
1307}
1308
1309
1310/**
1311 * @opcode 0x48
1312 */
1313FNIEMOP_DEF(iemOp_dec_eAX)
1314{
1315 /*
1316 * This is a REX prefix in 64-bit mode.
1317 */
1318 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1319 {
1320 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.w");
1321 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_SIZE_REX_W;
1322 iemRecalEffOpSize(pVCpu);
1323
1324 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1325 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1326 }
1327
1328 IEMOP_MNEMONIC(dec_eAX, "dec eAX");
1329 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xAX);
1330}
1331
1332
1333/**
1334 * @opcode 0x49
1335 */
1336FNIEMOP_DEF(iemOp_dec_eCX)
1337{
1338 /*
1339 * This is a REX prefix in 64-bit mode.
1340 */
1341 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1342 {
1343 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.bw");
1344 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_SIZE_REX_W;
1345 pVCpu->iem.s.uRexB = 1 << 3;
1346 iemRecalEffOpSize(pVCpu);
1347
1348 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1349 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1350 }
1351
1352 IEMOP_MNEMONIC(dec_eCX, "dec eCX");
1353 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xCX);
1354}
1355
1356
1357/**
1358 * @opcode 0x4a
1359 */
1360FNIEMOP_DEF(iemOp_dec_eDX)
1361{
1362 /*
1363 * This is a REX prefix in 64-bit mode.
1364 */
1365 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1366 {
1367 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.xw");
1368 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
1369 pVCpu->iem.s.uRexIndex = 1 << 3;
1370 iemRecalEffOpSize(pVCpu);
1371
1372 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1373 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1374 }
1375
1376 IEMOP_MNEMONIC(dec_eDX, "dec eDX");
1377 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xDX);
1378}
1379
1380
1381/**
1382 * @opcode 0x4b
1383 */
1384FNIEMOP_DEF(iemOp_dec_eBX)
1385{
1386 /*
1387 * This is a REX prefix in 64-bit mode.
1388 */
1389 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1390 {
1391 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.bxw");
1392 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
1393 pVCpu->iem.s.uRexB = 1 << 3;
1394 pVCpu->iem.s.uRexIndex = 1 << 3;
1395 iemRecalEffOpSize(pVCpu);
1396
1397 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1398 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1399 }
1400
1401 IEMOP_MNEMONIC(dec_eBX, "dec eBX");
1402 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xBX);
1403}
1404
1405
1406/**
1407 * @opcode 0x4c
1408 */
1409FNIEMOP_DEF(iemOp_dec_eSP)
1410{
1411 /*
1412 * This is a REX prefix in 64-bit mode.
1413 */
1414 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1415 {
1416 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rw");
1417 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_SIZE_REX_W;
1418 pVCpu->iem.s.uRexReg = 1 << 3;
1419 iemRecalEffOpSize(pVCpu);
1420
1421 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1422 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1423 }
1424
1425 IEMOP_MNEMONIC(dec_eSP, "dec eSP");
1426 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xSP);
1427}
1428
1429
1430/**
1431 * @opcode 0x4d
1432 */
1433FNIEMOP_DEF(iemOp_dec_eBP)
1434{
1435 /*
1436 * This is a REX prefix in 64-bit mode.
1437 */
1438 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1439 {
1440 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rbw");
1441 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_SIZE_REX_W;
1442 pVCpu->iem.s.uRexReg = 1 << 3;
1443 pVCpu->iem.s.uRexB = 1 << 3;
1444 iemRecalEffOpSize(pVCpu);
1445
1446 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1447 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1448 }
1449
1450 IEMOP_MNEMONIC(dec_eBP, "dec eBP");
1451 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xBP);
1452}
1453
1454
1455/**
1456 * @opcode 0x4e
1457 */
1458FNIEMOP_DEF(iemOp_dec_eSI)
1459{
1460 /*
1461 * This is a REX prefix in 64-bit mode.
1462 */
1463 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1464 {
1465 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rxw");
1466 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
1467 pVCpu->iem.s.uRexReg = 1 << 3;
1468 pVCpu->iem.s.uRexIndex = 1 << 3;
1469 iemRecalEffOpSize(pVCpu);
1470
1471 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1472 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1473 }
1474
1475 IEMOP_MNEMONIC(dec_eSI, "dec eSI");
1476 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xSI);
1477}
1478
1479
1480/**
1481 * @opcode 0x4f
1482 */
1483FNIEMOP_DEF(iemOp_dec_eDI)
1484{
1485 /*
1486 * This is a REX prefix in 64-bit mode.
1487 */
1488 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1489 {
1490 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("rex.rbxw");
1491 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W;
1492 pVCpu->iem.s.uRexReg = 1 << 3;
1493 pVCpu->iem.s.uRexB = 1 << 3;
1494 pVCpu->iem.s.uRexIndex = 1 << 3;
1495 iemRecalEffOpSize(pVCpu);
1496
1497 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
1498 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
1499 }
1500
1501 IEMOP_MNEMONIC(dec_eDI, "dec eDI");
1502 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, &g_iemAImpl_dec, X86_GREG_xDI);
1503}
1504
1505
1506/**
1507 * Common 'push register' helper.
1508 */
1509FNIEMOP_DEF_1(iemOpCommonPushGReg, uint8_t, iReg)
1510{
1511 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1512 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1513 {
1514 iReg |= pVCpu->iem.s.uRexB;
1515 pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
1516 pVCpu->iem.s.enmEffOpSize = !(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
1517 }
1518
1519 switch (pVCpu->iem.s.enmEffOpSize)
1520 {
1521 case IEMMODE_16BIT:
1522 IEM_MC_BEGIN(0, 1);
1523 IEM_MC_LOCAL(uint16_t, u16Value);
1524 IEM_MC_FETCH_GREG_U16(u16Value, iReg);
1525 IEM_MC_PUSH_U16(u16Value);
1526 IEM_MC_ADVANCE_RIP();
1527 IEM_MC_END();
1528 break;
1529
1530 case IEMMODE_32BIT:
1531 IEM_MC_BEGIN(0, 1);
1532 IEM_MC_LOCAL(uint32_t, u32Value);
1533 IEM_MC_FETCH_GREG_U32(u32Value, iReg);
1534 IEM_MC_PUSH_U32(u32Value);
1535 IEM_MC_ADVANCE_RIP();
1536 IEM_MC_END();
1537 break;
1538
1539 case IEMMODE_64BIT:
1540 IEM_MC_BEGIN(0, 1);
1541 IEM_MC_LOCAL(uint64_t, u64Value);
1542 IEM_MC_FETCH_GREG_U64(u64Value, iReg);
1543 IEM_MC_PUSH_U64(u64Value);
1544 IEM_MC_ADVANCE_RIP();
1545 IEM_MC_END();
1546 break;
1547 }
1548
1549 return VINF_SUCCESS;
1550}
1551
1552
1553/**
1554 * @opcode 0x50
1555 */
1556FNIEMOP_DEF(iemOp_push_eAX)
1557{
1558 IEMOP_MNEMONIC(push_rAX, "push rAX");
1559 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xAX);
1560}
1561
1562
1563/**
1564 * @opcode 0x51
1565 */
1566FNIEMOP_DEF(iemOp_push_eCX)
1567{
1568 IEMOP_MNEMONIC(push_rCX, "push rCX");
1569 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xCX);
1570}
1571
1572
1573/**
1574 * @opcode 0x52
1575 */
1576FNIEMOP_DEF(iemOp_push_eDX)
1577{
1578 IEMOP_MNEMONIC(push_rDX, "push rDX");
1579 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xDX);
1580}
1581
1582
1583/**
1584 * @opcode 0x53
1585 */
1586FNIEMOP_DEF(iemOp_push_eBX)
1587{
1588 IEMOP_MNEMONIC(push_rBX, "push rBX");
1589 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xBX);
1590}
1591
1592
1593/**
1594 * @opcode 0x54
1595 */
1596FNIEMOP_DEF(iemOp_push_eSP)
1597{
1598 IEMOP_MNEMONIC(push_rSP, "push rSP");
1599 if (IEM_GET_TARGET_CPU(pVCpu) == IEMTARGETCPU_8086)
1600 {
1601 IEM_MC_BEGIN(0, 1);
1602 IEM_MC_LOCAL(uint16_t, u16Value);
1603 IEM_MC_FETCH_GREG_U16(u16Value, X86_GREG_xSP);
1604 IEM_MC_SUB_LOCAL_U16(u16Value, 2);
1605 IEM_MC_PUSH_U16(u16Value);
1606 IEM_MC_ADVANCE_RIP();
1607 IEM_MC_END();
1608 }
1609 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSP);
1610}
1611
1612
1613/**
1614 * @opcode 0x55
1615 */
1616FNIEMOP_DEF(iemOp_push_eBP)
1617{
1618 IEMOP_MNEMONIC(push_rBP, "push rBP");
1619 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xBP);
1620}
1621
1622
1623/**
1624 * @opcode 0x56
1625 */
1626FNIEMOP_DEF(iemOp_push_eSI)
1627{
1628 IEMOP_MNEMONIC(push_rSI, "push rSI");
1629 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSI);
1630}
1631
1632
1633/**
1634 * @opcode 0x57
1635 */
1636FNIEMOP_DEF(iemOp_push_eDI)
1637{
1638 IEMOP_MNEMONIC(push_rDI, "push rDI");
1639 return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xDI);
1640}
1641
1642
1643/**
1644 * Common 'pop register' helper.
1645 */
1646FNIEMOP_DEF_1(iemOpCommonPopGReg, uint8_t, iReg)
1647{
1648 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1649 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1650 {
1651 iReg |= pVCpu->iem.s.uRexB;
1652 pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
1653 pVCpu->iem.s.enmEffOpSize = !(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
1654 }
1655
1656 switch (pVCpu->iem.s.enmEffOpSize)
1657 {
1658 case IEMMODE_16BIT:
1659 IEM_MC_BEGIN(0, 1);
1660 IEM_MC_LOCAL(uint16_t *, pu16Dst);
1661 IEM_MC_REF_GREG_U16(pu16Dst, iReg);
1662 IEM_MC_POP_U16(pu16Dst);
1663 IEM_MC_ADVANCE_RIP();
1664 IEM_MC_END();
1665 break;
1666
1667 case IEMMODE_32BIT:
1668 IEM_MC_BEGIN(0, 1);
1669 IEM_MC_LOCAL(uint32_t *, pu32Dst);
1670 IEM_MC_REF_GREG_U32(pu32Dst, iReg);
1671 IEM_MC_POP_U32(pu32Dst);
1672 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst); /** @todo testcase*/
1673 IEM_MC_ADVANCE_RIP();
1674 IEM_MC_END();
1675 break;
1676
1677 case IEMMODE_64BIT:
1678 IEM_MC_BEGIN(0, 1);
1679 IEM_MC_LOCAL(uint64_t *, pu64Dst);
1680 IEM_MC_REF_GREG_U64(pu64Dst, iReg);
1681 IEM_MC_POP_U64(pu64Dst);
1682 IEM_MC_ADVANCE_RIP();
1683 IEM_MC_END();
1684 break;
1685 }
1686
1687 return VINF_SUCCESS;
1688}
1689
1690
1691/**
1692 * @opcode 0x58
1693 */
1694FNIEMOP_DEF(iemOp_pop_eAX)
1695{
1696 IEMOP_MNEMONIC(pop_rAX, "pop rAX");
1697 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xAX);
1698}
1699
1700
1701/**
1702 * @opcode 0x59
1703 */
1704FNIEMOP_DEF(iemOp_pop_eCX)
1705{
1706 IEMOP_MNEMONIC(pop_rCX, "pop rCX");
1707 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xCX);
1708}
1709
1710
1711/**
1712 * @opcode 0x5a
1713 */
1714FNIEMOP_DEF(iemOp_pop_eDX)
1715{
1716 IEMOP_MNEMONIC(pop_rDX, "pop rDX");
1717 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xDX);
1718}
1719
1720
1721/**
1722 * @opcode 0x5b
1723 */
1724FNIEMOP_DEF(iemOp_pop_eBX)
1725{
1726 IEMOP_MNEMONIC(pop_rBX, "pop rBX");
1727 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xBX);
1728}
1729
1730
1731/**
1732 * @opcode 0x5c
1733 */
1734FNIEMOP_DEF(iemOp_pop_eSP)
1735{
1736 IEMOP_MNEMONIC(pop_rSP, "pop rSP");
1737 if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
1738 {
1739 if (pVCpu->iem.s.uRexB)
1740 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xSP);
1741 pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
1742 pVCpu->iem.s.enmEffOpSize = !(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP) ? IEMMODE_64BIT : IEMMODE_16BIT;
1743 }
1744
1745 IEMOP_HLP_DECODED_NL_1(OP_POP, IEMOPFORM_FIXED, OP_PARM_REG_ESP,
1746 DISOPTYPE_HARMLESS | DISOPTYPE_DEFAULT_64_OP_SIZE | DISOPTYPE_REXB_EXTENDS_OPREG);
1747 /** @todo add testcase for this instruction. */
1748 switch (pVCpu->iem.s.enmEffOpSize)
1749 {
1750 case IEMMODE_16BIT:
1751 IEM_MC_BEGIN(0, 1);
1752 IEM_MC_LOCAL(uint16_t, u16Dst);
1753 IEM_MC_POP_U16(&u16Dst); /** @todo not correct MC, fix later. */
1754 IEM_MC_STORE_GREG_U16(X86_GREG_xSP, u16Dst);
1755 IEM_MC_ADVANCE_RIP();
1756 IEM_MC_END();
1757 break;
1758
1759 case IEMMODE_32BIT:
1760 IEM_MC_BEGIN(0, 1);
1761 IEM_MC_LOCAL(uint32_t, u32Dst);
1762 IEM_MC_POP_U32(&u32Dst);
1763 IEM_MC_STORE_GREG_U32(X86_GREG_xSP, u32Dst);
1764 IEM_MC_ADVANCE_RIP();
1765 IEM_MC_END();
1766 break;
1767
1768 case IEMMODE_64BIT:
1769 IEM_MC_BEGIN(0, 1);
1770 IEM_MC_LOCAL(uint64_t, u64Dst);
1771 IEM_MC_POP_U64(&u64Dst);
1772 IEM_MC_STORE_GREG_U64(X86_GREG_xSP, u64Dst);
1773 IEM_MC_ADVANCE_RIP();
1774 IEM_MC_END();
1775 break;
1776 }
1777
1778 return VINF_SUCCESS;
1779}
1780
1781
1782/**
1783 * @opcode 0x5d
1784 */
1785FNIEMOP_DEF(iemOp_pop_eBP)
1786{
1787 IEMOP_MNEMONIC(pop_rBP, "pop rBP");
1788 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xBP);
1789}
1790
1791
1792/**
1793 * @opcode 0x5e
1794 */
1795FNIEMOP_DEF(iemOp_pop_eSI)
1796{
1797 IEMOP_MNEMONIC(pop_rSI, "pop rSI");
1798 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xSI);
1799}
1800
1801
1802/**
1803 * @opcode 0x5f
1804 */
1805FNIEMOP_DEF(iemOp_pop_eDI)
1806{
1807 IEMOP_MNEMONIC(pop_rDI, "pop rDI");
1808 return FNIEMOP_CALL_1(iemOpCommonPopGReg, X86_GREG_xDI);
1809}
1810
1811
1812/**
1813 * @opcode 0x60
1814 */
1815FNIEMOP_DEF(iemOp_pusha)
1816{
1817 IEMOP_MNEMONIC(pusha, "pusha");
1818 IEMOP_HLP_MIN_186();
1819 IEMOP_HLP_NO_64BIT();
1820 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
1821 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_pusha_16);
1822 Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_32BIT);
1823 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_pusha_32);
1824}
1825
1826
1827/**
1828 * @opcode 0x61
1829 */
1830FNIEMOP_DEF(iemOp_popa__mvex)
1831{
1832 if (pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT)
1833 {
1834 IEMOP_MNEMONIC(popa, "popa");
1835 IEMOP_HLP_MIN_186();
1836 IEMOP_HLP_NO_64BIT();
1837 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
1838 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_popa_16);
1839 Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_32BIT);
1840 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_popa_32);
1841 }
1842 IEMOP_MNEMONIC(mvex, "mvex");
1843 Log(("mvex prefix is not supported!\n"));
1844 return IEMOP_RAISE_INVALID_OPCODE();
1845}
1846
1847
1848/**
1849 * @opcode 0x62
1850 * @opmnemonic bound
1851 * @op1 Gv_RO
1852 * @op2 Ma
1853 * @opmincpu 80186
1854 * @ophints harmless invalid_64
1855 * @optest op1=0 op2=0 ->
1856 * @optest op1=1 op2=0 -> value.xcpt=5
1857 * @optest o16 / op1=0xffff op2=0x0000fffe ->
1858 * @optest o16 / op1=0xfffe op2=0x0000fffe ->
1859 * @optest o16 / op1=0x7fff op2=0x0000fffe -> value.xcpt=5
1860 * @optest o16 / op1=0x7fff op2=0x7ffffffe ->
1861 * @optest o16 / op1=0x7fff op2=0xfffe8000 -> value.xcpt=5
1862 * @optest o16 / op1=0x8000 op2=0xfffe8000 ->
1863 * @optest o16 / op1=0xffff op2=0xfffe8000 -> value.xcpt=5
1864 * @optest o16 / op1=0xfffe op2=0xfffe8000 ->
1865 * @optest o16 / op1=0xfffe op2=0x8000fffe -> value.xcpt=5
1866 * @optest o16 / op1=0x8000 op2=0x8000fffe -> value.xcpt=5
1867 * @optest o16 / op1=0x0000 op2=0x8000fffe -> value.xcpt=5
1868 * @optest o16 / op1=0x0001 op2=0x8000fffe -> value.xcpt=5
1869 * @optest o16 / op1=0xffff op2=0x0001000f -> value.xcpt=5
1870 * @optest o16 / op1=0x0000 op2=0x0001000f -> value.xcpt=5
1871 * @optest o16 / op1=0x0001 op2=0x0001000f -> value.xcpt=5
1872 * @optest o16 / op1=0x0002 op2=0x0001000f -> value.xcpt=5
1873 * @optest o16 / op1=0x0003 op2=0x0001000f -> value.xcpt=5
1874 * @optest o16 / op1=0x0004 op2=0x0001000f -> value.xcpt=5
1875 * @optest o16 / op1=0x000e op2=0x0001000f -> value.xcpt=5
1876 * @optest o16 / op1=0x000f op2=0x0001000f -> value.xcpt=5
1877 * @optest o16 / op1=0x0010 op2=0x0001000f -> value.xcpt=5
1878 * @optest o16 / op1=0x0011 op2=0x0001000f -> value.xcpt=5
1879 * @optest o32 / op1=0xffffffff op2=0x00000000fffffffe ->
1880 * @optest o32 / op1=0xfffffffe op2=0x00000000fffffffe ->
1881 * @optest o32 / op1=0x7fffffff op2=0x00000000fffffffe -> value.xcpt=5
1882 * @optest o32 / op1=0x7fffffff op2=0x7ffffffffffffffe ->
1883 * @optest o32 / op1=0x7fffffff op2=0xfffffffe80000000 -> value.xcpt=5
1884 * @optest o32 / op1=0x80000000 op2=0xfffffffe80000000 ->
1885 * @optest o32 / op1=0xffffffff op2=0xfffffffe80000000 -> value.xcpt=5
1886 * @optest o32 / op1=0xfffffffe op2=0xfffffffe80000000 ->
1887 * @optest o32 / op1=0xfffffffe op2=0x80000000fffffffe -> value.xcpt=5
1888 * @optest o32 / op1=0x80000000 op2=0x80000000fffffffe -> value.xcpt=5
1889 * @optest o32 / op1=0x00000000 op2=0x80000000fffffffe -> value.xcpt=5
1890 * @optest o32 / op1=0x00000002 op2=0x80000000fffffffe -> value.xcpt=5
1891 * @optest o32 / op1=0x00000001 op2=0x0000000100000003 -> value.xcpt=5
1892 * @optest o32 / op1=0x00000002 op2=0x0000000100000003 -> value.xcpt=5
1893 * @optest o32 / op1=0x00000003 op2=0x0000000100000003 -> value.xcpt=5
1894 * @optest o32 / op1=0x00000004 op2=0x0000000100000003 -> value.xcpt=5
1895 * @optest o32 / op1=0x00000005 op2=0x0000000100000003 -> value.xcpt=5
1896 * @optest o32 / op1=0x0000000e op2=0x0000000100000003 -> value.xcpt=5
1897 * @optest o32 / op1=0x0000000f op2=0x0000000100000003 -> value.xcpt=5
1898 * @optest o32 / op1=0x00000010 op2=0x0000000100000003 -> value.xcpt=5
1899 */
1900FNIEMOP_DEF(iemOp_bound_Gv_Ma__evex)
1901{
1902 /* The BOUND instruction is invalid 64-bit mode. In legacy and
1903 compatability mode it is invalid with MOD=3.
1904
1905 In 32-bit mode, the EVEX prefix works by having the top two bits (MOD)
1906 both be set. In the Intel EVEX documentation (sdm vol 2) these are simply
1907 given as R and X without an exact description, so we assume it builds on
1908 the VEX one and means they are inverted wrt REX.R and REX.X. Thus, just
1909 like with the 3-byte VEX, 32-bit code is restrict wrt addressable registers. */
1910 uint8_t bRm;
1911 if (pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT)
1912 {
1913 IEMOP_MNEMONIC2(RM_MEM, BOUND, bound, Gv_RO, Ma, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
1914 IEMOP_HLP_MIN_186();
1915 IEM_OPCODE_GET_NEXT_U8(&bRm);
1916 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
1917 {
1918 /** @todo testcase: check that there are two memory accesses involved. Check
1919 * whether they're both read before the \#BR triggers. */
1920 if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
1921 {
1922 IEM_MC_BEGIN(3, 1);
1923 IEM_MC_ARG(uint16_t, u16Index, 0); /* Note! All operands are actually signed. Lazy unsigned bird. */
1924 IEM_MC_ARG(uint16_t, u16LowerBounds, 1);
1925 IEM_MC_ARG(uint16_t, u16UpperBounds, 2);
1926 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1927
1928 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1929 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1930
1931 IEM_MC_FETCH_GREG_U16(u16Index, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
1932 IEM_MC_FETCH_MEM_U16(u16LowerBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1933 IEM_MC_FETCH_MEM_U16_DISP(u16UpperBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 2);
1934
1935 IEM_MC_CALL_CIMPL_3(iemCImpl_bound_16, u16Index, u16LowerBounds, u16UpperBounds); /* returns */
1936 IEM_MC_END();
1937 }
1938 else /* 32-bit operands */
1939 {
1940 IEM_MC_BEGIN(3, 1);
1941 IEM_MC_ARG(uint32_t, u32Index, 0); /* Note! All operands are actually signed. Lazy unsigned bird. */
1942 IEM_MC_ARG(uint32_t, u32LowerBounds, 1);
1943 IEM_MC_ARG(uint32_t, u32UpperBounds, 2);
1944 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
1945
1946 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
1947 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
1948
1949 IEM_MC_FETCH_GREG_U32(u32Index, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
1950 IEM_MC_FETCH_MEM_U32(u32LowerBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
1951 IEM_MC_FETCH_MEM_U32_DISP(u32UpperBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 4);
1952
1953 IEM_MC_CALL_CIMPL_3(iemCImpl_bound_32, u32Index, u32LowerBounds, u32UpperBounds); /* returns */
1954 IEM_MC_END();
1955 }
1956 }
1957
1958 /*
1959 * @opdone
1960 */
1961 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx512Foundation)
1962 {
1963 /* Note that there is no need for the CPU to fetch further bytes
1964 here because MODRM.MOD == 3. */
1965 Log(("evex not supported by the guest CPU!\n"));
1966 return IEMOP_RAISE_INVALID_OPCODE();
1967 }
1968 }
1969 else
1970 {
1971 /** @todo check how this is decoded in 64-bit mode w/o EVEX. Intel probably
1972 * does modr/m read, whereas AMD probably doesn't... */
1973 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx512Foundation)
1974 {
1975 Log(("evex not supported by the guest CPU!\n"));
1976 return FNIEMOP_CALL(iemOp_InvalidAllNeedRM);
1977 }
1978 IEM_OPCODE_GET_NEXT_U8(&bRm);
1979 }
1980
1981 IEMOP_MNEMONIC(evex, "evex");
1982 uint8_t bP2; IEM_OPCODE_GET_NEXT_U8(&bP2);
1983 uint8_t bP3; IEM_OPCODE_GET_NEXT_U8(&bP3);
1984 Log(("evex prefix is not implemented!\n"));
1985 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
1986}
1987
1988
1989/** Opcode 0x63 - non-64-bit modes. */
1990FNIEMOP_DEF(iemOp_arpl_Ew_Gw)
1991{
1992 IEMOP_MNEMONIC(arpl_Ew_Gw, "arpl Ew,Gw");
1993 IEMOP_HLP_MIN_286();
1994 IEMOP_HLP_NO_REAL_OR_V86_MODE();
1995 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
1996
1997 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
1998 {
1999 /* Register */
2000 IEMOP_HLP_DECODED_NL_2(OP_ARPL, IEMOPFORM_MR_REG, OP_PARM_Ew, OP_PARM_Gw, DISOPTYPE_HARMLESS);
2001 IEM_MC_BEGIN(3, 0);
2002 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2003 IEM_MC_ARG(uint16_t, u16Src, 1);
2004 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2005
2006 IEM_MC_FETCH_GREG_U16(u16Src, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
2007 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK));
2008 IEM_MC_REF_EFLAGS(pEFlags);
2009 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_arpl, pu16Dst, u16Src, pEFlags);
2010
2011 IEM_MC_ADVANCE_RIP();
2012 IEM_MC_END();
2013 }
2014 else
2015 {
2016 /* Memory */
2017 IEM_MC_BEGIN(3, 2);
2018 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2019 IEM_MC_ARG(uint16_t, u16Src, 1);
2020 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
2021 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2022
2023 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
2024 IEMOP_HLP_DECODED_NL_2(OP_ARPL, IEMOPFORM_MR_REG, OP_PARM_Ew, OP_PARM_Gw, DISOPTYPE_HARMLESS);
2025 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
2026 IEM_MC_FETCH_GREG_U16(u16Src, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
2027 IEM_MC_FETCH_EFLAGS(EFlags);
2028 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_arpl, pu16Dst, u16Src, pEFlags);
2029
2030 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
2031 IEM_MC_COMMIT_EFLAGS(EFlags);
2032 IEM_MC_ADVANCE_RIP();
2033 IEM_MC_END();
2034 }
2035 return VINF_SUCCESS;
2036
2037}
2038
2039
2040/**
2041 * @opcode 0x63
2042 *
2043 * @note This is a weird one. It works like a regular move instruction if
2044 * REX.W isn't set, at least according to AMD docs (rev 3.15, 2009-11).
2045 * @todo This definitely needs a testcase to verify the odd cases. */
2046FNIEMOP_DEF(iemOp_movsxd_Gv_Ev)
2047{
2048 Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_64BIT); /* Caller branched already . */
2049
2050 IEMOP_MNEMONIC(movsxd_Gv_Ev, "movsxd Gv,Ev");
2051 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2052
2053 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2054 {
2055 /*
2056 * Register to register.
2057 */
2058 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2059 IEM_MC_BEGIN(0, 1);
2060 IEM_MC_LOCAL(uint64_t, u64Value);
2061 IEM_MC_FETCH_GREG_U32_SX_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2062 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
2063 IEM_MC_ADVANCE_RIP();
2064 IEM_MC_END();
2065 }
2066 else
2067 {
2068 /*
2069 * We're loading a register from memory.
2070 */
2071 IEM_MC_BEGIN(0, 2);
2072 IEM_MC_LOCAL(uint64_t, u64Value);
2073 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2074 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
2075 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2076 IEM_MC_FETCH_MEM_U32_SX_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2077 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
2078 IEM_MC_ADVANCE_RIP();
2079 IEM_MC_END();
2080 }
2081 return VINF_SUCCESS;
2082}
2083
2084
2085/**
2086 * @opcode 0x64
2087 * @opmnemonic segfs
2088 * @opmincpu 80386
2089 * @opgroup og_prefixes
2090 */
2091FNIEMOP_DEF(iemOp_seg_FS)
2092{
2093 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg fs");
2094 IEMOP_HLP_MIN_386();
2095
2096 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_FS;
2097 pVCpu->iem.s.iEffSeg = X86_SREG_FS;
2098
2099 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2100 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2101}
2102
2103
2104/**
2105 * @opcode 0x65
2106 * @opmnemonic seggs
2107 * @opmincpu 80386
2108 * @opgroup og_prefixes
2109 */
2110FNIEMOP_DEF(iemOp_seg_GS)
2111{
2112 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("seg gs");
2113 IEMOP_HLP_MIN_386();
2114
2115 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SEG_GS;
2116 pVCpu->iem.s.iEffSeg = X86_SREG_GS;
2117
2118 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2119 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2120}
2121
2122
2123/**
2124 * @opcode 0x66
2125 * @opmnemonic opsize
2126 * @openc prefix
2127 * @opmincpu 80386
2128 * @ophints harmless
2129 * @opgroup og_prefixes
2130 */
2131FNIEMOP_DEF(iemOp_op_size)
2132{
2133 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("op size");
2134 IEMOP_HLP_MIN_386();
2135
2136 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_OP;
2137 iemRecalEffOpSize(pVCpu);
2138
2139 /* For the 4 entry opcode tables, the operand prefix doesn't not count
2140 when REPZ or REPNZ are present. */
2141 if (pVCpu->iem.s.idxPrefix == 0)
2142 pVCpu->iem.s.idxPrefix = 1;
2143
2144 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2145 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2146}
2147
2148
2149/**
2150 * @opcode 0x67
2151 * @opmnemonic addrsize
2152 * @openc prefix
2153 * @opmincpu 80386
2154 * @ophints harmless
2155 * @opgroup og_prefixes
2156 */
2157FNIEMOP_DEF(iemOp_addr_size)
2158{
2159 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("addr size");
2160 IEMOP_HLP_MIN_386();
2161
2162 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_ADDR;
2163 switch (pVCpu->iem.s.enmDefAddrMode)
2164 {
2165 case IEMMODE_16BIT: pVCpu->iem.s.enmEffAddrMode = IEMMODE_32BIT; break;
2166 case IEMMODE_32BIT: pVCpu->iem.s.enmEffAddrMode = IEMMODE_16BIT; break;
2167 case IEMMODE_64BIT: pVCpu->iem.s.enmEffAddrMode = IEMMODE_32BIT; break;
2168 default: AssertFailed();
2169 }
2170
2171 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
2172 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
2173}
2174
2175
2176/**
2177 * @opcode 0x68
2178 */
2179FNIEMOP_DEF(iemOp_push_Iz)
2180{
2181 IEMOP_MNEMONIC(push_Iz, "push Iz");
2182 IEMOP_HLP_MIN_186();
2183 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2184 switch (pVCpu->iem.s.enmEffOpSize)
2185 {
2186 case IEMMODE_16BIT:
2187 {
2188 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
2189 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2190 IEM_MC_BEGIN(0,0);
2191 IEM_MC_PUSH_U16(u16Imm);
2192 IEM_MC_ADVANCE_RIP();
2193 IEM_MC_END();
2194 return VINF_SUCCESS;
2195 }
2196
2197 case IEMMODE_32BIT:
2198 {
2199 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
2200 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2201 IEM_MC_BEGIN(0,0);
2202 IEM_MC_PUSH_U32(u32Imm);
2203 IEM_MC_ADVANCE_RIP();
2204 IEM_MC_END();
2205 return VINF_SUCCESS;
2206 }
2207
2208 case IEMMODE_64BIT:
2209 {
2210 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
2211 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2212 IEM_MC_BEGIN(0,0);
2213 IEM_MC_PUSH_U64(u64Imm);
2214 IEM_MC_ADVANCE_RIP();
2215 IEM_MC_END();
2216 return VINF_SUCCESS;
2217 }
2218
2219 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2220 }
2221}
2222
2223
2224/**
2225 * @opcode 0x69
2226 */
2227FNIEMOP_DEF(iemOp_imul_Gv_Ev_Iz)
2228{
2229 IEMOP_MNEMONIC(imul_Gv_Ev_Iz, "imul Gv,Ev,Iz"); /* Gv = Ev * Iz; */
2230 IEMOP_HLP_MIN_186();
2231 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2232 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
2233
2234 switch (pVCpu->iem.s.enmEffOpSize)
2235 {
2236 case IEMMODE_16BIT:
2237 {
2238 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2239 {
2240 /* register operand */
2241 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
2242 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2243
2244 IEM_MC_BEGIN(3, 1);
2245 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2246 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ u16Imm,1);
2247 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2248 IEM_MC_LOCAL(uint16_t, u16Tmp);
2249
2250 IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2251 IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
2252 IEM_MC_REF_EFLAGS(pEFlags);
2253 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
2254 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
2255
2256 IEM_MC_ADVANCE_RIP();
2257 IEM_MC_END();
2258 }
2259 else
2260 {
2261 /* memory operand */
2262 IEM_MC_BEGIN(3, 2);
2263 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2264 IEM_MC_ARG(uint16_t, u16Src, 1);
2265 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2266 IEM_MC_LOCAL(uint16_t, u16Tmp);
2267 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2268
2269 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
2270 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
2271 IEM_MC_ASSIGN(u16Src, u16Imm);
2272 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2273 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2274 IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
2275 IEM_MC_REF_EFLAGS(pEFlags);
2276 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
2277 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
2278
2279 IEM_MC_ADVANCE_RIP();
2280 IEM_MC_END();
2281 }
2282 return VINF_SUCCESS;
2283 }
2284
2285 case IEMMODE_32BIT:
2286 {
2287 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2288 {
2289 /* register operand */
2290 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
2291 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2292
2293 IEM_MC_BEGIN(3, 1);
2294 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
2295 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ u32Imm,1);
2296 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2297 IEM_MC_LOCAL(uint32_t, u32Tmp);
2298
2299 IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2300 IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
2301 IEM_MC_REF_EFLAGS(pEFlags);
2302 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
2303 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
2304
2305 IEM_MC_ADVANCE_RIP();
2306 IEM_MC_END();
2307 }
2308 else
2309 {
2310 /* memory operand */
2311 IEM_MC_BEGIN(3, 2);
2312 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
2313 IEM_MC_ARG(uint32_t, u32Src, 1);
2314 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2315 IEM_MC_LOCAL(uint32_t, u32Tmp);
2316 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2317
2318 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
2319 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
2320 IEM_MC_ASSIGN(u32Src, u32Imm);
2321 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2322 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2323 IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
2324 IEM_MC_REF_EFLAGS(pEFlags);
2325 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
2326 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
2327
2328 IEM_MC_ADVANCE_RIP();
2329 IEM_MC_END();
2330 }
2331 return VINF_SUCCESS;
2332 }
2333
2334 case IEMMODE_64BIT:
2335 {
2336 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2337 {
2338 /* register operand */
2339 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
2340 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2341
2342 IEM_MC_BEGIN(3, 1);
2343 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
2344 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ u64Imm,1);
2345 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2346 IEM_MC_LOCAL(uint64_t, u64Tmp);
2347
2348 IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2349 IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
2350 IEM_MC_REF_EFLAGS(pEFlags);
2351 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
2352 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
2353
2354 IEM_MC_ADVANCE_RIP();
2355 IEM_MC_END();
2356 }
2357 else
2358 {
2359 /* memory operand */
2360 IEM_MC_BEGIN(3, 2);
2361 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
2362 IEM_MC_ARG(uint64_t, u64Src, 1);
2363 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2364 IEM_MC_LOCAL(uint64_t, u64Tmp);
2365 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2366
2367 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
2368 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
2369 IEM_MC_ASSIGN(u64Src, u64Imm);
2370 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2371 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2372 IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
2373 IEM_MC_REF_EFLAGS(pEFlags);
2374 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
2375 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
2376
2377 IEM_MC_ADVANCE_RIP();
2378 IEM_MC_END();
2379 }
2380 return VINF_SUCCESS;
2381 }
2382 }
2383 AssertFailedReturn(VERR_IEM_IPE_9);
2384}
2385
2386
2387/**
2388 * @opcode 0x6a
2389 */
2390FNIEMOP_DEF(iemOp_push_Ib)
2391{
2392 IEMOP_MNEMONIC(push_Ib, "push Ib");
2393 IEMOP_HLP_MIN_186();
2394 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2395 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2396 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2397
2398 IEM_MC_BEGIN(0,0);
2399 switch (pVCpu->iem.s.enmEffOpSize)
2400 {
2401 case IEMMODE_16BIT:
2402 IEM_MC_PUSH_U16(i8Imm);
2403 break;
2404 case IEMMODE_32BIT:
2405 IEM_MC_PUSH_U32(i8Imm);
2406 break;
2407 case IEMMODE_64BIT:
2408 IEM_MC_PUSH_U64(i8Imm);
2409 break;
2410 }
2411 IEM_MC_ADVANCE_RIP();
2412 IEM_MC_END();
2413 return VINF_SUCCESS;
2414}
2415
2416
2417/**
2418 * @opcode 0x6b
2419 */
2420FNIEMOP_DEF(iemOp_imul_Gv_Ev_Ib)
2421{
2422 IEMOP_MNEMONIC(imul_Gv_Ev_Ib, "imul Gv,Ev,Ib"); /* Gv = Ev * Iz; */
2423 IEMOP_HLP_MIN_186();
2424 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
2425 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
2426
2427 switch (pVCpu->iem.s.enmEffOpSize)
2428 {
2429 case IEMMODE_16BIT:
2430 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2431 {
2432 /* register operand */
2433 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
2434 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2435
2436 IEM_MC_BEGIN(3, 1);
2437 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2438 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/ (int8_t)u8Imm, 1);
2439 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2440 IEM_MC_LOCAL(uint16_t, u16Tmp);
2441
2442 IEM_MC_FETCH_GREG_U16(u16Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2443 IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
2444 IEM_MC_REF_EFLAGS(pEFlags);
2445 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
2446 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
2447
2448 IEM_MC_ADVANCE_RIP();
2449 IEM_MC_END();
2450 }
2451 else
2452 {
2453 /* memory operand */
2454 IEM_MC_BEGIN(3, 2);
2455 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
2456 IEM_MC_ARG(uint16_t, u16Src, 1);
2457 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2458 IEM_MC_LOCAL(uint16_t, u16Tmp);
2459 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2460
2461 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
2462 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_S8_SX_U16(&u16Imm);
2463 IEM_MC_ASSIGN(u16Src, u16Imm);
2464 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2465 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2466 IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
2467 IEM_MC_REF_EFLAGS(pEFlags);
2468 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
2469 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
2470
2471 IEM_MC_ADVANCE_RIP();
2472 IEM_MC_END();
2473 }
2474 return VINF_SUCCESS;
2475
2476 case IEMMODE_32BIT:
2477 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2478 {
2479 /* register operand */
2480 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
2481 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2482
2483 IEM_MC_BEGIN(3, 1);
2484 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
2485 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/ (int8_t)u8Imm, 1);
2486 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2487 IEM_MC_LOCAL(uint32_t, u32Tmp);
2488
2489 IEM_MC_FETCH_GREG_U32(u32Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2490 IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
2491 IEM_MC_REF_EFLAGS(pEFlags);
2492 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
2493 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
2494
2495 IEM_MC_ADVANCE_RIP();
2496 IEM_MC_END();
2497 }
2498 else
2499 {
2500 /* memory operand */
2501 IEM_MC_BEGIN(3, 2);
2502 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
2503 IEM_MC_ARG(uint32_t, u32Src, 1);
2504 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2505 IEM_MC_LOCAL(uint32_t, u32Tmp);
2506 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2507
2508 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
2509 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_S8_SX_U32(&u32Imm);
2510 IEM_MC_ASSIGN(u32Src, u32Imm);
2511 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2512 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2513 IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
2514 IEM_MC_REF_EFLAGS(pEFlags);
2515 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
2516 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
2517
2518 IEM_MC_ADVANCE_RIP();
2519 IEM_MC_END();
2520 }
2521 return VINF_SUCCESS;
2522
2523 case IEMMODE_64BIT:
2524 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
2525 {
2526 /* register operand */
2527 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
2528 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2529
2530 IEM_MC_BEGIN(3, 1);
2531 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
2532 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/ (int8_t)u8Imm, 1);
2533 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2534 IEM_MC_LOCAL(uint64_t, u64Tmp);
2535
2536 IEM_MC_FETCH_GREG_U64(u64Tmp, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
2537 IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
2538 IEM_MC_REF_EFLAGS(pEFlags);
2539 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
2540 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
2541
2542 IEM_MC_ADVANCE_RIP();
2543 IEM_MC_END();
2544 }
2545 else
2546 {
2547 /* memory operand */
2548 IEM_MC_BEGIN(3, 2);
2549 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
2550 IEM_MC_ARG(uint64_t, u64Src, 1);
2551 IEM_MC_ARG(uint32_t *, pEFlags, 2);
2552 IEM_MC_LOCAL(uint64_t, u64Tmp);
2553 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
2554
2555 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
2556 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S8_SX_U64(&u64Imm);
2557 IEM_MC_ASSIGN(u64Src, u64Imm);
2558 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2559 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
2560 IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
2561 IEM_MC_REF_EFLAGS(pEFlags);
2562 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
2563 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
2564
2565 IEM_MC_ADVANCE_RIP();
2566 IEM_MC_END();
2567 }
2568 return VINF_SUCCESS;
2569 }
2570 AssertFailedReturn(VERR_IEM_IPE_8);
2571}
2572
2573
2574/**
2575 * @opcode 0x6c
2576 */
2577FNIEMOP_DEF(iemOp_insb_Yb_DX)
2578{
2579 IEMOP_HLP_MIN_186();
2580 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2581 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
2582 {
2583 IEMOP_MNEMONIC(rep_insb_Yb_DX, "rep ins Yb,DX");
2584 switch (pVCpu->iem.s.enmEffAddrMode)
2585 {
2586 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr16, false);
2587 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr32, false);
2588 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr64, false);
2589 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2590 }
2591 }
2592 else
2593 {
2594 IEMOP_MNEMONIC(ins_Yb_DX, "ins Yb,DX");
2595 switch (pVCpu->iem.s.enmEffAddrMode)
2596 {
2597 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr16, false);
2598 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr32, false);
2599 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr64, false);
2600 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2601 }
2602 }
2603}
2604
2605
2606/**
2607 * @opcode 0x6d
2608 */
2609FNIEMOP_DEF(iemOp_inswd_Yv_DX)
2610{
2611 IEMOP_HLP_MIN_186();
2612 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2613 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ))
2614 {
2615 IEMOP_MNEMONIC(rep_ins_Yv_DX, "rep ins Yv,DX");
2616 switch (pVCpu->iem.s.enmEffOpSize)
2617 {
2618 case IEMMODE_16BIT:
2619 switch (pVCpu->iem.s.enmEffAddrMode)
2620 {
2621 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr16, false);
2622 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr32, false);
2623 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr64, false);
2624 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2625 }
2626 break;
2627 case IEMMODE_64BIT:
2628 case IEMMODE_32BIT:
2629 switch (pVCpu->iem.s.enmEffAddrMode)
2630 {
2631 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr16, false);
2632 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr32, false);
2633 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr64, false);
2634 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2635 }
2636 break;
2637 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2638 }
2639 }
2640 else
2641 {
2642 IEMOP_MNEMONIC(ins_Yv_DX, "ins Yv,DX");
2643 switch (pVCpu->iem.s.enmEffOpSize)
2644 {
2645 case IEMMODE_16BIT:
2646 switch (pVCpu->iem.s.enmEffAddrMode)
2647 {
2648 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr16, false);
2649 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr32, false);
2650 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr64, false);
2651 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2652 }
2653 break;
2654 case IEMMODE_64BIT:
2655 case IEMMODE_32BIT:
2656 switch (pVCpu->iem.s.enmEffAddrMode)
2657 {
2658 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr16, false);
2659 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr32, false);
2660 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr64, false);
2661 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2662 }
2663 break;
2664 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2665 }
2666 }
2667}
2668
2669
2670/**
2671 * @opcode 0x6e
2672 */
2673FNIEMOP_DEF(iemOp_outsb_Yb_DX)
2674{
2675 IEMOP_HLP_MIN_186();
2676 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2677 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
2678 {
2679 IEMOP_MNEMONIC(rep_outsb_DX_Yb, "rep outs DX,Yb");
2680 switch (pVCpu->iem.s.enmEffAddrMode)
2681 {
2682 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr16, pVCpu->iem.s.iEffSeg, false);
2683 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr32, pVCpu->iem.s.iEffSeg, false);
2684 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr64, pVCpu->iem.s.iEffSeg, false);
2685 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2686 }
2687 }
2688 else
2689 {
2690 IEMOP_MNEMONIC(outs_DX_Yb, "outs DX,Yb");
2691 switch (pVCpu->iem.s.enmEffAddrMode)
2692 {
2693 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr16, pVCpu->iem.s.iEffSeg, false);
2694 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr32, pVCpu->iem.s.iEffSeg, false);
2695 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr64, pVCpu->iem.s.iEffSeg, false);
2696 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2697 }
2698 }
2699}
2700
2701
2702/**
2703 * @opcode 0x6f
2704 */
2705FNIEMOP_DEF(iemOp_outswd_Yv_DX)
2706{
2707 IEMOP_HLP_MIN_186();
2708 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2709 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ))
2710 {
2711 IEMOP_MNEMONIC(rep_outs_DX_Yv, "rep outs DX,Yv");
2712 switch (pVCpu->iem.s.enmEffOpSize)
2713 {
2714 case IEMMODE_16BIT:
2715 switch (pVCpu->iem.s.enmEffAddrMode)
2716 {
2717 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr16, pVCpu->iem.s.iEffSeg, false);
2718 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr32, pVCpu->iem.s.iEffSeg, false);
2719 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr64, pVCpu->iem.s.iEffSeg, false);
2720 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2721 }
2722 break;
2723 case IEMMODE_64BIT:
2724 case IEMMODE_32BIT:
2725 switch (pVCpu->iem.s.enmEffAddrMode)
2726 {
2727 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr16, pVCpu->iem.s.iEffSeg, false);
2728 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr32, pVCpu->iem.s.iEffSeg, false);
2729 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr64, pVCpu->iem.s.iEffSeg, false);
2730 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2731 }
2732 break;
2733 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2734 }
2735 }
2736 else
2737 {
2738 IEMOP_MNEMONIC(outs_DX_Yv, "outs DX,Yv");
2739 switch (pVCpu->iem.s.enmEffOpSize)
2740 {
2741 case IEMMODE_16BIT:
2742 switch (pVCpu->iem.s.enmEffAddrMode)
2743 {
2744 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr16, pVCpu->iem.s.iEffSeg, false);
2745 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr32, pVCpu->iem.s.iEffSeg, false);
2746 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr64, pVCpu->iem.s.iEffSeg, false);
2747 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2748 }
2749 break;
2750 case IEMMODE_64BIT:
2751 case IEMMODE_32BIT:
2752 switch (pVCpu->iem.s.enmEffAddrMode)
2753 {
2754 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr16, pVCpu->iem.s.iEffSeg, false);
2755 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr32, pVCpu->iem.s.iEffSeg, false);
2756 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr64, pVCpu->iem.s.iEffSeg, false);
2757 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2758 }
2759 break;
2760 IEM_NOT_REACHED_DEFAULT_CASE_RET();
2761 }
2762 }
2763}
2764
2765
2766/**
2767 * @opcode 0x70
2768 */
2769FNIEMOP_DEF(iemOp_jo_Jb)
2770{
2771 IEMOP_MNEMONIC(jo_Jb, "jo Jb");
2772 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2773 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2774 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2775
2776 IEM_MC_BEGIN(0, 0);
2777 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
2778 IEM_MC_REL_JMP_S8(i8Imm);
2779 } IEM_MC_ELSE() {
2780 IEM_MC_ADVANCE_RIP();
2781 } IEM_MC_ENDIF();
2782 IEM_MC_END();
2783 return VINF_SUCCESS;
2784}
2785
2786
2787/**
2788 * @opcode 0x71
2789 */
2790FNIEMOP_DEF(iemOp_jno_Jb)
2791{
2792 IEMOP_MNEMONIC(jno_Jb, "jno Jb");
2793 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2794 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2795 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2796
2797 IEM_MC_BEGIN(0, 0);
2798 IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
2799 IEM_MC_ADVANCE_RIP();
2800 } IEM_MC_ELSE() {
2801 IEM_MC_REL_JMP_S8(i8Imm);
2802 } IEM_MC_ENDIF();
2803 IEM_MC_END();
2804 return VINF_SUCCESS;
2805}
2806
2807/**
2808 * @opcode 0x72
2809 */
2810FNIEMOP_DEF(iemOp_jc_Jb)
2811{
2812 IEMOP_MNEMONIC(jc_Jb, "jc/jnae Jb");
2813 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2814 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2815 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2816
2817 IEM_MC_BEGIN(0, 0);
2818 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
2819 IEM_MC_REL_JMP_S8(i8Imm);
2820 } IEM_MC_ELSE() {
2821 IEM_MC_ADVANCE_RIP();
2822 } IEM_MC_ENDIF();
2823 IEM_MC_END();
2824 return VINF_SUCCESS;
2825}
2826
2827
2828/**
2829 * @opcode 0x73
2830 */
2831FNIEMOP_DEF(iemOp_jnc_Jb)
2832{
2833 IEMOP_MNEMONIC(jnc_Jb, "jnc/jnb Jb");
2834 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2835 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2836 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2837
2838 IEM_MC_BEGIN(0, 0);
2839 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
2840 IEM_MC_ADVANCE_RIP();
2841 } IEM_MC_ELSE() {
2842 IEM_MC_REL_JMP_S8(i8Imm);
2843 } IEM_MC_ENDIF();
2844 IEM_MC_END();
2845 return VINF_SUCCESS;
2846}
2847
2848
2849/**
2850 * @opcode 0x74
2851 */
2852FNIEMOP_DEF(iemOp_je_Jb)
2853{
2854 IEMOP_MNEMONIC(je_Jb, "je/jz Jb");
2855 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2856 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2857 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2858
2859 IEM_MC_BEGIN(0, 0);
2860 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
2861 IEM_MC_REL_JMP_S8(i8Imm);
2862 } IEM_MC_ELSE() {
2863 IEM_MC_ADVANCE_RIP();
2864 } IEM_MC_ENDIF();
2865 IEM_MC_END();
2866 return VINF_SUCCESS;
2867}
2868
2869
2870/**
2871 * @opcode 0x75
2872 */
2873FNIEMOP_DEF(iemOp_jne_Jb)
2874{
2875 IEMOP_MNEMONIC(jne_Jb, "jne/jnz Jb");
2876 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2877 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2878 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2879
2880 IEM_MC_BEGIN(0, 0);
2881 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
2882 IEM_MC_ADVANCE_RIP();
2883 } IEM_MC_ELSE() {
2884 IEM_MC_REL_JMP_S8(i8Imm);
2885 } IEM_MC_ENDIF();
2886 IEM_MC_END();
2887 return VINF_SUCCESS;
2888}
2889
2890
2891/**
2892 * @opcode 0x76
2893 */
2894FNIEMOP_DEF(iemOp_jbe_Jb)
2895{
2896 IEMOP_MNEMONIC(jbe_Jb, "jbe/jna Jb");
2897 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2898 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2899 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2900
2901 IEM_MC_BEGIN(0, 0);
2902 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
2903 IEM_MC_REL_JMP_S8(i8Imm);
2904 } IEM_MC_ELSE() {
2905 IEM_MC_ADVANCE_RIP();
2906 } IEM_MC_ENDIF();
2907 IEM_MC_END();
2908 return VINF_SUCCESS;
2909}
2910
2911
2912/**
2913 * @opcode 0x77
2914 */
2915FNIEMOP_DEF(iemOp_jnbe_Jb)
2916{
2917 IEMOP_MNEMONIC(ja_Jb, "ja/jnbe Jb");
2918 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2919 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2920 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2921
2922 IEM_MC_BEGIN(0, 0);
2923 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
2924 IEM_MC_ADVANCE_RIP();
2925 } IEM_MC_ELSE() {
2926 IEM_MC_REL_JMP_S8(i8Imm);
2927 } IEM_MC_ENDIF();
2928 IEM_MC_END();
2929 return VINF_SUCCESS;
2930}
2931
2932
2933/**
2934 * @opcode 0x78
2935 */
2936FNIEMOP_DEF(iemOp_js_Jb)
2937{
2938 IEMOP_MNEMONIC(js_Jb, "js Jb");
2939 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2940 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2941 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2942
2943 IEM_MC_BEGIN(0, 0);
2944 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
2945 IEM_MC_REL_JMP_S8(i8Imm);
2946 } IEM_MC_ELSE() {
2947 IEM_MC_ADVANCE_RIP();
2948 } IEM_MC_ENDIF();
2949 IEM_MC_END();
2950 return VINF_SUCCESS;
2951}
2952
2953
2954/**
2955 * @opcode 0x79
2956 */
2957FNIEMOP_DEF(iemOp_jns_Jb)
2958{
2959 IEMOP_MNEMONIC(jns_Jb, "jns Jb");
2960 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2961 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2962 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2963
2964 IEM_MC_BEGIN(0, 0);
2965 IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
2966 IEM_MC_ADVANCE_RIP();
2967 } IEM_MC_ELSE() {
2968 IEM_MC_REL_JMP_S8(i8Imm);
2969 } IEM_MC_ENDIF();
2970 IEM_MC_END();
2971 return VINF_SUCCESS;
2972}
2973
2974
2975/**
2976 * @opcode 0x7a
2977 */
2978FNIEMOP_DEF(iemOp_jp_Jb)
2979{
2980 IEMOP_MNEMONIC(jp_Jb, "jp Jb");
2981 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
2982 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
2983 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
2984
2985 IEM_MC_BEGIN(0, 0);
2986 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
2987 IEM_MC_REL_JMP_S8(i8Imm);
2988 } IEM_MC_ELSE() {
2989 IEM_MC_ADVANCE_RIP();
2990 } IEM_MC_ENDIF();
2991 IEM_MC_END();
2992 return VINF_SUCCESS;
2993}
2994
2995
2996/**
2997 * @opcode 0x7b
2998 */
2999FNIEMOP_DEF(iemOp_jnp_Jb)
3000{
3001 IEMOP_MNEMONIC(jnp_Jb, "jnp Jb");
3002 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3003 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3004 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
3005
3006 IEM_MC_BEGIN(0, 0);
3007 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
3008 IEM_MC_ADVANCE_RIP();
3009 } IEM_MC_ELSE() {
3010 IEM_MC_REL_JMP_S8(i8Imm);
3011 } IEM_MC_ENDIF();
3012 IEM_MC_END();
3013 return VINF_SUCCESS;
3014}
3015
3016
3017/**
3018 * @opcode 0x7c
3019 */
3020FNIEMOP_DEF(iemOp_jl_Jb)
3021{
3022 IEMOP_MNEMONIC(jl_Jb, "jl/jnge Jb");
3023 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3024 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3025 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
3026
3027 IEM_MC_BEGIN(0, 0);
3028 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
3029 IEM_MC_REL_JMP_S8(i8Imm);
3030 } IEM_MC_ELSE() {
3031 IEM_MC_ADVANCE_RIP();
3032 } IEM_MC_ENDIF();
3033 IEM_MC_END();
3034 return VINF_SUCCESS;
3035}
3036
3037
3038/**
3039 * @opcode 0x7d
3040 */
3041FNIEMOP_DEF(iemOp_jnl_Jb)
3042{
3043 IEMOP_MNEMONIC(jge_Jb, "jnl/jge Jb");
3044 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3045 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3046 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
3047
3048 IEM_MC_BEGIN(0, 0);
3049 IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
3050 IEM_MC_ADVANCE_RIP();
3051 } IEM_MC_ELSE() {
3052 IEM_MC_REL_JMP_S8(i8Imm);
3053 } IEM_MC_ENDIF();
3054 IEM_MC_END();
3055 return VINF_SUCCESS;
3056}
3057
3058
3059/**
3060 * @opcode 0x7e
3061 */
3062FNIEMOP_DEF(iemOp_jle_Jb)
3063{
3064 IEMOP_MNEMONIC(jle_Jb, "jle/jng Jb");
3065 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3066 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3067 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
3068
3069 IEM_MC_BEGIN(0, 0);
3070 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
3071 IEM_MC_REL_JMP_S8(i8Imm);
3072 } IEM_MC_ELSE() {
3073 IEM_MC_ADVANCE_RIP();
3074 } IEM_MC_ENDIF();
3075 IEM_MC_END();
3076 return VINF_SUCCESS;
3077}
3078
3079
3080/**
3081 * @opcode 0x7f
3082 */
3083FNIEMOP_DEF(iemOp_jnle_Jb)
3084{
3085 IEMOP_MNEMONIC(jg_Jb, "jnle/jg Jb");
3086 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
3087 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3088 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
3089
3090 IEM_MC_BEGIN(0, 0);
3091 IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
3092 IEM_MC_ADVANCE_RIP();
3093 } IEM_MC_ELSE() {
3094 IEM_MC_REL_JMP_S8(i8Imm);
3095 } IEM_MC_ENDIF();
3096 IEM_MC_END();
3097 return VINF_SUCCESS;
3098}
3099
3100
3101/**
3102 * @opcode 0x80
3103 */
3104FNIEMOP_DEF(iemOp_Grp1_Eb_Ib_80)
3105{
3106 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3107 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
3108 {
3109 case 0: IEMOP_MNEMONIC(add_Eb_Ib, "add Eb,Ib"); break;
3110 case 1: IEMOP_MNEMONIC(or_Eb_Ib, "or Eb,Ib"); break;
3111 case 2: IEMOP_MNEMONIC(adc_Eb_Ib, "adc Eb,Ib"); break;
3112 case 3: IEMOP_MNEMONIC(sbb_Eb_Ib, "sbb Eb,Ib"); break;
3113 case 4: IEMOP_MNEMONIC(and_Eb_Ib, "and Eb,Ib"); break;
3114 case 5: IEMOP_MNEMONIC(sub_Eb_Ib, "sub Eb,Ib"); break;
3115 case 6: IEMOP_MNEMONIC(xor_Eb_Ib, "xor Eb,Ib"); break;
3116 case 7: IEMOP_MNEMONIC(cmp_Eb_Ib, "cmp Eb,Ib"); break;
3117 }
3118 PCIEMOPBINSIZES pImpl = g_apIemImplGrp1[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK];
3119
3120 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3121 {
3122 /* register target */
3123 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3124 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3125 IEM_MC_BEGIN(3, 0);
3126 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
3127 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1);
3128 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3129
3130 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3131 IEM_MC_REF_EFLAGS(pEFlags);
3132 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
3133
3134 IEM_MC_ADVANCE_RIP();
3135 IEM_MC_END();
3136 }
3137 else
3138 {
3139 /* memory target */
3140 uint32_t fAccess;
3141 if (pImpl->pfnLockedU8)
3142 fAccess = IEM_ACCESS_DATA_RW;
3143 else /* CMP */
3144 fAccess = IEM_ACCESS_DATA_R;
3145 IEM_MC_BEGIN(3, 2);
3146 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
3147 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3148 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3149
3150 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3151 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3152 IEM_MC_ARG_CONST(uint8_t, u8Src, /*=*/ u8Imm, 1);
3153 if (pImpl->pfnLockedU8)
3154 IEMOP_HLP_DONE_DECODING();
3155 else
3156 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3157
3158 IEM_MC_MEM_MAP(pu8Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3159 IEM_MC_FETCH_EFLAGS(EFlags);
3160 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3161 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, u8Src, pEFlags);
3162 else
3163 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU8, pu8Dst, u8Src, pEFlags);
3164
3165 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, fAccess);
3166 IEM_MC_COMMIT_EFLAGS(EFlags);
3167 IEM_MC_ADVANCE_RIP();
3168 IEM_MC_END();
3169 }
3170 return VINF_SUCCESS;
3171}
3172
3173
3174/**
3175 * @opcode 0x81
3176 */
3177FNIEMOP_DEF(iemOp_Grp1_Ev_Iz)
3178{
3179 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3180 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
3181 {
3182 case 0: IEMOP_MNEMONIC(add_Ev_Iz, "add Ev,Iz"); break;
3183 case 1: IEMOP_MNEMONIC(or_Ev_Iz, "or Ev,Iz"); break;
3184 case 2: IEMOP_MNEMONIC(adc_Ev_Iz, "adc Ev,Iz"); break;
3185 case 3: IEMOP_MNEMONIC(sbb_Ev_Iz, "sbb Ev,Iz"); break;
3186 case 4: IEMOP_MNEMONIC(and_Ev_Iz, "and Ev,Iz"); break;
3187 case 5: IEMOP_MNEMONIC(sub_Ev_Iz, "sub Ev,Iz"); break;
3188 case 6: IEMOP_MNEMONIC(xor_Ev_Iz, "xor Ev,Iz"); break;
3189 case 7: IEMOP_MNEMONIC(cmp_Ev_Iz, "cmp Ev,Iz"); break;
3190 }
3191 PCIEMOPBINSIZES pImpl = g_apIemImplGrp1[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK];
3192
3193 switch (pVCpu->iem.s.enmEffOpSize)
3194 {
3195 case IEMMODE_16BIT:
3196 {
3197 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3198 {
3199 /* register target */
3200 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
3201 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3202 IEM_MC_BEGIN(3, 0);
3203 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
3204 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ u16Imm, 1);
3205 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3206
3207 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3208 IEM_MC_REF_EFLAGS(pEFlags);
3209 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
3210
3211 IEM_MC_ADVANCE_RIP();
3212 IEM_MC_END();
3213 }
3214 else
3215 {
3216 /* memory target */
3217 uint32_t fAccess;
3218 if (pImpl->pfnLockedU16)
3219 fAccess = IEM_ACCESS_DATA_RW;
3220 else /* CMP, TEST */
3221 fAccess = IEM_ACCESS_DATA_R;
3222 IEM_MC_BEGIN(3, 2);
3223 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
3224 IEM_MC_ARG(uint16_t, u16Src, 1);
3225 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3226 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3227
3228 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
3229 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
3230 IEM_MC_ASSIGN(u16Src, u16Imm);
3231 if (pImpl->pfnLockedU16)
3232 IEMOP_HLP_DONE_DECODING();
3233 else
3234 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3235 IEM_MC_MEM_MAP(pu16Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3236 IEM_MC_FETCH_EFLAGS(EFlags);
3237 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3238 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
3239 else
3240 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
3241
3242 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
3243 IEM_MC_COMMIT_EFLAGS(EFlags);
3244 IEM_MC_ADVANCE_RIP();
3245 IEM_MC_END();
3246 }
3247 break;
3248 }
3249
3250 case IEMMODE_32BIT:
3251 {
3252 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3253 {
3254 /* register target */
3255 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
3256 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3257 IEM_MC_BEGIN(3, 0);
3258 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
3259 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ u32Imm, 1);
3260 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3261
3262 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3263 IEM_MC_REF_EFLAGS(pEFlags);
3264 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
3265 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
3266
3267 IEM_MC_ADVANCE_RIP();
3268 IEM_MC_END();
3269 }
3270 else
3271 {
3272 /* memory target */
3273 uint32_t fAccess;
3274 if (pImpl->pfnLockedU32)
3275 fAccess = IEM_ACCESS_DATA_RW;
3276 else /* CMP, TEST */
3277 fAccess = IEM_ACCESS_DATA_R;
3278 IEM_MC_BEGIN(3, 2);
3279 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
3280 IEM_MC_ARG(uint32_t, u32Src, 1);
3281 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3282 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3283
3284 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
3285 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
3286 IEM_MC_ASSIGN(u32Src, u32Imm);
3287 if (pImpl->pfnLockedU32)
3288 IEMOP_HLP_DONE_DECODING();
3289 else
3290 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3291 IEM_MC_MEM_MAP(pu32Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3292 IEM_MC_FETCH_EFLAGS(EFlags);
3293 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3294 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
3295 else
3296 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
3297
3298 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
3299 IEM_MC_COMMIT_EFLAGS(EFlags);
3300 IEM_MC_ADVANCE_RIP();
3301 IEM_MC_END();
3302 }
3303 break;
3304 }
3305
3306 case IEMMODE_64BIT:
3307 {
3308 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3309 {
3310 /* register target */
3311 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
3312 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3313 IEM_MC_BEGIN(3, 0);
3314 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
3315 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ u64Imm, 1);
3316 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3317
3318 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3319 IEM_MC_REF_EFLAGS(pEFlags);
3320 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
3321
3322 IEM_MC_ADVANCE_RIP();
3323 IEM_MC_END();
3324 }
3325 else
3326 {
3327 /* memory target */
3328 uint32_t fAccess;
3329 if (pImpl->pfnLockedU64)
3330 fAccess = IEM_ACCESS_DATA_RW;
3331 else /* CMP */
3332 fAccess = IEM_ACCESS_DATA_R;
3333 IEM_MC_BEGIN(3, 2);
3334 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
3335 IEM_MC_ARG(uint64_t, u64Src, 1);
3336 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3337 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3338
3339 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
3340 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
3341 if (pImpl->pfnLockedU64)
3342 IEMOP_HLP_DONE_DECODING();
3343 else
3344 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3345 IEM_MC_ASSIGN(u64Src, u64Imm);
3346 IEM_MC_MEM_MAP(pu64Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3347 IEM_MC_FETCH_EFLAGS(EFlags);
3348 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3349 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
3350 else
3351 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
3352
3353 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
3354 IEM_MC_COMMIT_EFLAGS(EFlags);
3355 IEM_MC_ADVANCE_RIP();
3356 IEM_MC_END();
3357 }
3358 break;
3359 }
3360 }
3361 return VINF_SUCCESS;
3362}
3363
3364
3365/**
3366 * @opcode 0x82
3367 * @opmnemonic grp1_82
3368 * @opgroup og_groups
3369 */
3370FNIEMOP_DEF(iemOp_Grp1_Eb_Ib_82)
3371{
3372 IEMOP_HLP_NO_64BIT(); /** @todo do we need to decode the whole instruction or is this ok? */
3373 return FNIEMOP_CALL(iemOp_Grp1_Eb_Ib_80);
3374}
3375
3376
3377/**
3378 * @opcode 0x83
3379 */
3380FNIEMOP_DEF(iemOp_Grp1_Ev_Ib)
3381{
3382 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3383 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
3384 {
3385 case 0: IEMOP_MNEMONIC(add_Ev_Ib, "add Ev,Ib"); break;
3386 case 1: IEMOP_MNEMONIC(or_Ev_Ib, "or Ev,Ib"); break;
3387 case 2: IEMOP_MNEMONIC(adc_Ev_Ib, "adc Ev,Ib"); break;
3388 case 3: IEMOP_MNEMONIC(sbb_Ev_Ib, "sbb Ev,Ib"); break;
3389 case 4: IEMOP_MNEMONIC(and_Ev_Ib, "and Ev,Ib"); break;
3390 case 5: IEMOP_MNEMONIC(sub_Ev_Ib, "sub Ev,Ib"); break;
3391 case 6: IEMOP_MNEMONIC(xor_Ev_Ib, "xor Ev,Ib"); break;
3392 case 7: IEMOP_MNEMONIC(cmp_Ev_Ib, "cmp Ev,Ib"); break;
3393 }
3394 /* Note! Seems the OR, AND, and XOR instructions are present on CPUs prior
3395 to the 386 even if absent in the intel reference manuals and some
3396 3rd party opcode listings. */
3397 PCIEMOPBINSIZES pImpl = g_apIemImplGrp1[(bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK];
3398
3399 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3400 {
3401 /*
3402 * Register target
3403 */
3404 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3405 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3406 switch (pVCpu->iem.s.enmEffOpSize)
3407 {
3408 case IEMMODE_16BIT:
3409 {
3410 IEM_MC_BEGIN(3, 0);
3411 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
3412 IEM_MC_ARG_CONST(uint16_t, u16Src, /*=*/ (int8_t)u8Imm,1);
3413 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3414
3415 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3416 IEM_MC_REF_EFLAGS(pEFlags);
3417 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
3418
3419 IEM_MC_ADVANCE_RIP();
3420 IEM_MC_END();
3421 break;
3422 }
3423
3424 case IEMMODE_32BIT:
3425 {
3426 IEM_MC_BEGIN(3, 0);
3427 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
3428 IEM_MC_ARG_CONST(uint32_t, u32Src, /*=*/ (int8_t)u8Imm,1);
3429 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3430
3431 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3432 IEM_MC_REF_EFLAGS(pEFlags);
3433 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
3434 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
3435
3436 IEM_MC_ADVANCE_RIP();
3437 IEM_MC_END();
3438 break;
3439 }
3440
3441 case IEMMODE_64BIT:
3442 {
3443 IEM_MC_BEGIN(3, 0);
3444 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
3445 IEM_MC_ARG_CONST(uint64_t, u64Src, /*=*/ (int8_t)u8Imm,1);
3446 IEM_MC_ARG(uint32_t *, pEFlags, 2);
3447
3448 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3449 IEM_MC_REF_EFLAGS(pEFlags);
3450 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
3451
3452 IEM_MC_ADVANCE_RIP();
3453 IEM_MC_END();
3454 break;
3455 }
3456 }
3457 }
3458 else
3459 {
3460 /*
3461 * Memory target.
3462 */
3463 uint32_t fAccess;
3464 if (pImpl->pfnLockedU16)
3465 fAccess = IEM_ACCESS_DATA_RW;
3466 else /* CMP */
3467 fAccess = IEM_ACCESS_DATA_R;
3468
3469 switch (pVCpu->iem.s.enmEffOpSize)
3470 {
3471 case IEMMODE_16BIT:
3472 {
3473 IEM_MC_BEGIN(3, 2);
3474 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
3475 IEM_MC_ARG(uint16_t, u16Src, 1);
3476 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3477 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3478
3479 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3480 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3481 IEM_MC_ASSIGN(u16Src, (int8_t)u8Imm);
3482 if (pImpl->pfnLockedU16)
3483 IEMOP_HLP_DONE_DECODING();
3484 else
3485 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3486 IEM_MC_MEM_MAP(pu16Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3487 IEM_MC_FETCH_EFLAGS(EFlags);
3488 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3489 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, u16Src, pEFlags);
3490 else
3491 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU16, pu16Dst, u16Src, pEFlags);
3492
3493 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, fAccess);
3494 IEM_MC_COMMIT_EFLAGS(EFlags);
3495 IEM_MC_ADVANCE_RIP();
3496 IEM_MC_END();
3497 break;
3498 }
3499
3500 case IEMMODE_32BIT:
3501 {
3502 IEM_MC_BEGIN(3, 2);
3503 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
3504 IEM_MC_ARG(uint32_t, u32Src, 1);
3505 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3506 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3507
3508 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3509 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3510 IEM_MC_ASSIGN(u32Src, (int8_t)u8Imm);
3511 if (pImpl->pfnLockedU32)
3512 IEMOP_HLP_DONE_DECODING();
3513 else
3514 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3515 IEM_MC_MEM_MAP(pu32Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3516 IEM_MC_FETCH_EFLAGS(EFlags);
3517 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3518 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags);
3519 else
3520 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU32, pu32Dst, u32Src, pEFlags);
3521
3522 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, fAccess);
3523 IEM_MC_COMMIT_EFLAGS(EFlags);
3524 IEM_MC_ADVANCE_RIP();
3525 IEM_MC_END();
3526 break;
3527 }
3528
3529 case IEMMODE_64BIT:
3530 {
3531 IEM_MC_BEGIN(3, 2);
3532 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
3533 IEM_MC_ARG(uint64_t, u64Src, 1);
3534 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
3535 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3536
3537 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
3538 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
3539 IEM_MC_ASSIGN(u64Src, (int8_t)u8Imm);
3540 if (pImpl->pfnLockedU64)
3541 IEMOP_HLP_DONE_DECODING();
3542 else
3543 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3544 IEM_MC_MEM_MAP(pu64Dst, fAccess, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3545 IEM_MC_FETCH_EFLAGS(EFlags);
3546 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
3547 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, u64Src, pEFlags);
3548 else
3549 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnLockedU64, pu64Dst, u64Src, pEFlags);
3550
3551 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, fAccess);
3552 IEM_MC_COMMIT_EFLAGS(EFlags);
3553 IEM_MC_ADVANCE_RIP();
3554 IEM_MC_END();
3555 break;
3556 }
3557 }
3558 }
3559 return VINF_SUCCESS;
3560}
3561
3562
3563/**
3564 * @opcode 0x84
3565 */
3566FNIEMOP_DEF(iemOp_test_Eb_Gb)
3567{
3568 IEMOP_MNEMONIC(test_Eb_Gb, "test Eb,Gb");
3569 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
3570 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_r8, &g_iemAImpl_test);
3571}
3572
3573
3574/**
3575 * @opcode 0x85
3576 */
3577FNIEMOP_DEF(iemOp_test_Ev_Gv)
3578{
3579 IEMOP_MNEMONIC(test_Ev_Gv, "test Ev,Gv");
3580 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
3581 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rm_rv, &g_iemAImpl_test);
3582}
3583
3584
3585/**
3586 * @opcode 0x86
3587 */
3588FNIEMOP_DEF(iemOp_xchg_Eb_Gb)
3589{
3590 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3591 IEMOP_MNEMONIC(xchg_Eb_Gb, "xchg Eb,Gb");
3592
3593 /*
3594 * If rm is denoting a register, no more instruction bytes.
3595 */
3596 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3597 {
3598 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3599
3600 IEM_MC_BEGIN(0, 2);
3601 IEM_MC_LOCAL(uint8_t, uTmp1);
3602 IEM_MC_LOCAL(uint8_t, uTmp2);
3603
3604 IEM_MC_FETCH_GREG_U8(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3605 IEM_MC_FETCH_GREG_U8(uTmp2, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3606 IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uTmp1);
3607 IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uTmp2);
3608
3609 IEM_MC_ADVANCE_RIP();
3610 IEM_MC_END();
3611 }
3612 else
3613 {
3614 /*
3615 * We're accessing memory.
3616 */
3617/** @todo the register must be committed separately! */
3618 IEM_MC_BEGIN(2, 2);
3619 IEM_MC_ARG(uint8_t *, pu8Mem, 0);
3620 IEM_MC_ARG(uint8_t *, pu8Reg, 1);
3621 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3622
3623 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3624 IEM_MC_MEM_MAP(pu8Mem, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3625 IEM_MC_REF_GREG_U8(pu8Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3626 if (!pVCpu->iem.s.fDisregardLock)
3627 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u8_locked, pu8Mem, pu8Reg);
3628 else
3629 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u8_unlocked, pu8Mem, pu8Reg);
3630 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Mem, IEM_ACCESS_DATA_RW);
3631
3632 IEM_MC_ADVANCE_RIP();
3633 IEM_MC_END();
3634 }
3635 return VINF_SUCCESS;
3636}
3637
3638
3639/**
3640 * @opcode 0x87
3641 */
3642FNIEMOP_DEF(iemOp_xchg_Ev_Gv)
3643{
3644 IEMOP_MNEMONIC(xchg_Ev_Gv, "xchg Ev,Gv");
3645 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3646
3647 /*
3648 * If rm is denoting a register, no more instruction bytes.
3649 */
3650 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3651 {
3652 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3653
3654 switch (pVCpu->iem.s.enmEffOpSize)
3655 {
3656 case IEMMODE_16BIT:
3657 IEM_MC_BEGIN(0, 2);
3658 IEM_MC_LOCAL(uint16_t, uTmp1);
3659 IEM_MC_LOCAL(uint16_t, uTmp2);
3660
3661 IEM_MC_FETCH_GREG_U16(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3662 IEM_MC_FETCH_GREG_U16(uTmp2, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3663 IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uTmp1);
3664 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uTmp2);
3665
3666 IEM_MC_ADVANCE_RIP();
3667 IEM_MC_END();
3668 return VINF_SUCCESS;
3669
3670 case IEMMODE_32BIT:
3671 IEM_MC_BEGIN(0, 2);
3672 IEM_MC_LOCAL(uint32_t, uTmp1);
3673 IEM_MC_LOCAL(uint32_t, uTmp2);
3674
3675 IEM_MC_FETCH_GREG_U32(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3676 IEM_MC_FETCH_GREG_U32(uTmp2, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3677 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uTmp1);
3678 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uTmp2);
3679
3680 IEM_MC_ADVANCE_RIP();
3681 IEM_MC_END();
3682 return VINF_SUCCESS;
3683
3684 case IEMMODE_64BIT:
3685 IEM_MC_BEGIN(0, 2);
3686 IEM_MC_LOCAL(uint64_t, uTmp1);
3687 IEM_MC_LOCAL(uint64_t, uTmp2);
3688
3689 IEM_MC_FETCH_GREG_U64(uTmp1, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3690 IEM_MC_FETCH_GREG_U64(uTmp2, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3691 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, uTmp1);
3692 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, uTmp2);
3693
3694 IEM_MC_ADVANCE_RIP();
3695 IEM_MC_END();
3696 return VINF_SUCCESS;
3697
3698 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3699 }
3700 }
3701 else
3702 {
3703 /*
3704 * We're accessing memory.
3705 */
3706 switch (pVCpu->iem.s.enmEffOpSize)
3707 {
3708/** @todo the register must be committed separately! */
3709 case IEMMODE_16BIT:
3710 IEM_MC_BEGIN(2, 2);
3711 IEM_MC_ARG(uint16_t *, pu16Mem, 0);
3712 IEM_MC_ARG(uint16_t *, pu16Reg, 1);
3713 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3714
3715 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3716 IEM_MC_MEM_MAP(pu16Mem, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3717 IEM_MC_REF_GREG_U16(pu16Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3718 if (!pVCpu->iem.s.fDisregardLock)
3719 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u16_locked, pu16Mem, pu16Reg);
3720 else
3721 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u16_unlocked, pu16Mem, pu16Reg);
3722 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Mem, IEM_ACCESS_DATA_RW);
3723
3724 IEM_MC_ADVANCE_RIP();
3725 IEM_MC_END();
3726 return VINF_SUCCESS;
3727
3728 case IEMMODE_32BIT:
3729 IEM_MC_BEGIN(2, 2);
3730 IEM_MC_ARG(uint32_t *, pu32Mem, 0);
3731 IEM_MC_ARG(uint32_t *, pu32Reg, 1);
3732 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3733
3734 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3735 IEM_MC_MEM_MAP(pu32Mem, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3736 IEM_MC_REF_GREG_U32(pu32Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3737 if (!pVCpu->iem.s.fDisregardLock)
3738 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u32_locked, pu32Mem, pu32Reg);
3739 else
3740 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u32_unlocked, pu32Mem, pu32Reg);
3741 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Mem, IEM_ACCESS_DATA_RW);
3742
3743 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Reg);
3744 IEM_MC_ADVANCE_RIP();
3745 IEM_MC_END();
3746 return VINF_SUCCESS;
3747
3748 case IEMMODE_64BIT:
3749 IEM_MC_BEGIN(2, 2);
3750 IEM_MC_ARG(uint64_t *, pu64Mem, 0);
3751 IEM_MC_ARG(uint64_t *, pu64Reg, 1);
3752 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3753
3754 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3755 IEM_MC_MEM_MAP(pu64Mem, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
3756 IEM_MC_REF_GREG_U64(pu64Reg, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3757 if (!pVCpu->iem.s.fDisregardLock)
3758 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u64_locked, pu64Mem, pu64Reg);
3759 else
3760 IEM_MC_CALL_VOID_AIMPL_2(iemAImpl_xchg_u64_unlocked, pu64Mem, pu64Reg);
3761 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Mem, IEM_ACCESS_DATA_RW);
3762
3763 IEM_MC_ADVANCE_RIP();
3764 IEM_MC_END();
3765 return VINF_SUCCESS;
3766
3767 IEM_NOT_REACHED_DEFAULT_CASE_RET();
3768 }
3769 }
3770}
3771
3772
3773/**
3774 * @opcode 0x88
3775 */
3776FNIEMOP_DEF(iemOp_mov_Eb_Gb)
3777{
3778 IEMOP_MNEMONIC(mov_Eb_Gb, "mov Eb,Gb");
3779
3780 uint8_t bRm;
3781 IEM_OPCODE_GET_NEXT_U8(&bRm);
3782
3783 /*
3784 * If rm is denoting a register, no more instruction bytes.
3785 */
3786 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3787 {
3788 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3789 IEM_MC_BEGIN(0, 1);
3790 IEM_MC_LOCAL(uint8_t, u8Value);
3791 IEM_MC_FETCH_GREG_U8(u8Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3792 IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u8Value);
3793 IEM_MC_ADVANCE_RIP();
3794 IEM_MC_END();
3795 }
3796 else
3797 {
3798 /*
3799 * We're writing a register to memory.
3800 */
3801 IEM_MC_BEGIN(0, 2);
3802 IEM_MC_LOCAL(uint8_t, u8Value);
3803 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3804 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3805 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3806 IEM_MC_FETCH_GREG_U8(u8Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3807 IEM_MC_STORE_MEM_U8(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u8Value);
3808 IEM_MC_ADVANCE_RIP();
3809 IEM_MC_END();
3810 }
3811 return VINF_SUCCESS;
3812
3813}
3814
3815
3816/**
3817 * @opcode 0x89
3818 */
3819FNIEMOP_DEF(iemOp_mov_Ev_Gv)
3820{
3821 IEMOP_MNEMONIC(mov_Ev_Gv, "mov Ev,Gv");
3822
3823 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3824
3825 /*
3826 * If rm is denoting a register, no more instruction bytes.
3827 */
3828 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3829 {
3830 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3831 switch (pVCpu->iem.s.enmEffOpSize)
3832 {
3833 case IEMMODE_16BIT:
3834 IEM_MC_BEGIN(0, 1);
3835 IEM_MC_LOCAL(uint16_t, u16Value);
3836 IEM_MC_FETCH_GREG_U16(u16Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3837 IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u16Value);
3838 IEM_MC_ADVANCE_RIP();
3839 IEM_MC_END();
3840 break;
3841
3842 case IEMMODE_32BIT:
3843 IEM_MC_BEGIN(0, 1);
3844 IEM_MC_LOCAL(uint32_t, u32Value);
3845 IEM_MC_FETCH_GREG_U32(u32Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3846 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Value);
3847 IEM_MC_ADVANCE_RIP();
3848 IEM_MC_END();
3849 break;
3850
3851 case IEMMODE_64BIT:
3852 IEM_MC_BEGIN(0, 1);
3853 IEM_MC_LOCAL(uint64_t, u64Value);
3854 IEM_MC_FETCH_GREG_U64(u64Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3855 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Value);
3856 IEM_MC_ADVANCE_RIP();
3857 IEM_MC_END();
3858 break;
3859 }
3860 }
3861 else
3862 {
3863 /*
3864 * We're writing a register to memory.
3865 */
3866 switch (pVCpu->iem.s.enmEffOpSize)
3867 {
3868 case IEMMODE_16BIT:
3869 IEM_MC_BEGIN(0, 2);
3870 IEM_MC_LOCAL(uint16_t, u16Value);
3871 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3872 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3873 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3874 IEM_MC_FETCH_GREG_U16(u16Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3875 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Value);
3876 IEM_MC_ADVANCE_RIP();
3877 IEM_MC_END();
3878 break;
3879
3880 case IEMMODE_32BIT:
3881 IEM_MC_BEGIN(0, 2);
3882 IEM_MC_LOCAL(uint32_t, u32Value);
3883 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3884 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3885 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3886 IEM_MC_FETCH_GREG_U32(u32Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3887 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u32Value);
3888 IEM_MC_ADVANCE_RIP();
3889 IEM_MC_END();
3890 break;
3891
3892 case IEMMODE_64BIT:
3893 IEM_MC_BEGIN(0, 2);
3894 IEM_MC_LOCAL(uint64_t, u64Value);
3895 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3896 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3897 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3898 IEM_MC_FETCH_GREG_U64(u64Value, ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg);
3899 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u64Value);
3900 IEM_MC_ADVANCE_RIP();
3901 IEM_MC_END();
3902 break;
3903 }
3904 }
3905 return VINF_SUCCESS;
3906}
3907
3908
3909/**
3910 * @opcode 0x8a
3911 */
3912FNIEMOP_DEF(iemOp_mov_Gb_Eb)
3913{
3914 IEMOP_MNEMONIC(mov_Gb_Eb, "mov Gb,Eb");
3915
3916 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3917
3918 /*
3919 * If rm is denoting a register, no more instruction bytes.
3920 */
3921 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3922 {
3923 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3924 IEM_MC_BEGIN(0, 1);
3925 IEM_MC_LOCAL(uint8_t, u8Value);
3926 IEM_MC_FETCH_GREG_U8(u8Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3927 IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u8Value);
3928 IEM_MC_ADVANCE_RIP();
3929 IEM_MC_END();
3930 }
3931 else
3932 {
3933 /*
3934 * We're loading a register from memory.
3935 */
3936 IEM_MC_BEGIN(0, 2);
3937 IEM_MC_LOCAL(uint8_t, u8Value);
3938 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
3939 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
3940 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3941 IEM_MC_FETCH_MEM_U8(u8Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
3942 IEM_MC_STORE_GREG_U8(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u8Value);
3943 IEM_MC_ADVANCE_RIP();
3944 IEM_MC_END();
3945 }
3946 return VINF_SUCCESS;
3947}
3948
3949
3950/**
3951 * @opcode 0x8b
3952 */
3953FNIEMOP_DEF(iemOp_mov_Gv_Ev)
3954{
3955 IEMOP_MNEMONIC(mov_Gv_Ev, "mov Gv,Ev");
3956
3957 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
3958
3959 /*
3960 * If rm is denoting a register, no more instruction bytes.
3961 */
3962 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
3963 {
3964 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
3965 switch (pVCpu->iem.s.enmEffOpSize)
3966 {
3967 case IEMMODE_16BIT:
3968 IEM_MC_BEGIN(0, 1);
3969 IEM_MC_LOCAL(uint16_t, u16Value);
3970 IEM_MC_FETCH_GREG_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3971 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Value);
3972 IEM_MC_ADVANCE_RIP();
3973 IEM_MC_END();
3974 break;
3975
3976 case IEMMODE_32BIT:
3977 IEM_MC_BEGIN(0, 1);
3978 IEM_MC_LOCAL(uint32_t, u32Value);
3979 IEM_MC_FETCH_GREG_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3980 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
3981 IEM_MC_ADVANCE_RIP();
3982 IEM_MC_END();
3983 break;
3984
3985 case IEMMODE_64BIT:
3986 IEM_MC_BEGIN(0, 1);
3987 IEM_MC_LOCAL(uint64_t, u64Value);
3988 IEM_MC_FETCH_GREG_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
3989 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
3990 IEM_MC_ADVANCE_RIP();
3991 IEM_MC_END();
3992 break;
3993 }
3994 }
3995 else
3996 {
3997 /*
3998 * We're loading a register from memory.
3999 */
4000 switch (pVCpu->iem.s.enmEffOpSize)
4001 {
4002 case IEMMODE_16BIT:
4003 IEM_MC_BEGIN(0, 2);
4004 IEM_MC_LOCAL(uint16_t, u16Value);
4005 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
4006 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
4007 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4008 IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
4009 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Value);
4010 IEM_MC_ADVANCE_RIP();
4011 IEM_MC_END();
4012 break;
4013
4014 case IEMMODE_32BIT:
4015 IEM_MC_BEGIN(0, 2);
4016 IEM_MC_LOCAL(uint32_t, u32Value);
4017 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
4018 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
4019 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4020 IEM_MC_FETCH_MEM_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
4021 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Value);
4022 IEM_MC_ADVANCE_RIP();
4023 IEM_MC_END();
4024 break;
4025
4026 case IEMMODE_64BIT:
4027 IEM_MC_BEGIN(0, 2);
4028 IEM_MC_LOCAL(uint64_t, u64Value);
4029 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
4030 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
4031 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4032 IEM_MC_FETCH_MEM_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
4033 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Value);
4034 IEM_MC_ADVANCE_RIP();
4035 IEM_MC_END();
4036 break;
4037 }
4038 }
4039 return VINF_SUCCESS;
4040}
4041
4042
4043/**
4044 * opcode 0x63
4045 * @todo Table fixme
4046 */
4047FNIEMOP_DEF(iemOp_arpl_Ew_Gw_movsx_Gv_Ev)
4048{
4049 if (pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT)
4050 return FNIEMOP_CALL(iemOp_arpl_Ew_Gw);
4051 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_64BIT)
4052 return FNIEMOP_CALL(iemOp_mov_Gv_Ev);
4053 return FNIEMOP_CALL(iemOp_movsxd_Gv_Ev);
4054}
4055
4056
4057/**
4058 * @opcode 0x8c
4059 */
4060FNIEMOP_DEF(iemOp_mov_Ev_Sw)
4061{
4062 IEMOP_MNEMONIC(mov_Ev_Sw, "mov Ev,Sw");
4063
4064 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4065
4066 /*
4067 * Check that the destination register exists. The REX.R prefix is ignored.
4068 */
4069 uint8_t const iSegReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4070 if ( iSegReg > X86_SREG_GS)
4071 return IEMOP_RAISE_INVALID_OPCODE(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
4072
4073 /*
4074 * If rm is denoting a register, no more instruction bytes.
4075 * In that case, the operand size is respected and the upper bits are
4076 * cleared (starting with some pentium).
4077 */
4078 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4079 {
4080 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4081 switch (pVCpu->iem.s.enmEffOpSize)
4082 {
4083 case IEMMODE_16BIT:
4084 IEM_MC_BEGIN(0, 1);
4085 IEM_MC_LOCAL(uint16_t, u16Value);
4086 IEM_MC_FETCH_SREG_U16(u16Value, iSegReg);
4087 IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u16Value);
4088 IEM_MC_ADVANCE_RIP();
4089 IEM_MC_END();
4090 break;
4091
4092 case IEMMODE_32BIT:
4093 IEM_MC_BEGIN(0, 1);
4094 IEM_MC_LOCAL(uint32_t, u32Value);
4095 IEM_MC_FETCH_SREG_ZX_U32(u32Value, iSegReg);
4096 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Value);
4097 IEM_MC_ADVANCE_RIP();
4098 IEM_MC_END();
4099 break;
4100
4101 case IEMMODE_64BIT:
4102 IEM_MC_BEGIN(0, 1);
4103 IEM_MC_LOCAL(uint64_t, u64Value);
4104 IEM_MC_FETCH_SREG_ZX_U64(u64Value, iSegReg);
4105 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Value);
4106 IEM_MC_ADVANCE_RIP();
4107 IEM_MC_END();
4108 break;
4109 }
4110 }
4111 else
4112 {
4113 /*
4114 * We're saving the register to memory. The access is word sized
4115 * regardless of operand size prefixes.
4116 */
4117#if 0 /* not necessary */
4118 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_16BIT;
4119#endif
4120 IEM_MC_BEGIN(0, 2);
4121 IEM_MC_LOCAL(uint16_t, u16Value);
4122 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
4123 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
4124 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4125 IEM_MC_FETCH_SREG_U16(u16Value, iSegReg);
4126 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Value);
4127 IEM_MC_ADVANCE_RIP();
4128 IEM_MC_END();
4129 }
4130 return VINF_SUCCESS;
4131}
4132
4133
4134
4135
4136/**
4137 * @opcode 0x8d
4138 */
4139FNIEMOP_DEF(iemOp_lea_Gv_M)
4140{
4141 IEMOP_MNEMONIC(lea_Gv_M, "lea Gv,M");
4142 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4143 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4144 return IEMOP_RAISE_INVALID_OPCODE(); /* no register form */
4145
4146 switch (pVCpu->iem.s.enmEffOpSize)
4147 {
4148 case IEMMODE_16BIT:
4149 IEM_MC_BEGIN(0, 2);
4150 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4151 IEM_MC_LOCAL(uint16_t, u16Cast);
4152 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4153 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4154 IEM_MC_ASSIGN_TO_SMALLER(u16Cast, GCPtrEffSrc);
4155 IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Cast);
4156 IEM_MC_ADVANCE_RIP();
4157 IEM_MC_END();
4158 return VINF_SUCCESS;
4159
4160 case IEMMODE_32BIT:
4161 IEM_MC_BEGIN(0, 2);
4162 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4163 IEM_MC_LOCAL(uint32_t, u32Cast);
4164 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4165 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4166 IEM_MC_ASSIGN_TO_SMALLER(u32Cast, GCPtrEffSrc);
4167 IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Cast);
4168 IEM_MC_ADVANCE_RIP();
4169 IEM_MC_END();
4170 return VINF_SUCCESS;
4171
4172 case IEMMODE_64BIT:
4173 IEM_MC_BEGIN(0, 1);
4174 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
4175 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
4176 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4177 IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, GCPtrEffSrc);
4178 IEM_MC_ADVANCE_RIP();
4179 IEM_MC_END();
4180 return VINF_SUCCESS;
4181 }
4182 AssertFailedReturn(VERR_IEM_IPE_7);
4183}
4184
4185
4186/**
4187 * @opcode 0x8e
4188 */
4189FNIEMOP_DEF(iemOp_mov_Sw_Ev)
4190{
4191 IEMOP_MNEMONIC(mov_Sw_Ev, "mov Sw,Ev");
4192
4193 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4194
4195 /*
4196 * The practical operand size is 16-bit.
4197 */
4198#if 0 /* not necessary */
4199 pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize = IEMMODE_16BIT;
4200#endif
4201
4202 /*
4203 * Check that the destination register exists and can be used with this
4204 * instruction. The REX.R prefix is ignored.
4205 */
4206 uint8_t const iSegReg = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
4207 if ( iSegReg == X86_SREG_CS
4208 || iSegReg > X86_SREG_GS)
4209 return IEMOP_RAISE_INVALID_OPCODE(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
4210
4211 /*
4212 * If rm is denoting a register, no more instruction bytes.
4213 */
4214 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4215 {
4216 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4217 IEM_MC_BEGIN(2, 0);
4218 IEM_MC_ARG_CONST(uint8_t, iSRegArg, iSegReg, 0);
4219 IEM_MC_ARG(uint16_t, u16Value, 1);
4220 IEM_MC_FETCH_GREG_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4221 IEM_MC_CALL_CIMPL_2(iemCImpl_load_SReg, iSRegArg, u16Value);
4222 IEM_MC_END();
4223 }
4224 else
4225 {
4226 /*
4227 * We're loading the register from memory. The access is word sized
4228 * regardless of operand size prefixes.
4229 */
4230 IEM_MC_BEGIN(2, 1);
4231 IEM_MC_ARG_CONST(uint8_t, iSRegArg, iSegReg, 0);
4232 IEM_MC_ARG(uint16_t, u16Value, 1);
4233 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
4234 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
4235 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4236 IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
4237 IEM_MC_CALL_CIMPL_2(iemCImpl_load_SReg, iSRegArg, u16Value);
4238 IEM_MC_END();
4239 }
4240 return VINF_SUCCESS;
4241}
4242
4243
4244/** Opcode 0x8f /0. */
4245FNIEMOP_DEF_1(iemOp_pop_Ev, uint8_t, bRm)
4246{
4247 /* This bugger is rather annoying as it requires rSP to be updated before
4248 doing the effective address calculations. Will eventually require a
4249 split between the R/M+SIB decoding and the effective address
4250 calculation - which is something that is required for any attempt at
4251 reusing this code for a recompiler. It may also be good to have if we
4252 need to delay #UD exception caused by invalid lock prefixes.
4253
4254 For now, we'll do a mostly safe interpreter-only implementation here. */
4255 /** @todo What's the deal with the 'reg' field and pop Ev? Ignorning it for
4256 * now until tests show it's checked.. */
4257 IEMOP_MNEMONIC(pop_Ev, "pop Ev");
4258
4259 /* Register access is relatively easy and can share code. */
4260 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
4261 return FNIEMOP_CALL_1(iemOpCommonPopGReg, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
4262
4263 /*
4264 * Memory target.
4265 *
4266 * Intel says that RSP is incremented before it's used in any effective
4267 * address calcuations. This means some serious extra annoyance here since
4268 * we decode and calculate the effective address in one step and like to
4269 * delay committing registers till everything is done.
4270 *
4271 * So, we'll decode and calculate the effective address twice. This will
4272 * require some recoding if turned into a recompiler.
4273 */
4274 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE(); /* The common code does this differently. */
4275
4276#ifndef TST_IEM_CHECK_MC
4277 /* Calc effective address with modified ESP. */
4278/** @todo testcase */
4279 RTGCPTR GCPtrEff;
4280 VBOXSTRICTRC rcStrict;
4281 switch (pVCpu->iem.s.enmEffOpSize)
4282 {
4283 case IEMMODE_16BIT: rcStrict = iemOpHlpCalcRmEffAddrEx(pVCpu, bRm, 0, &GCPtrEff, 2); break;
4284 case IEMMODE_32BIT: rcStrict = iemOpHlpCalcRmEffAddrEx(pVCpu, bRm, 0, &GCPtrEff, 4); break;
4285 case IEMMODE_64BIT: rcStrict = iemOpHlpCalcRmEffAddrEx(pVCpu, bRm, 0, &GCPtrEff, 8); break;
4286 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4287 }
4288 if (rcStrict != VINF_SUCCESS)
4289 return rcStrict;
4290 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4291
4292 /* Perform the operation - this should be CImpl. */
4293 RTUINT64U TmpRsp;
4294 TmpRsp.u = pVCpu->cpum.GstCtx.rsp;
4295 switch (pVCpu->iem.s.enmEffOpSize)
4296 {
4297 case IEMMODE_16BIT:
4298 {
4299 uint16_t u16Value;
4300 rcStrict = iemMemStackPopU16Ex(pVCpu, &u16Value, &TmpRsp);
4301 if (rcStrict == VINF_SUCCESS)
4302 rcStrict = iemMemStoreDataU16(pVCpu, pVCpu->iem.s.iEffSeg, GCPtrEff, u16Value);
4303 break;
4304 }
4305
4306 case IEMMODE_32BIT:
4307 {
4308 uint32_t u32Value;
4309 rcStrict = iemMemStackPopU32Ex(pVCpu, &u32Value, &TmpRsp);
4310 if (rcStrict == VINF_SUCCESS)
4311 rcStrict = iemMemStoreDataU32(pVCpu, pVCpu->iem.s.iEffSeg, GCPtrEff, u32Value);
4312 break;
4313 }
4314
4315 case IEMMODE_64BIT:
4316 {
4317 uint64_t u64Value;
4318 rcStrict = iemMemStackPopU64Ex(pVCpu, &u64Value, &TmpRsp);
4319 if (rcStrict == VINF_SUCCESS)
4320 rcStrict = iemMemStoreDataU64(pVCpu, pVCpu->iem.s.iEffSeg, GCPtrEff, u64Value);
4321 break;
4322 }
4323
4324 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4325 }
4326 if (rcStrict == VINF_SUCCESS)
4327 {
4328 pVCpu->cpum.GstCtx.rsp = TmpRsp.u;
4329 iemRegUpdateRipAndClearRF(pVCpu);
4330 }
4331 return rcStrict;
4332
4333#else
4334 return VERR_IEM_IPE_2;
4335#endif
4336}
4337
4338
4339/**
4340 * @opcode 0x8f
4341 */
4342FNIEMOP_DEF(iemOp_Grp1A__xop)
4343{
4344 /*
4345 * AMD has defined /1 thru /7 as XOP prefix. The prefix is similar to the
4346 * three byte VEX prefix, except that the mmmmm field cannot have the values
4347 * 0 thru 7, because it would then be confused with pop Ev (modrm.reg == 0).
4348 */
4349 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
4350 if ((bRm & X86_MODRM_REG_MASK) == (0 << X86_MODRM_REG_SHIFT)) /* /0 */
4351 return FNIEMOP_CALL_1(iemOp_pop_Ev, bRm);
4352
4353 IEMOP_MNEMONIC(xop, "xop");
4354 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fXop)
4355 {
4356 /** @todo Test when exctly the XOP conformance checks kick in during
4357 * instruction decoding and fetching (using \#PF). */
4358 uint8_t bXop2; IEM_OPCODE_GET_NEXT_U8(&bXop2);
4359 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
4360 if ( ( pVCpu->iem.s.fPrefixes
4361 & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))
4362 == 0)
4363 {
4364 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_XOP;
4365 if ((bXop2 & 0x80 /* XOP.W */) && pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
4366 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_REX_W;
4367 pVCpu->iem.s.uRexReg = (~bRm >> (7 - 3)) & 0x8;
4368 pVCpu->iem.s.uRexIndex = (~bRm >> (6 - 3)) & 0x8;
4369 pVCpu->iem.s.uRexB = (~bRm >> (5 - 3)) & 0x8;
4370 pVCpu->iem.s.uVex3rdReg = (~bXop2 >> 3) & 0xf;
4371 pVCpu->iem.s.uVexLength = (bXop2 >> 2) & 1;
4372 pVCpu->iem.s.idxPrefix = bXop2 & 0x3;
4373
4374 /** @todo XOP: Just use new tables and decoders. */
4375 switch (bRm & 0x1f)
4376 {
4377 case 8: /* xop opcode map 8. */
4378 IEMOP_BITCH_ABOUT_STUB();
4379 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
4380
4381 case 9: /* xop opcode map 9. */
4382 IEMOP_BITCH_ABOUT_STUB();
4383 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
4384
4385 case 10: /* xop opcode map 10. */
4386 IEMOP_BITCH_ABOUT_STUB();
4387 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
4388
4389 default:
4390 Log(("XOP: Invalid vvvv value: %#x!\n", bRm & 0x1f));
4391 return IEMOP_RAISE_INVALID_OPCODE();
4392 }
4393 }
4394 else
4395 Log(("XOP: Invalid prefix mix!\n"));
4396 }
4397 else
4398 Log(("XOP: XOP support disabled!\n"));
4399 return IEMOP_RAISE_INVALID_OPCODE();
4400}
4401
4402
4403/**
4404 * Common 'xchg reg,rAX' helper.
4405 */
4406FNIEMOP_DEF_1(iemOpCommonXchgGRegRax, uint8_t, iReg)
4407{
4408 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4409
4410 iReg |= pVCpu->iem.s.uRexB;
4411 switch (pVCpu->iem.s.enmEffOpSize)
4412 {
4413 case IEMMODE_16BIT:
4414 IEM_MC_BEGIN(0, 2);
4415 IEM_MC_LOCAL(uint16_t, u16Tmp1);
4416 IEM_MC_LOCAL(uint16_t, u16Tmp2);
4417 IEM_MC_FETCH_GREG_U16(u16Tmp1, iReg);
4418 IEM_MC_FETCH_GREG_U16(u16Tmp2, X86_GREG_xAX);
4419 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp1);
4420 IEM_MC_STORE_GREG_U16(iReg, u16Tmp2);
4421 IEM_MC_ADVANCE_RIP();
4422 IEM_MC_END();
4423 return VINF_SUCCESS;
4424
4425 case IEMMODE_32BIT:
4426 IEM_MC_BEGIN(0, 2);
4427 IEM_MC_LOCAL(uint32_t, u32Tmp1);
4428 IEM_MC_LOCAL(uint32_t, u32Tmp2);
4429 IEM_MC_FETCH_GREG_U32(u32Tmp1, iReg);
4430 IEM_MC_FETCH_GREG_U32(u32Tmp2, X86_GREG_xAX);
4431 IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Tmp1);
4432 IEM_MC_STORE_GREG_U32(iReg, u32Tmp2);
4433 IEM_MC_ADVANCE_RIP();
4434 IEM_MC_END();
4435 return VINF_SUCCESS;
4436
4437 case IEMMODE_64BIT:
4438 IEM_MC_BEGIN(0, 2);
4439 IEM_MC_LOCAL(uint64_t, u64Tmp1);
4440 IEM_MC_LOCAL(uint64_t, u64Tmp2);
4441 IEM_MC_FETCH_GREG_U64(u64Tmp1, iReg);
4442 IEM_MC_FETCH_GREG_U64(u64Tmp2, X86_GREG_xAX);
4443 IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Tmp1);
4444 IEM_MC_STORE_GREG_U64(iReg, u64Tmp2);
4445 IEM_MC_ADVANCE_RIP();
4446 IEM_MC_END();
4447 return VINF_SUCCESS;
4448
4449 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4450 }
4451}
4452
4453
4454/**
4455 * @opcode 0x90
4456 */
4457FNIEMOP_DEF(iemOp_nop)
4458{
4459 /* R8/R8D and RAX/EAX can be exchanged. */
4460 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX_B)
4461 {
4462 IEMOP_MNEMONIC(xchg_r8_rAX, "xchg r8,rAX");
4463 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xAX);
4464 }
4465
4466 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK)
4467 {
4468 IEMOP_MNEMONIC(pause, "pause");
4469#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
4470 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmx)
4471 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmx_pause);
4472#endif
4473#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
4474 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSvm)
4475 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_svm_pause);
4476#endif
4477 }
4478 else
4479 IEMOP_MNEMONIC(nop, "nop");
4480 IEM_MC_BEGIN(0, 0);
4481 IEM_MC_ADVANCE_RIP();
4482 IEM_MC_END();
4483 return VINF_SUCCESS;
4484}
4485
4486
4487/**
4488 * @opcode 0x91
4489 */
4490FNIEMOP_DEF(iemOp_xchg_eCX_eAX)
4491{
4492 IEMOP_MNEMONIC(xchg_rCX_rAX, "xchg rCX,rAX");
4493 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xCX);
4494}
4495
4496
4497/**
4498 * @opcode 0x92
4499 */
4500FNIEMOP_DEF(iemOp_xchg_eDX_eAX)
4501{
4502 IEMOP_MNEMONIC(xchg_rDX_rAX, "xchg rDX,rAX");
4503 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xDX);
4504}
4505
4506
4507/**
4508 * @opcode 0x93
4509 */
4510FNIEMOP_DEF(iemOp_xchg_eBX_eAX)
4511{
4512 IEMOP_MNEMONIC(xchg_rBX_rAX, "xchg rBX,rAX");
4513 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xBX);
4514}
4515
4516
4517/**
4518 * @opcode 0x94
4519 */
4520FNIEMOP_DEF(iemOp_xchg_eSP_eAX)
4521{
4522 IEMOP_MNEMONIC(xchg_rSX_rAX, "xchg rSX,rAX");
4523 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xSP);
4524}
4525
4526
4527/**
4528 * @opcode 0x95
4529 */
4530FNIEMOP_DEF(iemOp_xchg_eBP_eAX)
4531{
4532 IEMOP_MNEMONIC(xchg_rBP_rAX, "xchg rBP,rAX");
4533 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xBP);
4534}
4535
4536
4537/**
4538 * @opcode 0x96
4539 */
4540FNIEMOP_DEF(iemOp_xchg_eSI_eAX)
4541{
4542 IEMOP_MNEMONIC(xchg_rSI_rAX, "xchg rSI,rAX");
4543 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xSI);
4544}
4545
4546
4547/**
4548 * @opcode 0x97
4549 */
4550FNIEMOP_DEF(iemOp_xchg_eDI_eAX)
4551{
4552 IEMOP_MNEMONIC(xchg_rDI_rAX, "xchg rDI,rAX");
4553 return FNIEMOP_CALL_1(iemOpCommonXchgGRegRax, X86_GREG_xDI);
4554}
4555
4556
4557/**
4558 * @opcode 0x98
4559 */
4560FNIEMOP_DEF(iemOp_cbw)
4561{
4562 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4563 switch (pVCpu->iem.s.enmEffOpSize)
4564 {
4565 case IEMMODE_16BIT:
4566 IEMOP_MNEMONIC(cbw, "cbw");
4567 IEM_MC_BEGIN(0, 1);
4568 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 7) {
4569 IEM_MC_OR_GREG_U16(X86_GREG_xAX, UINT16_C(0xff00));
4570 } IEM_MC_ELSE() {
4571 IEM_MC_AND_GREG_U16(X86_GREG_xAX, UINT16_C(0x00ff));
4572 } IEM_MC_ENDIF();
4573 IEM_MC_ADVANCE_RIP();
4574 IEM_MC_END();
4575 return VINF_SUCCESS;
4576
4577 case IEMMODE_32BIT:
4578 IEMOP_MNEMONIC(cwde, "cwde");
4579 IEM_MC_BEGIN(0, 1);
4580 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 15) {
4581 IEM_MC_OR_GREG_U32(X86_GREG_xAX, UINT32_C(0xffff0000));
4582 } IEM_MC_ELSE() {
4583 IEM_MC_AND_GREG_U32(X86_GREG_xAX, UINT32_C(0x0000ffff));
4584 } IEM_MC_ENDIF();
4585 IEM_MC_ADVANCE_RIP();
4586 IEM_MC_END();
4587 return VINF_SUCCESS;
4588
4589 case IEMMODE_64BIT:
4590 IEMOP_MNEMONIC(cdqe, "cdqe");
4591 IEM_MC_BEGIN(0, 1);
4592 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 31) {
4593 IEM_MC_OR_GREG_U64(X86_GREG_xAX, UINT64_C(0xffffffff00000000));
4594 } IEM_MC_ELSE() {
4595 IEM_MC_AND_GREG_U64(X86_GREG_xAX, UINT64_C(0x00000000ffffffff));
4596 } IEM_MC_ENDIF();
4597 IEM_MC_ADVANCE_RIP();
4598 IEM_MC_END();
4599 return VINF_SUCCESS;
4600
4601 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4602 }
4603}
4604
4605
4606/**
4607 * @opcode 0x99
4608 */
4609FNIEMOP_DEF(iemOp_cwd)
4610{
4611 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4612 switch (pVCpu->iem.s.enmEffOpSize)
4613 {
4614 case IEMMODE_16BIT:
4615 IEMOP_MNEMONIC(cwd, "cwd");
4616 IEM_MC_BEGIN(0, 1);
4617 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 15) {
4618 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xDX, UINT16_C(0xffff));
4619 } IEM_MC_ELSE() {
4620 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xDX, 0);
4621 } IEM_MC_ENDIF();
4622 IEM_MC_ADVANCE_RIP();
4623 IEM_MC_END();
4624 return VINF_SUCCESS;
4625
4626 case IEMMODE_32BIT:
4627 IEMOP_MNEMONIC(cdq, "cdq");
4628 IEM_MC_BEGIN(0, 1);
4629 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 31) {
4630 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xDX, UINT32_C(0xffffffff));
4631 } IEM_MC_ELSE() {
4632 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xDX, 0);
4633 } IEM_MC_ENDIF();
4634 IEM_MC_ADVANCE_RIP();
4635 IEM_MC_END();
4636 return VINF_SUCCESS;
4637
4638 case IEMMODE_64BIT:
4639 IEMOP_MNEMONIC(cqo, "cqo");
4640 IEM_MC_BEGIN(0, 1);
4641 IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 63) {
4642 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xDX, UINT64_C(0xffffffffffffffff));
4643 } IEM_MC_ELSE() {
4644 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xDX, 0);
4645 } IEM_MC_ENDIF();
4646 IEM_MC_ADVANCE_RIP();
4647 IEM_MC_END();
4648 return VINF_SUCCESS;
4649
4650 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4651 }
4652}
4653
4654
4655/**
4656 * @opcode 0x9a
4657 */
4658FNIEMOP_DEF(iemOp_call_Ap)
4659{
4660 IEMOP_MNEMONIC(call_Ap, "call Ap");
4661 IEMOP_HLP_NO_64BIT();
4662
4663 /* Decode the far pointer address and pass it on to the far call C implementation. */
4664 uint32_t offSeg;
4665 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_16BIT)
4666 IEM_OPCODE_GET_NEXT_U32(&offSeg);
4667 else
4668 IEM_OPCODE_GET_NEXT_U16_ZX_U32(&offSeg);
4669 uint16_t uSel; IEM_OPCODE_GET_NEXT_U16(&uSel);
4670 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4671 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_callf, uSel, offSeg, pVCpu->iem.s.enmEffOpSize);
4672}
4673
4674
4675/** Opcode 0x9b. (aka fwait) */
4676FNIEMOP_DEF(iemOp_wait)
4677{
4678 IEMOP_MNEMONIC(wait, "wait");
4679 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4680
4681 IEM_MC_BEGIN(0, 0);
4682 IEM_MC_MAYBE_RAISE_WAIT_DEVICE_NOT_AVAILABLE();
4683 IEM_MC_MAYBE_RAISE_FPU_XCPT();
4684 IEM_MC_ADVANCE_RIP();
4685 IEM_MC_END();
4686 return VINF_SUCCESS;
4687}
4688
4689
4690/**
4691 * @opcode 0x9c
4692 */
4693FNIEMOP_DEF(iemOp_pushf_Fv)
4694{
4695 IEMOP_MNEMONIC(pushf_Fv, "pushf Fv");
4696 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4697 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
4698 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_pushf, pVCpu->iem.s.enmEffOpSize);
4699}
4700
4701
4702/**
4703 * @opcode 0x9d
4704 */
4705FNIEMOP_DEF(iemOp_popf_Fv)
4706{
4707 IEMOP_MNEMONIC(popf_Fv, "popf Fv");
4708 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4709 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
4710 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_popf, pVCpu->iem.s.enmEffOpSize);
4711}
4712
4713
4714/**
4715 * @opcode 0x9e
4716 */
4717FNIEMOP_DEF(iemOp_sahf)
4718{
4719 IEMOP_MNEMONIC(sahf, "sahf");
4720 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4721 if ( pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
4722 && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLahfSahf)
4723 return IEMOP_RAISE_INVALID_OPCODE();
4724 IEM_MC_BEGIN(0, 2);
4725 IEM_MC_LOCAL(uint32_t, u32Flags);
4726 IEM_MC_LOCAL(uint32_t, EFlags);
4727 IEM_MC_FETCH_EFLAGS(EFlags);
4728 IEM_MC_FETCH_GREG_U8_ZX_U32(u32Flags, X86_GREG_xSP/*=AH*/);
4729 IEM_MC_AND_LOCAL_U32(u32Flags, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
4730 IEM_MC_AND_LOCAL_U32(EFlags, UINT32_C(0xffffff00));
4731 IEM_MC_OR_LOCAL_U32(u32Flags, X86_EFL_1);
4732 IEM_MC_OR_2LOCS_U32(EFlags, u32Flags);
4733 IEM_MC_COMMIT_EFLAGS(EFlags);
4734 IEM_MC_ADVANCE_RIP();
4735 IEM_MC_END();
4736 return VINF_SUCCESS;
4737}
4738
4739
4740/**
4741 * @opcode 0x9f
4742 */
4743FNIEMOP_DEF(iemOp_lahf)
4744{
4745 IEMOP_MNEMONIC(lahf, "lahf");
4746 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4747 if ( pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
4748 && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLahfSahf)
4749 return IEMOP_RAISE_INVALID_OPCODE();
4750 IEM_MC_BEGIN(0, 1);
4751 IEM_MC_LOCAL(uint8_t, u8Flags);
4752 IEM_MC_FETCH_EFLAGS_U8(u8Flags);
4753 IEM_MC_STORE_GREG_U8(X86_GREG_xSP/*=AH*/, u8Flags);
4754 IEM_MC_ADVANCE_RIP();
4755 IEM_MC_END();
4756 return VINF_SUCCESS;
4757}
4758
4759
4760/**
4761 * Macro used by iemOp_mov_AL_Ob, iemOp_mov_rAX_Ov, iemOp_mov_Ob_AL and
4762 * iemOp_mov_Ov_rAX to fetch the moffsXX bit of the opcode and fend off lock
4763 * prefixes. Will return on failures.
4764 * @param a_GCPtrMemOff The variable to store the offset in.
4765 */
4766#define IEMOP_FETCH_MOFFS_XX(a_GCPtrMemOff) \
4767 do \
4768 { \
4769 switch (pVCpu->iem.s.enmEffAddrMode) \
4770 { \
4771 case IEMMODE_16BIT: \
4772 IEM_OPCODE_GET_NEXT_U16_ZX_U64(&(a_GCPtrMemOff)); \
4773 break; \
4774 case IEMMODE_32BIT: \
4775 IEM_OPCODE_GET_NEXT_U32_ZX_U64(&(a_GCPtrMemOff)); \
4776 break; \
4777 case IEMMODE_64BIT: \
4778 IEM_OPCODE_GET_NEXT_U64(&(a_GCPtrMemOff)); \
4779 break; \
4780 IEM_NOT_REACHED_DEFAULT_CASE_RET(); \
4781 } \
4782 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
4783 } while (0)
4784
4785/**
4786 * @opcode 0xa0
4787 */
4788FNIEMOP_DEF(iemOp_mov_AL_Ob)
4789{
4790 /*
4791 * Get the offset and fend off lock prefixes.
4792 */
4793 IEMOP_MNEMONIC(mov_AL_Ob, "mov AL,Ob");
4794 RTGCPTR GCPtrMemOff;
4795 IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
4796
4797 /*
4798 * Fetch AL.
4799 */
4800 IEM_MC_BEGIN(0,1);
4801 IEM_MC_LOCAL(uint8_t, u8Tmp);
4802 IEM_MC_FETCH_MEM_U8(u8Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
4803 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
4804 IEM_MC_ADVANCE_RIP();
4805 IEM_MC_END();
4806 return VINF_SUCCESS;
4807}
4808
4809
4810/**
4811 * @opcode 0xa1
4812 */
4813FNIEMOP_DEF(iemOp_mov_rAX_Ov)
4814{
4815 /*
4816 * Get the offset and fend off lock prefixes.
4817 */
4818 IEMOP_MNEMONIC(mov_rAX_Ov, "mov rAX,Ov");
4819 RTGCPTR GCPtrMemOff;
4820 IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
4821
4822 /*
4823 * Fetch rAX.
4824 */
4825 switch (pVCpu->iem.s.enmEffOpSize)
4826 {
4827 case IEMMODE_16BIT:
4828 IEM_MC_BEGIN(0,1);
4829 IEM_MC_LOCAL(uint16_t, u16Tmp);
4830 IEM_MC_FETCH_MEM_U16(u16Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
4831 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp);
4832 IEM_MC_ADVANCE_RIP();
4833 IEM_MC_END();
4834 return VINF_SUCCESS;
4835
4836 case IEMMODE_32BIT:
4837 IEM_MC_BEGIN(0,1);
4838 IEM_MC_LOCAL(uint32_t, u32Tmp);
4839 IEM_MC_FETCH_MEM_U32(u32Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
4840 IEM_MC_STORE_GREG_U32(X86_GREG_xAX, u32Tmp);
4841 IEM_MC_ADVANCE_RIP();
4842 IEM_MC_END();
4843 return VINF_SUCCESS;
4844
4845 case IEMMODE_64BIT:
4846 IEM_MC_BEGIN(0,1);
4847 IEM_MC_LOCAL(uint64_t, u64Tmp);
4848 IEM_MC_FETCH_MEM_U64(u64Tmp, pVCpu->iem.s.iEffSeg, GCPtrMemOff);
4849 IEM_MC_STORE_GREG_U64(X86_GREG_xAX, u64Tmp);
4850 IEM_MC_ADVANCE_RIP();
4851 IEM_MC_END();
4852 return VINF_SUCCESS;
4853
4854 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4855 }
4856}
4857
4858
4859/**
4860 * @opcode 0xa2
4861 */
4862FNIEMOP_DEF(iemOp_mov_Ob_AL)
4863{
4864 /*
4865 * Get the offset and fend off lock prefixes.
4866 */
4867 IEMOP_MNEMONIC(mov_Ob_AL, "mov Ob,AL");
4868 RTGCPTR GCPtrMemOff;
4869 IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
4870
4871 /*
4872 * Store AL.
4873 */
4874 IEM_MC_BEGIN(0,1);
4875 IEM_MC_LOCAL(uint8_t, u8Tmp);
4876 IEM_MC_FETCH_GREG_U8(u8Tmp, X86_GREG_xAX);
4877 IEM_MC_STORE_MEM_U8(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u8Tmp);
4878 IEM_MC_ADVANCE_RIP();
4879 IEM_MC_END();
4880 return VINF_SUCCESS;
4881}
4882
4883
4884/**
4885 * @opcode 0xa3
4886 */
4887FNIEMOP_DEF(iemOp_mov_Ov_rAX)
4888{
4889 /*
4890 * Get the offset and fend off lock prefixes.
4891 */
4892 IEMOP_MNEMONIC(mov_Ov_rAX, "mov Ov,rAX");
4893 RTGCPTR GCPtrMemOff;
4894 IEMOP_FETCH_MOFFS_XX(GCPtrMemOff);
4895
4896 /*
4897 * Store rAX.
4898 */
4899 switch (pVCpu->iem.s.enmEffOpSize)
4900 {
4901 case IEMMODE_16BIT:
4902 IEM_MC_BEGIN(0,1);
4903 IEM_MC_LOCAL(uint16_t, u16Tmp);
4904 IEM_MC_FETCH_GREG_U16(u16Tmp, X86_GREG_xAX);
4905 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u16Tmp);
4906 IEM_MC_ADVANCE_RIP();
4907 IEM_MC_END();
4908 return VINF_SUCCESS;
4909
4910 case IEMMODE_32BIT:
4911 IEM_MC_BEGIN(0,1);
4912 IEM_MC_LOCAL(uint32_t, u32Tmp);
4913 IEM_MC_FETCH_GREG_U32(u32Tmp, X86_GREG_xAX);
4914 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u32Tmp);
4915 IEM_MC_ADVANCE_RIP();
4916 IEM_MC_END();
4917 return VINF_SUCCESS;
4918
4919 case IEMMODE_64BIT:
4920 IEM_MC_BEGIN(0,1);
4921 IEM_MC_LOCAL(uint64_t, u64Tmp);
4922 IEM_MC_FETCH_GREG_U64(u64Tmp, X86_GREG_xAX);
4923 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrMemOff, u64Tmp);
4924 IEM_MC_ADVANCE_RIP();
4925 IEM_MC_END();
4926 return VINF_SUCCESS;
4927
4928 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4929 }
4930}
4931
4932/** Macro used by iemOp_movsb_Xb_Yb and iemOp_movswd_Xv_Yv */
4933#define IEM_MOVS_CASE(ValBits, AddrBits) \
4934 IEM_MC_BEGIN(0, 2); \
4935 IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
4936 IEM_MC_LOCAL(RTGCPTR, uAddr); \
4937 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
4938 IEM_MC_FETCH_MEM_U##ValBits(uValue, pVCpu->iem.s.iEffSeg, uAddr); \
4939 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
4940 IEM_MC_STORE_MEM_U##ValBits(X86_SREG_ES, uAddr, uValue); \
4941 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
4942 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
4943 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
4944 } IEM_MC_ELSE() { \
4945 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
4946 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
4947 } IEM_MC_ENDIF(); \
4948 IEM_MC_ADVANCE_RIP(); \
4949 IEM_MC_END();
4950
4951/**
4952 * @opcode 0xa4
4953 */
4954FNIEMOP_DEF(iemOp_movsb_Xb_Yb)
4955{
4956 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4957
4958 /*
4959 * Use the C implementation if a repeat prefix is encountered.
4960 */
4961 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
4962 {
4963 IEMOP_MNEMONIC(rep_movsb_Xb_Yb, "rep movsb Xb,Yb");
4964 switch (pVCpu->iem.s.enmEffAddrMode)
4965 {
4966 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op8_addr16, pVCpu->iem.s.iEffSeg);
4967 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op8_addr32, pVCpu->iem.s.iEffSeg);
4968 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op8_addr64, pVCpu->iem.s.iEffSeg);
4969 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4970 }
4971 }
4972 IEMOP_MNEMONIC(movsb_Xb_Yb, "movsb Xb,Yb");
4973
4974 /*
4975 * Sharing case implementation with movs[wdq] below.
4976 */
4977 switch (pVCpu->iem.s.enmEffAddrMode)
4978 {
4979 case IEMMODE_16BIT: IEM_MOVS_CASE(8, 16); break;
4980 case IEMMODE_32BIT: IEM_MOVS_CASE(8, 32); break;
4981 case IEMMODE_64BIT: IEM_MOVS_CASE(8, 64); break;
4982 IEM_NOT_REACHED_DEFAULT_CASE_RET();
4983 }
4984 return VINF_SUCCESS;
4985}
4986
4987
4988/**
4989 * @opcode 0xa5
4990 */
4991FNIEMOP_DEF(iemOp_movswd_Xv_Yv)
4992{
4993 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
4994
4995 /*
4996 * Use the C implementation if a repeat prefix is encountered.
4997 */
4998 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
4999 {
5000 IEMOP_MNEMONIC(rep_movs_Xv_Yv, "rep movs Xv,Yv");
5001 switch (pVCpu->iem.s.enmEffOpSize)
5002 {
5003 case IEMMODE_16BIT:
5004 switch (pVCpu->iem.s.enmEffAddrMode)
5005 {
5006 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op16_addr16, pVCpu->iem.s.iEffSeg);
5007 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op16_addr32, pVCpu->iem.s.iEffSeg);
5008 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op16_addr64, pVCpu->iem.s.iEffSeg);
5009 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5010 }
5011 break;
5012 case IEMMODE_32BIT:
5013 switch (pVCpu->iem.s.enmEffAddrMode)
5014 {
5015 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op32_addr16, pVCpu->iem.s.iEffSeg);
5016 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op32_addr32, pVCpu->iem.s.iEffSeg);
5017 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op32_addr64, pVCpu->iem.s.iEffSeg);
5018 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5019 }
5020 case IEMMODE_64BIT:
5021 switch (pVCpu->iem.s.enmEffAddrMode)
5022 {
5023 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_6);
5024 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op64_addr32, pVCpu->iem.s.iEffSeg);
5025 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_movs_op64_addr64, pVCpu->iem.s.iEffSeg);
5026 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5027 }
5028 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5029 }
5030 }
5031 IEMOP_MNEMONIC(movs_Xv_Yv, "movs Xv,Yv");
5032
5033 /*
5034 * Annoying double switch here.
5035 * Using ugly macro for implementing the cases, sharing it with movsb.
5036 */
5037 switch (pVCpu->iem.s.enmEffOpSize)
5038 {
5039 case IEMMODE_16BIT:
5040 switch (pVCpu->iem.s.enmEffAddrMode)
5041 {
5042 case IEMMODE_16BIT: IEM_MOVS_CASE(16, 16); break;
5043 case IEMMODE_32BIT: IEM_MOVS_CASE(16, 32); break;
5044 case IEMMODE_64BIT: IEM_MOVS_CASE(16, 64); break;
5045 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5046 }
5047 break;
5048
5049 case IEMMODE_32BIT:
5050 switch (pVCpu->iem.s.enmEffAddrMode)
5051 {
5052 case IEMMODE_16BIT: IEM_MOVS_CASE(32, 16); break;
5053 case IEMMODE_32BIT: IEM_MOVS_CASE(32, 32); break;
5054 case IEMMODE_64BIT: IEM_MOVS_CASE(32, 64); break;
5055 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5056 }
5057 break;
5058
5059 case IEMMODE_64BIT:
5060 switch (pVCpu->iem.s.enmEffAddrMode)
5061 {
5062 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
5063 case IEMMODE_32BIT: IEM_MOVS_CASE(64, 32); break;
5064 case IEMMODE_64BIT: IEM_MOVS_CASE(64, 64); break;
5065 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5066 }
5067 break;
5068 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5069 }
5070 return VINF_SUCCESS;
5071}
5072
5073#undef IEM_MOVS_CASE
5074
5075/** Macro used by iemOp_cmpsb_Xb_Yb and iemOp_cmpswd_Xv_Yv */
5076#define IEM_CMPS_CASE(ValBits, AddrBits) \
5077 IEM_MC_BEGIN(3, 3); \
5078 IEM_MC_ARG(uint##ValBits##_t *, puValue1, 0); \
5079 IEM_MC_ARG(uint##ValBits##_t, uValue2, 1); \
5080 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
5081 IEM_MC_LOCAL(uint##ValBits##_t, uValue1); \
5082 IEM_MC_LOCAL(RTGCPTR, uAddr); \
5083 \
5084 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
5085 IEM_MC_FETCH_MEM_U##ValBits(uValue1, pVCpu->iem.s.iEffSeg, uAddr); \
5086 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
5087 IEM_MC_FETCH_MEM_U##ValBits(uValue2, X86_SREG_ES, uAddr); \
5088 IEM_MC_REF_LOCAL(puValue1, uValue1); \
5089 IEM_MC_REF_EFLAGS(pEFlags); \
5090 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puValue1, uValue2, pEFlags); \
5091 \
5092 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
5093 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
5094 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
5095 } IEM_MC_ELSE() { \
5096 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
5097 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
5098 } IEM_MC_ENDIF(); \
5099 IEM_MC_ADVANCE_RIP(); \
5100 IEM_MC_END(); \
5101
5102/**
5103 * @opcode 0xa6
5104 */
5105FNIEMOP_DEF(iemOp_cmpsb_Xb_Yb)
5106{
5107 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5108
5109 /*
5110 * Use the C implementation if a repeat prefix is encountered.
5111 */
5112 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
5113 {
5114 IEMOP_MNEMONIC(repz_cmps_Xb_Yb, "repz cmps Xb,Yb");
5115 switch (pVCpu->iem.s.enmEffAddrMode)
5116 {
5117 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr16, pVCpu->iem.s.iEffSeg);
5118 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr32, pVCpu->iem.s.iEffSeg);
5119 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr64, pVCpu->iem.s.iEffSeg);
5120 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5121 }
5122 }
5123 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
5124 {
5125 IEMOP_MNEMONIC(repnz_cmps_Xb_Yb, "repnz cmps Xb,Yb");
5126 switch (pVCpu->iem.s.enmEffAddrMode)
5127 {
5128 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr16, pVCpu->iem.s.iEffSeg);
5129 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr32, pVCpu->iem.s.iEffSeg);
5130 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr64, pVCpu->iem.s.iEffSeg);
5131 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5132 }
5133 }
5134 IEMOP_MNEMONIC(cmps_Xb_Yb, "cmps Xb,Yb");
5135
5136 /*
5137 * Sharing case implementation with cmps[wdq] below.
5138 */
5139 switch (pVCpu->iem.s.enmEffAddrMode)
5140 {
5141 case IEMMODE_16BIT: IEM_CMPS_CASE(8, 16); break;
5142 case IEMMODE_32BIT: IEM_CMPS_CASE(8, 32); break;
5143 case IEMMODE_64BIT: IEM_CMPS_CASE(8, 64); break;
5144 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5145 }
5146 return VINF_SUCCESS;
5147
5148}
5149
5150
5151/**
5152 * @opcode 0xa7
5153 */
5154FNIEMOP_DEF(iemOp_cmpswd_Xv_Yv)
5155{
5156 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5157
5158 /*
5159 * Use the C implementation if a repeat prefix is encountered.
5160 */
5161 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
5162 {
5163 IEMOP_MNEMONIC(repe_cmps_Xv_Yv, "repe cmps Xv,Yv");
5164 switch (pVCpu->iem.s.enmEffOpSize)
5165 {
5166 case IEMMODE_16BIT:
5167 switch (pVCpu->iem.s.enmEffAddrMode)
5168 {
5169 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr16, pVCpu->iem.s.iEffSeg);
5170 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr32, pVCpu->iem.s.iEffSeg);
5171 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr64, pVCpu->iem.s.iEffSeg);
5172 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5173 }
5174 break;
5175 case IEMMODE_32BIT:
5176 switch (pVCpu->iem.s.enmEffAddrMode)
5177 {
5178 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr16, pVCpu->iem.s.iEffSeg);
5179 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr32, pVCpu->iem.s.iEffSeg);
5180 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr64, pVCpu->iem.s.iEffSeg);
5181 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5182 }
5183 case IEMMODE_64BIT:
5184 switch (pVCpu->iem.s.enmEffAddrMode)
5185 {
5186 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_4);
5187 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op64_addr32, pVCpu->iem.s.iEffSeg);
5188 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op64_addr64, pVCpu->iem.s.iEffSeg);
5189 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5190 }
5191 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5192 }
5193 }
5194
5195 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
5196 {
5197 IEMOP_MNEMONIC(repne_cmps_Xv_Yv, "repne cmps Xv,Yv");
5198 switch (pVCpu->iem.s.enmEffOpSize)
5199 {
5200 case IEMMODE_16BIT:
5201 switch (pVCpu->iem.s.enmEffAddrMode)
5202 {
5203 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr16, pVCpu->iem.s.iEffSeg);
5204 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr32, pVCpu->iem.s.iEffSeg);
5205 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr64, pVCpu->iem.s.iEffSeg);
5206 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5207 }
5208 break;
5209 case IEMMODE_32BIT:
5210 switch (pVCpu->iem.s.enmEffAddrMode)
5211 {
5212 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr16, pVCpu->iem.s.iEffSeg);
5213 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr32, pVCpu->iem.s.iEffSeg);
5214 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr64, pVCpu->iem.s.iEffSeg);
5215 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5216 }
5217 case IEMMODE_64BIT:
5218 switch (pVCpu->iem.s.enmEffAddrMode)
5219 {
5220 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_2);
5221 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op64_addr32, pVCpu->iem.s.iEffSeg);
5222 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op64_addr64, pVCpu->iem.s.iEffSeg);
5223 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5224 }
5225 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5226 }
5227 }
5228
5229 IEMOP_MNEMONIC(cmps_Xv_Yv, "cmps Xv,Yv");
5230
5231 /*
5232 * Annoying double switch here.
5233 * Using ugly macro for implementing the cases, sharing it with cmpsb.
5234 */
5235 switch (pVCpu->iem.s.enmEffOpSize)
5236 {
5237 case IEMMODE_16BIT:
5238 switch (pVCpu->iem.s.enmEffAddrMode)
5239 {
5240 case IEMMODE_16BIT: IEM_CMPS_CASE(16, 16); break;
5241 case IEMMODE_32BIT: IEM_CMPS_CASE(16, 32); break;
5242 case IEMMODE_64BIT: IEM_CMPS_CASE(16, 64); break;
5243 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5244 }
5245 break;
5246
5247 case IEMMODE_32BIT:
5248 switch (pVCpu->iem.s.enmEffAddrMode)
5249 {
5250 case IEMMODE_16BIT: IEM_CMPS_CASE(32, 16); break;
5251 case IEMMODE_32BIT: IEM_CMPS_CASE(32, 32); break;
5252 case IEMMODE_64BIT: IEM_CMPS_CASE(32, 64); break;
5253 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5254 }
5255 break;
5256
5257 case IEMMODE_64BIT:
5258 switch (pVCpu->iem.s.enmEffAddrMode)
5259 {
5260 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
5261 case IEMMODE_32BIT: IEM_CMPS_CASE(64, 32); break;
5262 case IEMMODE_64BIT: IEM_CMPS_CASE(64, 64); break;
5263 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5264 }
5265 break;
5266 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5267 }
5268 return VINF_SUCCESS;
5269
5270}
5271
5272#undef IEM_CMPS_CASE
5273
5274/**
5275 * @opcode 0xa8
5276 */
5277FNIEMOP_DEF(iemOp_test_AL_Ib)
5278{
5279 IEMOP_MNEMONIC(test_al_Ib, "test al,Ib");
5280 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
5281 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_AL_Ib, &g_iemAImpl_test);
5282}
5283
5284
5285/**
5286 * @opcode 0xa9
5287 */
5288FNIEMOP_DEF(iemOp_test_eAX_Iz)
5289{
5290 IEMOP_MNEMONIC(test_rAX_Iz, "test rAX,Iz");
5291 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
5292 return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rAX_Iz, &g_iemAImpl_test);
5293}
5294
5295
5296/** Macro used by iemOp_stosb_Yb_AL and iemOp_stoswd_Yv_eAX */
5297#define IEM_STOS_CASE(ValBits, AddrBits) \
5298 IEM_MC_BEGIN(0, 2); \
5299 IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
5300 IEM_MC_LOCAL(RTGCPTR, uAddr); \
5301 IEM_MC_FETCH_GREG_U##ValBits(uValue, X86_GREG_xAX); \
5302 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
5303 IEM_MC_STORE_MEM_U##ValBits(X86_SREG_ES, uAddr, uValue); \
5304 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
5305 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
5306 } IEM_MC_ELSE() { \
5307 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
5308 } IEM_MC_ENDIF(); \
5309 IEM_MC_ADVANCE_RIP(); \
5310 IEM_MC_END(); \
5311
5312/**
5313 * @opcode 0xaa
5314 */
5315FNIEMOP_DEF(iemOp_stosb_Yb_AL)
5316{
5317 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5318
5319 /*
5320 * Use the C implementation if a repeat prefix is encountered.
5321 */
5322 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
5323 {
5324 IEMOP_MNEMONIC(rep_stos_Yb_al, "rep stos Yb,al");
5325 switch (pVCpu->iem.s.enmEffAddrMode)
5326 {
5327 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_al_m16);
5328 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_al_m32);
5329 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_al_m64);
5330 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5331 }
5332 }
5333 IEMOP_MNEMONIC(stos_Yb_al, "stos Yb,al");
5334
5335 /*
5336 * Sharing case implementation with stos[wdq] below.
5337 */
5338 switch (pVCpu->iem.s.enmEffAddrMode)
5339 {
5340 case IEMMODE_16BIT: IEM_STOS_CASE(8, 16); break;
5341 case IEMMODE_32BIT: IEM_STOS_CASE(8, 32); break;
5342 case IEMMODE_64BIT: IEM_STOS_CASE(8, 64); break;
5343 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5344 }
5345 return VINF_SUCCESS;
5346}
5347
5348
5349/**
5350 * @opcode 0xab
5351 */
5352FNIEMOP_DEF(iemOp_stoswd_Yv_eAX)
5353{
5354 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5355
5356 /*
5357 * Use the C implementation if a repeat prefix is encountered.
5358 */
5359 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
5360 {
5361 IEMOP_MNEMONIC(rep_stos_Yv_rAX, "rep stos Yv,rAX");
5362 switch (pVCpu->iem.s.enmEffOpSize)
5363 {
5364 case IEMMODE_16BIT:
5365 switch (pVCpu->iem.s.enmEffAddrMode)
5366 {
5367 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_ax_m16);
5368 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_ax_m32);
5369 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_ax_m64);
5370 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5371 }
5372 break;
5373 case IEMMODE_32BIT:
5374 switch (pVCpu->iem.s.enmEffAddrMode)
5375 {
5376 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_eax_m16);
5377 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_eax_m32);
5378 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_eax_m64);
5379 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5380 }
5381 case IEMMODE_64BIT:
5382 switch (pVCpu->iem.s.enmEffAddrMode)
5383 {
5384 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_9);
5385 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_rax_m32);
5386 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_stos_rax_m64);
5387 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5388 }
5389 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5390 }
5391 }
5392 IEMOP_MNEMONIC(stos_Yv_rAX, "stos Yv,rAX");
5393
5394 /*
5395 * Annoying double switch here.
5396 * Using ugly macro for implementing the cases, sharing it with stosb.
5397 */
5398 switch (pVCpu->iem.s.enmEffOpSize)
5399 {
5400 case IEMMODE_16BIT:
5401 switch (pVCpu->iem.s.enmEffAddrMode)
5402 {
5403 case IEMMODE_16BIT: IEM_STOS_CASE(16, 16); break;
5404 case IEMMODE_32BIT: IEM_STOS_CASE(16, 32); break;
5405 case IEMMODE_64BIT: IEM_STOS_CASE(16, 64); break;
5406 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5407 }
5408 break;
5409
5410 case IEMMODE_32BIT:
5411 switch (pVCpu->iem.s.enmEffAddrMode)
5412 {
5413 case IEMMODE_16BIT: IEM_STOS_CASE(32, 16); break;
5414 case IEMMODE_32BIT: IEM_STOS_CASE(32, 32); break;
5415 case IEMMODE_64BIT: IEM_STOS_CASE(32, 64); break;
5416 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5417 }
5418 break;
5419
5420 case IEMMODE_64BIT:
5421 switch (pVCpu->iem.s.enmEffAddrMode)
5422 {
5423 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
5424 case IEMMODE_32BIT: IEM_STOS_CASE(64, 32); break;
5425 case IEMMODE_64BIT: IEM_STOS_CASE(64, 64); break;
5426 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5427 }
5428 break;
5429 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5430 }
5431 return VINF_SUCCESS;
5432}
5433
5434#undef IEM_STOS_CASE
5435
5436/** Macro used by iemOp_lodsb_AL_Xb and iemOp_lodswd_eAX_Xv */
5437#define IEM_LODS_CASE(ValBits, AddrBits) \
5438 IEM_MC_BEGIN(0, 2); \
5439 IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
5440 IEM_MC_LOCAL(RTGCPTR, uAddr); \
5441 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xSI); \
5442 IEM_MC_FETCH_MEM_U##ValBits(uValue, pVCpu->iem.s.iEffSeg, uAddr); \
5443 IEM_MC_STORE_GREG_U##ValBits(X86_GREG_xAX, uValue); \
5444 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
5445 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
5446 } IEM_MC_ELSE() { \
5447 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
5448 } IEM_MC_ENDIF(); \
5449 IEM_MC_ADVANCE_RIP(); \
5450 IEM_MC_END();
5451
5452/**
5453 * @opcode 0xac
5454 */
5455FNIEMOP_DEF(iemOp_lodsb_AL_Xb)
5456{
5457 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5458
5459 /*
5460 * Use the C implementation if a repeat prefix is encountered.
5461 */
5462 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
5463 {
5464 IEMOP_MNEMONIC(rep_lodsb_AL_Xb, "rep lodsb AL,Xb");
5465 switch (pVCpu->iem.s.enmEffAddrMode)
5466 {
5467 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m16, pVCpu->iem.s.iEffSeg);
5468 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m32, pVCpu->iem.s.iEffSeg);
5469 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m64, pVCpu->iem.s.iEffSeg);
5470 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5471 }
5472 }
5473 IEMOP_MNEMONIC(lodsb_AL_Xb, "lodsb AL,Xb");
5474
5475 /*
5476 * Sharing case implementation with stos[wdq] below.
5477 */
5478 switch (pVCpu->iem.s.enmEffAddrMode)
5479 {
5480 case IEMMODE_16BIT: IEM_LODS_CASE(8, 16); break;
5481 case IEMMODE_32BIT: IEM_LODS_CASE(8, 32); break;
5482 case IEMMODE_64BIT: IEM_LODS_CASE(8, 64); break;
5483 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5484 }
5485 return VINF_SUCCESS;
5486}
5487
5488
5489/**
5490 * @opcode 0xad
5491 */
5492FNIEMOP_DEF(iemOp_lodswd_eAX_Xv)
5493{
5494 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5495
5496 /*
5497 * Use the C implementation if a repeat prefix is encountered.
5498 */
5499 if (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
5500 {
5501 IEMOP_MNEMONIC(rep_lods_rAX_Xv, "rep lods rAX,Xv");
5502 switch (pVCpu->iem.s.enmEffOpSize)
5503 {
5504 case IEMMODE_16BIT:
5505 switch (pVCpu->iem.s.enmEffAddrMode)
5506 {
5507 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m16, pVCpu->iem.s.iEffSeg);
5508 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m32, pVCpu->iem.s.iEffSeg);
5509 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m64, pVCpu->iem.s.iEffSeg);
5510 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5511 }
5512 break;
5513 case IEMMODE_32BIT:
5514 switch (pVCpu->iem.s.enmEffAddrMode)
5515 {
5516 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m16, pVCpu->iem.s.iEffSeg);
5517 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m32, pVCpu->iem.s.iEffSeg);
5518 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m64, pVCpu->iem.s.iEffSeg);
5519 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5520 }
5521 case IEMMODE_64BIT:
5522 switch (pVCpu->iem.s.enmEffAddrMode)
5523 {
5524 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_7);
5525 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_rax_m32, pVCpu->iem.s.iEffSeg);
5526 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_rax_m64, pVCpu->iem.s.iEffSeg);
5527 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5528 }
5529 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5530 }
5531 }
5532 IEMOP_MNEMONIC(lods_rAX_Xv, "lods rAX,Xv");
5533
5534 /*
5535 * Annoying double switch here.
5536 * Using ugly macro for implementing the cases, sharing it with lodsb.
5537 */
5538 switch (pVCpu->iem.s.enmEffOpSize)
5539 {
5540 case IEMMODE_16BIT:
5541 switch (pVCpu->iem.s.enmEffAddrMode)
5542 {
5543 case IEMMODE_16BIT: IEM_LODS_CASE(16, 16); break;
5544 case IEMMODE_32BIT: IEM_LODS_CASE(16, 32); break;
5545 case IEMMODE_64BIT: IEM_LODS_CASE(16, 64); break;
5546 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5547 }
5548 break;
5549
5550 case IEMMODE_32BIT:
5551 switch (pVCpu->iem.s.enmEffAddrMode)
5552 {
5553 case IEMMODE_16BIT: IEM_LODS_CASE(32, 16); break;
5554 case IEMMODE_32BIT: IEM_LODS_CASE(32, 32); break;
5555 case IEMMODE_64BIT: IEM_LODS_CASE(32, 64); break;
5556 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5557 }
5558 break;
5559
5560 case IEMMODE_64BIT:
5561 switch (pVCpu->iem.s.enmEffAddrMode)
5562 {
5563 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
5564 case IEMMODE_32BIT: IEM_LODS_CASE(64, 32); break;
5565 case IEMMODE_64BIT: IEM_LODS_CASE(64, 64); break;
5566 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5567 }
5568 break;
5569 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5570 }
5571 return VINF_SUCCESS;
5572}
5573
5574#undef IEM_LODS_CASE
5575
5576/** Macro used by iemOp_scasb_AL_Xb and iemOp_scaswd_eAX_Xv */
5577#define IEM_SCAS_CASE(ValBits, AddrBits) \
5578 IEM_MC_BEGIN(3, 2); \
5579 IEM_MC_ARG(uint##ValBits##_t *, puRax, 0); \
5580 IEM_MC_ARG(uint##ValBits##_t, uValue, 1); \
5581 IEM_MC_ARG(uint32_t *, pEFlags, 2); \
5582 IEM_MC_LOCAL(RTGCPTR, uAddr); \
5583 \
5584 IEM_MC_FETCH_GREG_U##AddrBits##_ZX_U64(uAddr, X86_GREG_xDI); \
5585 IEM_MC_FETCH_MEM_U##ValBits(uValue, X86_SREG_ES, uAddr); \
5586 IEM_MC_REF_GREG_U##ValBits(puRax, X86_GREG_xAX); \
5587 IEM_MC_REF_EFLAGS(pEFlags); \
5588 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puRax, uValue, pEFlags); \
5589 \
5590 IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
5591 IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
5592 } IEM_MC_ELSE() { \
5593 IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
5594 } IEM_MC_ENDIF(); \
5595 IEM_MC_ADVANCE_RIP(); \
5596 IEM_MC_END();
5597
5598/**
5599 * @opcode 0xae
5600 */
5601FNIEMOP_DEF(iemOp_scasb_AL_Xb)
5602{
5603 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5604
5605 /*
5606 * Use the C implementation if a repeat prefix is encountered.
5607 */
5608 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
5609 {
5610 IEMOP_MNEMONIC(repe_scasb_AL_Xb, "repe scasb AL,Xb");
5611 switch (pVCpu->iem.s.enmEffAddrMode)
5612 {
5613 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m16);
5614 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m32);
5615 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m64);
5616 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5617 }
5618 }
5619 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
5620 {
5621 IEMOP_MNEMONIC(repone_scasb_AL_Xb, "repne scasb AL,Xb");
5622 switch (pVCpu->iem.s.enmEffAddrMode)
5623 {
5624 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m16);
5625 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m32);
5626 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m64);
5627 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5628 }
5629 }
5630 IEMOP_MNEMONIC(scasb_AL_Xb, "scasb AL,Xb");
5631
5632 /*
5633 * Sharing case implementation with stos[wdq] below.
5634 */
5635 switch (pVCpu->iem.s.enmEffAddrMode)
5636 {
5637 case IEMMODE_16BIT: IEM_SCAS_CASE(8, 16); break;
5638 case IEMMODE_32BIT: IEM_SCAS_CASE(8, 32); break;
5639 case IEMMODE_64BIT: IEM_SCAS_CASE(8, 64); break;
5640 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5641 }
5642 return VINF_SUCCESS;
5643}
5644
5645
5646/**
5647 * @opcode 0xaf
5648 */
5649FNIEMOP_DEF(iemOp_scaswd_eAX_Xv)
5650{
5651 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5652
5653 /*
5654 * Use the C implementation if a repeat prefix is encountered.
5655 */
5656 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPZ)
5657 {
5658 IEMOP_MNEMONIC(repe_scas_rAX_Xv, "repe scas rAX,Xv");
5659 switch (pVCpu->iem.s.enmEffOpSize)
5660 {
5661 case IEMMODE_16BIT:
5662 switch (pVCpu->iem.s.enmEffAddrMode)
5663 {
5664 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m16);
5665 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m32);
5666 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m64);
5667 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5668 }
5669 break;
5670 case IEMMODE_32BIT:
5671 switch (pVCpu->iem.s.enmEffAddrMode)
5672 {
5673 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m16);
5674 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m32);
5675 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m64);
5676 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5677 }
5678 case IEMMODE_64BIT:
5679 switch (pVCpu->iem.s.enmEffAddrMode)
5680 {
5681 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_6); /** @todo It's this wrong, we can do 16-bit addressing in 64-bit mode, but not 32-bit. right? */
5682 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m32);
5683 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m64);
5684 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5685 }
5686 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5687 }
5688 }
5689 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REPNZ)
5690 {
5691 IEMOP_MNEMONIC(repne_scas_rAX_Xv, "repne scas rAX,Xv");
5692 switch (pVCpu->iem.s.enmEffOpSize)
5693 {
5694 case IEMMODE_16BIT:
5695 switch (pVCpu->iem.s.enmEffAddrMode)
5696 {
5697 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_ax_m16);
5698 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_ax_m32);
5699 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_ax_m64);
5700 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5701 }
5702 break;
5703 case IEMMODE_32BIT:
5704 switch (pVCpu->iem.s.enmEffAddrMode)
5705 {
5706 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_eax_m16);
5707 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_eax_m32);
5708 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_eax_m64);
5709 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5710 }
5711 case IEMMODE_64BIT:
5712 switch (pVCpu->iem.s.enmEffAddrMode)
5713 {
5714 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_5);
5715 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_rax_m32);
5716 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_rax_m64);
5717 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5718 }
5719 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5720 }
5721 }
5722 IEMOP_MNEMONIC(scas_rAX_Xv, "scas rAX,Xv");
5723
5724 /*
5725 * Annoying double switch here.
5726 * Using ugly macro for implementing the cases, sharing it with scasb.
5727 */
5728 switch (pVCpu->iem.s.enmEffOpSize)
5729 {
5730 case IEMMODE_16BIT:
5731 switch (pVCpu->iem.s.enmEffAddrMode)
5732 {
5733 case IEMMODE_16BIT: IEM_SCAS_CASE(16, 16); break;
5734 case IEMMODE_32BIT: IEM_SCAS_CASE(16, 32); break;
5735 case IEMMODE_64BIT: IEM_SCAS_CASE(16, 64); break;
5736 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5737 }
5738 break;
5739
5740 case IEMMODE_32BIT:
5741 switch (pVCpu->iem.s.enmEffAddrMode)
5742 {
5743 case IEMMODE_16BIT: IEM_SCAS_CASE(32, 16); break;
5744 case IEMMODE_32BIT: IEM_SCAS_CASE(32, 32); break;
5745 case IEMMODE_64BIT: IEM_SCAS_CASE(32, 64); break;
5746 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5747 }
5748 break;
5749
5750 case IEMMODE_64BIT:
5751 switch (pVCpu->iem.s.enmEffAddrMode)
5752 {
5753 case IEMMODE_16BIT: AssertFailedReturn(VERR_IEM_IPE_1); /* cannot be encoded */ break;
5754 case IEMMODE_32BIT: IEM_SCAS_CASE(64, 32); break;
5755 case IEMMODE_64BIT: IEM_SCAS_CASE(64, 64); break;
5756 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5757 }
5758 break;
5759 IEM_NOT_REACHED_DEFAULT_CASE_RET();
5760 }
5761 return VINF_SUCCESS;
5762}
5763
5764#undef IEM_SCAS_CASE
5765
5766/**
5767 * Common 'mov r8, imm8' helper.
5768 */
5769FNIEMOP_DEF_1(iemOpCommonMov_r8_Ib, uint8_t, iReg)
5770{
5771 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
5772 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5773
5774 IEM_MC_BEGIN(0, 1);
5775 IEM_MC_LOCAL_CONST(uint8_t, u8Value,/*=*/ u8Imm);
5776 IEM_MC_STORE_GREG_U8(iReg, u8Value);
5777 IEM_MC_ADVANCE_RIP();
5778 IEM_MC_END();
5779
5780 return VINF_SUCCESS;
5781}
5782
5783
5784/**
5785 * @opcode 0xb0
5786 */
5787FNIEMOP_DEF(iemOp_mov_AL_Ib)
5788{
5789 IEMOP_MNEMONIC(mov_AL_Ib, "mov AL,Ib");
5790 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xAX | pVCpu->iem.s.uRexB);
5791}
5792
5793
5794/**
5795 * @opcode 0xb1
5796 */
5797FNIEMOP_DEF(iemOp_CL_Ib)
5798{
5799 IEMOP_MNEMONIC(mov_CL_Ib, "mov CL,Ib");
5800 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xCX | pVCpu->iem.s.uRexB);
5801}
5802
5803
5804/**
5805 * @opcode 0xb2
5806 */
5807FNIEMOP_DEF(iemOp_DL_Ib)
5808{
5809 IEMOP_MNEMONIC(mov_DL_Ib, "mov DL,Ib");
5810 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xDX | pVCpu->iem.s.uRexB);
5811}
5812
5813
5814/**
5815 * @opcode 0xb3
5816 */
5817FNIEMOP_DEF(iemOp_BL_Ib)
5818{
5819 IEMOP_MNEMONIC(mov_BL_Ib, "mov BL,Ib");
5820 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xBX | pVCpu->iem.s.uRexB);
5821}
5822
5823
5824/**
5825 * @opcode 0xb4
5826 */
5827FNIEMOP_DEF(iemOp_mov_AH_Ib)
5828{
5829 IEMOP_MNEMONIC(mov_AH_Ib, "mov AH,Ib");
5830 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xSP | pVCpu->iem.s.uRexB);
5831}
5832
5833
5834/**
5835 * @opcode 0xb5
5836 */
5837FNIEMOP_DEF(iemOp_CH_Ib)
5838{
5839 IEMOP_MNEMONIC(mov_CH_Ib, "mov CH,Ib");
5840 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xBP | pVCpu->iem.s.uRexB);
5841}
5842
5843
5844/**
5845 * @opcode 0xb6
5846 */
5847FNIEMOP_DEF(iemOp_DH_Ib)
5848{
5849 IEMOP_MNEMONIC(mov_DH_Ib, "mov DH,Ib");
5850 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xSI | pVCpu->iem.s.uRexB);
5851}
5852
5853
5854/**
5855 * @opcode 0xb7
5856 */
5857FNIEMOP_DEF(iemOp_BH_Ib)
5858{
5859 IEMOP_MNEMONIC(mov_BH_Ib, "mov BH,Ib");
5860 return FNIEMOP_CALL_1(iemOpCommonMov_r8_Ib, X86_GREG_xDI | pVCpu->iem.s.uRexB);
5861}
5862
5863
5864/**
5865 * Common 'mov regX,immX' helper.
5866 */
5867FNIEMOP_DEF_1(iemOpCommonMov_Rv_Iv, uint8_t, iReg)
5868{
5869 switch (pVCpu->iem.s.enmEffOpSize)
5870 {
5871 case IEMMODE_16BIT:
5872 {
5873 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
5874 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5875
5876 IEM_MC_BEGIN(0, 1);
5877 IEM_MC_LOCAL_CONST(uint16_t, u16Value,/*=*/ u16Imm);
5878 IEM_MC_STORE_GREG_U16(iReg, u16Value);
5879 IEM_MC_ADVANCE_RIP();
5880 IEM_MC_END();
5881 break;
5882 }
5883
5884 case IEMMODE_32BIT:
5885 {
5886 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
5887 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5888
5889 IEM_MC_BEGIN(0, 1);
5890 IEM_MC_LOCAL_CONST(uint32_t, u32Value,/*=*/ u32Imm);
5891 IEM_MC_STORE_GREG_U32(iReg, u32Value);
5892 IEM_MC_ADVANCE_RIP();
5893 IEM_MC_END();
5894 break;
5895 }
5896 case IEMMODE_64BIT:
5897 {
5898 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_U64(&u64Imm); /* 64-bit immediate! */
5899 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
5900
5901 IEM_MC_BEGIN(0, 1);
5902 IEM_MC_LOCAL_CONST(uint64_t, u64Value,/*=*/ u64Imm);
5903 IEM_MC_STORE_GREG_U64(iReg, u64Value);
5904 IEM_MC_ADVANCE_RIP();
5905 IEM_MC_END();
5906 break;
5907 }
5908 }
5909
5910 return VINF_SUCCESS;
5911}
5912
5913
5914/**
5915 * @opcode 0xb8
5916 */
5917FNIEMOP_DEF(iemOp_eAX_Iv)
5918{
5919 IEMOP_MNEMONIC(mov_rAX_IV, "mov rAX,IV");
5920 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xAX | pVCpu->iem.s.uRexB);
5921}
5922
5923
5924/**
5925 * @opcode 0xb9
5926 */
5927FNIEMOP_DEF(iemOp_eCX_Iv)
5928{
5929 IEMOP_MNEMONIC(mov_rCX_IV, "mov rCX,IV");
5930 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xCX | pVCpu->iem.s.uRexB);
5931}
5932
5933
5934/**
5935 * @opcode 0xba
5936 */
5937FNIEMOP_DEF(iemOp_eDX_Iv)
5938{
5939 IEMOP_MNEMONIC(mov_rDX_IV, "mov rDX,IV");
5940 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xDX | pVCpu->iem.s.uRexB);
5941}
5942
5943
5944/**
5945 * @opcode 0xbb
5946 */
5947FNIEMOP_DEF(iemOp_eBX_Iv)
5948{
5949 IEMOP_MNEMONIC(mov_rBX_IV, "mov rBX,IV");
5950 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xBX | pVCpu->iem.s.uRexB);
5951}
5952
5953
5954/**
5955 * @opcode 0xbc
5956 */
5957FNIEMOP_DEF(iemOp_eSP_Iv)
5958{
5959 IEMOP_MNEMONIC(mov_rSP_IV, "mov rSP,IV");
5960 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xSP | pVCpu->iem.s.uRexB);
5961}
5962
5963
5964/**
5965 * @opcode 0xbd
5966 */
5967FNIEMOP_DEF(iemOp_eBP_Iv)
5968{
5969 IEMOP_MNEMONIC(mov_rBP_IV, "mov rBP,IV");
5970 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xBP | pVCpu->iem.s.uRexB);
5971}
5972
5973
5974/**
5975 * @opcode 0xbe
5976 */
5977FNIEMOP_DEF(iemOp_eSI_Iv)
5978{
5979 IEMOP_MNEMONIC(mov_rSI_IV, "mov rSI,IV");
5980 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xSI | pVCpu->iem.s.uRexB);
5981}
5982
5983
5984/**
5985 * @opcode 0xbf
5986 */
5987FNIEMOP_DEF(iemOp_eDI_Iv)
5988{
5989 IEMOP_MNEMONIC(mov_rDI_IV, "mov rDI,IV");
5990 return FNIEMOP_CALL_1(iemOpCommonMov_Rv_Iv, X86_GREG_xDI | pVCpu->iem.s.uRexB);
5991}
5992
5993
5994/**
5995 * @opcode 0xc0
5996 */
5997FNIEMOP_DEF(iemOp_Grp2_Eb_Ib)
5998{
5999 IEMOP_HLP_MIN_186();
6000 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6001 PCIEMOPSHIFTSIZES pImpl;
6002 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
6003 {
6004 case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC(rol_Eb_Ib, "rol Eb,Ib"); break;
6005 case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC(ror_Eb_Ib, "ror Eb,Ib"); break;
6006 case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC(rcl_Eb_Ib, "rcl Eb,Ib"); break;
6007 case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC(rcr_Eb_Ib, "rcr Eb,Ib"); break;
6008 case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC(shl_Eb_Ib, "shl Eb,Ib"); break;
6009 case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC(shr_Eb_Ib, "shr Eb,Ib"); break;
6010 case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC(sar_Eb_Ib, "sar Eb,Ib"); break;
6011 case 6: return IEMOP_RAISE_INVALID_OPCODE();
6012 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
6013 }
6014 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
6015
6016 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6017 {
6018 /* register */
6019 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6020 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6021 IEM_MC_BEGIN(3, 0);
6022 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
6023 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
6024 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6025 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6026 IEM_MC_REF_EFLAGS(pEFlags);
6027 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
6028 IEM_MC_ADVANCE_RIP();
6029 IEM_MC_END();
6030 }
6031 else
6032 {
6033 /* memory */
6034 IEM_MC_BEGIN(3, 2);
6035 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
6036 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6037 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6038 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6039
6040 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6041 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6042 IEM_MC_ASSIGN(cShiftArg, cShift);
6043 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6044 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6045 IEM_MC_FETCH_EFLAGS(EFlags);
6046 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
6047
6048 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
6049 IEM_MC_COMMIT_EFLAGS(EFlags);
6050 IEM_MC_ADVANCE_RIP();
6051 IEM_MC_END();
6052 }
6053 return VINF_SUCCESS;
6054}
6055
6056
6057/**
6058 * @opcode 0xc1
6059 */
6060FNIEMOP_DEF(iemOp_Grp2_Ev_Ib)
6061{
6062 IEMOP_HLP_MIN_186();
6063 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6064 PCIEMOPSHIFTSIZES pImpl;
6065 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
6066 {
6067 case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC(rol_Ev_Ib, "rol Ev,Ib"); break;
6068 case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC(ror_Ev_Ib, "ror Ev,Ib"); break;
6069 case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC(rcl_Ev_Ib, "rcl Ev,Ib"); break;
6070 case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC(rcr_Ev_Ib, "rcr Ev,Ib"); break;
6071 case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC(shl_Ev_Ib, "shl Ev,Ib"); break;
6072 case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC(shr_Ev_Ib, "shr Ev,Ib"); break;
6073 case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC(sar_Ev_Ib, "sar Ev,Ib"); break;
6074 case 6: return IEMOP_RAISE_INVALID_OPCODE();
6075 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
6076 }
6077 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
6078
6079 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6080 {
6081 /* register */
6082 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6083 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6084 switch (pVCpu->iem.s.enmEffOpSize)
6085 {
6086 case IEMMODE_16BIT:
6087 IEM_MC_BEGIN(3, 0);
6088 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6089 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
6090 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6091 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6092 IEM_MC_REF_EFLAGS(pEFlags);
6093 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
6094 IEM_MC_ADVANCE_RIP();
6095 IEM_MC_END();
6096 return VINF_SUCCESS;
6097
6098 case IEMMODE_32BIT:
6099 IEM_MC_BEGIN(3, 0);
6100 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6101 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
6102 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6103 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6104 IEM_MC_REF_EFLAGS(pEFlags);
6105 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
6106 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
6107 IEM_MC_ADVANCE_RIP();
6108 IEM_MC_END();
6109 return VINF_SUCCESS;
6110
6111 case IEMMODE_64BIT:
6112 IEM_MC_BEGIN(3, 0);
6113 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6114 IEM_MC_ARG_CONST(uint8_t, cShiftArg, cShift, 1);
6115 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6116 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6117 IEM_MC_REF_EFLAGS(pEFlags);
6118 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
6119 IEM_MC_ADVANCE_RIP();
6120 IEM_MC_END();
6121 return VINF_SUCCESS;
6122
6123 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6124 }
6125 }
6126 else
6127 {
6128 /* memory */
6129 switch (pVCpu->iem.s.enmEffOpSize)
6130 {
6131 case IEMMODE_16BIT:
6132 IEM_MC_BEGIN(3, 2);
6133 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6134 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6135 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6136 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6137
6138 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6139 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6140 IEM_MC_ASSIGN(cShiftArg, cShift);
6141 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6142 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6143 IEM_MC_FETCH_EFLAGS(EFlags);
6144 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
6145
6146 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
6147 IEM_MC_COMMIT_EFLAGS(EFlags);
6148 IEM_MC_ADVANCE_RIP();
6149 IEM_MC_END();
6150 return VINF_SUCCESS;
6151
6152 case IEMMODE_32BIT:
6153 IEM_MC_BEGIN(3, 2);
6154 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6155 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6156 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6157 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6158
6159 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6160 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6161 IEM_MC_ASSIGN(cShiftArg, cShift);
6162 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6163 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6164 IEM_MC_FETCH_EFLAGS(EFlags);
6165 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
6166
6167 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
6168 IEM_MC_COMMIT_EFLAGS(EFlags);
6169 IEM_MC_ADVANCE_RIP();
6170 IEM_MC_END();
6171 return VINF_SUCCESS;
6172
6173 case IEMMODE_64BIT:
6174 IEM_MC_BEGIN(3, 2);
6175 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6176 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6177 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6178 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6179
6180 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6181 uint8_t cShift; IEM_OPCODE_GET_NEXT_U8(&cShift);
6182 IEM_MC_ASSIGN(cShiftArg, cShift);
6183 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6184 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6185 IEM_MC_FETCH_EFLAGS(EFlags);
6186 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
6187
6188 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
6189 IEM_MC_COMMIT_EFLAGS(EFlags);
6190 IEM_MC_ADVANCE_RIP();
6191 IEM_MC_END();
6192 return VINF_SUCCESS;
6193
6194 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6195 }
6196 }
6197}
6198
6199
6200/**
6201 * @opcode 0xc2
6202 */
6203FNIEMOP_DEF(iemOp_retn_Iw)
6204{
6205 IEMOP_MNEMONIC(retn_Iw, "retn Iw");
6206 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
6207 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6208 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6209 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retn, pVCpu->iem.s.enmEffOpSize, u16Imm);
6210}
6211
6212
6213/**
6214 * @opcode 0xc3
6215 */
6216FNIEMOP_DEF(iemOp_retn)
6217{
6218 IEMOP_MNEMONIC(retn, "retn");
6219 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6220 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6221 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retn, pVCpu->iem.s.enmEffOpSize, 0);
6222}
6223
6224
6225/**
6226 * @opcode 0xc4
6227 */
6228FNIEMOP_DEF(iemOp_les_Gv_Mp__vex3)
6229{
6230 /* The LDS instruction is invalid 64-bit mode. In legacy and
6231 compatability mode it is invalid with MOD=3.
6232 The use as a VEX prefix is made possible by assigning the inverted
6233 REX.R and REX.X to the two MOD bits, since the REX bits are ignored
6234 outside of 64-bit mode. VEX is not available in real or v86 mode. */
6235 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6236 if ( pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
6237 || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT) )
6238 {
6239 IEMOP_MNEMONIC(vex3_prefix, "vex3");
6240 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
6241 {
6242 /* Note! The real mode, v8086 mode and invalid prefix checks are done once
6243 the instruction is fully decoded. Even when XCR0=3 and CR4.OSXSAVE=0. */
6244 uint8_t bVex2; IEM_OPCODE_GET_NEXT_U8(&bVex2);
6245 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
6246 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
6247 if ((bVex2 & 0x80 /* VEX.W */) && pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
6248 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_SIZE_REX_W;
6249 pVCpu->iem.s.uRexReg = (~bRm >> (7 - 3)) & 0x8;
6250 pVCpu->iem.s.uRexIndex = (~bRm >> (6 - 3)) & 0x8;
6251 pVCpu->iem.s.uRexB = (~bRm >> (5 - 3)) & 0x8;
6252 pVCpu->iem.s.uVex3rdReg = (~bVex2 >> 3) & 0xf;
6253 pVCpu->iem.s.uVexLength = (bVex2 >> 2) & 1;
6254 pVCpu->iem.s.idxPrefix = bVex2 & 0x3;
6255
6256 switch (bRm & 0x1f)
6257 {
6258 case 1: /* 0x0f lead opcode byte. */
6259#ifdef IEM_WITH_VEX
6260 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
6261#else
6262 IEMOP_BITCH_ABOUT_STUB();
6263 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6264#endif
6265
6266 case 2: /* 0x0f 0x38 lead opcode bytes. */
6267#ifdef IEM_WITH_VEX
6268 return FNIEMOP_CALL(g_apfnVexMap2[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
6269#else
6270 IEMOP_BITCH_ABOUT_STUB();
6271 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6272#endif
6273
6274 case 3: /* 0x0f 0x3a lead opcode bytes. */
6275#ifdef IEM_WITH_VEX
6276 return FNIEMOP_CALL(g_apfnVexMap3[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
6277#else
6278 IEMOP_BITCH_ABOUT_STUB();
6279 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6280#endif
6281
6282 default:
6283 Log(("VEX3: Invalid vvvv value: %#x!\n", bRm & 0x1f));
6284 return IEMOP_RAISE_INVALID_OPCODE();
6285 }
6286 }
6287 Log(("VEX3: AVX support disabled!\n"));
6288 return IEMOP_RAISE_INVALID_OPCODE();
6289 }
6290
6291 IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");
6292 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);
6293}
6294
6295
6296/**
6297 * @opcode 0xc5
6298 */
6299FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex2)
6300{
6301 /* The LES instruction is invalid 64-bit mode. In legacy and
6302 compatability mode it is invalid with MOD=3.
6303 The use as a VEX prefix is made possible by assigning the inverted
6304 REX.R to the top MOD bit, and the top bit in the inverted register
6305 specifier to the bottom MOD bit, thereby effectively limiting 32-bit
6306 to accessing registers 0..7 in this VEX form. */
6307 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6308 if ( pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
6309 || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6310 {
6311 IEMOP_MNEMONIC(vex2_prefix, "vex2");
6312 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
6313 {
6314 /* Note! The real mode, v8086 mode and invalid prefix checks are done once
6315 the instruction is fully decoded. Even when XCR0=3 and CR4.OSXSAVE=0. */
6316 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
6317 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
6318 pVCpu->iem.s.uRexReg = (~bRm >> (7 - 3)) & 0x8;
6319 pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;
6320 pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;
6321 pVCpu->iem.s.idxPrefix = bRm & 0x3;
6322
6323#ifdef IEM_WITH_VEX
6324 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
6325#else
6326 IEMOP_BITCH_ABOUT_STUB();
6327 return VERR_IEM_INSTR_NOT_IMPLEMENTED;
6328#endif
6329 }
6330
6331 /** @todo does intel completely decode the sequence with SIB/disp before \#UD? */
6332 Log(("VEX2: AVX support disabled!\n"));
6333 return IEMOP_RAISE_INVALID_OPCODE();
6334 }
6335
6336 IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp");
6337 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm);
6338}
6339
6340
6341/**
6342 * @opcode 0xc6
6343 */
6344FNIEMOP_DEF(iemOp_Grp11_Eb_Ib)
6345{
6346 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6347 if ((bRm & X86_MODRM_REG_MASK) != (0 << X86_MODRM_REG_SHIFT)) /* only mov Eb,Ib in this group. */
6348 return IEMOP_RAISE_INVALID_OPCODE();
6349 IEMOP_MNEMONIC(mov_Eb_Ib, "mov Eb,Ib");
6350
6351 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6352 {
6353 /* register access */
6354 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
6355 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6356 IEM_MC_BEGIN(0, 0);
6357 IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u8Imm);
6358 IEM_MC_ADVANCE_RIP();
6359 IEM_MC_END();
6360 }
6361 else
6362 {
6363 /* memory access. */
6364 IEM_MC_BEGIN(0, 1);
6365 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6366 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
6367 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
6368 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6369 IEM_MC_STORE_MEM_U8(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u8Imm);
6370 IEM_MC_ADVANCE_RIP();
6371 IEM_MC_END();
6372 }
6373 return VINF_SUCCESS;
6374}
6375
6376
6377/**
6378 * @opcode 0xc7
6379 */
6380FNIEMOP_DEF(iemOp_Grp11_Ev_Iz)
6381{
6382 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6383 if ((bRm & X86_MODRM_REG_MASK) != (0 << X86_MODRM_REG_SHIFT)) /* only mov Eb,Ib in this group. */
6384 return IEMOP_RAISE_INVALID_OPCODE();
6385 IEMOP_MNEMONIC(mov_Ev_Iz, "mov Ev,Iz");
6386
6387 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6388 {
6389 /* register access */
6390 switch (pVCpu->iem.s.enmEffOpSize)
6391 {
6392 case IEMMODE_16BIT:
6393 IEM_MC_BEGIN(0, 0);
6394 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
6395 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6396 IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u16Imm);
6397 IEM_MC_ADVANCE_RIP();
6398 IEM_MC_END();
6399 return VINF_SUCCESS;
6400
6401 case IEMMODE_32BIT:
6402 IEM_MC_BEGIN(0, 0);
6403 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
6404 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6405 IEM_MC_STORE_GREG_U32((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u32Imm);
6406 IEM_MC_ADVANCE_RIP();
6407 IEM_MC_END();
6408 return VINF_SUCCESS;
6409
6410 case IEMMODE_64BIT:
6411 IEM_MC_BEGIN(0, 0);
6412 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
6413 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6414 IEM_MC_STORE_GREG_U64((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB, u64Imm);
6415 IEM_MC_ADVANCE_RIP();
6416 IEM_MC_END();
6417 return VINF_SUCCESS;
6418
6419 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6420 }
6421 }
6422 else
6423 {
6424 /* memory access. */
6425 switch (pVCpu->iem.s.enmEffOpSize)
6426 {
6427 case IEMMODE_16BIT:
6428 IEM_MC_BEGIN(0, 1);
6429 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6430 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
6431 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
6432 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6433 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Imm);
6434 IEM_MC_ADVANCE_RIP();
6435 IEM_MC_END();
6436 return VINF_SUCCESS;
6437
6438 case IEMMODE_32BIT:
6439 IEM_MC_BEGIN(0, 1);
6440 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6441 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
6442 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
6443 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6444 IEM_MC_STORE_MEM_U32(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u32Imm);
6445 IEM_MC_ADVANCE_RIP();
6446 IEM_MC_END();
6447 return VINF_SUCCESS;
6448
6449 case IEMMODE_64BIT:
6450 IEM_MC_BEGIN(0, 1);
6451 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6452 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
6453 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
6454 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6455 IEM_MC_STORE_MEM_U64(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u64Imm);
6456 IEM_MC_ADVANCE_RIP();
6457 IEM_MC_END();
6458 return VINF_SUCCESS;
6459
6460 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6461 }
6462 }
6463}
6464
6465
6466
6467
6468/**
6469 * @opcode 0xc8
6470 */
6471FNIEMOP_DEF(iemOp_enter_Iw_Ib)
6472{
6473 IEMOP_MNEMONIC(enter_Iw_Ib, "enter Iw,Ib");
6474 IEMOP_HLP_MIN_186();
6475 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6476 uint16_t cbFrame; IEM_OPCODE_GET_NEXT_U16(&cbFrame);
6477 uint8_t u8NestingLevel; IEM_OPCODE_GET_NEXT_U8(&u8NestingLevel);
6478 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6479 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_enter, pVCpu->iem.s.enmEffOpSize, cbFrame, u8NestingLevel);
6480}
6481
6482
6483/**
6484 * @opcode 0xc9
6485 */
6486FNIEMOP_DEF(iemOp_leave)
6487{
6488 IEMOP_MNEMONIC(leave, "leave");
6489 IEMOP_HLP_MIN_186();
6490 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6491 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6492 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_leave, pVCpu->iem.s.enmEffOpSize);
6493}
6494
6495
6496/**
6497 * @opcode 0xca
6498 */
6499FNIEMOP_DEF(iemOp_retf_Iw)
6500{
6501 IEMOP_MNEMONIC(retf_Iw, "retf Iw");
6502 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
6503 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6504 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6505 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retf, pVCpu->iem.s.enmEffOpSize, u16Imm);
6506}
6507
6508
6509/**
6510 * @opcode 0xcb
6511 */
6512FNIEMOP_DEF(iemOp_retf)
6513{
6514 IEMOP_MNEMONIC(retf, "retf");
6515 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6516 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
6517 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_retf, pVCpu->iem.s.enmEffOpSize, 0);
6518}
6519
6520
6521/**
6522 * @opcode 0xcc
6523 */
6524FNIEMOP_DEF(iemOp_int3)
6525{
6526 IEMOP_MNEMONIC(int3, "int3");
6527 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6528 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_int, X86_XCPT_BP, IEMINT_INT3);
6529}
6530
6531
6532/**
6533 * @opcode 0xcd
6534 */
6535FNIEMOP_DEF(iemOp_int_Ib)
6536{
6537 IEMOP_MNEMONIC(int_Ib, "int Ib");
6538 uint8_t u8Int; IEM_OPCODE_GET_NEXT_U8(&u8Int);
6539 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6540 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_int, u8Int, IEMINT_INTN);
6541}
6542
6543
6544/**
6545 * @opcode 0xce
6546 */
6547FNIEMOP_DEF(iemOp_into)
6548{
6549 IEMOP_MNEMONIC(into, "into");
6550 IEMOP_HLP_NO_64BIT();
6551
6552 IEM_MC_BEGIN(2, 0);
6553 IEM_MC_ARG_CONST(uint8_t, u8Int, /*=*/ X86_XCPT_OF, 0);
6554 IEM_MC_ARG_CONST(IEMINT, enmInt, /*=*/ IEMINT_INTO, 1);
6555 IEM_MC_CALL_CIMPL_2(iemCImpl_int, u8Int, enmInt);
6556 IEM_MC_END();
6557 return VINF_SUCCESS;
6558}
6559
6560
6561/**
6562 * @opcode 0xcf
6563 */
6564FNIEMOP_DEF(iemOp_iret)
6565{
6566 IEMOP_MNEMONIC(iret, "iret");
6567 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6568 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_iret, pVCpu->iem.s.enmEffOpSize);
6569}
6570
6571
6572/**
6573 * @opcode 0xd0
6574 */
6575FNIEMOP_DEF(iemOp_Grp2_Eb_1)
6576{
6577 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6578 PCIEMOPSHIFTSIZES pImpl;
6579 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
6580 {
6581 case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC(rol_Eb_1, "rol Eb,1"); break;
6582 case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC(ror_Eb_1, "ror Eb,1"); break;
6583 case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC(rcl_Eb_1, "rcl Eb,1"); break;
6584 case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC(rcr_Eb_1, "rcr Eb,1"); break;
6585 case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC(shl_Eb_1, "shl Eb,1"); break;
6586 case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC(shr_Eb_1, "shr Eb,1"); break;
6587 case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC(sar_Eb_1, "sar Eb,1"); break;
6588 case 6: return IEMOP_RAISE_INVALID_OPCODE();
6589 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
6590 }
6591 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
6592
6593 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6594 {
6595 /* register */
6596 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6597 IEM_MC_BEGIN(3, 0);
6598 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
6599 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=*/1, 1);
6600 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6601 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6602 IEM_MC_REF_EFLAGS(pEFlags);
6603 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
6604 IEM_MC_ADVANCE_RIP();
6605 IEM_MC_END();
6606 }
6607 else
6608 {
6609 /* memory */
6610 IEM_MC_BEGIN(3, 2);
6611 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
6612 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=*/1, 1);
6613 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6614 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6615
6616 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6617 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6618 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6619 IEM_MC_FETCH_EFLAGS(EFlags);
6620 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
6621
6622 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
6623 IEM_MC_COMMIT_EFLAGS(EFlags);
6624 IEM_MC_ADVANCE_RIP();
6625 IEM_MC_END();
6626 }
6627 return VINF_SUCCESS;
6628}
6629
6630
6631
6632/**
6633 * @opcode 0xd1
6634 */
6635FNIEMOP_DEF(iemOp_Grp2_Ev_1)
6636{
6637 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6638 PCIEMOPSHIFTSIZES pImpl;
6639 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
6640 {
6641 case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC(rol_Ev_1, "rol Ev,1"); break;
6642 case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC(ror_Ev_1, "ror Ev,1"); break;
6643 case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC(rcl_Ev_1, "rcl Ev,1"); break;
6644 case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC(rcr_Ev_1, "rcr Ev,1"); break;
6645 case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC(shl_Ev_1, "shl Ev,1"); break;
6646 case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC(shr_Ev_1, "shr Ev,1"); break;
6647 case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC(sar_Ev_1, "sar Ev,1"); break;
6648 case 6: return IEMOP_RAISE_INVALID_OPCODE();
6649 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
6650 }
6651 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
6652
6653 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6654 {
6655 /* register */
6656 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6657 switch (pVCpu->iem.s.enmEffOpSize)
6658 {
6659 case IEMMODE_16BIT:
6660 IEM_MC_BEGIN(3, 0);
6661 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6662 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
6663 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6664 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6665 IEM_MC_REF_EFLAGS(pEFlags);
6666 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
6667 IEM_MC_ADVANCE_RIP();
6668 IEM_MC_END();
6669 return VINF_SUCCESS;
6670
6671 case IEMMODE_32BIT:
6672 IEM_MC_BEGIN(3, 0);
6673 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6674 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
6675 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6676 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6677 IEM_MC_REF_EFLAGS(pEFlags);
6678 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
6679 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
6680 IEM_MC_ADVANCE_RIP();
6681 IEM_MC_END();
6682 return VINF_SUCCESS;
6683
6684 case IEMMODE_64BIT:
6685 IEM_MC_BEGIN(3, 0);
6686 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6687 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
6688 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6689 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6690 IEM_MC_REF_EFLAGS(pEFlags);
6691 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
6692 IEM_MC_ADVANCE_RIP();
6693 IEM_MC_END();
6694 return VINF_SUCCESS;
6695
6696 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6697 }
6698 }
6699 else
6700 {
6701 /* memory */
6702 switch (pVCpu->iem.s.enmEffOpSize)
6703 {
6704 case IEMMODE_16BIT:
6705 IEM_MC_BEGIN(3, 2);
6706 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6707 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
6708 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6709 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6710
6711 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6712 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6713 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6714 IEM_MC_FETCH_EFLAGS(EFlags);
6715 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
6716
6717 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
6718 IEM_MC_COMMIT_EFLAGS(EFlags);
6719 IEM_MC_ADVANCE_RIP();
6720 IEM_MC_END();
6721 return VINF_SUCCESS;
6722
6723 case IEMMODE_32BIT:
6724 IEM_MC_BEGIN(3, 2);
6725 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6726 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
6727 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6728 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6729
6730 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6731 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6732 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6733 IEM_MC_FETCH_EFLAGS(EFlags);
6734 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
6735
6736 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
6737 IEM_MC_COMMIT_EFLAGS(EFlags);
6738 IEM_MC_ADVANCE_RIP();
6739 IEM_MC_END();
6740 return VINF_SUCCESS;
6741
6742 case IEMMODE_64BIT:
6743 IEM_MC_BEGIN(3, 2);
6744 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6745 IEM_MC_ARG_CONST(uint8_t, cShiftArg,/*=1*/1, 1);
6746 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6747 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6748
6749 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6750 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6751 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6752 IEM_MC_FETCH_EFLAGS(EFlags);
6753 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
6754
6755 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
6756 IEM_MC_COMMIT_EFLAGS(EFlags);
6757 IEM_MC_ADVANCE_RIP();
6758 IEM_MC_END();
6759 return VINF_SUCCESS;
6760
6761 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6762 }
6763 }
6764}
6765
6766
6767/**
6768 * @opcode 0xd2
6769 */
6770FNIEMOP_DEF(iemOp_Grp2_Eb_CL)
6771{
6772 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6773 PCIEMOPSHIFTSIZES pImpl;
6774 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
6775 {
6776 case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC(rol_Eb_CL, "rol Eb,CL"); break;
6777 case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC(ror_Eb_CL, "ror Eb,CL"); break;
6778 case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC(rcl_Eb_CL, "rcl Eb,CL"); break;
6779 case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC(rcr_Eb_CL, "rcr Eb,CL"); break;
6780 case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC(shl_Eb_CL, "shl Eb,CL"); break;
6781 case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC(shr_Eb_CL, "shr Eb,CL"); break;
6782 case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC(sar_Eb_CL, "sar Eb,CL"); break;
6783 case 6: return IEMOP_RAISE_INVALID_OPCODE();
6784 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc, grr. */
6785 }
6786 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
6787
6788 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6789 {
6790 /* register */
6791 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6792 IEM_MC_BEGIN(3, 0);
6793 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
6794 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6795 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6796 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6797 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6798 IEM_MC_REF_EFLAGS(pEFlags);
6799 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
6800 IEM_MC_ADVANCE_RIP();
6801 IEM_MC_END();
6802 }
6803 else
6804 {
6805 /* memory */
6806 IEM_MC_BEGIN(3, 2);
6807 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
6808 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6809 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6810 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6811
6812 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6813 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6814 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6815 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6816 IEM_MC_FETCH_EFLAGS(EFlags);
6817 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU8, pu8Dst, cShiftArg, pEFlags);
6818
6819 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
6820 IEM_MC_COMMIT_EFLAGS(EFlags);
6821 IEM_MC_ADVANCE_RIP();
6822 IEM_MC_END();
6823 }
6824 return VINF_SUCCESS;
6825}
6826
6827
6828/**
6829 * @opcode 0xd3
6830 */
6831FNIEMOP_DEF(iemOp_Grp2_Ev_CL)
6832{
6833 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
6834 PCIEMOPSHIFTSIZES pImpl;
6835 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
6836 {
6837 case 0: pImpl = &g_iemAImpl_rol; IEMOP_MNEMONIC(rol_Ev_CL, "rol Ev,CL"); break;
6838 case 1: pImpl = &g_iemAImpl_ror; IEMOP_MNEMONIC(ror_Ev_CL, "ror Ev,CL"); break;
6839 case 2: pImpl = &g_iemAImpl_rcl; IEMOP_MNEMONIC(rcl_Ev_CL, "rcl Ev,CL"); break;
6840 case 3: pImpl = &g_iemAImpl_rcr; IEMOP_MNEMONIC(rcr_Ev_CL, "rcr Ev,CL"); break;
6841 case 4: pImpl = &g_iemAImpl_shl; IEMOP_MNEMONIC(shl_Ev_CL, "shl Ev,CL"); break;
6842 case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC(shr_Ev_CL, "shr Ev,CL"); break;
6843 case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC(sar_Ev_CL, "sar Ev,CL"); break;
6844 case 6: return IEMOP_RAISE_INVALID_OPCODE();
6845 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
6846 }
6847 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_AF);
6848
6849 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
6850 {
6851 /* register */
6852 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6853 switch (pVCpu->iem.s.enmEffOpSize)
6854 {
6855 case IEMMODE_16BIT:
6856 IEM_MC_BEGIN(3, 0);
6857 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6858 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6859 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6860 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6861 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6862 IEM_MC_REF_EFLAGS(pEFlags);
6863 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
6864 IEM_MC_ADVANCE_RIP();
6865 IEM_MC_END();
6866 return VINF_SUCCESS;
6867
6868 case IEMMODE_32BIT:
6869 IEM_MC_BEGIN(3, 0);
6870 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6871 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6872 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6873 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6874 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6875 IEM_MC_REF_EFLAGS(pEFlags);
6876 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
6877 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
6878 IEM_MC_ADVANCE_RIP();
6879 IEM_MC_END();
6880 return VINF_SUCCESS;
6881
6882 case IEMMODE_64BIT:
6883 IEM_MC_BEGIN(3, 0);
6884 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6885 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6886 IEM_MC_ARG(uint32_t *, pEFlags, 2);
6887 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
6888 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6889 IEM_MC_REF_EFLAGS(pEFlags);
6890 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
6891 IEM_MC_ADVANCE_RIP();
6892 IEM_MC_END();
6893 return VINF_SUCCESS;
6894
6895 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6896 }
6897 }
6898 else
6899 {
6900 /* memory */
6901 switch (pVCpu->iem.s.enmEffOpSize)
6902 {
6903 case IEMMODE_16BIT:
6904 IEM_MC_BEGIN(3, 2);
6905 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
6906 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6907 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6908 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6909
6910 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6911 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6912 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6913 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6914 IEM_MC_FETCH_EFLAGS(EFlags);
6915 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU16, pu16Dst, cShiftArg, pEFlags);
6916
6917 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
6918 IEM_MC_COMMIT_EFLAGS(EFlags);
6919 IEM_MC_ADVANCE_RIP();
6920 IEM_MC_END();
6921 return VINF_SUCCESS;
6922
6923 case IEMMODE_32BIT:
6924 IEM_MC_BEGIN(3, 2);
6925 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
6926 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6927 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6928 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6929
6930 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6931 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6932 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6933 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6934 IEM_MC_FETCH_EFLAGS(EFlags);
6935 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, cShiftArg, pEFlags);
6936
6937 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
6938 IEM_MC_COMMIT_EFLAGS(EFlags);
6939 IEM_MC_ADVANCE_RIP();
6940 IEM_MC_END();
6941 return VINF_SUCCESS;
6942
6943 case IEMMODE_64BIT:
6944 IEM_MC_BEGIN(3, 2);
6945 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
6946 IEM_MC_ARG(uint8_t, cShiftArg, 1);
6947 IEM_MC_ARG_LOCAL_EFLAGS(pEFlags, EFlags, 2);
6948 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
6949
6950 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
6951 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6952 IEM_MC_FETCH_GREG_U8(cShiftArg, X86_GREG_xCX);
6953 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
6954 IEM_MC_FETCH_EFLAGS(EFlags);
6955 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU64, pu64Dst, cShiftArg, pEFlags);
6956
6957 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
6958 IEM_MC_COMMIT_EFLAGS(EFlags);
6959 IEM_MC_ADVANCE_RIP();
6960 IEM_MC_END();
6961 return VINF_SUCCESS;
6962
6963 IEM_NOT_REACHED_DEFAULT_CASE_RET();
6964 }
6965 }
6966}
6967
6968/**
6969 * @opcode 0xd4
6970 */
6971FNIEMOP_DEF(iemOp_aam_Ib)
6972{
6973 IEMOP_MNEMONIC(aam_Ib, "aam Ib");
6974 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
6975 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6976 IEMOP_HLP_NO_64BIT();
6977 if (!bImm)
6978 return IEMOP_RAISE_DIVIDE_ERROR();
6979 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_aam, bImm);
6980}
6981
6982
6983/**
6984 * @opcode 0xd5
6985 */
6986FNIEMOP_DEF(iemOp_aad_Ib)
6987{
6988 IEMOP_MNEMONIC(aad_Ib, "aad Ib");
6989 uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
6990 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
6991 IEMOP_HLP_NO_64BIT();
6992 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_aad, bImm);
6993}
6994
6995
6996/**
6997 * @opcode 0xd6
6998 */
6999FNIEMOP_DEF(iemOp_salc)
7000{
7001 IEMOP_MNEMONIC(salc, "salc");
7002 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7003 IEMOP_HLP_NO_64BIT();
7004
7005 IEM_MC_BEGIN(0, 0);
7006 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
7007 IEM_MC_STORE_GREG_U8_CONST(X86_GREG_xAX, 0xff);
7008 } IEM_MC_ELSE() {
7009 IEM_MC_STORE_GREG_U8_CONST(X86_GREG_xAX, 0x00);
7010 } IEM_MC_ENDIF();
7011 IEM_MC_ADVANCE_RIP();
7012 IEM_MC_END();
7013 return VINF_SUCCESS;
7014}
7015
7016
7017/**
7018 * @opcode 0xd7
7019 */
7020FNIEMOP_DEF(iemOp_xlat)
7021{
7022 IEMOP_MNEMONIC(xlat, "xlat");
7023 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7024 switch (pVCpu->iem.s.enmEffAddrMode)
7025 {
7026 case IEMMODE_16BIT:
7027 IEM_MC_BEGIN(2, 0);
7028 IEM_MC_LOCAL(uint8_t, u8Tmp);
7029 IEM_MC_LOCAL(uint16_t, u16Addr);
7030 IEM_MC_FETCH_GREG_U8_ZX_U16(u16Addr, X86_GREG_xAX);
7031 IEM_MC_ADD_GREG_U16_TO_LOCAL(u16Addr, X86_GREG_xBX);
7032 IEM_MC_FETCH_MEM16_U8(u8Tmp, pVCpu->iem.s.iEffSeg, u16Addr);
7033 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
7034 IEM_MC_ADVANCE_RIP();
7035 IEM_MC_END();
7036 return VINF_SUCCESS;
7037
7038 case IEMMODE_32BIT:
7039 IEM_MC_BEGIN(2, 0);
7040 IEM_MC_LOCAL(uint8_t, u8Tmp);
7041 IEM_MC_LOCAL(uint32_t, u32Addr);
7042 IEM_MC_FETCH_GREG_U8_ZX_U32(u32Addr, X86_GREG_xAX);
7043 IEM_MC_ADD_GREG_U32_TO_LOCAL(u32Addr, X86_GREG_xBX);
7044 IEM_MC_FETCH_MEM32_U8(u8Tmp, pVCpu->iem.s.iEffSeg, u32Addr);
7045 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
7046 IEM_MC_ADVANCE_RIP();
7047 IEM_MC_END();
7048 return VINF_SUCCESS;
7049
7050 case IEMMODE_64BIT:
7051 IEM_MC_BEGIN(2, 0);
7052 IEM_MC_LOCAL(uint8_t, u8Tmp);
7053 IEM_MC_LOCAL(uint64_t, u64Addr);
7054 IEM_MC_FETCH_GREG_U8_ZX_U64(u64Addr, X86_GREG_xAX);
7055 IEM_MC_ADD_GREG_U64_TO_LOCAL(u64Addr, X86_GREG_xBX);
7056 IEM_MC_FETCH_MEM_U8(u8Tmp, pVCpu->iem.s.iEffSeg, u64Addr);
7057 IEM_MC_STORE_GREG_U8(X86_GREG_xAX, u8Tmp);
7058 IEM_MC_ADVANCE_RIP();
7059 IEM_MC_END();
7060 return VINF_SUCCESS;
7061
7062 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7063 }
7064}
7065
7066
7067/**
7068 * Common worker for FPU instructions working on ST0 and STn, and storing the
7069 * result in ST0.
7070 *
7071 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7072 */
7073FNIEMOP_DEF_2(iemOpHlpFpu_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
7074{
7075 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7076
7077 IEM_MC_BEGIN(3, 1);
7078 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7079 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
7080 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7081 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
7082
7083 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7084 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7085 IEM_MC_PREPARE_FPU_USAGE();
7086 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK)
7087 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr80Value2);
7088 IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
7089 IEM_MC_ELSE()
7090 IEM_MC_FPU_STACK_UNDERFLOW(0);
7091 IEM_MC_ENDIF();
7092 IEM_MC_ADVANCE_RIP();
7093
7094 IEM_MC_END();
7095 return VINF_SUCCESS;
7096}
7097
7098
7099/**
7100 * Common worker for FPU instructions working on ST0 and STn, and only affecting
7101 * flags.
7102 *
7103 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7104 */
7105FNIEMOP_DEF_2(iemOpHlpFpuNoStore_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
7106{
7107 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7108
7109 IEM_MC_BEGIN(3, 1);
7110 IEM_MC_LOCAL(uint16_t, u16Fsw);
7111 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7112 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7113 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
7114
7115 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7116 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7117 IEM_MC_PREPARE_FPU_USAGE();
7118 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK)
7119 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16Fsw, pr80Value1, pr80Value2);
7120 IEM_MC_UPDATE_FSW(u16Fsw);
7121 IEM_MC_ELSE()
7122 IEM_MC_FPU_STACK_UNDERFLOW(UINT8_MAX);
7123 IEM_MC_ENDIF();
7124 IEM_MC_ADVANCE_RIP();
7125
7126 IEM_MC_END();
7127 return VINF_SUCCESS;
7128}
7129
7130
7131/**
7132 * Common worker for FPU instructions working on ST0 and STn, only affecting
7133 * flags, and popping when done.
7134 *
7135 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7136 */
7137FNIEMOP_DEF_2(iemOpHlpFpuNoStore_st0_stN_pop, uint8_t, bRm, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
7138{
7139 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7140
7141 IEM_MC_BEGIN(3, 1);
7142 IEM_MC_LOCAL(uint16_t, u16Fsw);
7143 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7144 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7145 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
7146
7147 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7148 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7149 IEM_MC_PREPARE_FPU_USAGE();
7150 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK)
7151 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16Fsw, pr80Value1, pr80Value2);
7152 IEM_MC_UPDATE_FSW_THEN_POP(u16Fsw);
7153 IEM_MC_ELSE()
7154 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(UINT8_MAX);
7155 IEM_MC_ENDIF();
7156 IEM_MC_ADVANCE_RIP();
7157
7158 IEM_MC_END();
7159 return VINF_SUCCESS;
7160}
7161
7162
7163/** Opcode 0xd8 11/0. */
7164FNIEMOP_DEF_1(iemOp_fadd_stN, uint8_t, bRm)
7165{
7166 IEMOP_MNEMONIC(fadd_st0_stN, "fadd st0,stN");
7167 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fadd_r80_by_r80);
7168}
7169
7170
7171/** Opcode 0xd8 11/1. */
7172FNIEMOP_DEF_1(iemOp_fmul_stN, uint8_t, bRm)
7173{
7174 IEMOP_MNEMONIC(fmul_st0_stN, "fmul st0,stN");
7175 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fmul_r80_by_r80);
7176}
7177
7178
7179/** Opcode 0xd8 11/2. */
7180FNIEMOP_DEF_1(iemOp_fcom_stN, uint8_t, bRm)
7181{
7182 IEMOP_MNEMONIC(fcom_st0_stN, "fcom st0,stN");
7183 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN, bRm, iemAImpl_fcom_r80_by_r80);
7184}
7185
7186
7187/** Opcode 0xd8 11/3. */
7188FNIEMOP_DEF_1(iemOp_fcomp_stN, uint8_t, bRm)
7189{
7190 IEMOP_MNEMONIC(fcomp_st0_stN, "fcomp st0,stN");
7191 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN_pop, bRm, iemAImpl_fcom_r80_by_r80);
7192}
7193
7194
7195/** Opcode 0xd8 11/4. */
7196FNIEMOP_DEF_1(iemOp_fsub_stN, uint8_t, bRm)
7197{
7198 IEMOP_MNEMONIC(fsub_st0_stN, "fsub st0,stN");
7199 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fsub_r80_by_r80);
7200}
7201
7202
7203/** Opcode 0xd8 11/5. */
7204FNIEMOP_DEF_1(iemOp_fsubr_stN, uint8_t, bRm)
7205{
7206 IEMOP_MNEMONIC(fsubr_st0_stN, "fsubr st0,stN");
7207 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fsubr_r80_by_r80);
7208}
7209
7210
7211/** Opcode 0xd8 11/6. */
7212FNIEMOP_DEF_1(iemOp_fdiv_stN, uint8_t, bRm)
7213{
7214 IEMOP_MNEMONIC(fdiv_st0_stN, "fdiv st0,stN");
7215 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fdiv_r80_by_r80);
7216}
7217
7218
7219/** Opcode 0xd8 11/7. */
7220FNIEMOP_DEF_1(iemOp_fdivr_stN, uint8_t, bRm)
7221{
7222 IEMOP_MNEMONIC(fdivr_st0_stN, "fdivr st0,stN");
7223 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fdivr_r80_by_r80);
7224}
7225
7226
7227/**
7228 * Common worker for FPU instructions working on ST0 and an m32r, and storing
7229 * the result in ST0.
7230 *
7231 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7232 */
7233FNIEMOP_DEF_2(iemOpHlpFpu_st0_m32r, uint8_t, bRm, PFNIEMAIMPLFPUR32, pfnAImpl)
7234{
7235 IEM_MC_BEGIN(3, 3);
7236 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
7237 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7238 IEM_MC_LOCAL(RTFLOAT32U, r32Val2);
7239 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
7240 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7241 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val2, r32Val2, 2);
7242
7243 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
7244 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7245
7246 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7247 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7248 IEM_MC_FETCH_MEM_R32(r32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7249
7250 IEM_MC_PREPARE_FPU_USAGE();
7251 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
7252 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr32Val2);
7253 IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
7254 IEM_MC_ELSE()
7255 IEM_MC_FPU_STACK_UNDERFLOW(0);
7256 IEM_MC_ENDIF();
7257 IEM_MC_ADVANCE_RIP();
7258
7259 IEM_MC_END();
7260 return VINF_SUCCESS;
7261}
7262
7263
7264/** Opcode 0xd8 !11/0. */
7265FNIEMOP_DEF_1(iemOp_fadd_m32r, uint8_t, bRm)
7266{
7267 IEMOP_MNEMONIC(fadd_st0_m32r, "fadd st0,m32r");
7268 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fadd_r80_by_r32);
7269}
7270
7271
7272/** Opcode 0xd8 !11/1. */
7273FNIEMOP_DEF_1(iemOp_fmul_m32r, uint8_t, bRm)
7274{
7275 IEMOP_MNEMONIC(fmul_st0_m32r, "fmul st0,m32r");
7276 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fmul_r80_by_r32);
7277}
7278
7279
7280/** Opcode 0xd8 !11/2. */
7281FNIEMOP_DEF_1(iemOp_fcom_m32r, uint8_t, bRm)
7282{
7283 IEMOP_MNEMONIC(fcom_st0_m32r, "fcom st0,m32r");
7284
7285 IEM_MC_BEGIN(3, 3);
7286 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
7287 IEM_MC_LOCAL(uint16_t, u16Fsw);
7288 IEM_MC_LOCAL(RTFLOAT32U, r32Val2);
7289 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7290 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7291 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val2, r32Val2, 2);
7292
7293 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
7294 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7295
7296 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7297 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7298 IEM_MC_FETCH_MEM_R32(r32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7299
7300 IEM_MC_PREPARE_FPU_USAGE();
7301 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
7302 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r32, pu16Fsw, pr80Value1, pr32Val2);
7303 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7304 IEM_MC_ELSE()
7305 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7306 IEM_MC_ENDIF();
7307 IEM_MC_ADVANCE_RIP();
7308
7309 IEM_MC_END();
7310 return VINF_SUCCESS;
7311}
7312
7313
7314/** Opcode 0xd8 !11/3. */
7315FNIEMOP_DEF_1(iemOp_fcomp_m32r, uint8_t, bRm)
7316{
7317 IEMOP_MNEMONIC(fcomp_st0_m32r, "fcomp st0,m32r");
7318
7319 IEM_MC_BEGIN(3, 3);
7320 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
7321 IEM_MC_LOCAL(uint16_t, u16Fsw);
7322 IEM_MC_LOCAL(RTFLOAT32U, r32Val2);
7323 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7324 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7325 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val2, r32Val2, 2);
7326
7327 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
7328 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7329
7330 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7331 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7332 IEM_MC_FETCH_MEM_R32(r32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7333
7334 IEM_MC_PREPARE_FPU_USAGE();
7335 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
7336 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r32, pu16Fsw, pr80Value1, pr32Val2);
7337 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7338 IEM_MC_ELSE()
7339 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7340 IEM_MC_ENDIF();
7341 IEM_MC_ADVANCE_RIP();
7342
7343 IEM_MC_END();
7344 return VINF_SUCCESS;
7345}
7346
7347
7348/** Opcode 0xd8 !11/4. */
7349FNIEMOP_DEF_1(iemOp_fsub_m32r, uint8_t, bRm)
7350{
7351 IEMOP_MNEMONIC(fsub_st0_m32r, "fsub st0,m32r");
7352 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fsub_r80_by_r32);
7353}
7354
7355
7356/** Opcode 0xd8 !11/5. */
7357FNIEMOP_DEF_1(iemOp_fsubr_m32r, uint8_t, bRm)
7358{
7359 IEMOP_MNEMONIC(fsubr_st0_m32r, "fsubr st0,m32r");
7360 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fsubr_r80_by_r32);
7361}
7362
7363
7364/** Opcode 0xd8 !11/6. */
7365FNIEMOP_DEF_1(iemOp_fdiv_m32r, uint8_t, bRm)
7366{
7367 IEMOP_MNEMONIC(fdiv_st0_m32r, "fdiv st0,m32r");
7368 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fdiv_r80_by_r32);
7369}
7370
7371
7372/** Opcode 0xd8 !11/7. */
7373FNIEMOP_DEF_1(iemOp_fdivr_m32r, uint8_t, bRm)
7374{
7375 IEMOP_MNEMONIC(fdivr_st0_m32r, "fdivr st0,m32r");
7376 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fdivr_r80_by_r32);
7377}
7378
7379
7380/**
7381 * @opcode 0xd8
7382 */
7383FNIEMOP_DEF(iemOp_EscF0)
7384{
7385 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
7386 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xd8 & 0x7);
7387
7388 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
7389 {
7390 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
7391 {
7392 case 0: return FNIEMOP_CALL_1(iemOp_fadd_stN, bRm);
7393 case 1: return FNIEMOP_CALL_1(iemOp_fmul_stN, bRm);
7394 case 2: return FNIEMOP_CALL_1(iemOp_fcom_stN, bRm);
7395 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_stN, bRm);
7396 case 4: return FNIEMOP_CALL_1(iemOp_fsub_stN, bRm);
7397 case 5: return FNIEMOP_CALL_1(iemOp_fsubr_stN, bRm);
7398 case 6: return FNIEMOP_CALL_1(iemOp_fdiv_stN, bRm);
7399 case 7: return FNIEMOP_CALL_1(iemOp_fdivr_stN, bRm);
7400 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7401 }
7402 }
7403 else
7404 {
7405 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
7406 {
7407 case 0: return FNIEMOP_CALL_1(iemOp_fadd_m32r, bRm);
7408 case 1: return FNIEMOP_CALL_1(iemOp_fmul_m32r, bRm);
7409 case 2: return FNIEMOP_CALL_1(iemOp_fcom_m32r, bRm);
7410 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_m32r, bRm);
7411 case 4: return FNIEMOP_CALL_1(iemOp_fsub_m32r, bRm);
7412 case 5: return FNIEMOP_CALL_1(iemOp_fsubr_m32r, bRm);
7413 case 6: return FNIEMOP_CALL_1(iemOp_fdiv_m32r, bRm);
7414 case 7: return FNIEMOP_CALL_1(iemOp_fdivr_m32r, bRm);
7415 IEM_NOT_REACHED_DEFAULT_CASE_RET();
7416 }
7417 }
7418}
7419
7420
7421/** Opcode 0xd9 /0 mem32real
7422 * @sa iemOp_fld_m64r */
7423FNIEMOP_DEF_1(iemOp_fld_m32r, uint8_t, bRm)
7424{
7425 IEMOP_MNEMONIC(fld_m32r, "fld m32r");
7426
7427 IEM_MC_BEGIN(2, 3);
7428 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
7429 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7430 IEM_MC_LOCAL(RTFLOAT32U, r32Val);
7431 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
7432 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U, pr32Val, r32Val, 1);
7433
7434 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
7435 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7436
7437 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7438 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7439 IEM_MC_FETCH_MEM_R32(r32Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7440
7441 IEM_MC_PREPARE_FPU_USAGE();
7442 IEM_MC_IF_FPUREG_IS_EMPTY(7)
7443 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r32_to_r80, pFpuRes, pr32Val);
7444 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7445 IEM_MC_ELSE()
7446 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7447 IEM_MC_ENDIF();
7448 IEM_MC_ADVANCE_RIP();
7449
7450 IEM_MC_END();
7451 return VINF_SUCCESS;
7452}
7453
7454
7455/** Opcode 0xd9 !11/2 mem32real */
7456FNIEMOP_DEF_1(iemOp_fst_m32r, uint8_t, bRm)
7457{
7458 IEMOP_MNEMONIC(fst_m32r, "fst m32r");
7459 IEM_MC_BEGIN(3, 2);
7460 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7461 IEM_MC_LOCAL(uint16_t, u16Fsw);
7462 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7463 IEM_MC_ARG(PRTFLOAT32U, pr32Dst, 1);
7464 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
7465
7466 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7467 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7468 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7469 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7470
7471 IEM_MC_MEM_MAP(pr32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
7472 IEM_MC_PREPARE_FPU_USAGE();
7473 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
7474 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r32, pu16Fsw, pr32Dst, pr80Value);
7475 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr32Dst, IEM_ACCESS_DATA_W, u16Fsw);
7476 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7477 IEM_MC_ELSE()
7478 IEM_MC_IF_FCW_IM()
7479 IEM_MC_STORE_MEM_NEG_QNAN_R32_BY_REF(pr32Dst);
7480 IEM_MC_MEM_COMMIT_AND_UNMAP(pr32Dst, IEM_ACCESS_DATA_W);
7481 IEM_MC_ENDIF();
7482 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7483 IEM_MC_ENDIF();
7484 IEM_MC_ADVANCE_RIP();
7485
7486 IEM_MC_END();
7487 return VINF_SUCCESS;
7488}
7489
7490
7491/** Opcode 0xd9 !11/3 */
7492FNIEMOP_DEF_1(iemOp_fstp_m32r, uint8_t, bRm)
7493{
7494 IEMOP_MNEMONIC(fstp_m32r, "fstp m32r");
7495 IEM_MC_BEGIN(3, 2);
7496 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7497 IEM_MC_LOCAL(uint16_t, u16Fsw);
7498 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7499 IEM_MC_ARG(PRTFLOAT32U, pr32Dst, 1);
7500 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
7501
7502 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7503 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7504 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7505 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7506
7507 IEM_MC_MEM_MAP(pr32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
7508 IEM_MC_PREPARE_FPU_USAGE();
7509 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
7510 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r32, pu16Fsw, pr32Dst, pr80Value);
7511 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr32Dst, IEM_ACCESS_DATA_W, u16Fsw);
7512 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7513 IEM_MC_ELSE()
7514 IEM_MC_IF_FCW_IM()
7515 IEM_MC_STORE_MEM_NEG_QNAN_R32_BY_REF(pr32Dst);
7516 IEM_MC_MEM_COMMIT_AND_UNMAP(pr32Dst, IEM_ACCESS_DATA_W);
7517 IEM_MC_ENDIF();
7518 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
7519 IEM_MC_ENDIF();
7520 IEM_MC_ADVANCE_RIP();
7521
7522 IEM_MC_END();
7523 return VINF_SUCCESS;
7524}
7525
7526
7527/** Opcode 0xd9 !11/4 */
7528FNIEMOP_DEF_1(iemOp_fldenv, uint8_t, bRm)
7529{
7530 IEMOP_MNEMONIC(fldenv, "fldenv m14/28byte");
7531 IEM_MC_BEGIN(3, 0);
7532 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
7533 IEM_MC_ARG(uint8_t, iEffSeg, 1);
7534 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 2);
7535 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
7536 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7537 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7538 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
7539 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
7540 IEM_MC_CALL_CIMPL_3(iemCImpl_fldenv, enmEffOpSize, iEffSeg, GCPtrEffSrc);
7541 IEM_MC_END();
7542 return VINF_SUCCESS;
7543}
7544
7545
7546/** Opcode 0xd9 !11/5 */
7547FNIEMOP_DEF_1(iemOp_fldcw, uint8_t, bRm)
7548{
7549 IEMOP_MNEMONIC(fldcw_m2byte, "fldcw m2byte");
7550 IEM_MC_BEGIN(1, 1);
7551 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
7552 IEM_MC_ARG(uint16_t, u16Fsw, 0);
7553 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
7554 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7555 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7556 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
7557 IEM_MC_FETCH_MEM_U16(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
7558 IEM_MC_CALL_CIMPL_1(iemCImpl_fldcw, u16Fsw);
7559 IEM_MC_END();
7560 return VINF_SUCCESS;
7561}
7562
7563
7564/** Opcode 0xd9 !11/6 */
7565FNIEMOP_DEF_1(iemOp_fnstenv, uint8_t, bRm)
7566{
7567 IEMOP_MNEMONIC(fstenv, "fstenv m14/m28byte");
7568 IEM_MC_BEGIN(3, 0);
7569 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
7570 IEM_MC_ARG(uint8_t, iEffSeg, 1);
7571 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 2);
7572 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7573 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7574 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7575 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
7576 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
7577 IEM_MC_CALL_CIMPL_3(iemCImpl_fnstenv, enmEffOpSize, iEffSeg, GCPtrEffDst);
7578 IEM_MC_END();
7579 return VINF_SUCCESS;
7580}
7581
7582
7583/** Opcode 0xd9 !11/7 */
7584FNIEMOP_DEF_1(iemOp_fnstcw, uint8_t, bRm)
7585{
7586 IEMOP_MNEMONIC(fnstcw_m2byte, "fnstcw m2byte");
7587 IEM_MC_BEGIN(2, 0);
7588 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
7589 IEM_MC_LOCAL(uint16_t, u16Fcw);
7590 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
7591 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7592 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7593 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
7594 IEM_MC_FETCH_FCW(u16Fcw);
7595 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Fcw);
7596 IEM_MC_ADVANCE_RIP(); /* C0-C3 are documented as undefined, we leave them unmodified. */
7597 IEM_MC_END();
7598 return VINF_SUCCESS;
7599}
7600
7601
7602/** Opcode 0xd9 0xd0, 0xd9 0xd8-0xdf, ++?. */
7603FNIEMOP_DEF(iemOp_fnop)
7604{
7605 IEMOP_MNEMONIC(fnop, "fnop");
7606 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7607
7608 IEM_MC_BEGIN(0, 0);
7609 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7610 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7611 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
7612 /** @todo Testcase: looks like FNOP leaves FOP alone but updates FPUIP. Could be
7613 * intel optimizations. Investigate. */
7614 IEM_MC_UPDATE_FPU_OPCODE_IP();
7615 IEM_MC_ADVANCE_RIP(); /* C0-C3 are documented as undefined, we leave them unmodified. */
7616 IEM_MC_END();
7617 return VINF_SUCCESS;
7618}
7619
7620
7621/** Opcode 0xd9 11/0 stN */
7622FNIEMOP_DEF_1(iemOp_fld_stN, uint8_t, bRm)
7623{
7624 IEMOP_MNEMONIC(fld_stN, "fld stN");
7625 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7626
7627 /** @todo Testcase: Check if this raises \#MF? Intel mentioned it not. AMD
7628 * indicates that it does. */
7629 IEM_MC_BEGIN(0, 2);
7630 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value);
7631 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7632 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7633 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7634
7635 IEM_MC_PREPARE_FPU_USAGE();
7636 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, bRm & X86_MODRM_RM_MASK)
7637 IEM_MC_SET_FPU_RESULT(FpuRes, 0 /*FSW*/, pr80Value);
7638 IEM_MC_PUSH_FPU_RESULT(FpuRes);
7639 IEM_MC_ELSE()
7640 IEM_MC_FPU_STACK_PUSH_UNDERFLOW();
7641 IEM_MC_ENDIF();
7642
7643 IEM_MC_ADVANCE_RIP();
7644 IEM_MC_END();
7645
7646 return VINF_SUCCESS;
7647}
7648
7649
7650/** Opcode 0xd9 11/3 stN */
7651FNIEMOP_DEF_1(iemOp_fxch_stN, uint8_t, bRm)
7652{
7653 IEMOP_MNEMONIC(fxch_stN, "fxch stN");
7654 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7655
7656 /** @todo Testcase: Check if this raises \#MF? Intel mentioned it not. AMD
7657 * indicates that it does. */
7658 IEM_MC_BEGIN(1, 3);
7659 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value1);
7660 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value2);
7661 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7662 IEM_MC_ARG_CONST(uint8_t, iStReg, /*=*/ bRm & X86_MODRM_RM_MASK, 0);
7663 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7664 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7665
7666 IEM_MC_PREPARE_FPU_USAGE();
7667 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK)
7668 IEM_MC_SET_FPU_RESULT(FpuRes, X86_FSW_C1, pr80Value2);
7669 IEM_MC_STORE_FPUREG_R80_SRC_REF(bRm & X86_MODRM_RM_MASK, pr80Value1);
7670 IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
7671 IEM_MC_ELSE()
7672 IEM_MC_CALL_CIMPL_1(iemCImpl_fxch_underflow, iStReg);
7673 IEM_MC_ENDIF();
7674
7675 IEM_MC_ADVANCE_RIP();
7676 IEM_MC_END();
7677
7678 return VINF_SUCCESS;
7679}
7680
7681
7682/** Opcode 0xd9 11/4, 0xdd 11/2. */
7683FNIEMOP_DEF_1(iemOp_fstp_stN, uint8_t, bRm)
7684{
7685 IEMOP_MNEMONIC(fstp_st0_stN, "fstp st0,stN");
7686 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7687
7688 /* fstp st0, st0 is frequently used as an official 'ffreep st0' sequence. */
7689 uint8_t const iDstReg = bRm & X86_MODRM_RM_MASK;
7690 if (!iDstReg)
7691 {
7692 IEM_MC_BEGIN(0, 1);
7693 IEM_MC_LOCAL_CONST(uint16_t, u16Fsw, /*=*/ 0);
7694 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7695 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7696
7697 IEM_MC_PREPARE_FPU_USAGE();
7698 IEM_MC_IF_FPUREG_NOT_EMPTY(0)
7699 IEM_MC_UPDATE_FSW_THEN_POP(u16Fsw);
7700 IEM_MC_ELSE()
7701 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(0);
7702 IEM_MC_ENDIF();
7703
7704 IEM_MC_ADVANCE_RIP();
7705 IEM_MC_END();
7706 }
7707 else
7708 {
7709 IEM_MC_BEGIN(0, 2);
7710 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value);
7711 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7712 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7713 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7714
7715 IEM_MC_PREPARE_FPU_USAGE();
7716 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
7717 IEM_MC_SET_FPU_RESULT(FpuRes, 0 /*FSW*/, pr80Value);
7718 IEM_MC_STORE_FPU_RESULT_THEN_POP(FpuRes, iDstReg);
7719 IEM_MC_ELSE()
7720 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(iDstReg);
7721 IEM_MC_ENDIF();
7722
7723 IEM_MC_ADVANCE_RIP();
7724 IEM_MC_END();
7725 }
7726 return VINF_SUCCESS;
7727}
7728
7729
7730/**
7731 * Common worker for FPU instructions working on ST0 and replaces it with the
7732 * result, i.e. unary operators.
7733 *
7734 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7735 */
7736FNIEMOP_DEF_1(iemOpHlpFpu_st0, PFNIEMAIMPLFPUR80UNARY, pfnAImpl)
7737{
7738 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7739
7740 IEM_MC_BEGIN(2, 1);
7741 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7742 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
7743 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
7744
7745 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7746 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7747 IEM_MC_PREPARE_FPU_USAGE();
7748 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
7749 IEM_MC_CALL_FPU_AIMPL_2(pfnAImpl, pFpuRes, pr80Value);
7750 IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
7751 IEM_MC_ELSE()
7752 IEM_MC_FPU_STACK_UNDERFLOW(0);
7753 IEM_MC_ENDIF();
7754 IEM_MC_ADVANCE_RIP();
7755
7756 IEM_MC_END();
7757 return VINF_SUCCESS;
7758}
7759
7760
7761/** Opcode 0xd9 0xe0. */
7762FNIEMOP_DEF(iemOp_fchs)
7763{
7764 IEMOP_MNEMONIC(fchs_st0, "fchs st0");
7765 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fchs_r80);
7766}
7767
7768
7769/** Opcode 0xd9 0xe1. */
7770FNIEMOP_DEF(iemOp_fabs)
7771{
7772 IEMOP_MNEMONIC(fabs_st0, "fabs st0");
7773 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fabs_r80);
7774}
7775
7776
7777/**
7778 * Common worker for FPU instructions working on ST0 and only returns FSW.
7779 *
7780 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7781 */
7782FNIEMOP_DEF_1(iemOpHlpFpuNoStore_st0, PFNIEMAIMPLFPUR80UNARYFSW, pfnAImpl)
7783{
7784 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7785
7786 IEM_MC_BEGIN(2, 1);
7787 IEM_MC_LOCAL(uint16_t, u16Fsw);
7788 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
7789 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
7790
7791 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7792 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7793 IEM_MC_PREPARE_FPU_USAGE();
7794 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
7795 IEM_MC_CALL_FPU_AIMPL_2(pfnAImpl, pu16Fsw, pr80Value);
7796 IEM_MC_UPDATE_FSW(u16Fsw);
7797 IEM_MC_ELSE()
7798 IEM_MC_FPU_STACK_UNDERFLOW(UINT8_MAX);
7799 IEM_MC_ENDIF();
7800 IEM_MC_ADVANCE_RIP();
7801
7802 IEM_MC_END();
7803 return VINF_SUCCESS;
7804}
7805
7806
7807/** Opcode 0xd9 0xe4. */
7808FNIEMOP_DEF(iemOp_ftst)
7809{
7810 IEMOP_MNEMONIC(ftst_st0, "ftst st0");
7811 return FNIEMOP_CALL_1(iemOpHlpFpuNoStore_st0, iemAImpl_ftst_r80);
7812}
7813
7814
7815/** Opcode 0xd9 0xe5. */
7816FNIEMOP_DEF(iemOp_fxam)
7817{
7818 IEMOP_MNEMONIC(fxam_st0, "fxam st0");
7819 return FNIEMOP_CALL_1(iemOpHlpFpuNoStore_st0, iemAImpl_fxam_r80);
7820}
7821
7822
7823/**
7824 * Common worker for FPU instructions pushing a constant onto the FPU stack.
7825 *
7826 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7827 */
7828FNIEMOP_DEF_1(iemOpHlpFpuPushConstant, PFNIEMAIMPLFPUR80LDCONST, pfnAImpl)
7829{
7830 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7831
7832 IEM_MC_BEGIN(1, 1);
7833 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7834 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
7835
7836 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7837 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7838 IEM_MC_PREPARE_FPU_USAGE();
7839 IEM_MC_IF_FPUREG_IS_EMPTY(7)
7840 IEM_MC_CALL_FPU_AIMPL_1(pfnAImpl, pFpuRes);
7841 IEM_MC_PUSH_FPU_RESULT(FpuRes);
7842 IEM_MC_ELSE()
7843 IEM_MC_FPU_STACK_PUSH_OVERFLOW();
7844 IEM_MC_ENDIF();
7845 IEM_MC_ADVANCE_RIP();
7846
7847 IEM_MC_END();
7848 return VINF_SUCCESS;
7849}
7850
7851
7852/** Opcode 0xd9 0xe8. */
7853FNIEMOP_DEF(iemOp_fld1)
7854{
7855 IEMOP_MNEMONIC(fld1, "fld1");
7856 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fld1);
7857}
7858
7859
7860/** Opcode 0xd9 0xe9. */
7861FNIEMOP_DEF(iemOp_fldl2t)
7862{
7863 IEMOP_MNEMONIC(fldl2t, "fldl2t");
7864 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldl2t);
7865}
7866
7867
7868/** Opcode 0xd9 0xea. */
7869FNIEMOP_DEF(iemOp_fldl2e)
7870{
7871 IEMOP_MNEMONIC(fldl2e, "fldl2e");
7872 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldl2e);
7873}
7874
7875/** Opcode 0xd9 0xeb. */
7876FNIEMOP_DEF(iemOp_fldpi)
7877{
7878 IEMOP_MNEMONIC(fldpi, "fldpi");
7879 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldpi);
7880}
7881
7882
7883/** Opcode 0xd9 0xec. */
7884FNIEMOP_DEF(iemOp_fldlg2)
7885{
7886 IEMOP_MNEMONIC(fldlg2, "fldlg2");
7887 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldlg2);
7888}
7889
7890/** Opcode 0xd9 0xed. */
7891FNIEMOP_DEF(iemOp_fldln2)
7892{
7893 IEMOP_MNEMONIC(fldln2, "fldln2");
7894 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldln2);
7895}
7896
7897
7898/** Opcode 0xd9 0xee. */
7899FNIEMOP_DEF(iemOp_fldz)
7900{
7901 IEMOP_MNEMONIC(fldz, "fldz");
7902 return FNIEMOP_CALL_1(iemOpHlpFpuPushConstant, iemAImpl_fldz);
7903}
7904
7905
7906/** Opcode 0xd9 0xf0. */
7907FNIEMOP_DEF(iemOp_f2xm1)
7908{
7909 IEMOP_MNEMONIC(f2xm1_st0, "f2xm1 st0");
7910 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_f2xm1_r80);
7911}
7912
7913
7914/**
7915 * Common worker for FPU instructions working on STn and ST0, storing the result
7916 * in STn, and popping the stack unless IE, DE or ZE was raised.
7917 *
7918 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7919 */
7920FNIEMOP_DEF_2(iemOpHlpFpu_stN_st0_pop, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
7921{
7922 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7923
7924 IEM_MC_BEGIN(3, 1);
7925 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
7926 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
7927 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
7928 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
7929
7930 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7931 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7932
7933 IEM_MC_PREPARE_FPU_USAGE();
7934 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, bRm & X86_MODRM_RM_MASK, pr80Value2, 0)
7935 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr80Value2);
7936 IEM_MC_STORE_FPU_RESULT_THEN_POP(FpuRes, bRm & X86_MODRM_RM_MASK);
7937 IEM_MC_ELSE()
7938 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(bRm & X86_MODRM_RM_MASK);
7939 IEM_MC_ENDIF();
7940 IEM_MC_ADVANCE_RIP();
7941
7942 IEM_MC_END();
7943 return VINF_SUCCESS;
7944}
7945
7946
7947/** Opcode 0xd9 0xf1. */
7948FNIEMOP_DEF(iemOp_fyl2x)
7949{
7950 IEMOP_MNEMONIC(fyl2x_st0, "fyl2x st1,st0");
7951 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, 1, iemAImpl_fyl2x_r80_by_r80);
7952}
7953
7954
7955/**
7956 * Common worker for FPU instructions working on ST0 and having two outputs, one
7957 * replacing ST0 and one pushed onto the stack.
7958 *
7959 * @param pfnAImpl Pointer to the instruction implementation (assembly).
7960 */
7961FNIEMOP_DEF_1(iemOpHlpFpuReplace_st0_push, PFNIEMAIMPLFPUR80UNARYTWO, pfnAImpl)
7962{
7963 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
7964
7965 IEM_MC_BEGIN(2, 1);
7966 IEM_MC_LOCAL(IEMFPURESULTTWO, FpuResTwo);
7967 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULTTWO, pFpuResTwo, FpuResTwo, 0);
7968 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 1);
7969
7970 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
7971 IEM_MC_MAYBE_RAISE_FPU_XCPT();
7972 IEM_MC_PREPARE_FPU_USAGE();
7973 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
7974 IEM_MC_CALL_FPU_AIMPL_2(pfnAImpl, pFpuResTwo, pr80Value);
7975 IEM_MC_PUSH_FPU_RESULT_TWO(FpuResTwo);
7976 IEM_MC_ELSE()
7977 IEM_MC_FPU_STACK_PUSH_UNDERFLOW_TWO();
7978 IEM_MC_ENDIF();
7979 IEM_MC_ADVANCE_RIP();
7980
7981 IEM_MC_END();
7982 return VINF_SUCCESS;
7983}
7984
7985
7986/** Opcode 0xd9 0xf2. */
7987FNIEMOP_DEF(iemOp_fptan)
7988{
7989 IEMOP_MNEMONIC(fptan_st0, "fptan st0");
7990 return FNIEMOP_CALL_1(iemOpHlpFpuReplace_st0_push, iemAImpl_fptan_r80_r80);
7991}
7992
7993
7994/** Opcode 0xd9 0xf3. */
7995FNIEMOP_DEF(iemOp_fpatan)
7996{
7997 IEMOP_MNEMONIC(fpatan_st1_st0, "fpatan st1,st0");
7998 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, 1, iemAImpl_fpatan_r80_by_r80);
7999}
8000
8001
8002/** Opcode 0xd9 0xf4. */
8003FNIEMOP_DEF(iemOp_fxtract)
8004{
8005 IEMOP_MNEMONIC(fxtract_st0, "fxtract st0");
8006 return FNIEMOP_CALL_1(iemOpHlpFpuReplace_st0_push, iemAImpl_fxtract_r80_r80);
8007}
8008
8009
8010/** Opcode 0xd9 0xf5. */
8011FNIEMOP_DEF(iemOp_fprem1)
8012{
8013 IEMOP_MNEMONIC(fprem1_st0_st1, "fprem1 st0,st1");
8014 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, 1, iemAImpl_fprem1_r80_by_r80);
8015}
8016
8017
8018/** Opcode 0xd9 0xf6. */
8019FNIEMOP_DEF(iemOp_fdecstp)
8020{
8021 IEMOP_MNEMONIC(fdecstp, "fdecstp");
8022 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8023 /* Note! C0, C2 and C3 are documented as undefined, we clear them. */
8024 /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
8025 * FINCSTP and FDECSTP. */
8026
8027 IEM_MC_BEGIN(0,0);
8028
8029 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8030 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8031
8032 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
8033 IEM_MC_FPU_STACK_DEC_TOP();
8034 IEM_MC_UPDATE_FSW_CONST(0);
8035
8036 IEM_MC_ADVANCE_RIP();
8037 IEM_MC_END();
8038 return VINF_SUCCESS;
8039}
8040
8041
8042/** Opcode 0xd9 0xf7. */
8043FNIEMOP_DEF(iemOp_fincstp)
8044{
8045 IEMOP_MNEMONIC(fincstp, "fincstp");
8046 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8047 /* Note! C0, C2 and C3 are documented as undefined, we clear them. */
8048 /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
8049 * FINCSTP and FDECSTP. */
8050
8051 IEM_MC_BEGIN(0,0);
8052
8053 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8054 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8055
8056 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
8057 IEM_MC_FPU_STACK_INC_TOP();
8058 IEM_MC_UPDATE_FSW_CONST(0);
8059
8060 IEM_MC_ADVANCE_RIP();
8061 IEM_MC_END();
8062 return VINF_SUCCESS;
8063}
8064
8065
8066/** Opcode 0xd9 0xf8. */
8067FNIEMOP_DEF(iemOp_fprem)
8068{
8069 IEMOP_MNEMONIC(fprem_st0_st1, "fprem st0,st1");
8070 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, 1, iemAImpl_fprem_r80_by_r80);
8071}
8072
8073
8074/** Opcode 0xd9 0xf9. */
8075FNIEMOP_DEF(iemOp_fyl2xp1)
8076{
8077 IEMOP_MNEMONIC(fyl2xp1_st1_st0, "fyl2xp1 st1,st0");
8078 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, 1, iemAImpl_fyl2xp1_r80_by_r80);
8079}
8080
8081
8082/** Opcode 0xd9 0xfa. */
8083FNIEMOP_DEF(iemOp_fsqrt)
8084{
8085 IEMOP_MNEMONIC(fsqrt_st0, "fsqrt st0");
8086 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fsqrt_r80);
8087}
8088
8089
8090/** Opcode 0xd9 0xfb. */
8091FNIEMOP_DEF(iemOp_fsincos)
8092{
8093 IEMOP_MNEMONIC(fsincos_st0, "fsincos st0");
8094 return FNIEMOP_CALL_1(iemOpHlpFpuReplace_st0_push, iemAImpl_fsincos_r80_r80);
8095}
8096
8097
8098/** Opcode 0xd9 0xfc. */
8099FNIEMOP_DEF(iemOp_frndint)
8100{
8101 IEMOP_MNEMONIC(frndint_st0, "frndint st0");
8102 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_frndint_r80);
8103}
8104
8105
8106/** Opcode 0xd9 0xfd. */
8107FNIEMOP_DEF(iemOp_fscale)
8108{
8109 IEMOP_MNEMONIC(fscale_st0_st1, "fscale st0,st1");
8110 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, 1, iemAImpl_fscale_r80_by_r80);
8111}
8112
8113
8114/** Opcode 0xd9 0xfe. */
8115FNIEMOP_DEF(iemOp_fsin)
8116{
8117 IEMOP_MNEMONIC(fsin_st0, "fsin st0");
8118 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fsin_r80);
8119}
8120
8121
8122/** Opcode 0xd9 0xff. */
8123FNIEMOP_DEF(iemOp_fcos)
8124{
8125 IEMOP_MNEMONIC(fcos_st0, "fcos st0");
8126 return FNIEMOP_CALL_1(iemOpHlpFpu_st0, iemAImpl_fcos_r80);
8127}
8128
8129
8130/** Used by iemOp_EscF1. */
8131IEM_STATIC const PFNIEMOP g_apfnEscF1_E0toFF[32] =
8132{
8133 /* 0xe0 */ iemOp_fchs,
8134 /* 0xe1 */ iemOp_fabs,
8135 /* 0xe2 */ iemOp_Invalid,
8136 /* 0xe3 */ iemOp_Invalid,
8137 /* 0xe4 */ iemOp_ftst,
8138 /* 0xe5 */ iemOp_fxam,
8139 /* 0xe6 */ iemOp_Invalid,
8140 /* 0xe7 */ iemOp_Invalid,
8141 /* 0xe8 */ iemOp_fld1,
8142 /* 0xe9 */ iemOp_fldl2t,
8143 /* 0xea */ iemOp_fldl2e,
8144 /* 0xeb */ iemOp_fldpi,
8145 /* 0xec */ iemOp_fldlg2,
8146 /* 0xed */ iemOp_fldln2,
8147 /* 0xee */ iemOp_fldz,
8148 /* 0xef */ iemOp_Invalid,
8149 /* 0xf0 */ iemOp_f2xm1,
8150 /* 0xf1 */ iemOp_fyl2x,
8151 /* 0xf2 */ iemOp_fptan,
8152 /* 0xf3 */ iemOp_fpatan,
8153 /* 0xf4 */ iemOp_fxtract,
8154 /* 0xf5 */ iemOp_fprem1,
8155 /* 0xf6 */ iemOp_fdecstp,
8156 /* 0xf7 */ iemOp_fincstp,
8157 /* 0xf8 */ iemOp_fprem,
8158 /* 0xf9 */ iemOp_fyl2xp1,
8159 /* 0xfa */ iemOp_fsqrt,
8160 /* 0xfb */ iemOp_fsincos,
8161 /* 0xfc */ iemOp_frndint,
8162 /* 0xfd */ iemOp_fscale,
8163 /* 0xfe */ iemOp_fsin,
8164 /* 0xff */ iemOp_fcos
8165};
8166
8167
8168/**
8169 * @opcode 0xd9
8170 */
8171FNIEMOP_DEF(iemOp_EscF1)
8172{
8173 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8174 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xd9 & 0x7);
8175
8176 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8177 {
8178 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
8179 {
8180 case 0: return FNIEMOP_CALL_1(iemOp_fld_stN, bRm);
8181 case 1: return FNIEMOP_CALL_1(iemOp_fxch_stN, bRm);
8182 case 2:
8183 if (bRm == 0xd0)
8184 return FNIEMOP_CALL(iemOp_fnop);
8185 return IEMOP_RAISE_INVALID_OPCODE();
8186 case 3: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm); /* Reserved. Intel behavior seems to be FSTP ST(i) though. */
8187 case 4:
8188 case 5:
8189 case 6:
8190 case 7:
8191 Assert((unsigned)bRm - 0xe0U < RT_ELEMENTS(g_apfnEscF1_E0toFF));
8192 return FNIEMOP_CALL(g_apfnEscF1_E0toFF[bRm - 0xe0]);
8193 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8194 }
8195 }
8196 else
8197 {
8198 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
8199 {
8200 case 0: return FNIEMOP_CALL_1(iemOp_fld_m32r, bRm);
8201 case 1: return IEMOP_RAISE_INVALID_OPCODE();
8202 case 2: return FNIEMOP_CALL_1(iemOp_fst_m32r, bRm);
8203 case 3: return FNIEMOP_CALL_1(iemOp_fstp_m32r, bRm);
8204 case 4: return FNIEMOP_CALL_1(iemOp_fldenv, bRm);
8205 case 5: return FNIEMOP_CALL_1(iemOp_fldcw, bRm);
8206 case 6: return FNIEMOP_CALL_1(iemOp_fnstenv, bRm);
8207 case 7: return FNIEMOP_CALL_1(iemOp_fnstcw, bRm);
8208 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8209 }
8210 }
8211}
8212
8213
8214/** Opcode 0xda 11/0. */
8215FNIEMOP_DEF_1(iemOp_fcmovb_stN, uint8_t, bRm)
8216{
8217 IEMOP_MNEMONIC(fcmovb_st0_stN, "fcmovb st0,stN");
8218 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8219
8220 IEM_MC_BEGIN(0, 1);
8221 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8222
8223 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8224 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8225
8226 IEM_MC_PREPARE_FPU_USAGE();
8227 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8228 IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF)
8229 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8230 IEM_MC_ENDIF();
8231 IEM_MC_UPDATE_FPU_OPCODE_IP();
8232 IEM_MC_ELSE()
8233 IEM_MC_FPU_STACK_UNDERFLOW(0);
8234 IEM_MC_ENDIF();
8235 IEM_MC_ADVANCE_RIP();
8236
8237 IEM_MC_END();
8238 return VINF_SUCCESS;
8239}
8240
8241
8242/** Opcode 0xda 11/1. */
8243FNIEMOP_DEF_1(iemOp_fcmove_stN, uint8_t, bRm)
8244{
8245 IEMOP_MNEMONIC(fcmove_st0_stN, "fcmove st0,stN");
8246 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8247
8248 IEM_MC_BEGIN(0, 1);
8249 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8250
8251 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8252 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8253
8254 IEM_MC_PREPARE_FPU_USAGE();
8255 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8256 IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF)
8257 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8258 IEM_MC_ENDIF();
8259 IEM_MC_UPDATE_FPU_OPCODE_IP();
8260 IEM_MC_ELSE()
8261 IEM_MC_FPU_STACK_UNDERFLOW(0);
8262 IEM_MC_ENDIF();
8263 IEM_MC_ADVANCE_RIP();
8264
8265 IEM_MC_END();
8266 return VINF_SUCCESS;
8267}
8268
8269
8270/** Opcode 0xda 11/2. */
8271FNIEMOP_DEF_1(iemOp_fcmovbe_stN, uint8_t, bRm)
8272{
8273 IEMOP_MNEMONIC(fcmovbe_st0_stN, "fcmovbe st0,stN");
8274 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8275
8276 IEM_MC_BEGIN(0, 1);
8277 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8278
8279 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8280 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8281
8282 IEM_MC_PREPARE_FPU_USAGE();
8283 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8284 IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF)
8285 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8286 IEM_MC_ENDIF();
8287 IEM_MC_UPDATE_FPU_OPCODE_IP();
8288 IEM_MC_ELSE()
8289 IEM_MC_FPU_STACK_UNDERFLOW(0);
8290 IEM_MC_ENDIF();
8291 IEM_MC_ADVANCE_RIP();
8292
8293 IEM_MC_END();
8294 return VINF_SUCCESS;
8295}
8296
8297
8298/** Opcode 0xda 11/3. */
8299FNIEMOP_DEF_1(iemOp_fcmovu_stN, uint8_t, bRm)
8300{
8301 IEMOP_MNEMONIC(fcmovu_st0_stN, "fcmovu st0,stN");
8302 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8303
8304 IEM_MC_BEGIN(0, 1);
8305 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8306
8307 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8308 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8309
8310 IEM_MC_PREPARE_FPU_USAGE();
8311 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8312 IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF)
8313 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8314 IEM_MC_ENDIF();
8315 IEM_MC_UPDATE_FPU_OPCODE_IP();
8316 IEM_MC_ELSE()
8317 IEM_MC_FPU_STACK_UNDERFLOW(0);
8318 IEM_MC_ENDIF();
8319 IEM_MC_ADVANCE_RIP();
8320
8321 IEM_MC_END();
8322 return VINF_SUCCESS;
8323}
8324
8325
8326/**
8327 * Common worker for FPU instructions working on ST0 and STn, only affecting
8328 * flags, and popping twice when done.
8329 *
8330 * @param pfnAImpl Pointer to the instruction implementation (assembly).
8331 */
8332FNIEMOP_DEF_1(iemOpHlpFpuNoStore_st0_stN_pop_pop, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
8333{
8334 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8335
8336 IEM_MC_BEGIN(3, 1);
8337 IEM_MC_LOCAL(uint16_t, u16Fsw);
8338 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8339 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
8340 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
8341
8342 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8343 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8344
8345 IEM_MC_PREPARE_FPU_USAGE();
8346 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, 1)
8347 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16Fsw, pr80Value1, pr80Value2);
8348 IEM_MC_UPDATE_FSW_THEN_POP_POP(u16Fsw);
8349 IEM_MC_ELSE()
8350 IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP_POP();
8351 IEM_MC_ENDIF();
8352 IEM_MC_ADVANCE_RIP();
8353
8354 IEM_MC_END();
8355 return VINF_SUCCESS;
8356}
8357
8358
8359/** Opcode 0xda 0xe9. */
8360FNIEMOP_DEF(iemOp_fucompp)
8361{
8362 IEMOP_MNEMONIC(fucompp_st0_stN, "fucompp st0,stN");
8363 return FNIEMOP_CALL_1(iemOpHlpFpuNoStore_st0_stN_pop_pop, iemAImpl_fucom_r80_by_r80);
8364}
8365
8366
8367/**
8368 * Common worker for FPU instructions working on ST0 and an m32i, and storing
8369 * the result in ST0.
8370 *
8371 * @param pfnAImpl Pointer to the instruction implementation (assembly).
8372 */
8373FNIEMOP_DEF_2(iemOpHlpFpu_st0_m32i, uint8_t, bRm, PFNIEMAIMPLFPUI32, pfnAImpl)
8374{
8375 IEM_MC_BEGIN(3, 3);
8376 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
8377 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
8378 IEM_MC_LOCAL(int32_t, i32Val2);
8379 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
8380 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
8381 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val2, i32Val2, 2);
8382
8383 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8384 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8385
8386 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8387 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8388 IEM_MC_FETCH_MEM_I32(i32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8389
8390 IEM_MC_PREPARE_FPU_USAGE();
8391 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
8392 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pi32Val2);
8393 IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
8394 IEM_MC_ELSE()
8395 IEM_MC_FPU_STACK_UNDERFLOW(0);
8396 IEM_MC_ENDIF();
8397 IEM_MC_ADVANCE_RIP();
8398
8399 IEM_MC_END();
8400 return VINF_SUCCESS;
8401}
8402
8403
8404/** Opcode 0xda !11/0. */
8405FNIEMOP_DEF_1(iemOp_fiadd_m32i, uint8_t, bRm)
8406{
8407 IEMOP_MNEMONIC(fiadd_m32i, "fiadd m32i");
8408 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fiadd_r80_by_i32);
8409}
8410
8411
8412/** Opcode 0xda !11/1. */
8413FNIEMOP_DEF_1(iemOp_fimul_m32i, uint8_t, bRm)
8414{
8415 IEMOP_MNEMONIC(fimul_m32i, "fimul m32i");
8416 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fimul_r80_by_i32);
8417}
8418
8419
8420/** Opcode 0xda !11/2. */
8421FNIEMOP_DEF_1(iemOp_ficom_m32i, uint8_t, bRm)
8422{
8423 IEMOP_MNEMONIC(ficom_st0_m32i, "ficom st0,m32i");
8424
8425 IEM_MC_BEGIN(3, 3);
8426 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
8427 IEM_MC_LOCAL(uint16_t, u16Fsw);
8428 IEM_MC_LOCAL(int32_t, i32Val2);
8429 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8430 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
8431 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val2, i32Val2, 2);
8432
8433 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8434 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8435
8436 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8437 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8438 IEM_MC_FETCH_MEM_I32(i32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8439
8440 IEM_MC_PREPARE_FPU_USAGE();
8441 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
8442 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i32, pu16Fsw, pr80Value1, pi32Val2);
8443 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8444 IEM_MC_ELSE()
8445 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8446 IEM_MC_ENDIF();
8447 IEM_MC_ADVANCE_RIP();
8448
8449 IEM_MC_END();
8450 return VINF_SUCCESS;
8451}
8452
8453
8454/** Opcode 0xda !11/3. */
8455FNIEMOP_DEF_1(iemOp_ficomp_m32i, uint8_t, bRm)
8456{
8457 IEMOP_MNEMONIC(ficomp_st0_m32i, "ficomp st0,m32i");
8458
8459 IEM_MC_BEGIN(3, 3);
8460 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
8461 IEM_MC_LOCAL(uint16_t, u16Fsw);
8462 IEM_MC_LOCAL(int32_t, i32Val2);
8463 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8464 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
8465 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val2, i32Val2, 2);
8466
8467 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8468 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8469
8470 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8471 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8472 IEM_MC_FETCH_MEM_I32(i32Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8473
8474 IEM_MC_PREPARE_FPU_USAGE();
8475 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
8476 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i32, pu16Fsw, pr80Value1, pi32Val2);
8477 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8478 IEM_MC_ELSE()
8479 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8480 IEM_MC_ENDIF();
8481 IEM_MC_ADVANCE_RIP();
8482
8483 IEM_MC_END();
8484 return VINF_SUCCESS;
8485}
8486
8487
8488/** Opcode 0xda !11/4. */
8489FNIEMOP_DEF_1(iemOp_fisub_m32i, uint8_t, bRm)
8490{
8491 IEMOP_MNEMONIC(fisub_m32i, "fisub m32i");
8492 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fisub_r80_by_i32);
8493}
8494
8495
8496/** Opcode 0xda !11/5. */
8497FNIEMOP_DEF_1(iemOp_fisubr_m32i, uint8_t, bRm)
8498{
8499 IEMOP_MNEMONIC(fisubr_m32i, "fisubr m32i");
8500 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fisubr_r80_by_i32);
8501}
8502
8503
8504/** Opcode 0xda !11/6. */
8505FNIEMOP_DEF_1(iemOp_fidiv_m32i, uint8_t, bRm)
8506{
8507 IEMOP_MNEMONIC(fidiv_m32i, "fidiv m32i");
8508 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fidiv_r80_by_i32);
8509}
8510
8511
8512/** Opcode 0xda !11/7. */
8513FNIEMOP_DEF_1(iemOp_fidivr_m32i, uint8_t, bRm)
8514{
8515 IEMOP_MNEMONIC(fidivr_m32i, "fidivr m32i");
8516 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32i, bRm, iemAImpl_fidivr_r80_by_i32);
8517}
8518
8519
8520/**
8521 * @opcode 0xda
8522 */
8523FNIEMOP_DEF(iemOp_EscF2)
8524{
8525 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8526 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xda & 0x7);
8527 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8528 {
8529 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
8530 {
8531 case 0: return FNIEMOP_CALL_1(iemOp_fcmovb_stN, bRm);
8532 case 1: return FNIEMOP_CALL_1(iemOp_fcmove_stN, bRm);
8533 case 2: return FNIEMOP_CALL_1(iemOp_fcmovbe_stN, bRm);
8534 case 3: return FNIEMOP_CALL_1(iemOp_fcmovu_stN, bRm);
8535 case 4: return IEMOP_RAISE_INVALID_OPCODE();
8536 case 5:
8537 if (bRm == 0xe9)
8538 return FNIEMOP_CALL(iemOp_fucompp);
8539 return IEMOP_RAISE_INVALID_OPCODE();
8540 case 6: return IEMOP_RAISE_INVALID_OPCODE();
8541 case 7: return IEMOP_RAISE_INVALID_OPCODE();
8542 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8543 }
8544 }
8545 else
8546 {
8547 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
8548 {
8549 case 0: return FNIEMOP_CALL_1(iemOp_fiadd_m32i, bRm);
8550 case 1: return FNIEMOP_CALL_1(iemOp_fimul_m32i, bRm);
8551 case 2: return FNIEMOP_CALL_1(iemOp_ficom_m32i, bRm);
8552 case 3: return FNIEMOP_CALL_1(iemOp_ficomp_m32i, bRm);
8553 case 4: return FNIEMOP_CALL_1(iemOp_fisub_m32i, bRm);
8554 case 5: return FNIEMOP_CALL_1(iemOp_fisubr_m32i, bRm);
8555 case 6: return FNIEMOP_CALL_1(iemOp_fidiv_m32i, bRm);
8556 case 7: return FNIEMOP_CALL_1(iemOp_fidivr_m32i, bRm);
8557 IEM_NOT_REACHED_DEFAULT_CASE_RET();
8558 }
8559 }
8560}
8561
8562
8563/** Opcode 0xdb !11/0. */
8564FNIEMOP_DEF_1(iemOp_fild_m32i, uint8_t, bRm)
8565{
8566 IEMOP_MNEMONIC(fild_m32i, "fild m32i");
8567
8568 IEM_MC_BEGIN(2, 3);
8569 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
8570 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
8571 IEM_MC_LOCAL(int32_t, i32Val);
8572 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
8573 IEM_MC_ARG_LOCAL_REF(int32_t const *, pi32Val, i32Val, 1);
8574
8575 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8576 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8577
8578 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8579 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8580 IEM_MC_FETCH_MEM_I32(i32Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8581
8582 IEM_MC_PREPARE_FPU_USAGE();
8583 IEM_MC_IF_FPUREG_IS_EMPTY(7)
8584 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fild_i32_to_r80, pFpuRes, pi32Val);
8585 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8586 IEM_MC_ELSE()
8587 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8588 IEM_MC_ENDIF();
8589 IEM_MC_ADVANCE_RIP();
8590
8591 IEM_MC_END();
8592 return VINF_SUCCESS;
8593}
8594
8595
8596/** Opcode 0xdb !11/1. */
8597FNIEMOP_DEF_1(iemOp_fisttp_m32i, uint8_t, bRm)
8598{
8599 IEMOP_MNEMONIC(fisttp_m32i, "fisttp m32i");
8600 IEM_MC_BEGIN(3, 2);
8601 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8602 IEM_MC_LOCAL(uint16_t, u16Fsw);
8603 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8604 IEM_MC_ARG(int32_t *, pi32Dst, 1);
8605 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
8606
8607 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8608 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8609 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8610 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8611
8612 IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
8613 IEM_MC_PREPARE_FPU_USAGE();
8614 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
8615 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
8616 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi32Dst, IEM_ACCESS_DATA_W, u16Fsw);
8617 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8618 IEM_MC_ELSE()
8619 IEM_MC_IF_FCW_IM()
8620 IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
8621 IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
8622 IEM_MC_ENDIF();
8623 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8624 IEM_MC_ENDIF();
8625 IEM_MC_ADVANCE_RIP();
8626
8627 IEM_MC_END();
8628 return VINF_SUCCESS;
8629}
8630
8631
8632/** Opcode 0xdb !11/2. */
8633FNIEMOP_DEF_1(iemOp_fist_m32i, uint8_t, bRm)
8634{
8635 IEMOP_MNEMONIC(fist_m32i, "fist m32i");
8636 IEM_MC_BEGIN(3, 2);
8637 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8638 IEM_MC_LOCAL(uint16_t, u16Fsw);
8639 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8640 IEM_MC_ARG(int32_t *, pi32Dst, 1);
8641 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
8642
8643 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8644 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8645 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8646 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8647
8648 IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
8649 IEM_MC_PREPARE_FPU_USAGE();
8650 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
8651 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
8652 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi32Dst, IEM_ACCESS_DATA_W, u16Fsw);
8653 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8654 IEM_MC_ELSE()
8655 IEM_MC_IF_FCW_IM()
8656 IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
8657 IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
8658 IEM_MC_ENDIF();
8659 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8660 IEM_MC_ENDIF();
8661 IEM_MC_ADVANCE_RIP();
8662
8663 IEM_MC_END();
8664 return VINF_SUCCESS;
8665}
8666
8667
8668/** Opcode 0xdb !11/3. */
8669FNIEMOP_DEF_1(iemOp_fistp_m32i, uint8_t, bRm)
8670{
8671 IEMOP_MNEMONIC(fistp_m32i, "fistp m32i");
8672 IEM_MC_BEGIN(3, 2);
8673 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8674 IEM_MC_LOCAL(uint16_t, u16Fsw);
8675 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8676 IEM_MC_ARG(int32_t *, pi32Dst, 1);
8677 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
8678
8679 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8680 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8681 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8682 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8683
8684 IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
8685 IEM_MC_PREPARE_FPU_USAGE();
8686 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
8687 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
8688 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi32Dst, IEM_ACCESS_DATA_W, u16Fsw);
8689 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8690 IEM_MC_ELSE()
8691 IEM_MC_IF_FCW_IM()
8692 IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
8693 IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
8694 IEM_MC_ENDIF();
8695 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8696 IEM_MC_ENDIF();
8697 IEM_MC_ADVANCE_RIP();
8698
8699 IEM_MC_END();
8700 return VINF_SUCCESS;
8701}
8702
8703
8704/** Opcode 0xdb !11/5. */
8705FNIEMOP_DEF_1(iemOp_fld_m80r, uint8_t, bRm)
8706{
8707 IEMOP_MNEMONIC(fld_m80r, "fld m80r");
8708
8709 IEM_MC_BEGIN(2, 3);
8710 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
8711 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
8712 IEM_MC_LOCAL(RTFLOAT80U, r80Val);
8713 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
8714 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT80U, pr80Val, r80Val, 1);
8715
8716 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
8717 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8718
8719 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8720 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8721 IEM_MC_FETCH_MEM_R80(r80Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8722
8723 IEM_MC_PREPARE_FPU_USAGE();
8724 IEM_MC_IF_FPUREG_IS_EMPTY(7)
8725 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r80_from_r80, pFpuRes, pr80Val);
8726 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8727 IEM_MC_ELSE()
8728 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
8729 IEM_MC_ENDIF();
8730 IEM_MC_ADVANCE_RIP();
8731
8732 IEM_MC_END();
8733 return VINF_SUCCESS;
8734}
8735
8736
8737/** Opcode 0xdb !11/7. */
8738FNIEMOP_DEF_1(iemOp_fstp_m80r, uint8_t, bRm)
8739{
8740 IEMOP_MNEMONIC(fstp_m80r, "fstp m80r");
8741 IEM_MC_BEGIN(3, 2);
8742 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
8743 IEM_MC_LOCAL(uint16_t, u16Fsw);
8744 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
8745 IEM_MC_ARG(PRTFLOAT80U, pr80Dst, 1);
8746 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
8747
8748 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
8749 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8750 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8751 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8752
8753 IEM_MC_MEM_MAP(pr80Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
8754 IEM_MC_PREPARE_FPU_USAGE();
8755 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
8756 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r80, pu16Fsw, pr80Dst, pr80Value);
8757 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr80Dst, IEM_ACCESS_DATA_W, u16Fsw);
8758 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8759 IEM_MC_ELSE()
8760 IEM_MC_IF_FCW_IM()
8761 IEM_MC_STORE_MEM_NEG_QNAN_R80_BY_REF(pr80Dst);
8762 IEM_MC_MEM_COMMIT_AND_UNMAP(pr80Dst, IEM_ACCESS_DATA_W);
8763 IEM_MC_ENDIF();
8764 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
8765 IEM_MC_ENDIF();
8766 IEM_MC_ADVANCE_RIP();
8767
8768 IEM_MC_END();
8769 return VINF_SUCCESS;
8770}
8771
8772
8773/** Opcode 0xdb 11/0. */
8774FNIEMOP_DEF_1(iemOp_fcmovnb_stN, uint8_t, bRm)
8775{
8776 IEMOP_MNEMONIC(fcmovnb_st0_stN, "fcmovnb st0,stN");
8777 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8778
8779 IEM_MC_BEGIN(0, 1);
8780 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8781
8782 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8783 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8784
8785 IEM_MC_PREPARE_FPU_USAGE();
8786 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8787 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_CF)
8788 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8789 IEM_MC_ENDIF();
8790 IEM_MC_UPDATE_FPU_OPCODE_IP();
8791 IEM_MC_ELSE()
8792 IEM_MC_FPU_STACK_UNDERFLOW(0);
8793 IEM_MC_ENDIF();
8794 IEM_MC_ADVANCE_RIP();
8795
8796 IEM_MC_END();
8797 return VINF_SUCCESS;
8798}
8799
8800
8801/** Opcode 0xdb 11/1. */
8802FNIEMOP_DEF_1(iemOp_fcmovne_stN, uint8_t, bRm)
8803{
8804 IEMOP_MNEMONIC(fcmovne_st0_stN, "fcmovne st0,stN");
8805 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8806
8807 IEM_MC_BEGIN(0, 1);
8808 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8809
8810 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8811 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8812
8813 IEM_MC_PREPARE_FPU_USAGE();
8814 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8815 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF)
8816 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8817 IEM_MC_ENDIF();
8818 IEM_MC_UPDATE_FPU_OPCODE_IP();
8819 IEM_MC_ELSE()
8820 IEM_MC_FPU_STACK_UNDERFLOW(0);
8821 IEM_MC_ENDIF();
8822 IEM_MC_ADVANCE_RIP();
8823
8824 IEM_MC_END();
8825 return VINF_SUCCESS;
8826}
8827
8828
8829/** Opcode 0xdb 11/2. */
8830FNIEMOP_DEF_1(iemOp_fcmovnbe_stN, uint8_t, bRm)
8831{
8832 IEMOP_MNEMONIC(fcmovnbe_st0_stN, "fcmovnbe st0,stN");
8833 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8834
8835 IEM_MC_BEGIN(0, 1);
8836 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8837
8838 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8839 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8840
8841 IEM_MC_PREPARE_FPU_USAGE();
8842 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8843 IEM_MC_IF_EFL_NO_BITS_SET(X86_EFL_CF | X86_EFL_ZF)
8844 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8845 IEM_MC_ENDIF();
8846 IEM_MC_UPDATE_FPU_OPCODE_IP();
8847 IEM_MC_ELSE()
8848 IEM_MC_FPU_STACK_UNDERFLOW(0);
8849 IEM_MC_ENDIF();
8850 IEM_MC_ADVANCE_RIP();
8851
8852 IEM_MC_END();
8853 return VINF_SUCCESS;
8854}
8855
8856
8857/** Opcode 0xdb 11/3. */
8858FNIEMOP_DEF_1(iemOp_fcmovnnu_stN, uint8_t, bRm)
8859{
8860 IEMOP_MNEMONIC(fcmovnnu_st0_stN, "fcmovnnu st0,stN");
8861 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8862
8863 IEM_MC_BEGIN(0, 1);
8864 IEM_MC_LOCAL(PCRTFLOAT80U, pr80ValueN);
8865
8866 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8867 IEM_MC_MAYBE_RAISE_FPU_XCPT();
8868
8869 IEM_MC_PREPARE_FPU_USAGE();
8870 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
8871 IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_PF)
8872 IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
8873 IEM_MC_ENDIF();
8874 IEM_MC_UPDATE_FPU_OPCODE_IP();
8875 IEM_MC_ELSE()
8876 IEM_MC_FPU_STACK_UNDERFLOW(0);
8877 IEM_MC_ENDIF();
8878 IEM_MC_ADVANCE_RIP();
8879
8880 IEM_MC_END();
8881 return VINF_SUCCESS;
8882}
8883
8884
8885/** Opcode 0xdb 0xe0. */
8886FNIEMOP_DEF(iemOp_fneni)
8887{
8888 IEMOP_MNEMONIC(fneni, "fneni (8087/ign)");
8889 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8890 IEM_MC_BEGIN(0,0);
8891 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8892 IEM_MC_ADVANCE_RIP();
8893 IEM_MC_END();
8894 return VINF_SUCCESS;
8895}
8896
8897
8898/** Opcode 0xdb 0xe1. */
8899FNIEMOP_DEF(iemOp_fndisi)
8900{
8901 IEMOP_MNEMONIC(fndisi, "fndisi (8087/ign)");
8902 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8903 IEM_MC_BEGIN(0,0);
8904 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8905 IEM_MC_ADVANCE_RIP();
8906 IEM_MC_END();
8907 return VINF_SUCCESS;
8908}
8909
8910
8911/** Opcode 0xdb 0xe2. */
8912FNIEMOP_DEF(iemOp_fnclex)
8913{
8914 IEMOP_MNEMONIC(fnclex, "fnclex");
8915 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8916
8917 IEM_MC_BEGIN(0,0);
8918 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8919 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
8920 IEM_MC_CLEAR_FSW_EX();
8921 IEM_MC_ADVANCE_RIP();
8922 IEM_MC_END();
8923 return VINF_SUCCESS;
8924}
8925
8926
8927/** Opcode 0xdb 0xe3. */
8928FNIEMOP_DEF(iemOp_fninit)
8929{
8930 IEMOP_MNEMONIC(fninit, "fninit");
8931 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8932 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_finit, false /*fCheckXcpts*/);
8933}
8934
8935
8936/** Opcode 0xdb 0xe4. */
8937FNIEMOP_DEF(iemOp_fnsetpm)
8938{
8939 IEMOP_MNEMONIC(fnsetpm, "fnsetpm (80287/ign)"); /* set protected mode on fpu. */
8940 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8941 IEM_MC_BEGIN(0,0);
8942 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8943 IEM_MC_ADVANCE_RIP();
8944 IEM_MC_END();
8945 return VINF_SUCCESS;
8946}
8947
8948
8949/** Opcode 0xdb 0xe5. */
8950FNIEMOP_DEF(iemOp_frstpm)
8951{
8952 IEMOP_MNEMONIC(frstpm, "frstpm (80287XL/ign)"); /* reset pm, back to real mode. */
8953#if 0 /* #UDs on newer CPUs */
8954 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
8955 IEM_MC_BEGIN(0,0);
8956 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
8957 IEM_MC_ADVANCE_RIP();
8958 IEM_MC_END();
8959 return VINF_SUCCESS;
8960#else
8961 return IEMOP_RAISE_INVALID_OPCODE();
8962#endif
8963}
8964
8965
8966/** Opcode 0xdb 11/5. */
8967FNIEMOP_DEF_1(iemOp_fucomi_stN, uint8_t, bRm)
8968{
8969 IEMOP_MNEMONIC(fucomi_st0_stN, "fucomi st0,stN");
8970 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fucomi_r80_by_r80, false /*fPop*/);
8971}
8972
8973
8974/** Opcode 0xdb 11/6. */
8975FNIEMOP_DEF_1(iemOp_fcomi_stN, uint8_t, bRm)
8976{
8977 IEMOP_MNEMONIC(fcomi_st0_stN, "fcomi st0,stN");
8978 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fcomi_r80_by_r80, false /*fPop*/);
8979}
8980
8981
8982/**
8983 * @opcode 0xdb
8984 */
8985FNIEMOP_DEF(iemOp_EscF3)
8986{
8987 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
8988 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdb & 0x7);
8989 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
8990 {
8991 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
8992 {
8993 case 0: return FNIEMOP_CALL_1(iemOp_fcmovnb_stN, bRm);
8994 case 1: return FNIEMOP_CALL_1(iemOp_fcmovne_stN, bRm);
8995 case 2: return FNIEMOP_CALL_1(iemOp_fcmovnbe_stN, bRm);
8996 case 3: return FNIEMOP_CALL_1(iemOp_fcmovnnu_stN, bRm);
8997 case 4:
8998 switch (bRm)
8999 {
9000 case 0xe0: return FNIEMOP_CALL(iemOp_fneni);
9001 case 0xe1: return FNIEMOP_CALL(iemOp_fndisi);
9002 case 0xe2: return FNIEMOP_CALL(iemOp_fnclex);
9003 case 0xe3: return FNIEMOP_CALL(iemOp_fninit);
9004 case 0xe4: return FNIEMOP_CALL(iemOp_fnsetpm);
9005 case 0xe5: return FNIEMOP_CALL(iemOp_frstpm);
9006 case 0xe6: return IEMOP_RAISE_INVALID_OPCODE();
9007 case 0xe7: return IEMOP_RAISE_INVALID_OPCODE();
9008 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9009 }
9010 break;
9011 case 5: return FNIEMOP_CALL_1(iemOp_fucomi_stN, bRm);
9012 case 6: return FNIEMOP_CALL_1(iemOp_fcomi_stN, bRm);
9013 case 7: return IEMOP_RAISE_INVALID_OPCODE();
9014 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9015 }
9016 }
9017 else
9018 {
9019 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9020 {
9021 case 0: return FNIEMOP_CALL_1(iemOp_fild_m32i, bRm);
9022 case 1: return FNIEMOP_CALL_1(iemOp_fisttp_m32i,bRm);
9023 case 2: return FNIEMOP_CALL_1(iemOp_fist_m32i, bRm);
9024 case 3: return FNIEMOP_CALL_1(iemOp_fistp_m32i, bRm);
9025 case 4: return IEMOP_RAISE_INVALID_OPCODE();
9026 case 5: return FNIEMOP_CALL_1(iemOp_fld_m80r, bRm);
9027 case 6: return IEMOP_RAISE_INVALID_OPCODE();
9028 case 7: return FNIEMOP_CALL_1(iemOp_fstp_m80r, bRm);
9029 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9030 }
9031 }
9032}
9033
9034
9035/**
9036 * Common worker for FPU instructions working on STn and ST0, and storing the
9037 * result in STn unless IE, DE or ZE was raised.
9038 *
9039 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9040 */
9041FNIEMOP_DEF_2(iemOpHlpFpu_stN_st0, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
9042{
9043 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9044
9045 IEM_MC_BEGIN(3, 1);
9046 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9047 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9048 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9049 IEM_MC_ARG(PCRTFLOAT80U, pr80Value2, 2);
9050
9051 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9052 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9053
9054 IEM_MC_PREPARE_FPU_USAGE();
9055 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, bRm & X86_MODRM_RM_MASK, pr80Value2, 0)
9056 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr80Value2);
9057 IEM_MC_STORE_FPU_RESULT(FpuRes, bRm & X86_MODRM_RM_MASK);
9058 IEM_MC_ELSE()
9059 IEM_MC_FPU_STACK_UNDERFLOW(bRm & X86_MODRM_RM_MASK);
9060 IEM_MC_ENDIF();
9061 IEM_MC_ADVANCE_RIP();
9062
9063 IEM_MC_END();
9064 return VINF_SUCCESS;
9065}
9066
9067
9068/** Opcode 0xdc 11/0. */
9069FNIEMOP_DEF_1(iemOp_fadd_stN_st0, uint8_t, bRm)
9070{
9071 IEMOP_MNEMONIC(fadd_stN_st0, "fadd stN,st0");
9072 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fadd_r80_by_r80);
9073}
9074
9075
9076/** Opcode 0xdc 11/1. */
9077FNIEMOP_DEF_1(iemOp_fmul_stN_st0, uint8_t, bRm)
9078{
9079 IEMOP_MNEMONIC(fmul_stN_st0, "fmul stN,st0");
9080 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fmul_r80_by_r80);
9081}
9082
9083
9084/** Opcode 0xdc 11/4. */
9085FNIEMOP_DEF_1(iemOp_fsubr_stN_st0, uint8_t, bRm)
9086{
9087 IEMOP_MNEMONIC(fsubr_stN_st0, "fsubr stN,st0");
9088 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fsubr_r80_by_r80);
9089}
9090
9091
9092/** Opcode 0xdc 11/5. */
9093FNIEMOP_DEF_1(iemOp_fsub_stN_st0, uint8_t, bRm)
9094{
9095 IEMOP_MNEMONIC(fsub_stN_st0, "fsub stN,st0");
9096 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fsub_r80_by_r80);
9097}
9098
9099
9100/** Opcode 0xdc 11/6. */
9101FNIEMOP_DEF_1(iemOp_fdivr_stN_st0, uint8_t, bRm)
9102{
9103 IEMOP_MNEMONIC(fdivr_stN_st0, "fdivr stN,st0");
9104 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fdivr_r80_by_r80);
9105}
9106
9107
9108/** Opcode 0xdc 11/7. */
9109FNIEMOP_DEF_1(iemOp_fdiv_stN_st0, uint8_t, bRm)
9110{
9111 IEMOP_MNEMONIC(fdiv_stN_st0, "fdiv stN,st0");
9112 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0, bRm, iemAImpl_fdiv_r80_by_r80);
9113}
9114
9115
9116/**
9117 * Common worker for FPU instructions working on ST0 and a 64-bit floating point
9118 * memory operand, and storing the result in ST0.
9119 *
9120 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9121 */
9122FNIEMOP_DEF_2(iemOpHlpFpu_ST0_m64r, uint8_t, bRm, PFNIEMAIMPLFPUR64, pfnImpl)
9123{
9124 IEM_MC_BEGIN(3, 3);
9125 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9126 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9127 IEM_MC_LOCAL(RTFLOAT64U, r64Factor2);
9128 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9129 IEM_MC_ARG(PCRTFLOAT80U, pr80Factor1, 1);
9130 IEM_MC_ARG_LOCAL_REF(PRTFLOAT64U, pr64Factor2, r64Factor2, 2);
9131
9132 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9133 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9134 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9135 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9136
9137 IEM_MC_FETCH_MEM_R64(r64Factor2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9138 IEM_MC_PREPARE_FPU_USAGE();
9139 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Factor1, 0)
9140 IEM_MC_CALL_FPU_AIMPL_3(pfnImpl, pFpuRes, pr80Factor1, pr64Factor2);
9141 IEM_MC_STORE_FPU_RESULT_MEM_OP(FpuRes, 0, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9142 IEM_MC_ELSE()
9143 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(0, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9144 IEM_MC_ENDIF();
9145 IEM_MC_ADVANCE_RIP();
9146
9147 IEM_MC_END();
9148 return VINF_SUCCESS;
9149}
9150
9151
9152/** Opcode 0xdc !11/0. */
9153FNIEMOP_DEF_1(iemOp_fadd_m64r, uint8_t, bRm)
9154{
9155 IEMOP_MNEMONIC(fadd_m64r, "fadd m64r");
9156 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fadd_r80_by_r64);
9157}
9158
9159
9160/** Opcode 0xdc !11/1. */
9161FNIEMOP_DEF_1(iemOp_fmul_m64r, uint8_t, bRm)
9162{
9163 IEMOP_MNEMONIC(fmul_m64r, "fmul m64r");
9164 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fmul_r80_by_r64);
9165}
9166
9167
9168/** Opcode 0xdc !11/2. */
9169FNIEMOP_DEF_1(iemOp_fcom_m64r, uint8_t, bRm)
9170{
9171 IEMOP_MNEMONIC(fcom_st0_m64r, "fcom st0,m64r");
9172
9173 IEM_MC_BEGIN(3, 3);
9174 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9175 IEM_MC_LOCAL(uint16_t, u16Fsw);
9176 IEM_MC_LOCAL(RTFLOAT64U, r64Val2);
9177 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9178 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9179 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val2, r64Val2, 2);
9180
9181 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9182 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9183
9184 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9185 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9186 IEM_MC_FETCH_MEM_R64(r64Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9187
9188 IEM_MC_PREPARE_FPU_USAGE();
9189 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
9190 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r64, pu16Fsw, pr80Value1, pr64Val2);
9191 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9192 IEM_MC_ELSE()
9193 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9194 IEM_MC_ENDIF();
9195 IEM_MC_ADVANCE_RIP();
9196
9197 IEM_MC_END();
9198 return VINF_SUCCESS;
9199}
9200
9201
9202/** Opcode 0xdc !11/3. */
9203FNIEMOP_DEF_1(iemOp_fcomp_m64r, uint8_t, bRm)
9204{
9205 IEMOP_MNEMONIC(fcomp_st0_m64r, "fcomp st0,m64r");
9206
9207 IEM_MC_BEGIN(3, 3);
9208 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9209 IEM_MC_LOCAL(uint16_t, u16Fsw);
9210 IEM_MC_LOCAL(RTFLOAT64U, r64Val2);
9211 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9212 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9213 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val2, r64Val2, 2);
9214
9215 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9216 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9217
9218 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9219 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9220 IEM_MC_FETCH_MEM_R64(r64Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9221
9222 IEM_MC_PREPARE_FPU_USAGE();
9223 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
9224 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r64, pu16Fsw, pr80Value1, pr64Val2);
9225 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9226 IEM_MC_ELSE()
9227 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9228 IEM_MC_ENDIF();
9229 IEM_MC_ADVANCE_RIP();
9230
9231 IEM_MC_END();
9232 return VINF_SUCCESS;
9233}
9234
9235
9236/** Opcode 0xdc !11/4. */
9237FNIEMOP_DEF_1(iemOp_fsub_m64r, uint8_t, bRm)
9238{
9239 IEMOP_MNEMONIC(fsub_m64r, "fsub m64r");
9240 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fsub_r80_by_r64);
9241}
9242
9243
9244/** Opcode 0xdc !11/5. */
9245FNIEMOP_DEF_1(iemOp_fsubr_m64r, uint8_t, bRm)
9246{
9247 IEMOP_MNEMONIC(fsubr_m64r, "fsubr m64r");
9248 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fsubr_r80_by_r64);
9249}
9250
9251
9252/** Opcode 0xdc !11/6. */
9253FNIEMOP_DEF_1(iemOp_fdiv_m64r, uint8_t, bRm)
9254{
9255 IEMOP_MNEMONIC(fdiv_m64r, "fdiv m64r");
9256 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fdiv_r80_by_r64);
9257}
9258
9259
9260/** Opcode 0xdc !11/7. */
9261FNIEMOP_DEF_1(iemOp_fdivr_m64r, uint8_t, bRm)
9262{
9263 IEMOP_MNEMONIC(fdivr_m64r, "fdivr m64r");
9264 return FNIEMOP_CALL_2(iemOpHlpFpu_ST0_m64r, bRm, iemAImpl_fdivr_r80_by_r64);
9265}
9266
9267
9268/**
9269 * @opcode 0xdc
9270 */
9271FNIEMOP_DEF(iemOp_EscF4)
9272{
9273 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9274 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdc & 0x7);
9275 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
9276 {
9277 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9278 {
9279 case 0: return FNIEMOP_CALL_1(iemOp_fadd_stN_st0, bRm);
9280 case 1: return FNIEMOP_CALL_1(iemOp_fmul_stN_st0, bRm);
9281 case 2: return FNIEMOP_CALL_1(iemOp_fcom_stN, bRm); /* Marked reserved, intel behavior is that of FCOM ST(i). */
9282 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_stN, bRm); /* Marked reserved, intel behavior is that of FCOMP ST(i). */
9283 case 4: return FNIEMOP_CALL_1(iemOp_fsubr_stN_st0, bRm);
9284 case 5: return FNIEMOP_CALL_1(iemOp_fsub_stN_st0, bRm);
9285 case 6: return FNIEMOP_CALL_1(iemOp_fdivr_stN_st0, bRm);
9286 case 7: return FNIEMOP_CALL_1(iemOp_fdiv_stN_st0, bRm);
9287 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9288 }
9289 }
9290 else
9291 {
9292 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9293 {
9294 case 0: return FNIEMOP_CALL_1(iemOp_fadd_m64r, bRm);
9295 case 1: return FNIEMOP_CALL_1(iemOp_fmul_m64r, bRm);
9296 case 2: return FNIEMOP_CALL_1(iemOp_fcom_m64r, bRm);
9297 case 3: return FNIEMOP_CALL_1(iemOp_fcomp_m64r, bRm);
9298 case 4: return FNIEMOP_CALL_1(iemOp_fsub_m64r, bRm);
9299 case 5: return FNIEMOP_CALL_1(iemOp_fsubr_m64r, bRm);
9300 case 6: return FNIEMOP_CALL_1(iemOp_fdiv_m64r, bRm);
9301 case 7: return FNIEMOP_CALL_1(iemOp_fdivr_m64r, bRm);
9302 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9303 }
9304 }
9305}
9306
9307
9308/** Opcode 0xdd !11/0.
9309 * @sa iemOp_fld_m32r */
9310FNIEMOP_DEF_1(iemOp_fld_m64r, uint8_t, bRm)
9311{
9312 IEMOP_MNEMONIC(fld_m64r, "fld m64r");
9313
9314 IEM_MC_BEGIN(2, 3);
9315 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9316 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9317 IEM_MC_LOCAL(RTFLOAT64U, r64Val);
9318 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9319 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val, r64Val, 1);
9320
9321 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9322 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9323 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9324 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9325
9326 IEM_MC_FETCH_MEM_R64(r64Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9327 IEM_MC_PREPARE_FPU_USAGE();
9328 IEM_MC_IF_FPUREG_IS_EMPTY(7)
9329 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r64_to_r80, pFpuRes, pr64Val);
9330 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9331 IEM_MC_ELSE()
9332 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9333 IEM_MC_ENDIF();
9334 IEM_MC_ADVANCE_RIP();
9335
9336 IEM_MC_END();
9337 return VINF_SUCCESS;
9338}
9339
9340
9341/** Opcode 0xdd !11/0. */
9342FNIEMOP_DEF_1(iemOp_fisttp_m64i, uint8_t, bRm)
9343{
9344 IEMOP_MNEMONIC(fisttp_m64i, "fisttp m64i");
9345 IEM_MC_BEGIN(3, 2);
9346 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9347 IEM_MC_LOCAL(uint16_t, u16Fsw);
9348 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9349 IEM_MC_ARG(int64_t *, pi64Dst, 1);
9350 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
9351
9352 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9353 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9354 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9355 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9356
9357 IEM_MC_MEM_MAP(pi64Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
9358 IEM_MC_PREPARE_FPU_USAGE();
9359 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
9360 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i64, pu16Fsw, pi64Dst, pr80Value);
9361 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi64Dst, IEM_ACCESS_DATA_W, u16Fsw);
9362 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9363 IEM_MC_ELSE()
9364 IEM_MC_IF_FCW_IM()
9365 IEM_MC_STORE_MEM_I64_CONST_BY_REF(pi64Dst, INT64_MIN /* (integer indefinite) */);
9366 IEM_MC_MEM_COMMIT_AND_UNMAP(pi64Dst, IEM_ACCESS_DATA_W);
9367 IEM_MC_ENDIF();
9368 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9369 IEM_MC_ENDIF();
9370 IEM_MC_ADVANCE_RIP();
9371
9372 IEM_MC_END();
9373 return VINF_SUCCESS;
9374}
9375
9376
9377/** Opcode 0xdd !11/0. */
9378FNIEMOP_DEF_1(iemOp_fst_m64r, uint8_t, bRm)
9379{
9380 IEMOP_MNEMONIC(fst_m64r, "fst m64r");
9381 IEM_MC_BEGIN(3, 2);
9382 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9383 IEM_MC_LOCAL(uint16_t, u16Fsw);
9384 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9385 IEM_MC_ARG(PRTFLOAT64U, pr64Dst, 1);
9386 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
9387
9388 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9389 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9390 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9391 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9392
9393 IEM_MC_MEM_MAP(pr64Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
9394 IEM_MC_PREPARE_FPU_USAGE();
9395 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
9396 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r64, pu16Fsw, pr64Dst, pr80Value);
9397 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr64Dst, IEM_ACCESS_DATA_W, u16Fsw);
9398 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9399 IEM_MC_ELSE()
9400 IEM_MC_IF_FCW_IM()
9401 IEM_MC_STORE_MEM_NEG_QNAN_R64_BY_REF(pr64Dst);
9402 IEM_MC_MEM_COMMIT_AND_UNMAP(pr64Dst, IEM_ACCESS_DATA_W);
9403 IEM_MC_ENDIF();
9404 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9405 IEM_MC_ENDIF();
9406 IEM_MC_ADVANCE_RIP();
9407
9408 IEM_MC_END();
9409 return VINF_SUCCESS;
9410}
9411
9412
9413
9414
9415/** Opcode 0xdd !11/0. */
9416FNIEMOP_DEF_1(iemOp_fstp_m64r, uint8_t, bRm)
9417{
9418 IEMOP_MNEMONIC(fstp_m64r, "fstp m64r");
9419 IEM_MC_BEGIN(3, 2);
9420 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9421 IEM_MC_LOCAL(uint16_t, u16Fsw);
9422 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9423 IEM_MC_ARG(PRTFLOAT64U, pr64Dst, 1);
9424 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
9425
9426 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9427 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9428 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9429 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9430
9431 IEM_MC_MEM_MAP(pr64Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
9432 IEM_MC_PREPARE_FPU_USAGE();
9433 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
9434 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r64, pu16Fsw, pr64Dst, pr80Value);
9435 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr64Dst, IEM_ACCESS_DATA_W, u16Fsw);
9436 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9437 IEM_MC_ELSE()
9438 IEM_MC_IF_FCW_IM()
9439 IEM_MC_STORE_MEM_NEG_QNAN_R64_BY_REF(pr64Dst);
9440 IEM_MC_MEM_COMMIT_AND_UNMAP(pr64Dst, IEM_ACCESS_DATA_W);
9441 IEM_MC_ENDIF();
9442 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9443 IEM_MC_ENDIF();
9444 IEM_MC_ADVANCE_RIP();
9445
9446 IEM_MC_END();
9447 return VINF_SUCCESS;
9448}
9449
9450
9451/** Opcode 0xdd !11/0. */
9452FNIEMOP_DEF_1(iemOp_frstor, uint8_t, bRm)
9453{
9454 IEMOP_MNEMONIC(frstor, "frstor m94/108byte");
9455 IEM_MC_BEGIN(3, 0);
9456 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
9457 IEM_MC_ARG(uint8_t, iEffSeg, 1);
9458 IEM_MC_ARG(RTGCPTR, GCPtrEffSrc, 2);
9459 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9460 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9461 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9462 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9463 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
9464 IEM_MC_CALL_CIMPL_3(iemCImpl_frstor, enmEffOpSize, iEffSeg, GCPtrEffSrc);
9465 IEM_MC_END();
9466 return VINF_SUCCESS;
9467}
9468
9469
9470/** Opcode 0xdd !11/0. */
9471FNIEMOP_DEF_1(iemOp_fnsave, uint8_t, bRm)
9472{
9473 IEMOP_MNEMONIC(fnsave, "fnsave m94/108byte");
9474 IEM_MC_BEGIN(3, 0);
9475 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, /*=*/ pVCpu->iem.s.enmEffOpSize, 0);
9476 IEM_MC_ARG(uint8_t, iEffSeg, 1);
9477 IEM_MC_ARG(RTGCPTR, GCPtrEffDst, 2);
9478 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9479 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9480 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9481 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
9482 IEM_MC_ASSIGN(iEffSeg, pVCpu->iem.s.iEffSeg);
9483 IEM_MC_CALL_CIMPL_3(iemCImpl_fnsave, enmEffOpSize, iEffSeg, GCPtrEffDst);
9484 IEM_MC_END();
9485 return VINF_SUCCESS;
9486
9487}
9488
9489/** Opcode 0xdd !11/0. */
9490FNIEMOP_DEF_1(iemOp_fnstsw, uint8_t, bRm)
9491{
9492 IEMOP_MNEMONIC(fnstsw_m16, "fnstsw m16");
9493
9494 IEM_MC_BEGIN(0, 2);
9495 IEM_MC_LOCAL(uint16_t, u16Tmp);
9496 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9497
9498 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9499 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9500 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9501
9502 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
9503 IEM_MC_FETCH_FSW(u16Tmp);
9504 IEM_MC_STORE_MEM_U16(pVCpu->iem.s.iEffSeg, GCPtrEffDst, u16Tmp);
9505 IEM_MC_ADVANCE_RIP();
9506
9507/** @todo Debug / drop a hint to the verifier that things may differ
9508 * from REM. Seen 0x4020 (iem) vs 0x4000 (rem) at 0008:801c6b88 booting
9509 * NT4SP1. (X86_FSW_PE) */
9510 IEM_MC_END();
9511 return VINF_SUCCESS;
9512}
9513
9514
9515/** Opcode 0xdd 11/0. */
9516FNIEMOP_DEF_1(iemOp_ffree_stN, uint8_t, bRm)
9517{
9518 IEMOP_MNEMONIC(ffree_stN, "ffree stN");
9519 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9520 /* Note! C0, C1, C2 and C3 are documented as undefined, we leave the
9521 unmodified. */
9522
9523 IEM_MC_BEGIN(0, 0);
9524
9525 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9526 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9527
9528 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9529 IEM_MC_FPU_STACK_FREE(bRm & X86_MODRM_RM_MASK);
9530 IEM_MC_UPDATE_FPU_OPCODE_IP();
9531
9532 IEM_MC_ADVANCE_RIP();
9533 IEM_MC_END();
9534 return VINF_SUCCESS;
9535}
9536
9537
9538/** Opcode 0xdd 11/1. */
9539FNIEMOP_DEF_1(iemOp_fst_stN, uint8_t, bRm)
9540{
9541 IEMOP_MNEMONIC(fst_st0_stN, "fst st0,stN");
9542 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9543
9544 IEM_MC_BEGIN(0, 2);
9545 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value);
9546 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9547 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9548 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9549
9550 IEM_MC_PREPARE_FPU_USAGE();
9551 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
9552 IEM_MC_SET_FPU_RESULT(FpuRes, 0 /*FSW*/, pr80Value);
9553 IEM_MC_STORE_FPU_RESULT(FpuRes, bRm & X86_MODRM_RM_MASK);
9554 IEM_MC_ELSE()
9555 IEM_MC_FPU_STACK_UNDERFLOW(bRm & X86_MODRM_RM_MASK);
9556 IEM_MC_ENDIF();
9557
9558 IEM_MC_ADVANCE_RIP();
9559 IEM_MC_END();
9560 return VINF_SUCCESS;
9561}
9562
9563
9564/** Opcode 0xdd 11/3. */
9565FNIEMOP_DEF_1(iemOp_fucom_stN_st0, uint8_t, bRm)
9566{
9567 IEMOP_MNEMONIC(fucom_st0_stN, "fucom st0,stN");
9568 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN, bRm, iemAImpl_fucom_r80_by_r80);
9569}
9570
9571
9572/** Opcode 0xdd 11/4. */
9573FNIEMOP_DEF_1(iemOp_fucomp_stN, uint8_t, bRm)
9574{
9575 IEMOP_MNEMONIC(fucomp_st0_stN, "fucomp st0,stN");
9576 return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN_pop, bRm, iemAImpl_fucom_r80_by_r80);
9577}
9578
9579
9580/**
9581 * @opcode 0xdd
9582 */
9583FNIEMOP_DEF(iemOp_EscF5)
9584{
9585 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9586 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdd & 0x7);
9587 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
9588 {
9589 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9590 {
9591 case 0: return FNIEMOP_CALL_1(iemOp_ffree_stN, bRm);
9592 case 1: return FNIEMOP_CALL_1(iemOp_fxch_stN, bRm); /* Reserved, intel behavior is that of XCHG ST(i). */
9593 case 2: return FNIEMOP_CALL_1(iemOp_fst_stN, bRm);
9594 case 3: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm);
9595 case 4: return FNIEMOP_CALL_1(iemOp_fucom_stN_st0,bRm);
9596 case 5: return FNIEMOP_CALL_1(iemOp_fucomp_stN, bRm);
9597 case 6: return IEMOP_RAISE_INVALID_OPCODE();
9598 case 7: return IEMOP_RAISE_INVALID_OPCODE();
9599 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9600 }
9601 }
9602 else
9603 {
9604 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9605 {
9606 case 0: return FNIEMOP_CALL_1(iemOp_fld_m64r, bRm);
9607 case 1: return FNIEMOP_CALL_1(iemOp_fisttp_m64i, bRm);
9608 case 2: return FNIEMOP_CALL_1(iemOp_fst_m64r, bRm);
9609 case 3: return FNIEMOP_CALL_1(iemOp_fstp_m64r, bRm);
9610 case 4: return FNIEMOP_CALL_1(iemOp_frstor, bRm);
9611 case 5: return IEMOP_RAISE_INVALID_OPCODE();
9612 case 6: return FNIEMOP_CALL_1(iemOp_fnsave, bRm);
9613 case 7: return FNIEMOP_CALL_1(iemOp_fnstsw, bRm);
9614 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9615 }
9616 }
9617}
9618
9619
9620/** Opcode 0xde 11/0. */
9621FNIEMOP_DEF_1(iemOp_faddp_stN_st0, uint8_t, bRm)
9622{
9623 IEMOP_MNEMONIC(faddp_stN_st0, "faddp stN,st0");
9624 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fadd_r80_by_r80);
9625}
9626
9627
9628/** Opcode 0xde 11/0. */
9629FNIEMOP_DEF_1(iemOp_fmulp_stN_st0, uint8_t, bRm)
9630{
9631 IEMOP_MNEMONIC(fmulp_stN_st0, "fmulp stN,st0");
9632 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fmul_r80_by_r80);
9633}
9634
9635
9636/** Opcode 0xde 0xd9. */
9637FNIEMOP_DEF(iemOp_fcompp)
9638{
9639 IEMOP_MNEMONIC(fcompp_st0_stN, "fcompp st0,stN");
9640 return FNIEMOP_CALL_1(iemOpHlpFpuNoStore_st0_stN_pop_pop, iemAImpl_fcom_r80_by_r80);
9641}
9642
9643
9644/** Opcode 0xde 11/4. */
9645FNIEMOP_DEF_1(iemOp_fsubrp_stN_st0, uint8_t, bRm)
9646{
9647 IEMOP_MNEMONIC(fsubrp_stN_st0, "fsubrp stN,st0");
9648 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fsubr_r80_by_r80);
9649}
9650
9651
9652/** Opcode 0xde 11/5. */
9653FNIEMOP_DEF_1(iemOp_fsubp_stN_st0, uint8_t, bRm)
9654{
9655 IEMOP_MNEMONIC(fsubp_stN_st0, "fsubp stN,st0");
9656 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fsub_r80_by_r80);
9657}
9658
9659
9660/** Opcode 0xde 11/6. */
9661FNIEMOP_DEF_1(iemOp_fdivrp_stN_st0, uint8_t, bRm)
9662{
9663 IEMOP_MNEMONIC(fdivrp_stN_st0, "fdivrp stN,st0");
9664 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fdivr_r80_by_r80);
9665}
9666
9667
9668/** Opcode 0xde 11/7. */
9669FNIEMOP_DEF_1(iemOp_fdivp_stN_st0, uint8_t, bRm)
9670{
9671 IEMOP_MNEMONIC(fdivp_stN_st0, "fdivp stN,st0");
9672 return FNIEMOP_CALL_2(iemOpHlpFpu_stN_st0_pop, bRm, iemAImpl_fdiv_r80_by_r80);
9673}
9674
9675
9676/**
9677 * Common worker for FPU instructions working on ST0 and an m16i, and storing
9678 * the result in ST0.
9679 *
9680 * @param pfnAImpl Pointer to the instruction implementation (assembly).
9681 */
9682FNIEMOP_DEF_2(iemOpHlpFpu_st0_m16i, uint8_t, bRm, PFNIEMAIMPLFPUI16, pfnAImpl)
9683{
9684 IEM_MC_BEGIN(3, 3);
9685 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9686 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9687 IEM_MC_LOCAL(int16_t, i16Val2);
9688 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9689 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9690 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val2, i16Val2, 2);
9691
9692 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9693 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9694
9695 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9696 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9697 IEM_MC_FETCH_MEM_I16(i16Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9698
9699 IEM_MC_PREPARE_FPU_USAGE();
9700 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
9701 IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pi16Val2);
9702 IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
9703 IEM_MC_ELSE()
9704 IEM_MC_FPU_STACK_UNDERFLOW(0);
9705 IEM_MC_ENDIF();
9706 IEM_MC_ADVANCE_RIP();
9707
9708 IEM_MC_END();
9709 return VINF_SUCCESS;
9710}
9711
9712
9713/** Opcode 0xde !11/0. */
9714FNIEMOP_DEF_1(iemOp_fiadd_m16i, uint8_t, bRm)
9715{
9716 IEMOP_MNEMONIC(fiadd_m16i, "fiadd m16i");
9717 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fiadd_r80_by_i16);
9718}
9719
9720
9721/** Opcode 0xde !11/1. */
9722FNIEMOP_DEF_1(iemOp_fimul_m16i, uint8_t, bRm)
9723{
9724 IEMOP_MNEMONIC(fimul_m16i, "fimul m16i");
9725 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fimul_r80_by_i16);
9726}
9727
9728
9729/** Opcode 0xde !11/2. */
9730FNIEMOP_DEF_1(iemOp_ficom_m16i, uint8_t, bRm)
9731{
9732 IEMOP_MNEMONIC(ficom_st0_m16i, "ficom st0,m16i");
9733
9734 IEM_MC_BEGIN(3, 3);
9735 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9736 IEM_MC_LOCAL(uint16_t, u16Fsw);
9737 IEM_MC_LOCAL(int16_t, i16Val2);
9738 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9739 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9740 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val2, i16Val2, 2);
9741
9742 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9743 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9744
9745 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9746 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9747 IEM_MC_FETCH_MEM_I16(i16Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9748
9749 IEM_MC_PREPARE_FPU_USAGE();
9750 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
9751 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i16, pu16Fsw, pr80Value1, pi16Val2);
9752 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9753 IEM_MC_ELSE()
9754 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9755 IEM_MC_ENDIF();
9756 IEM_MC_ADVANCE_RIP();
9757
9758 IEM_MC_END();
9759 return VINF_SUCCESS;
9760}
9761
9762
9763/** Opcode 0xde !11/3. */
9764FNIEMOP_DEF_1(iemOp_ficomp_m16i, uint8_t, bRm)
9765{
9766 IEMOP_MNEMONIC(ficomp_st0_m16i, "ficomp st0,m16i");
9767
9768 IEM_MC_BEGIN(3, 3);
9769 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9770 IEM_MC_LOCAL(uint16_t, u16Fsw);
9771 IEM_MC_LOCAL(int16_t, i16Val2);
9772 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9773 IEM_MC_ARG(PCRTFLOAT80U, pr80Value1, 1);
9774 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val2, i16Val2, 2);
9775
9776 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9777 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9778
9779 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9780 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9781 IEM_MC_FETCH_MEM_I16(i16Val2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9782
9783 IEM_MC_PREPARE_FPU_USAGE();
9784 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
9785 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_ficom_r80_by_i16, pu16Fsw, pr80Value1, pi16Val2);
9786 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9787 IEM_MC_ELSE()
9788 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9789 IEM_MC_ENDIF();
9790 IEM_MC_ADVANCE_RIP();
9791
9792 IEM_MC_END();
9793 return VINF_SUCCESS;
9794}
9795
9796
9797/** Opcode 0xde !11/4. */
9798FNIEMOP_DEF_1(iemOp_fisub_m16i, uint8_t, bRm)
9799{
9800 IEMOP_MNEMONIC(fisub_m16i, "fisub m16i");
9801 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fisub_r80_by_i16);
9802}
9803
9804
9805/** Opcode 0xde !11/5. */
9806FNIEMOP_DEF_1(iemOp_fisubr_m16i, uint8_t, bRm)
9807{
9808 IEMOP_MNEMONIC(fisubr_m16i, "fisubr m16i");
9809 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fisubr_r80_by_i16);
9810}
9811
9812
9813/** Opcode 0xde !11/6. */
9814FNIEMOP_DEF_1(iemOp_fidiv_m16i, uint8_t, bRm)
9815{
9816 IEMOP_MNEMONIC(fidiv_m16i, "fidiv m16i");
9817 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fidiv_r80_by_i16);
9818}
9819
9820
9821/** Opcode 0xde !11/7. */
9822FNIEMOP_DEF_1(iemOp_fidivr_m16i, uint8_t, bRm)
9823{
9824 IEMOP_MNEMONIC(fidivr_m16i, "fidivr m16i");
9825 return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m16i, bRm, iemAImpl_fidivr_r80_by_i16);
9826}
9827
9828
9829/**
9830 * @opcode 0xde
9831 */
9832FNIEMOP_DEF(iemOp_EscF6)
9833{
9834 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
9835 pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xde & 0x7);
9836 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
9837 {
9838 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9839 {
9840 case 0: return FNIEMOP_CALL_1(iemOp_faddp_stN_st0, bRm);
9841 case 1: return FNIEMOP_CALL_1(iemOp_fmulp_stN_st0, bRm);
9842 case 2: return FNIEMOP_CALL_1(iemOp_fcomp_stN, bRm);
9843 case 3: if (bRm == 0xd9)
9844 return FNIEMOP_CALL(iemOp_fcompp);
9845 return IEMOP_RAISE_INVALID_OPCODE();
9846 case 4: return FNIEMOP_CALL_1(iemOp_fsubrp_stN_st0, bRm);
9847 case 5: return FNIEMOP_CALL_1(iemOp_fsubp_stN_st0, bRm);
9848 case 6: return FNIEMOP_CALL_1(iemOp_fdivrp_stN_st0, bRm);
9849 case 7: return FNIEMOP_CALL_1(iemOp_fdivp_stN_st0, bRm);
9850 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9851 }
9852 }
9853 else
9854 {
9855 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
9856 {
9857 case 0: return FNIEMOP_CALL_1(iemOp_fiadd_m16i, bRm);
9858 case 1: return FNIEMOP_CALL_1(iemOp_fimul_m16i, bRm);
9859 case 2: return FNIEMOP_CALL_1(iemOp_ficom_m16i, bRm);
9860 case 3: return FNIEMOP_CALL_1(iemOp_ficomp_m16i, bRm);
9861 case 4: return FNIEMOP_CALL_1(iemOp_fisub_m16i, bRm);
9862 case 5: return FNIEMOP_CALL_1(iemOp_fisubr_m16i, bRm);
9863 case 6: return FNIEMOP_CALL_1(iemOp_fidiv_m16i, bRm);
9864 case 7: return FNIEMOP_CALL_1(iemOp_fidivr_m16i, bRm);
9865 IEM_NOT_REACHED_DEFAULT_CASE_RET();
9866 }
9867 }
9868}
9869
9870
9871/** Opcode 0xdf 11/0.
9872 * Undocument instruction, assumed to work like ffree + fincstp. */
9873FNIEMOP_DEF_1(iemOp_ffreep_stN, uint8_t, bRm)
9874{
9875 IEMOP_MNEMONIC(ffreep_stN, "ffreep stN");
9876 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9877
9878 IEM_MC_BEGIN(0, 0);
9879
9880 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9881 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9882
9883 IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE();
9884 IEM_MC_FPU_STACK_FREE(bRm & X86_MODRM_RM_MASK);
9885 IEM_MC_FPU_STACK_INC_TOP();
9886 IEM_MC_UPDATE_FPU_OPCODE_IP();
9887
9888 IEM_MC_ADVANCE_RIP();
9889 IEM_MC_END();
9890 return VINF_SUCCESS;
9891}
9892
9893
9894/** Opcode 0xdf 0xe0. */
9895FNIEMOP_DEF(iemOp_fnstsw_ax)
9896{
9897 IEMOP_MNEMONIC(fnstsw_ax, "fnstsw ax");
9898 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9899
9900 IEM_MC_BEGIN(0, 1);
9901 IEM_MC_LOCAL(uint16_t, u16Tmp);
9902 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9903 IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ();
9904 IEM_MC_FETCH_FSW(u16Tmp);
9905 IEM_MC_STORE_GREG_U16(X86_GREG_xAX, u16Tmp);
9906 IEM_MC_ADVANCE_RIP();
9907 IEM_MC_END();
9908 return VINF_SUCCESS;
9909}
9910
9911
9912/** Opcode 0xdf 11/5. */
9913FNIEMOP_DEF_1(iemOp_fucomip_st0_stN, uint8_t, bRm)
9914{
9915 IEMOP_MNEMONIC(fucomip_st0_stN, "fucomip st0,stN");
9916 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fcomi_r80_by_r80, true /*fPop*/);
9917}
9918
9919
9920/** Opcode 0xdf 11/6. */
9921FNIEMOP_DEF_1(iemOp_fcomip_st0_stN, uint8_t, bRm)
9922{
9923 IEMOP_MNEMONIC(fcomip_st0_stN, "fcomip st0,stN");
9924 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fcomi_r80_by_r80, true /*fPop*/);
9925}
9926
9927
9928/** Opcode 0xdf !11/0. */
9929FNIEMOP_DEF_1(iemOp_fild_m16i, uint8_t, bRm)
9930{
9931 IEMOP_MNEMONIC(fild_m16i, "fild m16i");
9932
9933 IEM_MC_BEGIN(2, 3);
9934 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
9935 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
9936 IEM_MC_LOCAL(int16_t, i16Val);
9937 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
9938 IEM_MC_ARG_LOCAL_REF(int16_t const *, pi16Val, i16Val, 1);
9939
9940 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
9941 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9942
9943 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9944 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9945 IEM_MC_FETCH_MEM_I16(i16Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9946
9947 IEM_MC_PREPARE_FPU_USAGE();
9948 IEM_MC_IF_FPUREG_IS_EMPTY(7)
9949 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fild_i16_to_r80, pFpuRes, pi16Val);
9950 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9951 IEM_MC_ELSE()
9952 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
9953 IEM_MC_ENDIF();
9954 IEM_MC_ADVANCE_RIP();
9955
9956 IEM_MC_END();
9957 return VINF_SUCCESS;
9958}
9959
9960
9961/** Opcode 0xdf !11/1. */
9962FNIEMOP_DEF_1(iemOp_fisttp_m16i, uint8_t, bRm)
9963{
9964 IEMOP_MNEMONIC(fisttp_m16i, "fisttp m16i");
9965 IEM_MC_BEGIN(3, 2);
9966 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
9967 IEM_MC_LOCAL(uint16_t, u16Fsw);
9968 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
9969 IEM_MC_ARG(int16_t *, pi16Dst, 1);
9970 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
9971
9972 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
9973 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
9974 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
9975 IEM_MC_MAYBE_RAISE_FPU_XCPT();
9976
9977 IEM_MC_MEM_MAP(pi16Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
9978 IEM_MC_PREPARE_FPU_USAGE();
9979 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
9980 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i16, pu16Fsw, pi16Dst, pr80Value);
9981 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi16Dst, IEM_ACCESS_DATA_W, u16Fsw);
9982 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9983 IEM_MC_ELSE()
9984 IEM_MC_IF_FCW_IM()
9985 IEM_MC_STORE_MEM_I16_CONST_BY_REF(pi16Dst, INT16_MIN /* (integer indefinite) */);
9986 IEM_MC_MEM_COMMIT_AND_UNMAP(pi16Dst, IEM_ACCESS_DATA_W);
9987 IEM_MC_ENDIF();
9988 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
9989 IEM_MC_ENDIF();
9990 IEM_MC_ADVANCE_RIP();
9991
9992 IEM_MC_END();
9993 return VINF_SUCCESS;
9994}
9995
9996
9997/** Opcode 0xdf !11/2. */
9998FNIEMOP_DEF_1(iemOp_fist_m16i, uint8_t, bRm)
9999{
10000 IEMOP_MNEMONIC(fist_m16i, "fist m16i");
10001 IEM_MC_BEGIN(3, 2);
10002 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10003 IEM_MC_LOCAL(uint16_t, u16Fsw);
10004 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10005 IEM_MC_ARG(int16_t *, pi16Dst, 1);
10006 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10007
10008 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10009 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10010 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10011 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10012
10013 IEM_MC_MEM_MAP(pi16Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
10014 IEM_MC_PREPARE_FPU_USAGE();
10015 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
10016 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i16, pu16Fsw, pi16Dst, pr80Value);
10017 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi16Dst, IEM_ACCESS_DATA_W, u16Fsw);
10018 IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10019 IEM_MC_ELSE()
10020 IEM_MC_IF_FCW_IM()
10021 IEM_MC_STORE_MEM_I16_CONST_BY_REF(pi16Dst, INT16_MIN /* (integer indefinite) */);
10022 IEM_MC_MEM_COMMIT_AND_UNMAP(pi16Dst, IEM_ACCESS_DATA_W);
10023 IEM_MC_ENDIF();
10024 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10025 IEM_MC_ENDIF();
10026 IEM_MC_ADVANCE_RIP();
10027
10028 IEM_MC_END();
10029 return VINF_SUCCESS;
10030}
10031
10032
10033/** Opcode 0xdf !11/3. */
10034FNIEMOP_DEF_1(iemOp_fistp_m16i, uint8_t, bRm)
10035{
10036 IEMOP_MNEMONIC(fistp_m16i, "fistp m16i");
10037 IEM_MC_BEGIN(3, 2);
10038 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10039 IEM_MC_LOCAL(uint16_t, u16Fsw);
10040 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10041 IEM_MC_ARG(int16_t *, pi16Dst, 1);
10042 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10043
10044 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10045 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10046 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10047 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10048
10049 IEM_MC_MEM_MAP(pi16Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
10050 IEM_MC_PREPARE_FPU_USAGE();
10051 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
10052 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i16, pu16Fsw, pi16Dst, pr80Value);
10053 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi16Dst, IEM_ACCESS_DATA_W, u16Fsw);
10054 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10055 IEM_MC_ELSE()
10056 IEM_MC_IF_FCW_IM()
10057 IEM_MC_STORE_MEM_I16_CONST_BY_REF(pi16Dst, INT16_MIN /* (integer indefinite) */);
10058 IEM_MC_MEM_COMMIT_AND_UNMAP(pi16Dst, IEM_ACCESS_DATA_W);
10059 IEM_MC_ENDIF();
10060 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10061 IEM_MC_ENDIF();
10062 IEM_MC_ADVANCE_RIP();
10063
10064 IEM_MC_END();
10065 return VINF_SUCCESS;
10066}
10067
10068
10069/** Opcode 0xdf !11/4. */
10070FNIEMOP_STUB_1(iemOp_fbld_m80d, uint8_t, bRm);
10071
10072
10073/** Opcode 0xdf !11/5. */
10074FNIEMOP_DEF_1(iemOp_fild_m64i, uint8_t, bRm)
10075{
10076 IEMOP_MNEMONIC(fild_m64i, "fild m64i");
10077
10078 IEM_MC_BEGIN(2, 3);
10079 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
10080 IEM_MC_LOCAL(IEMFPURESULT, FpuRes);
10081 IEM_MC_LOCAL(int64_t, i64Val);
10082 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0);
10083 IEM_MC_ARG_LOCAL_REF(int64_t const *, pi64Val, i64Val, 1);
10084
10085 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
10086 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10087
10088 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10089 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10090 IEM_MC_FETCH_MEM_I64(i64Val, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10091
10092 IEM_MC_PREPARE_FPU_USAGE();
10093 IEM_MC_IF_FPUREG_IS_EMPTY(7)
10094 IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fild_i64_to_r80, pFpuRes, pi64Val);
10095 IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10096 IEM_MC_ELSE()
10097 IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
10098 IEM_MC_ENDIF();
10099 IEM_MC_ADVANCE_RIP();
10100
10101 IEM_MC_END();
10102 return VINF_SUCCESS;
10103}
10104
10105
10106/** Opcode 0xdf !11/6. */
10107FNIEMOP_DEF_1(iemOp_fbstp_m80d, uint8_t, bRm)
10108{
10109 IEMOP_MNEMONIC(fbstp_m80d, "fbstp m80d");
10110 IEM_MC_BEGIN(3, 2);
10111 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10112 IEM_MC_LOCAL(uint16_t, u16Fsw);
10113 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10114 IEM_MC_ARG(PRTPBCD80U, pd80Dst, 1);
10115 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10116
10117 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10118 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10119 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10120 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10121
10122 IEM_MC_MEM_MAP(pd80Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
10123 IEM_MC_PREPARE_FPU_USAGE();
10124 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
10125 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_d80, pu16Fsw, pd80Dst, pr80Value);
10126 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pd80Dst, IEM_ACCESS_DATA_W, u16Fsw);
10127 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10128 IEM_MC_ELSE()
10129 IEM_MC_IF_FCW_IM()
10130 IEM_MC_STORE_MEM_INDEF_D80_BY_REF(pd80Dst);
10131 IEM_MC_MEM_COMMIT_AND_UNMAP(pd80Dst, IEM_ACCESS_DATA_W);
10132 IEM_MC_ENDIF();
10133 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10134 IEM_MC_ENDIF();
10135 IEM_MC_ADVANCE_RIP();
10136
10137 IEM_MC_END();
10138 return VINF_SUCCESS;
10139}
10140
10141
10142/** Opcode 0xdf !11/7. */
10143FNIEMOP_DEF_1(iemOp_fistp_m64i, uint8_t, bRm)
10144{
10145 IEMOP_MNEMONIC(fistp_m64i, "fistp m64i");
10146 IEM_MC_BEGIN(3, 2);
10147 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10148 IEM_MC_LOCAL(uint16_t, u16Fsw);
10149 IEM_MC_ARG_LOCAL_REF(uint16_t *, pu16Fsw, u16Fsw, 0);
10150 IEM_MC_ARG(int64_t *, pi64Dst, 1);
10151 IEM_MC_ARG(PCRTFLOAT80U, pr80Value, 2);
10152
10153 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10154 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10155 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
10156 IEM_MC_MAYBE_RAISE_FPU_XCPT();
10157
10158 IEM_MC_MEM_MAP(pi64Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
10159 IEM_MC_PREPARE_FPU_USAGE();
10160 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
10161 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i64, pu16Fsw, pi64Dst, pr80Value);
10162 IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi64Dst, IEM_ACCESS_DATA_W, u16Fsw);
10163 IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10164 IEM_MC_ELSE()
10165 IEM_MC_IF_FCW_IM()
10166 IEM_MC_STORE_MEM_I64_CONST_BY_REF(pi64Dst, INT64_MIN /* (integer indefinite) */);
10167 IEM_MC_MEM_COMMIT_AND_UNMAP(pi64Dst, IEM_ACCESS_DATA_W);
10168 IEM_MC_ENDIF();
10169 IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
10170 IEM_MC_ENDIF();
10171 IEM_MC_ADVANCE_RIP();
10172
10173 IEM_MC_END();
10174 return VINF_SUCCESS;
10175}
10176
10177
10178/**
10179 * @opcode 0xdf
10180 */
10181FNIEMOP_DEF(iemOp_EscF7)
10182{
10183 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
10184 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
10185 {
10186 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
10187 {
10188 case 0: return FNIEMOP_CALL_1(iemOp_ffreep_stN, bRm); /* ffree + pop afterwards, since forever according to AMD. */
10189 case 1: return FNIEMOP_CALL_1(iemOp_fxch_stN, bRm); /* Reserved, behaves like FXCH ST(i) on intel. */
10190 case 2: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm); /* Reserved, behaves like FSTP ST(i) on intel. */
10191 case 3: return FNIEMOP_CALL_1(iemOp_fstp_stN, bRm); /* Reserved, behaves like FSTP ST(i) on intel. */
10192 case 4: if (bRm == 0xe0)
10193 return FNIEMOP_CALL(iemOp_fnstsw_ax);
10194 return IEMOP_RAISE_INVALID_OPCODE();
10195 case 5: return FNIEMOP_CALL_1(iemOp_fucomip_st0_stN, bRm);
10196 case 6: return FNIEMOP_CALL_1(iemOp_fcomip_st0_stN, bRm);
10197 case 7: return IEMOP_RAISE_INVALID_OPCODE();
10198 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10199 }
10200 }
10201 else
10202 {
10203 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
10204 {
10205 case 0: return FNIEMOP_CALL_1(iemOp_fild_m16i, bRm);
10206 case 1: return FNIEMOP_CALL_1(iemOp_fisttp_m16i, bRm);
10207 case 2: return FNIEMOP_CALL_1(iemOp_fist_m16i, bRm);
10208 case 3: return FNIEMOP_CALL_1(iemOp_fistp_m16i, bRm);
10209 case 4: return FNIEMOP_CALL_1(iemOp_fbld_m80d, bRm);
10210 case 5: return FNIEMOP_CALL_1(iemOp_fild_m64i, bRm);
10211 case 6: return FNIEMOP_CALL_1(iemOp_fbstp_m80d, bRm);
10212 case 7: return FNIEMOP_CALL_1(iemOp_fistp_m64i, bRm);
10213 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10214 }
10215 }
10216}
10217
10218
10219/**
10220 * @opcode 0xe0
10221 */
10222FNIEMOP_DEF(iemOp_loopne_Jb)
10223{
10224 IEMOP_MNEMONIC(loopne_Jb, "loopne Jb");
10225 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
10226 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10227 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10228
10229 switch (pVCpu->iem.s.enmEffAddrMode)
10230 {
10231 case IEMMODE_16BIT:
10232 IEM_MC_BEGIN(0,0);
10233 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
10234 IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
10235 IEM_MC_REL_JMP_S8(i8Imm);
10236 } IEM_MC_ELSE() {
10237 IEM_MC_ADVANCE_RIP();
10238 } IEM_MC_ENDIF();
10239 IEM_MC_END();
10240 return VINF_SUCCESS;
10241
10242 case IEMMODE_32BIT:
10243 IEM_MC_BEGIN(0,0);
10244 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
10245 IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
10246 IEM_MC_REL_JMP_S8(i8Imm);
10247 } IEM_MC_ELSE() {
10248 IEM_MC_ADVANCE_RIP();
10249 } IEM_MC_ENDIF();
10250 IEM_MC_END();
10251 return VINF_SUCCESS;
10252
10253 case IEMMODE_64BIT:
10254 IEM_MC_BEGIN(0,0);
10255 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
10256 IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_NOT_SET(X86_EFL_ZF) {
10257 IEM_MC_REL_JMP_S8(i8Imm);
10258 } IEM_MC_ELSE() {
10259 IEM_MC_ADVANCE_RIP();
10260 } IEM_MC_ENDIF();
10261 IEM_MC_END();
10262 return VINF_SUCCESS;
10263
10264 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10265 }
10266}
10267
10268
10269/**
10270 * @opcode 0xe1
10271 */
10272FNIEMOP_DEF(iemOp_loope_Jb)
10273{
10274 IEMOP_MNEMONIC(loope_Jb, "loope Jb");
10275 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
10276 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10277 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10278
10279 switch (pVCpu->iem.s.enmEffAddrMode)
10280 {
10281 case IEMMODE_16BIT:
10282 IEM_MC_BEGIN(0,0);
10283 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
10284 IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
10285 IEM_MC_REL_JMP_S8(i8Imm);
10286 } IEM_MC_ELSE() {
10287 IEM_MC_ADVANCE_RIP();
10288 } IEM_MC_ENDIF();
10289 IEM_MC_END();
10290 return VINF_SUCCESS;
10291
10292 case IEMMODE_32BIT:
10293 IEM_MC_BEGIN(0,0);
10294 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
10295 IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
10296 IEM_MC_REL_JMP_S8(i8Imm);
10297 } IEM_MC_ELSE() {
10298 IEM_MC_ADVANCE_RIP();
10299 } IEM_MC_ENDIF();
10300 IEM_MC_END();
10301 return VINF_SUCCESS;
10302
10303 case IEMMODE_64BIT:
10304 IEM_MC_BEGIN(0,0);
10305 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
10306 IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_SET(X86_EFL_ZF) {
10307 IEM_MC_REL_JMP_S8(i8Imm);
10308 } IEM_MC_ELSE() {
10309 IEM_MC_ADVANCE_RIP();
10310 } IEM_MC_ENDIF();
10311 IEM_MC_END();
10312 return VINF_SUCCESS;
10313
10314 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10315 }
10316}
10317
10318
10319/**
10320 * @opcode 0xe2
10321 */
10322FNIEMOP_DEF(iemOp_loop_Jb)
10323{
10324 IEMOP_MNEMONIC(loop_Jb, "loop Jb");
10325 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
10326 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10327 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10328
10329 /** @todo Check out the #GP case if EIP < CS.Base or EIP > CS.Limit when
10330 * using the 32-bit operand size override. How can that be restarted? See
10331 * weird pseudo code in intel manual. */
10332
10333 /** NB: At least Windows for Workgroups 3.11 (NDIS.386) and Windows 95 (NDIS.VXD, IOS)
10334 * use LOOP $-2 to implement NdisStallExecution and other CPU stall APIs. Shortcutting
10335 * the loop causes guest crashes, but when logging it's nice to skip a few million
10336 * lines of useless output. */
10337#if defined(LOG_ENABLED)
10338 if ((LogIs3Enabled() || LogIs4Enabled()) && (-(int8_t)IEM_GET_INSTR_LEN(pVCpu) == i8Imm))
10339 switch (pVCpu->iem.s.enmEffAddrMode)
10340 {
10341 case IEMMODE_16BIT:
10342 IEM_MC_BEGIN(0,0);
10343 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xCX, 0);
10344 IEM_MC_ADVANCE_RIP();
10345 IEM_MC_END();
10346 return VINF_SUCCESS;
10347
10348 case IEMMODE_32BIT:
10349 IEM_MC_BEGIN(0,0);
10350 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xCX, 0);
10351 IEM_MC_ADVANCE_RIP();
10352 IEM_MC_END();
10353 return VINF_SUCCESS;
10354
10355 case IEMMODE_64BIT:
10356 IEM_MC_BEGIN(0,0);
10357 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xCX, 0);
10358 IEM_MC_ADVANCE_RIP();
10359 IEM_MC_END();
10360 return VINF_SUCCESS;
10361
10362 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10363 }
10364#endif
10365
10366 switch (pVCpu->iem.s.enmEffAddrMode)
10367 {
10368 case IEMMODE_16BIT:
10369 IEM_MC_BEGIN(0,0);
10370
10371 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
10372 IEM_MC_IF_CX_IS_NZ() {
10373 IEM_MC_REL_JMP_S8(i8Imm);
10374 } IEM_MC_ELSE() {
10375 IEM_MC_ADVANCE_RIP();
10376 } IEM_MC_ENDIF();
10377 IEM_MC_END();
10378 return VINF_SUCCESS;
10379
10380 case IEMMODE_32BIT:
10381 IEM_MC_BEGIN(0,0);
10382 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
10383 IEM_MC_IF_ECX_IS_NZ() {
10384 IEM_MC_REL_JMP_S8(i8Imm);
10385 } IEM_MC_ELSE() {
10386 IEM_MC_ADVANCE_RIP();
10387 } IEM_MC_ENDIF();
10388 IEM_MC_END();
10389 return VINF_SUCCESS;
10390
10391 case IEMMODE_64BIT:
10392 IEM_MC_BEGIN(0,0);
10393 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
10394 IEM_MC_IF_RCX_IS_NZ() {
10395 IEM_MC_REL_JMP_S8(i8Imm);
10396 } IEM_MC_ELSE() {
10397 IEM_MC_ADVANCE_RIP();
10398 } IEM_MC_ENDIF();
10399 IEM_MC_END();
10400 return VINF_SUCCESS;
10401
10402 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10403 }
10404}
10405
10406
10407/**
10408 * @opcode 0xe3
10409 */
10410FNIEMOP_DEF(iemOp_jecxz_Jb)
10411{
10412 IEMOP_MNEMONIC(jecxz_Jb, "jecxz Jb");
10413 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
10414 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10415 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10416
10417 switch (pVCpu->iem.s.enmEffAddrMode)
10418 {
10419 case IEMMODE_16BIT:
10420 IEM_MC_BEGIN(0,0);
10421 IEM_MC_IF_CX_IS_NZ() {
10422 IEM_MC_ADVANCE_RIP();
10423 } IEM_MC_ELSE() {
10424 IEM_MC_REL_JMP_S8(i8Imm);
10425 } IEM_MC_ENDIF();
10426 IEM_MC_END();
10427 return VINF_SUCCESS;
10428
10429 case IEMMODE_32BIT:
10430 IEM_MC_BEGIN(0,0);
10431 IEM_MC_IF_ECX_IS_NZ() {
10432 IEM_MC_ADVANCE_RIP();
10433 } IEM_MC_ELSE() {
10434 IEM_MC_REL_JMP_S8(i8Imm);
10435 } IEM_MC_ENDIF();
10436 IEM_MC_END();
10437 return VINF_SUCCESS;
10438
10439 case IEMMODE_64BIT:
10440 IEM_MC_BEGIN(0,0);
10441 IEM_MC_IF_RCX_IS_NZ() {
10442 IEM_MC_ADVANCE_RIP();
10443 } IEM_MC_ELSE() {
10444 IEM_MC_REL_JMP_S8(i8Imm);
10445 } IEM_MC_ENDIF();
10446 IEM_MC_END();
10447 return VINF_SUCCESS;
10448
10449 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10450 }
10451}
10452
10453
10454/** Opcode 0xe4 */
10455FNIEMOP_DEF(iemOp_in_AL_Ib)
10456{
10457 IEMOP_MNEMONIC(in_AL_Ib, "in AL,Ib");
10458 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
10459 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10460 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_in, u8Imm, true /* fImm */, 1);
10461}
10462
10463
10464/** Opcode 0xe5 */
10465FNIEMOP_DEF(iemOp_in_eAX_Ib)
10466{
10467 IEMOP_MNEMONIC(in_eAX_Ib, "in eAX,Ib");
10468 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
10469 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10470 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_in, u8Imm, true /* fImm */, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
10471}
10472
10473
10474/** Opcode 0xe6 */
10475FNIEMOP_DEF(iemOp_out_Ib_AL)
10476{
10477 IEMOP_MNEMONIC(out_Ib_AL, "out Ib,AL");
10478 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
10479 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10480 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_out, u8Imm, true /* fImm */, 1);
10481}
10482
10483
10484/** Opcode 0xe7 */
10485FNIEMOP_DEF(iemOp_out_Ib_eAX)
10486{
10487 IEMOP_MNEMONIC(out_Ib_eAX, "out Ib,eAX");
10488 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
10489 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10490 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_out, u8Imm, true /* fImm */, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
10491}
10492
10493
10494/**
10495 * @opcode 0xe8
10496 */
10497FNIEMOP_DEF(iemOp_call_Jv)
10498{
10499 IEMOP_MNEMONIC(call_Jv, "call Jv");
10500 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10501 switch (pVCpu->iem.s.enmEffOpSize)
10502 {
10503 case IEMMODE_16BIT:
10504 {
10505 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
10506 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_16, (int16_t)u16Imm);
10507 }
10508
10509 case IEMMODE_32BIT:
10510 {
10511 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
10512 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_32, (int32_t)u32Imm);
10513 }
10514
10515 case IEMMODE_64BIT:
10516 {
10517 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
10518 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_64, u64Imm);
10519 }
10520
10521 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10522 }
10523}
10524
10525
10526/**
10527 * @opcode 0xe9
10528 */
10529FNIEMOP_DEF(iemOp_jmp_Jv)
10530{
10531 IEMOP_MNEMONIC(jmp_Jv, "jmp Jv");
10532 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10533 switch (pVCpu->iem.s.enmEffOpSize)
10534 {
10535 case IEMMODE_16BIT:
10536 {
10537 int16_t i16Imm; IEM_OPCODE_GET_NEXT_S16(&i16Imm);
10538 IEM_MC_BEGIN(0, 0);
10539 IEM_MC_REL_JMP_S16(i16Imm);
10540 IEM_MC_END();
10541 return VINF_SUCCESS;
10542 }
10543
10544 case IEMMODE_64BIT:
10545 case IEMMODE_32BIT:
10546 {
10547 int32_t i32Imm; IEM_OPCODE_GET_NEXT_S32(&i32Imm);
10548 IEM_MC_BEGIN(0, 0);
10549 IEM_MC_REL_JMP_S32(i32Imm);
10550 IEM_MC_END();
10551 return VINF_SUCCESS;
10552 }
10553
10554 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10555 }
10556}
10557
10558
10559/**
10560 * @opcode 0xea
10561 */
10562FNIEMOP_DEF(iemOp_jmp_Ap)
10563{
10564 IEMOP_MNEMONIC(jmp_Ap, "jmp Ap");
10565 IEMOP_HLP_NO_64BIT();
10566
10567 /* Decode the far pointer address and pass it on to the far call C implementation. */
10568 uint32_t offSeg;
10569 if (pVCpu->iem.s.enmEffOpSize != IEMMODE_16BIT)
10570 IEM_OPCODE_GET_NEXT_U32(&offSeg);
10571 else
10572 IEM_OPCODE_GET_NEXT_U16_ZX_U32(&offSeg);
10573 uint16_t uSel; IEM_OPCODE_GET_NEXT_U16(&uSel);
10574 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10575 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_FarJmp, uSel, offSeg, pVCpu->iem.s.enmEffOpSize);
10576}
10577
10578
10579/**
10580 * @opcode 0xeb
10581 */
10582FNIEMOP_DEF(iemOp_jmp_Jb)
10583{
10584 IEMOP_MNEMONIC(jmp_Jb, "jmp Jb");
10585 int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
10586 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10587 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
10588
10589 IEM_MC_BEGIN(0, 0);
10590 IEM_MC_REL_JMP_S8(i8Imm);
10591 IEM_MC_END();
10592 return VINF_SUCCESS;
10593}
10594
10595
10596/** Opcode 0xec */
10597FNIEMOP_DEF(iemOp_in_AL_DX)
10598{
10599 IEMOP_MNEMONIC(in_AL_DX, "in AL,DX");
10600 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10601 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_in_eAX_DX, 1);
10602}
10603
10604
10605/** Opcode 0xed */
10606FNIEMOP_DEF(iemOp_in_eAX_DX)
10607{
10608 IEMOP_MNEMONIC(in_eAX_DX, "in eAX,DX");
10609 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10610 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_in_eAX_DX, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
10611}
10612
10613
10614/** Opcode 0xee */
10615FNIEMOP_DEF(iemOp_out_DX_AL)
10616{
10617 IEMOP_MNEMONIC(out_DX_AL, "out DX,AL");
10618 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10619 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_out_DX_eAX, 1);
10620}
10621
10622
10623/** Opcode 0xef */
10624FNIEMOP_DEF(iemOp_out_DX_eAX)
10625{
10626 IEMOP_MNEMONIC(out_DX_eAX, "out DX,eAX");
10627 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10628 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_out_DX_eAX, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4);
10629}
10630
10631
10632/**
10633 * @opcode 0xf0
10634 */
10635FNIEMOP_DEF(iemOp_lock)
10636{
10637 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("lock");
10638 if (!pVCpu->iem.s.fDisregardLock)
10639 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_LOCK;
10640
10641 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
10642 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
10643}
10644
10645
10646/**
10647 * @opcode 0xf1
10648 */
10649FNIEMOP_DEF(iemOp_int1)
10650{
10651 IEMOP_MNEMONIC(int1, "int1"); /* icebp */
10652 /** @todo Does not generate #UD on 286, or so they say... Was allegedly a
10653 * prefix byte on 8086 and/or/maybe 80286 without meaning according to the 286
10654 * LOADALL memo. Needs some testing. */
10655 IEMOP_HLP_MIN_386();
10656 /** @todo testcase! */
10657 return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_int, X86_XCPT_DB, IEMINT_INT1);
10658}
10659
10660
10661/**
10662 * @opcode 0xf2
10663 */
10664FNIEMOP_DEF(iemOp_repne)
10665{
10666 /* This overrides any previous REPE prefix. */
10667 pVCpu->iem.s.fPrefixes &= ~IEM_OP_PRF_REPZ;
10668 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("repne");
10669 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REPNZ;
10670
10671 /* For the 4 entry opcode tables, REPNZ overrides any previous
10672 REPZ and operand size prefixes. */
10673 pVCpu->iem.s.idxPrefix = 3;
10674
10675 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
10676 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
10677}
10678
10679
10680/**
10681 * @opcode 0xf3
10682 */
10683FNIEMOP_DEF(iemOp_repe)
10684{
10685 /* This overrides any previous REPNE prefix. */
10686 pVCpu->iem.s.fPrefixes &= ~IEM_OP_PRF_REPNZ;
10687 IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE("repe");
10688 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_REPZ;
10689
10690 /* For the 4 entry opcode tables, REPNZ overrides any previous
10691 REPNZ and operand size prefixes. */
10692 pVCpu->iem.s.idxPrefix = 2;
10693
10694 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
10695 return FNIEMOP_CALL(g_apfnOneByteMap[b]);
10696}
10697
10698
10699/**
10700 * @opcode 0xf4
10701 */
10702FNIEMOP_DEF(iemOp_hlt)
10703{
10704 IEMOP_MNEMONIC(hlt, "hlt");
10705 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10706 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_hlt);
10707}
10708
10709
10710/**
10711 * @opcode 0xf5
10712 */
10713FNIEMOP_DEF(iemOp_cmc)
10714{
10715 IEMOP_MNEMONIC(cmc, "cmc");
10716 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10717 IEM_MC_BEGIN(0, 0);
10718 IEM_MC_FLIP_EFL_BIT(X86_EFL_CF);
10719 IEM_MC_ADVANCE_RIP();
10720 IEM_MC_END();
10721 return VINF_SUCCESS;
10722}
10723
10724
10725/**
10726 * Common implementation of 'inc/dec/not/neg Eb'.
10727 *
10728 * @param bRm The RM byte.
10729 * @param pImpl The instruction implementation.
10730 */
10731FNIEMOP_DEF_2(iemOpCommonUnaryEb, uint8_t, bRm, PCIEMOPUNARYSIZES, pImpl)
10732{
10733 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
10734 {
10735 /* register access */
10736 IEM_MC_BEGIN(2, 0);
10737 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
10738 IEM_MC_ARG(uint32_t *, pEFlags, 1);
10739 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
10740 IEM_MC_REF_EFLAGS(pEFlags);
10741 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU8, pu8Dst, pEFlags);
10742 IEM_MC_ADVANCE_RIP();
10743 IEM_MC_END();
10744 }
10745 else
10746 {
10747 /* memory access. */
10748 IEM_MC_BEGIN(2, 2);
10749 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
10750 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
10751 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10752
10753 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10754 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
10755 IEM_MC_FETCH_EFLAGS(EFlags);
10756 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
10757 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU8, pu8Dst, pEFlags);
10758 else
10759 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU8, pu8Dst, pEFlags);
10760
10761 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_RW);
10762 IEM_MC_COMMIT_EFLAGS(EFlags);
10763 IEM_MC_ADVANCE_RIP();
10764 IEM_MC_END();
10765 }
10766 return VINF_SUCCESS;
10767}
10768
10769
10770/**
10771 * Common implementation of 'inc/dec/not/neg Ev'.
10772 *
10773 * @param bRm The RM byte.
10774 * @param pImpl The instruction implementation.
10775 */
10776FNIEMOP_DEF_2(iemOpCommonUnaryEv, uint8_t, bRm, PCIEMOPUNARYSIZES, pImpl)
10777{
10778 /* Registers are handled by a common worker. */
10779 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
10780 return FNIEMOP_CALL_2(iemOpCommonUnaryGReg, pImpl, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
10781
10782 /* Memory we do here. */
10783 switch (pVCpu->iem.s.enmEffOpSize)
10784 {
10785 case IEMMODE_16BIT:
10786 IEM_MC_BEGIN(2, 2);
10787 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
10788 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
10789 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10790
10791 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10792 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
10793 IEM_MC_FETCH_EFLAGS(EFlags);
10794 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
10795 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU16, pu16Dst, pEFlags);
10796 else
10797 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU16, pu16Dst, pEFlags);
10798
10799 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_RW);
10800 IEM_MC_COMMIT_EFLAGS(EFlags);
10801 IEM_MC_ADVANCE_RIP();
10802 IEM_MC_END();
10803 return VINF_SUCCESS;
10804
10805 case IEMMODE_32BIT:
10806 IEM_MC_BEGIN(2, 2);
10807 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
10808 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
10809 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10810
10811 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10812 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
10813 IEM_MC_FETCH_EFLAGS(EFlags);
10814 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
10815 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU32, pu32Dst, pEFlags);
10816 else
10817 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU32, pu32Dst, pEFlags);
10818
10819 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_RW);
10820 IEM_MC_COMMIT_EFLAGS(EFlags);
10821 IEM_MC_ADVANCE_RIP();
10822 IEM_MC_END();
10823 return VINF_SUCCESS;
10824
10825 case IEMMODE_64BIT:
10826 IEM_MC_BEGIN(2, 2);
10827 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
10828 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 1);
10829 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10830
10831 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
10832 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_RW, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
10833 IEM_MC_FETCH_EFLAGS(EFlags);
10834 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
10835 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnNormalU64, pu64Dst, pEFlags);
10836 else
10837 IEM_MC_CALL_VOID_AIMPL_2(pImpl->pfnLockedU64, pu64Dst, pEFlags);
10838
10839 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_RW);
10840 IEM_MC_COMMIT_EFLAGS(EFlags);
10841 IEM_MC_ADVANCE_RIP();
10842 IEM_MC_END();
10843 return VINF_SUCCESS;
10844
10845 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10846 }
10847}
10848
10849
10850/** Opcode 0xf6 /0. */
10851FNIEMOP_DEF_1(iemOp_grp3_test_Eb, uint8_t, bRm)
10852{
10853 IEMOP_MNEMONIC(test_Eb_Ib, "test Eb,Ib");
10854 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
10855
10856 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
10857 {
10858 /* register access */
10859 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
10860 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10861
10862 IEM_MC_BEGIN(3, 0);
10863 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
10864 IEM_MC_ARG_CONST(uint8_t, u8Src,/*=*/u8Imm, 1);
10865 IEM_MC_ARG(uint32_t *, pEFlags, 2);
10866 IEM_MC_REF_GREG_U8(pu8Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
10867 IEM_MC_REF_EFLAGS(pEFlags);
10868 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
10869 IEM_MC_ADVANCE_RIP();
10870 IEM_MC_END();
10871 }
10872 else
10873 {
10874 /* memory access. */
10875 IEM_MC_BEGIN(3, 2);
10876 IEM_MC_ARG(uint8_t *, pu8Dst, 0);
10877 IEM_MC_ARG(uint8_t, u8Src, 1);
10878 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
10879 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10880
10881 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 1);
10882 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
10883 IEM_MC_ASSIGN(u8Src, u8Imm);
10884 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10885 IEM_MC_MEM_MAP(pu8Dst, IEM_ACCESS_DATA_R, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
10886 IEM_MC_FETCH_EFLAGS(EFlags);
10887 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
10888
10889 IEM_MC_MEM_COMMIT_AND_UNMAP(pu8Dst, IEM_ACCESS_DATA_R);
10890 IEM_MC_COMMIT_EFLAGS(EFlags);
10891 IEM_MC_ADVANCE_RIP();
10892 IEM_MC_END();
10893 }
10894 return VINF_SUCCESS;
10895}
10896
10897
10898/** Opcode 0xf7 /0. */
10899FNIEMOP_DEF_1(iemOp_grp3_test_Ev, uint8_t, bRm)
10900{
10901 IEMOP_MNEMONIC(test_Ev_Iv, "test Ev,Iv");
10902 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
10903
10904 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
10905 {
10906 /* register access */
10907 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10908 switch (pVCpu->iem.s.enmEffOpSize)
10909 {
10910 case IEMMODE_16BIT:
10911 {
10912 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
10913 IEM_MC_BEGIN(3, 0);
10914 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
10915 IEM_MC_ARG_CONST(uint16_t, u16Src,/*=*/u16Imm, 1);
10916 IEM_MC_ARG(uint32_t *, pEFlags, 2);
10917 IEM_MC_REF_GREG_U16(pu16Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
10918 IEM_MC_REF_EFLAGS(pEFlags);
10919 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
10920 IEM_MC_ADVANCE_RIP();
10921 IEM_MC_END();
10922 return VINF_SUCCESS;
10923 }
10924
10925 case IEMMODE_32BIT:
10926 {
10927 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
10928 IEM_MC_BEGIN(3, 0);
10929 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
10930 IEM_MC_ARG_CONST(uint32_t, u32Src,/*=*/u32Imm, 1);
10931 IEM_MC_ARG(uint32_t *, pEFlags, 2);
10932 IEM_MC_REF_GREG_U32(pu32Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
10933 IEM_MC_REF_EFLAGS(pEFlags);
10934 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
10935 /* No clearing the high dword here - test doesn't write back the result. */
10936 IEM_MC_ADVANCE_RIP();
10937 IEM_MC_END();
10938 return VINF_SUCCESS;
10939 }
10940
10941 case IEMMODE_64BIT:
10942 {
10943 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
10944 IEM_MC_BEGIN(3, 0);
10945 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
10946 IEM_MC_ARG_CONST(uint64_t, u64Src,/*=*/u64Imm, 1);
10947 IEM_MC_ARG(uint32_t *, pEFlags, 2);
10948 IEM_MC_REF_GREG_U64(pu64Dst, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
10949 IEM_MC_REF_EFLAGS(pEFlags);
10950 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
10951 IEM_MC_ADVANCE_RIP();
10952 IEM_MC_END();
10953 return VINF_SUCCESS;
10954 }
10955
10956 IEM_NOT_REACHED_DEFAULT_CASE_RET();
10957 }
10958 }
10959 else
10960 {
10961 /* memory access. */
10962 switch (pVCpu->iem.s.enmEffOpSize)
10963 {
10964 case IEMMODE_16BIT:
10965 {
10966 IEM_MC_BEGIN(3, 2);
10967 IEM_MC_ARG(uint16_t *, pu16Dst, 0);
10968 IEM_MC_ARG(uint16_t, u16Src, 1);
10969 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
10970 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10971
10972 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 2);
10973 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
10974 IEM_MC_ASSIGN(u16Src, u16Imm);
10975 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10976 IEM_MC_MEM_MAP(pu16Dst, IEM_ACCESS_DATA_R, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
10977 IEM_MC_FETCH_EFLAGS(EFlags);
10978 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
10979
10980 IEM_MC_MEM_COMMIT_AND_UNMAP(pu16Dst, IEM_ACCESS_DATA_R);
10981 IEM_MC_COMMIT_EFLAGS(EFlags);
10982 IEM_MC_ADVANCE_RIP();
10983 IEM_MC_END();
10984 return VINF_SUCCESS;
10985 }
10986
10987 case IEMMODE_32BIT:
10988 {
10989 IEM_MC_BEGIN(3, 2);
10990 IEM_MC_ARG(uint32_t *, pu32Dst, 0);
10991 IEM_MC_ARG(uint32_t, u32Src, 1);
10992 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
10993 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
10994
10995 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
10996 uint32_t u32Imm; IEM_OPCODE_GET_NEXT_U32(&u32Imm);
10997 IEM_MC_ASSIGN(u32Src, u32Imm);
10998 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
10999 IEM_MC_MEM_MAP(pu32Dst, IEM_ACCESS_DATA_R, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
11000 IEM_MC_FETCH_EFLAGS(EFlags);
11001 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
11002
11003 IEM_MC_MEM_COMMIT_AND_UNMAP(pu32Dst, IEM_ACCESS_DATA_R);
11004 IEM_MC_COMMIT_EFLAGS(EFlags);
11005 IEM_MC_ADVANCE_RIP();
11006 IEM_MC_END();
11007 return VINF_SUCCESS;
11008 }
11009
11010 case IEMMODE_64BIT:
11011 {
11012 IEM_MC_BEGIN(3, 2);
11013 IEM_MC_ARG(uint64_t *, pu64Dst, 0);
11014 IEM_MC_ARG(uint64_t, u64Src, 1);
11015 IEM_MC_ARG_LOCAL_EFLAGS( pEFlags, EFlags, 2);
11016 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11017
11018 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 4);
11019 uint64_t u64Imm; IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64Imm);
11020 IEM_MC_ASSIGN(u64Src, u64Imm);
11021 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11022 IEM_MC_MEM_MAP(pu64Dst, IEM_ACCESS_DATA_R, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 0 /*arg*/);
11023 IEM_MC_FETCH_EFLAGS(EFlags);
11024 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
11025
11026 IEM_MC_MEM_COMMIT_AND_UNMAP(pu64Dst, IEM_ACCESS_DATA_R);
11027 IEM_MC_COMMIT_EFLAGS(EFlags);
11028 IEM_MC_ADVANCE_RIP();
11029 IEM_MC_END();
11030 return VINF_SUCCESS;
11031 }
11032
11033 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11034 }
11035 }
11036}
11037
11038
11039/** Opcode 0xf6 /4, /5, /6 and /7. */
11040FNIEMOP_DEF_2(iemOpCommonGrp3MulDivEb, uint8_t, bRm, PFNIEMAIMPLMULDIVU8, pfnU8)
11041{
11042 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
11043 {
11044 /* register access */
11045 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11046 IEM_MC_BEGIN(3, 1);
11047 IEM_MC_ARG(uint16_t *, pu16AX, 0);
11048 IEM_MC_ARG(uint8_t, u8Value, 1);
11049 IEM_MC_ARG(uint32_t *, pEFlags, 2);
11050 IEM_MC_LOCAL(int32_t, rc);
11051
11052 IEM_MC_FETCH_GREG_U8(u8Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11053 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
11054 IEM_MC_REF_EFLAGS(pEFlags);
11055 IEM_MC_CALL_AIMPL_3(rc, pfnU8, pu16AX, u8Value, pEFlags);
11056 IEM_MC_IF_LOCAL_IS_Z(rc) {
11057 IEM_MC_ADVANCE_RIP();
11058 } IEM_MC_ELSE() {
11059 IEM_MC_RAISE_DIVIDE_ERROR();
11060 } IEM_MC_ENDIF();
11061
11062 IEM_MC_END();
11063 }
11064 else
11065 {
11066 /* memory access. */
11067 IEM_MC_BEGIN(3, 2);
11068 IEM_MC_ARG(uint16_t *, pu16AX, 0);
11069 IEM_MC_ARG(uint8_t, u8Value, 1);
11070 IEM_MC_ARG(uint32_t *, pEFlags, 2);
11071 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11072 IEM_MC_LOCAL(int32_t, rc);
11073
11074 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11075 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11076 IEM_MC_FETCH_MEM_U8(u8Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11077 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
11078 IEM_MC_REF_EFLAGS(pEFlags);
11079 IEM_MC_CALL_AIMPL_3(rc, pfnU8, pu16AX, u8Value, pEFlags);
11080 IEM_MC_IF_LOCAL_IS_Z(rc) {
11081 IEM_MC_ADVANCE_RIP();
11082 } IEM_MC_ELSE() {
11083 IEM_MC_RAISE_DIVIDE_ERROR();
11084 } IEM_MC_ENDIF();
11085
11086 IEM_MC_END();
11087 }
11088 return VINF_SUCCESS;
11089}
11090
11091
11092/** Opcode 0xf7 /4, /5, /6 and /7. */
11093FNIEMOP_DEF_2(iemOpCommonGrp3MulDivEv, uint8_t, bRm, PCIEMOPMULDIVSIZES, pImpl)
11094{
11095 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
11096
11097 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
11098 {
11099 /* register access */
11100 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11101 switch (pVCpu->iem.s.enmEffOpSize)
11102 {
11103 case IEMMODE_16BIT:
11104 {
11105 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11106 IEM_MC_BEGIN(4, 1);
11107 IEM_MC_ARG(uint16_t *, pu16AX, 0);
11108 IEM_MC_ARG(uint16_t *, pu16DX, 1);
11109 IEM_MC_ARG(uint16_t, u16Value, 2);
11110 IEM_MC_ARG(uint32_t *, pEFlags, 3);
11111 IEM_MC_LOCAL(int32_t, rc);
11112
11113 IEM_MC_FETCH_GREG_U16(u16Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11114 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
11115 IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX);
11116 IEM_MC_REF_EFLAGS(pEFlags);
11117 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags);
11118 IEM_MC_IF_LOCAL_IS_Z(rc) {
11119 IEM_MC_ADVANCE_RIP();
11120 } IEM_MC_ELSE() {
11121 IEM_MC_RAISE_DIVIDE_ERROR();
11122 } IEM_MC_ENDIF();
11123
11124 IEM_MC_END();
11125 return VINF_SUCCESS;
11126 }
11127
11128 case IEMMODE_32BIT:
11129 {
11130 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11131 IEM_MC_BEGIN(4, 1);
11132 IEM_MC_ARG(uint32_t *, pu32AX, 0);
11133 IEM_MC_ARG(uint32_t *, pu32DX, 1);
11134 IEM_MC_ARG(uint32_t, u32Value, 2);
11135 IEM_MC_ARG(uint32_t *, pEFlags, 3);
11136 IEM_MC_LOCAL(int32_t, rc);
11137
11138 IEM_MC_FETCH_GREG_U32(u32Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11139 IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX);
11140 IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX);
11141 IEM_MC_REF_EFLAGS(pEFlags);
11142 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags);
11143 IEM_MC_IF_LOCAL_IS_Z(rc) {
11144 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32AX);
11145 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32DX);
11146 IEM_MC_ADVANCE_RIP();
11147 } IEM_MC_ELSE() {
11148 IEM_MC_RAISE_DIVIDE_ERROR();
11149 } IEM_MC_ENDIF();
11150
11151 IEM_MC_END();
11152 return VINF_SUCCESS;
11153 }
11154
11155 case IEMMODE_64BIT:
11156 {
11157 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11158 IEM_MC_BEGIN(4, 1);
11159 IEM_MC_ARG(uint64_t *, pu64AX, 0);
11160 IEM_MC_ARG(uint64_t *, pu64DX, 1);
11161 IEM_MC_ARG(uint64_t, u64Value, 2);
11162 IEM_MC_ARG(uint32_t *, pEFlags, 3);
11163 IEM_MC_LOCAL(int32_t, rc);
11164
11165 IEM_MC_FETCH_GREG_U64(u64Value, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11166 IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX);
11167 IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX);
11168 IEM_MC_REF_EFLAGS(pEFlags);
11169 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags);
11170 IEM_MC_IF_LOCAL_IS_Z(rc) {
11171 IEM_MC_ADVANCE_RIP();
11172 } IEM_MC_ELSE() {
11173 IEM_MC_RAISE_DIVIDE_ERROR();
11174 } IEM_MC_ENDIF();
11175
11176 IEM_MC_END();
11177 return VINF_SUCCESS;
11178 }
11179
11180 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11181 }
11182 }
11183 else
11184 {
11185 /* memory access. */
11186 switch (pVCpu->iem.s.enmEffOpSize)
11187 {
11188 case IEMMODE_16BIT:
11189 {
11190 IEM_MC_BEGIN(4, 2);
11191 IEM_MC_ARG(uint16_t *, pu16AX, 0);
11192 IEM_MC_ARG(uint16_t *, pu16DX, 1);
11193 IEM_MC_ARG(uint16_t, u16Value, 2);
11194 IEM_MC_ARG(uint32_t *, pEFlags, 3);
11195 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11196 IEM_MC_LOCAL(int32_t, rc);
11197
11198 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11199 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11200 IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11201 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
11202 IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX);
11203 IEM_MC_REF_EFLAGS(pEFlags);
11204 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags);
11205 IEM_MC_IF_LOCAL_IS_Z(rc) {
11206 IEM_MC_ADVANCE_RIP();
11207 } IEM_MC_ELSE() {
11208 IEM_MC_RAISE_DIVIDE_ERROR();
11209 } IEM_MC_ENDIF();
11210
11211 IEM_MC_END();
11212 return VINF_SUCCESS;
11213 }
11214
11215 case IEMMODE_32BIT:
11216 {
11217 IEM_MC_BEGIN(4, 2);
11218 IEM_MC_ARG(uint32_t *, pu32AX, 0);
11219 IEM_MC_ARG(uint32_t *, pu32DX, 1);
11220 IEM_MC_ARG(uint32_t, u32Value, 2);
11221 IEM_MC_ARG(uint32_t *, pEFlags, 3);
11222 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11223 IEM_MC_LOCAL(int32_t, rc);
11224
11225 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11226 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11227 IEM_MC_FETCH_MEM_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11228 IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX);
11229 IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX);
11230 IEM_MC_REF_EFLAGS(pEFlags);
11231 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags);
11232 IEM_MC_IF_LOCAL_IS_Z(rc) {
11233 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32AX);
11234 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32DX);
11235 IEM_MC_ADVANCE_RIP();
11236 } IEM_MC_ELSE() {
11237 IEM_MC_RAISE_DIVIDE_ERROR();
11238 } IEM_MC_ENDIF();
11239
11240 IEM_MC_END();
11241 return VINF_SUCCESS;
11242 }
11243
11244 case IEMMODE_64BIT:
11245 {
11246 IEM_MC_BEGIN(4, 2);
11247 IEM_MC_ARG(uint64_t *, pu64AX, 0);
11248 IEM_MC_ARG(uint64_t *, pu64DX, 1);
11249 IEM_MC_ARG(uint64_t, u64Value, 2);
11250 IEM_MC_ARG(uint32_t *, pEFlags, 3);
11251 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
11252 IEM_MC_LOCAL(int32_t, rc);
11253
11254 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
11255 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11256 IEM_MC_FETCH_MEM_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
11257 IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX);
11258 IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX);
11259 IEM_MC_REF_EFLAGS(pEFlags);
11260 IEM_MC_CALL_AIMPL_4(rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags);
11261 IEM_MC_IF_LOCAL_IS_Z(rc) {
11262 IEM_MC_ADVANCE_RIP();
11263 } IEM_MC_ELSE() {
11264 IEM_MC_RAISE_DIVIDE_ERROR();
11265 } IEM_MC_ENDIF();
11266
11267 IEM_MC_END();
11268 return VINF_SUCCESS;
11269 }
11270
11271 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11272 }
11273 }
11274}
11275
11276/**
11277 * @opcode 0xf6
11278 */
11279FNIEMOP_DEF(iemOp_Grp3_Eb)
11280{
11281 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11282 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
11283 {
11284 case 0:
11285 return FNIEMOP_CALL_1(iemOp_grp3_test_Eb, bRm);
11286 case 1:
11287/** @todo testcase: Present on <=386, most 486 (not early), Pentiums, and current CPUs too. CPUUNDOC.EXE */
11288 return IEMOP_RAISE_INVALID_OPCODE();
11289 case 2:
11290 IEMOP_MNEMONIC(not_Eb, "not Eb");
11291 return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_not);
11292 case 3:
11293 IEMOP_MNEMONIC(neg_Eb, "neg Eb");
11294 return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_neg);
11295 case 4:
11296 IEMOP_MNEMONIC(mul_Eb, "mul Eb");
11297 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
11298 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_mul_u8);
11299 case 5:
11300 IEMOP_MNEMONIC(imul_Eb, "imul Eb");
11301 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
11302 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_imul_u8);
11303 case 6:
11304 IEMOP_MNEMONIC(div_Eb, "div Eb");
11305 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
11306 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_div_u8);
11307 case 7:
11308 IEMOP_MNEMONIC(idiv_Eb, "idiv Eb");
11309 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
11310 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_idiv_u8);
11311 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11312 }
11313}
11314
11315
11316/**
11317 * @opcode 0xf7
11318 */
11319FNIEMOP_DEF(iemOp_Grp3_Ev)
11320{
11321 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11322 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
11323 {
11324 case 0:
11325 return FNIEMOP_CALL_1(iemOp_grp3_test_Ev, bRm);
11326 case 1:
11327/** @todo testcase: Present on <=386, most 486 (not early), Pentiums, and current CPUs too. CPUUNDOC.EXE */
11328 return IEMOP_RAISE_INVALID_OPCODE();
11329 case 2:
11330 IEMOP_MNEMONIC(not_Ev, "not Ev");
11331 return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_not);
11332 case 3:
11333 IEMOP_MNEMONIC(neg_Ev, "neg Ev");
11334 return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_neg);
11335 case 4:
11336 IEMOP_MNEMONIC(mul_Ev, "mul Ev");
11337 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
11338 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_mul);
11339 case 5:
11340 IEMOP_MNEMONIC(imul_Ev, "imul Ev");
11341 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
11342 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_imul);
11343 case 6:
11344 IEMOP_MNEMONIC(div_Ev, "div Ev");
11345 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
11346 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_div);
11347 case 7:
11348 IEMOP_MNEMONIC(idiv_Ev, "idiv Ev");
11349 IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
11350 return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_idiv);
11351 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11352 }
11353}
11354
11355
11356/**
11357 * @opcode 0xf8
11358 */
11359FNIEMOP_DEF(iemOp_clc)
11360{
11361 IEMOP_MNEMONIC(clc, "clc");
11362 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11363 IEM_MC_BEGIN(0, 0);
11364 IEM_MC_CLEAR_EFL_BIT(X86_EFL_CF);
11365 IEM_MC_ADVANCE_RIP();
11366 IEM_MC_END();
11367 return VINF_SUCCESS;
11368}
11369
11370
11371/**
11372 * @opcode 0xf9
11373 */
11374FNIEMOP_DEF(iemOp_stc)
11375{
11376 IEMOP_MNEMONIC(stc, "stc");
11377 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11378 IEM_MC_BEGIN(0, 0);
11379 IEM_MC_SET_EFL_BIT(X86_EFL_CF);
11380 IEM_MC_ADVANCE_RIP();
11381 IEM_MC_END();
11382 return VINF_SUCCESS;
11383}
11384
11385
11386/**
11387 * @opcode 0xfa
11388 */
11389FNIEMOP_DEF(iemOp_cli)
11390{
11391 IEMOP_MNEMONIC(cli, "cli");
11392 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11393 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_cli);
11394}
11395
11396
11397FNIEMOP_DEF(iemOp_sti)
11398{
11399 IEMOP_MNEMONIC(sti, "sti");
11400 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11401 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_sti);
11402}
11403
11404
11405/**
11406 * @opcode 0xfc
11407 */
11408FNIEMOP_DEF(iemOp_cld)
11409{
11410 IEMOP_MNEMONIC(cld, "cld");
11411 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11412 IEM_MC_BEGIN(0, 0);
11413 IEM_MC_CLEAR_EFL_BIT(X86_EFL_DF);
11414 IEM_MC_ADVANCE_RIP();
11415 IEM_MC_END();
11416 return VINF_SUCCESS;
11417}
11418
11419
11420/**
11421 * @opcode 0xfd
11422 */
11423FNIEMOP_DEF(iemOp_std)
11424{
11425 IEMOP_MNEMONIC(std, "std");
11426 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11427 IEM_MC_BEGIN(0, 0);
11428 IEM_MC_SET_EFL_BIT(X86_EFL_DF);
11429 IEM_MC_ADVANCE_RIP();
11430 IEM_MC_END();
11431 return VINF_SUCCESS;
11432}
11433
11434
11435/**
11436 * @opcode 0xfe
11437 */
11438FNIEMOP_DEF(iemOp_Grp4)
11439{
11440 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11441 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
11442 {
11443 case 0:
11444 IEMOP_MNEMONIC(inc_Eb, "inc Eb");
11445 return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_inc);
11446 case 1:
11447 IEMOP_MNEMONIC(dec_Eb, "dec Eb");
11448 return FNIEMOP_CALL_2(iemOpCommonUnaryEb, bRm, &g_iemAImpl_dec);
11449 default:
11450 IEMOP_MNEMONIC(grp4_ud, "grp4-ud");
11451 return IEMOP_RAISE_INVALID_OPCODE();
11452 }
11453}
11454
11455
11456/**
11457 * Opcode 0xff /2.
11458 * @param bRm The RM byte.
11459 */
11460FNIEMOP_DEF_1(iemOp_Grp5_calln_Ev, uint8_t, bRm)
11461{
11462 IEMOP_MNEMONIC(calln_Ev, "calln Ev");
11463 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
11464
11465 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
11466 {
11467 /* The new RIP is taken from a register. */
11468 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11469 switch (pVCpu->iem.s.enmEffOpSize)
11470 {
11471 case IEMMODE_16BIT:
11472 IEM_MC_BEGIN(1, 0);
11473 IEM_MC_ARG(uint16_t, u16Target, 0);
11474 IEM_MC_FETCH_GREG_U16(u16Target, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11475 IEM_MC_CALL_CIMPL_1(iemCImpl_call_16, u16Target);
11476 IEM_MC_END()
11477 return VINF_SUCCESS;
11478
11479 case IEMMODE_32BIT:
11480 IEM_MC_BEGIN(1, 0);
11481 IEM_MC_ARG(uint32_t, u32Target, 0);
11482 IEM_MC_FETCH_GREG_U32(u32Target, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11483 IEM_MC_CALL_CIMPL_1(iemCImpl_call_32, u32Target);
11484 IEM_MC_END()
11485 return VINF_SUCCESS;
11486
11487 case IEMMODE_64BIT:
11488 IEM_MC_BEGIN(1, 0);
11489 IEM_MC_ARG(uint64_t, u64Target, 0);
11490 IEM_MC_FETCH_GREG_U64(u64Target, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11491 IEM_MC_CALL_CIMPL_1(iemCImpl_call_64, u64Target);
11492 IEM_MC_END()
11493 return VINF_SUCCESS;
11494
11495 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11496 }
11497 }
11498 else
11499 {
11500 /* The new RIP is taken from a register. */
11501 switch (pVCpu->iem.s.enmEffOpSize)
11502 {
11503 case IEMMODE_16BIT:
11504 IEM_MC_BEGIN(1, 1);
11505 IEM_MC_ARG(uint16_t, u16Target, 0);
11506 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11507 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11508 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11509 IEM_MC_FETCH_MEM_U16(u16Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11510 IEM_MC_CALL_CIMPL_1(iemCImpl_call_16, u16Target);
11511 IEM_MC_END()
11512 return VINF_SUCCESS;
11513
11514 case IEMMODE_32BIT:
11515 IEM_MC_BEGIN(1, 1);
11516 IEM_MC_ARG(uint32_t, u32Target, 0);
11517 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11518 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11519 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11520 IEM_MC_FETCH_MEM_U32(u32Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11521 IEM_MC_CALL_CIMPL_1(iemCImpl_call_32, u32Target);
11522 IEM_MC_END()
11523 return VINF_SUCCESS;
11524
11525 case IEMMODE_64BIT:
11526 IEM_MC_BEGIN(1, 1);
11527 IEM_MC_ARG(uint64_t, u64Target, 0);
11528 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11529 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11530 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11531 IEM_MC_FETCH_MEM_U64(u64Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11532 IEM_MC_CALL_CIMPL_1(iemCImpl_call_64, u64Target);
11533 IEM_MC_END()
11534 return VINF_SUCCESS;
11535
11536 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11537 }
11538 }
11539}
11540
11541typedef IEM_CIMPL_DECL_TYPE_3(FNIEMCIMPLFARBRANCH, uint16_t, uSel, uint64_t, offSeg, IEMMODE, enmOpSize);
11542
11543FNIEMOP_DEF_2(iemOpHlp_Grp5_far_Ep, uint8_t, bRm, FNIEMCIMPLFARBRANCH *, pfnCImpl)
11544{
11545 /* Registers? How?? */
11546 if (RT_LIKELY((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT)))
11547 { /* likely */ }
11548 else
11549 return IEMOP_RAISE_INVALID_OPCODE(); /* callf eax is not legal */
11550
11551 /* Far pointer loaded from memory. */
11552 switch (pVCpu->iem.s.enmEffOpSize)
11553 {
11554 case IEMMODE_16BIT:
11555 IEM_MC_BEGIN(3, 1);
11556 IEM_MC_ARG(uint16_t, u16Sel, 0);
11557 IEM_MC_ARG(uint16_t, offSeg, 1);
11558 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2);
11559 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11560 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11561 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11562 IEM_MC_FETCH_MEM_U16(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11563 IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 2);
11564 IEM_MC_CALL_CIMPL_3(pfnCImpl, u16Sel, offSeg, enmEffOpSize);
11565 IEM_MC_END();
11566 return VINF_SUCCESS;
11567
11568 case IEMMODE_64BIT:
11569 /** @todo testcase: AMD does not seem to believe in the case (see bs-cpu-xcpt-1)
11570 * and will apparently ignore REX.W, at least for the jmp far qword [rsp]
11571 * and call far qword [rsp] encodings. */
11572 if (!IEM_IS_GUEST_CPU_AMD(pVCpu))
11573 {
11574 IEM_MC_BEGIN(3, 1);
11575 IEM_MC_ARG(uint16_t, u16Sel, 0);
11576 IEM_MC_ARG(uint64_t, offSeg, 1);
11577 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_16BIT, 2);
11578 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11579 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11580 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11581 IEM_MC_FETCH_MEM_U64(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11582 IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 8);
11583 IEM_MC_CALL_CIMPL_3(pfnCImpl, u16Sel, offSeg, enmEffOpSize);
11584 IEM_MC_END();
11585 return VINF_SUCCESS;
11586 }
11587 /* AMD falls thru. */
11588 RT_FALL_THRU();
11589
11590 case IEMMODE_32BIT:
11591 IEM_MC_BEGIN(3, 1);
11592 IEM_MC_ARG(uint16_t, u16Sel, 0);
11593 IEM_MC_ARG(uint32_t, offSeg, 1);
11594 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize, IEMMODE_32BIT, 2);
11595 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11596 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11597 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11598 IEM_MC_FETCH_MEM_U32(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11599 IEM_MC_FETCH_MEM_U16_DISP(u16Sel, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 4);
11600 IEM_MC_CALL_CIMPL_3(pfnCImpl, u16Sel, offSeg, enmEffOpSize);
11601 IEM_MC_END();
11602 return VINF_SUCCESS;
11603
11604 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11605 }
11606}
11607
11608
11609/**
11610 * Opcode 0xff /3.
11611 * @param bRm The RM byte.
11612 */
11613FNIEMOP_DEF_1(iemOp_Grp5_callf_Ep, uint8_t, bRm)
11614{
11615 IEMOP_MNEMONIC(callf_Ep, "callf Ep");
11616 return FNIEMOP_CALL_2(iemOpHlp_Grp5_far_Ep, bRm, iemCImpl_callf);
11617}
11618
11619
11620/**
11621 * Opcode 0xff /4.
11622 * @param bRm The RM byte.
11623 */
11624FNIEMOP_DEF_1(iemOp_Grp5_jmpn_Ev, uint8_t, bRm)
11625{
11626 IEMOP_MNEMONIC(jmpn_Ev, "jmpn Ev");
11627 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
11628
11629 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
11630 {
11631 /* The new RIP is taken from a register. */
11632 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11633 switch (pVCpu->iem.s.enmEffOpSize)
11634 {
11635 case IEMMODE_16BIT:
11636 IEM_MC_BEGIN(0, 1);
11637 IEM_MC_LOCAL(uint16_t, u16Target);
11638 IEM_MC_FETCH_GREG_U16(u16Target, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11639 IEM_MC_SET_RIP_U16(u16Target);
11640 IEM_MC_END()
11641 return VINF_SUCCESS;
11642
11643 case IEMMODE_32BIT:
11644 IEM_MC_BEGIN(0, 1);
11645 IEM_MC_LOCAL(uint32_t, u32Target);
11646 IEM_MC_FETCH_GREG_U32(u32Target, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11647 IEM_MC_SET_RIP_U32(u32Target);
11648 IEM_MC_END()
11649 return VINF_SUCCESS;
11650
11651 case IEMMODE_64BIT:
11652 IEM_MC_BEGIN(0, 1);
11653 IEM_MC_LOCAL(uint64_t, u64Target);
11654 IEM_MC_FETCH_GREG_U64(u64Target, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11655 IEM_MC_SET_RIP_U64(u64Target);
11656 IEM_MC_END()
11657 return VINF_SUCCESS;
11658
11659 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11660 }
11661 }
11662 else
11663 {
11664 /* The new RIP is taken from a memory location. */
11665 switch (pVCpu->iem.s.enmEffOpSize)
11666 {
11667 case IEMMODE_16BIT:
11668 IEM_MC_BEGIN(0, 2);
11669 IEM_MC_LOCAL(uint16_t, u16Target);
11670 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11671 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11672 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11673 IEM_MC_FETCH_MEM_U16(u16Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11674 IEM_MC_SET_RIP_U16(u16Target);
11675 IEM_MC_END()
11676 return VINF_SUCCESS;
11677
11678 case IEMMODE_32BIT:
11679 IEM_MC_BEGIN(0, 2);
11680 IEM_MC_LOCAL(uint32_t, u32Target);
11681 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11682 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11683 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11684 IEM_MC_FETCH_MEM_U32(u32Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11685 IEM_MC_SET_RIP_U32(u32Target);
11686 IEM_MC_END()
11687 return VINF_SUCCESS;
11688
11689 case IEMMODE_64BIT:
11690 IEM_MC_BEGIN(0, 2);
11691 IEM_MC_LOCAL(uint64_t, u64Target);
11692 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11693 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11694 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11695 IEM_MC_FETCH_MEM_U64(u64Target, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11696 IEM_MC_SET_RIP_U64(u64Target);
11697 IEM_MC_END()
11698 return VINF_SUCCESS;
11699
11700 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11701 }
11702 }
11703}
11704
11705
11706/**
11707 * Opcode 0xff /5.
11708 * @param bRm The RM byte.
11709 */
11710FNIEMOP_DEF_1(iemOp_Grp5_jmpf_Ep, uint8_t, bRm)
11711{
11712 IEMOP_MNEMONIC(jmpf_Ep, "jmpf Ep");
11713 return FNIEMOP_CALL_2(iemOpHlp_Grp5_far_Ep, bRm, iemCImpl_FarJmp);
11714}
11715
11716
11717/**
11718 * Opcode 0xff /6.
11719 * @param bRm The RM byte.
11720 */
11721FNIEMOP_DEF_1(iemOp_Grp5_push_Ev, uint8_t, bRm)
11722{
11723 IEMOP_MNEMONIC(push_Ev, "push Ev");
11724
11725 /* Registers are handled by a common worker. */
11726 if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
11727 return FNIEMOP_CALL_1(iemOpCommonPushGReg, (bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB);
11728
11729 /* Memory we do here. */
11730 IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
11731 switch (pVCpu->iem.s.enmEffOpSize)
11732 {
11733 case IEMMODE_16BIT:
11734 IEM_MC_BEGIN(0, 2);
11735 IEM_MC_LOCAL(uint16_t, u16Src);
11736 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11737 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11738 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11739 IEM_MC_FETCH_MEM_U16(u16Src, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11740 IEM_MC_PUSH_U16(u16Src);
11741 IEM_MC_ADVANCE_RIP();
11742 IEM_MC_END();
11743 return VINF_SUCCESS;
11744
11745 case IEMMODE_32BIT:
11746 IEM_MC_BEGIN(0, 2);
11747 IEM_MC_LOCAL(uint32_t, u32Src);
11748 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11749 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11750 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11751 IEM_MC_FETCH_MEM_U32(u32Src, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11752 IEM_MC_PUSH_U32(u32Src);
11753 IEM_MC_ADVANCE_RIP();
11754 IEM_MC_END();
11755 return VINF_SUCCESS;
11756
11757 case IEMMODE_64BIT:
11758 IEM_MC_BEGIN(0, 2);
11759 IEM_MC_LOCAL(uint64_t, u64Src);
11760 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc);
11761 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
11762 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
11763 IEM_MC_FETCH_MEM_U64(u64Src, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
11764 IEM_MC_PUSH_U64(u64Src);
11765 IEM_MC_ADVANCE_RIP();
11766 IEM_MC_END();
11767 return VINF_SUCCESS;
11768
11769 IEM_NOT_REACHED_DEFAULT_CASE_RET();
11770 }
11771}
11772
11773
11774/**
11775 * @opcode 0xff
11776 */
11777FNIEMOP_DEF(iemOp_Grp5)
11778{
11779 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
11780 switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
11781 {
11782 case 0:
11783 IEMOP_MNEMONIC(inc_Ev, "inc Ev");
11784 return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_inc);
11785 case 1:
11786 IEMOP_MNEMONIC(dec_Ev, "dec Ev");
11787 return FNIEMOP_CALL_2(iemOpCommonUnaryEv, bRm, &g_iemAImpl_dec);
11788 case 2:
11789 return FNIEMOP_CALL_1(iemOp_Grp5_calln_Ev, bRm);
11790 case 3:
11791 return FNIEMOP_CALL_1(iemOp_Grp5_callf_Ep, bRm);
11792 case 4:
11793 return FNIEMOP_CALL_1(iemOp_Grp5_jmpn_Ev, bRm);
11794 case 5:
11795 return FNIEMOP_CALL_1(iemOp_Grp5_jmpf_Ep, bRm);
11796 case 6:
11797 return FNIEMOP_CALL_1(iemOp_Grp5_push_Ev, bRm);
11798 case 7:
11799 IEMOP_MNEMONIC(grp5_ud, "grp5-ud");
11800 return IEMOP_RAISE_INVALID_OPCODE();
11801 }
11802 AssertFailedReturn(VERR_IEM_IPE_3);
11803}
11804
11805
11806
11807const PFNIEMOP g_apfnOneByteMap[256] =
11808{
11809 /* 0x00 */ iemOp_add_Eb_Gb, iemOp_add_Ev_Gv, iemOp_add_Gb_Eb, iemOp_add_Gv_Ev,
11810 /* 0x04 */ iemOp_add_Al_Ib, iemOp_add_eAX_Iz, iemOp_push_ES, iemOp_pop_ES,
11811 /* 0x08 */ iemOp_or_Eb_Gb, iemOp_or_Ev_Gv, iemOp_or_Gb_Eb, iemOp_or_Gv_Ev,
11812 /* 0x0c */ iemOp_or_Al_Ib, iemOp_or_eAX_Iz, iemOp_push_CS, iemOp_2byteEscape,
11813 /* 0x10 */ iemOp_adc_Eb_Gb, iemOp_adc_Ev_Gv, iemOp_adc_Gb_Eb, iemOp_adc_Gv_Ev,
11814 /* 0x14 */ iemOp_adc_Al_Ib, iemOp_adc_eAX_Iz, iemOp_push_SS, iemOp_pop_SS,
11815 /* 0x18 */ iemOp_sbb_Eb_Gb, iemOp_sbb_Ev_Gv, iemOp_sbb_Gb_Eb, iemOp_sbb_Gv_Ev,
11816 /* 0x1c */ iemOp_sbb_Al_Ib, iemOp_sbb_eAX_Iz, iemOp_push_DS, iemOp_pop_DS,
11817 /* 0x20 */ iemOp_and_Eb_Gb, iemOp_and_Ev_Gv, iemOp_and_Gb_Eb, iemOp_and_Gv_Ev,
11818 /* 0x24 */ iemOp_and_Al_Ib, iemOp_and_eAX_Iz, iemOp_seg_ES, iemOp_daa,
11819 /* 0x28 */ iemOp_sub_Eb_Gb, iemOp_sub_Ev_Gv, iemOp_sub_Gb_Eb, iemOp_sub_Gv_Ev,
11820 /* 0x2c */ iemOp_sub_Al_Ib, iemOp_sub_eAX_Iz, iemOp_seg_CS, iemOp_das,
11821 /* 0x30 */ iemOp_xor_Eb_Gb, iemOp_xor_Ev_Gv, iemOp_xor_Gb_Eb, iemOp_xor_Gv_Ev,
11822 /* 0x34 */ iemOp_xor_Al_Ib, iemOp_xor_eAX_Iz, iemOp_seg_SS, iemOp_aaa,
11823 /* 0x38 */ iemOp_cmp_Eb_Gb, iemOp_cmp_Ev_Gv, iemOp_cmp_Gb_Eb, iemOp_cmp_Gv_Ev,
11824 /* 0x3c */ iemOp_cmp_Al_Ib, iemOp_cmp_eAX_Iz, iemOp_seg_DS, iemOp_aas,
11825 /* 0x40 */ iemOp_inc_eAX, iemOp_inc_eCX, iemOp_inc_eDX, iemOp_inc_eBX,
11826 /* 0x44 */ iemOp_inc_eSP, iemOp_inc_eBP, iemOp_inc_eSI, iemOp_inc_eDI,
11827 /* 0x48 */ iemOp_dec_eAX, iemOp_dec_eCX, iemOp_dec_eDX, iemOp_dec_eBX,
11828 /* 0x4c */ iemOp_dec_eSP, iemOp_dec_eBP, iemOp_dec_eSI, iemOp_dec_eDI,
11829 /* 0x50 */ iemOp_push_eAX, iemOp_push_eCX, iemOp_push_eDX, iemOp_push_eBX,
11830 /* 0x54 */ iemOp_push_eSP, iemOp_push_eBP, iemOp_push_eSI, iemOp_push_eDI,
11831 /* 0x58 */ iemOp_pop_eAX, iemOp_pop_eCX, iemOp_pop_eDX, iemOp_pop_eBX,
11832 /* 0x5c */ iemOp_pop_eSP, iemOp_pop_eBP, iemOp_pop_eSI, iemOp_pop_eDI,
11833 /* 0x60 */ iemOp_pusha, iemOp_popa__mvex, iemOp_bound_Gv_Ma__evex, iemOp_arpl_Ew_Gw_movsx_Gv_Ev,
11834 /* 0x64 */ iemOp_seg_FS, iemOp_seg_GS, iemOp_op_size, iemOp_addr_size,
11835 /* 0x68 */ iemOp_push_Iz, iemOp_imul_Gv_Ev_Iz, iemOp_push_Ib, iemOp_imul_Gv_Ev_Ib,
11836 /* 0x6c */ iemOp_insb_Yb_DX, iemOp_inswd_Yv_DX, iemOp_outsb_Yb_DX, iemOp_outswd_Yv_DX,
11837 /* 0x70 */ iemOp_jo_Jb, iemOp_jno_Jb, iemOp_jc_Jb, iemOp_jnc_Jb,
11838 /* 0x74 */ iemOp_je_Jb, iemOp_jne_Jb, iemOp_jbe_Jb, iemOp_jnbe_Jb,
11839 /* 0x78 */ iemOp_js_Jb, iemOp_jns_Jb, iemOp_jp_Jb, iemOp_jnp_Jb,
11840 /* 0x7c */ iemOp_jl_Jb, iemOp_jnl_Jb, iemOp_jle_Jb, iemOp_jnle_Jb,
11841 /* 0x80 */ iemOp_Grp1_Eb_Ib_80, iemOp_Grp1_Ev_Iz, iemOp_Grp1_Eb_Ib_82, iemOp_Grp1_Ev_Ib,
11842 /* 0x84 */ iemOp_test_Eb_Gb, iemOp_test_Ev_Gv, iemOp_xchg_Eb_Gb, iemOp_xchg_Ev_Gv,
11843 /* 0x88 */ iemOp_mov_Eb_Gb, iemOp_mov_Ev_Gv, iemOp_mov_Gb_Eb, iemOp_mov_Gv_Ev,
11844 /* 0x8c */ iemOp_mov_Ev_Sw, iemOp_lea_Gv_M, iemOp_mov_Sw_Ev, iemOp_Grp1A__xop,
11845 /* 0x90 */ iemOp_nop, iemOp_xchg_eCX_eAX, iemOp_xchg_eDX_eAX, iemOp_xchg_eBX_eAX,
11846 /* 0x94 */ iemOp_xchg_eSP_eAX, iemOp_xchg_eBP_eAX, iemOp_xchg_eSI_eAX, iemOp_xchg_eDI_eAX,
11847 /* 0x98 */ iemOp_cbw, iemOp_cwd, iemOp_call_Ap, iemOp_wait,
11848 /* 0x9c */ iemOp_pushf_Fv, iemOp_popf_Fv, iemOp_sahf, iemOp_lahf,
11849 /* 0xa0 */ iemOp_mov_AL_Ob, iemOp_mov_rAX_Ov, iemOp_mov_Ob_AL, iemOp_mov_Ov_rAX,
11850 /* 0xa4 */ iemOp_movsb_Xb_Yb, iemOp_movswd_Xv_Yv, iemOp_cmpsb_Xb_Yb, iemOp_cmpswd_Xv_Yv,
11851 /* 0xa8 */ iemOp_test_AL_Ib, iemOp_test_eAX_Iz, iemOp_stosb_Yb_AL, iemOp_stoswd_Yv_eAX,
11852 /* 0xac */ iemOp_lodsb_AL_Xb, iemOp_lodswd_eAX_Xv, iemOp_scasb_AL_Xb, iemOp_scaswd_eAX_Xv,
11853 /* 0xb0 */ iemOp_mov_AL_Ib, iemOp_CL_Ib, iemOp_DL_Ib, iemOp_BL_Ib,
11854 /* 0xb4 */ iemOp_mov_AH_Ib, iemOp_CH_Ib, iemOp_DH_Ib, iemOp_BH_Ib,
11855 /* 0xb8 */ iemOp_eAX_Iv, iemOp_eCX_Iv, iemOp_eDX_Iv, iemOp_eBX_Iv,
11856 /* 0xbc */ iemOp_eSP_Iv, iemOp_eBP_Iv, iemOp_eSI_Iv, iemOp_eDI_Iv,
11857 /* 0xc0 */ iemOp_Grp2_Eb_Ib, iemOp_Grp2_Ev_Ib, iemOp_retn_Iw, iemOp_retn,
11858 /* 0xc4 */ iemOp_les_Gv_Mp__vex3, iemOp_lds_Gv_Mp__vex2, iemOp_Grp11_Eb_Ib, iemOp_Grp11_Ev_Iz,
11859 /* 0xc8 */ iemOp_enter_Iw_Ib, iemOp_leave, iemOp_retf_Iw, iemOp_retf,
11860 /* 0xcc */ iemOp_int3, iemOp_int_Ib, iemOp_into, iemOp_iret,
11861 /* 0xd0 */ iemOp_Grp2_Eb_1, iemOp_Grp2_Ev_1, iemOp_Grp2_Eb_CL, iemOp_Grp2_Ev_CL,
11862 /* 0xd4 */ iemOp_aam_Ib, iemOp_aad_Ib, iemOp_salc, iemOp_xlat,
11863 /* 0xd8 */ iemOp_EscF0, iemOp_EscF1, iemOp_EscF2, iemOp_EscF3,
11864 /* 0xdc */ iemOp_EscF4, iemOp_EscF5, iemOp_EscF6, iemOp_EscF7,
11865 /* 0xe0 */ iemOp_loopne_Jb, iemOp_loope_Jb, iemOp_loop_Jb, iemOp_jecxz_Jb,
11866 /* 0xe4 */ iemOp_in_AL_Ib, iemOp_in_eAX_Ib, iemOp_out_Ib_AL, iemOp_out_Ib_eAX,
11867 /* 0xe8 */ iemOp_call_Jv, iemOp_jmp_Jv, iemOp_jmp_Ap, iemOp_jmp_Jb,
11868 /* 0xec */ iemOp_in_AL_DX, iemOp_in_eAX_DX, iemOp_out_DX_AL, iemOp_out_DX_eAX,
11869 /* 0xf0 */ iemOp_lock, iemOp_int1, iemOp_repne, iemOp_repe,
11870 /* 0xf4 */ iemOp_hlt, iemOp_cmc, iemOp_Grp3_Eb, iemOp_Grp3_Ev,
11871 /* 0xf8 */ iemOp_clc, iemOp_stc, iemOp_cli, iemOp_sti,
11872 /* 0xfc */ iemOp_cld, iemOp_std, iemOp_Grp4, iemOp_Grp5,
11873};
11874
11875
11876/** @} */
11877
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