1 /////////////////////////////////////////////////////////////////////////
2 // $Id: arith32.cc,v 1.82 2008/08/09 21:05:05 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
31 #define LOG_THIS BX_CPU_THIS_PTR
33 #if BX_SUPPORT_X86_64==0
34 // Make life easier for merging cpu64 and cpu code.
39 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INC_ERX(bxInstruction_c
*i
)
41 Bit32u erx
= ++BX_READ_32BIT_REG(i
->opcodeReg());
42 SET_FLAGS_OSZAPC_INC_32(erx
);
43 BX_CLEAR_64BIT_HIGH(i
->opcodeReg());
46 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DEC_ERX(bxInstruction_c
*i
)
48 Bit32u erx
= --BX_READ_32BIT_REG(i
->opcodeReg());
49 SET_FLAGS_OSZAPC_DEC_32(erx
);
50 BX_CLEAR_64BIT_HIGH(i
->opcodeReg());
53 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EdGdM(bxInstruction_c
*i
)
55 Bit32u op1_32
, op2_32
, sum_32
;
57 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
59 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
60 op2_32
= BX_READ_32BIT_REG(i
->nnn());
61 sum_32
= op1_32
+ op2_32
;
62 write_RMW_virtual_dword(sum_32
);
64 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
67 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_GdEdR(bxInstruction_c
*i
)
69 Bit32u op1_32
, op2_32
, sum_32
;
71 op1_32
= BX_READ_32BIT_REG(i
->nnn());
72 op2_32
= BX_READ_32BIT_REG(i
->rm());
73 sum_32
= op1_32
+ op2_32
;
75 BX_WRITE_32BIT_REGZ(i
->nnn(), sum_32
);
77 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
80 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EAXId(bxInstruction_c
*i
)
82 Bit32u op1_32
, op2_32
= i
->Id(), sum_32
;
85 sum_32
= op1_32
+ op2_32
;
88 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
91 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EdGdM(bxInstruction_c
*i
)
93 bx_bool temp_CF
= getB_CF();
95 Bit32u op1_32
, op2_32
, sum_32
;
97 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
99 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
100 op2_32
= BX_READ_32BIT_REG(i
->nnn());
101 sum_32
= op1_32
+ op2_32
+ temp_CF
;
102 write_RMW_virtual_dword(sum_32
);
104 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, sum_32
, BX_LF_INSTR_ADD_ADC32(temp_CF
));
107 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_GdEdR(bxInstruction_c
*i
)
109 bx_bool temp_CF
= getB_CF();
111 Bit32u op1_32
, op2_32
, sum_32
;
113 op1_32
= BX_READ_32BIT_REG(i
->nnn());
114 op2_32
= BX_READ_32BIT_REG(i
->rm());
115 sum_32
= op1_32
+ op2_32
+ temp_CF
;
116 BX_WRITE_32BIT_REGZ(i
->nnn(), sum_32
);
118 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, sum_32
, BX_LF_INSTR_ADD_ADC32(temp_CF
));
121 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EAXId(bxInstruction_c
*i
)
123 bx_bool temp_CF
= getB_CF();
125 Bit32u op1_32
, op2_32
= i
->Id(), sum_32
;
128 sum_32
= op1_32
+ op2_32
+ temp_CF
;
131 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, sum_32
, BX_LF_INSTR_ADD_ADC32(temp_CF
));
134 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EdGdM(bxInstruction_c
*i
)
136 bx_bool temp_CF
= getB_CF();
138 Bit32u op1_32
, op2_32
, diff_32
;
140 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
142 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
143 op2_32
= BX_READ_32BIT_REG(i
->nnn());
144 diff_32
= op1_32
- (op2_32
+ temp_CF
);
145 write_RMW_virtual_dword(diff_32
);
147 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, diff_32
, BX_LF_INSTR_SUB_SBB32(temp_CF
));
150 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_GdEdR(bxInstruction_c
*i
)
152 bx_bool temp_CF
= getB_CF();
154 Bit32u op1_32
, op2_32
, diff_32
;
156 op1_32
= BX_READ_32BIT_REG(i
->nnn());
157 op2_32
= BX_READ_32BIT_REG(i
->rm());
158 diff_32
= op1_32
- (op2_32
+ temp_CF
);
159 BX_WRITE_32BIT_REGZ(i
->nnn(), diff_32
);
161 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, diff_32
, BX_LF_INSTR_SUB_SBB32(temp_CF
));
164 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EAXId(bxInstruction_c
*i
)
166 bx_bool temp_CF
= getB_CF();
168 Bit32u op1_32
, op2_32
, diff_32
;
172 diff_32
= op1_32
- (op2_32
+ temp_CF
);
175 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, diff_32
, BX_LF_INSTR_SUB_SBB32(temp_CF
));
178 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EdIdM(bxInstruction_c
*i
)
180 bx_bool temp_CF
= getB_CF();
182 Bit32u op1_32
, op2_32
= i
->Id(), diff_32
;
184 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
186 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
187 diff_32
= op1_32
- (op2_32
+ temp_CF
);
188 write_RMW_virtual_dword(diff_32
);
190 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, diff_32
, BX_LF_INSTR_SUB_SBB32(temp_CF
));
193 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EdIdR(bxInstruction_c
*i
)
195 bx_bool temp_CF
= getB_CF();
197 Bit32u op1_32
, op2_32
= i
->Id(), diff_32
;
199 op1_32
= BX_READ_32BIT_REG(i
->rm());
200 diff_32
= op1_32
- (op2_32
+ temp_CF
);
201 BX_WRITE_32BIT_REGZ(i
->rm(), diff_32
);
203 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, diff_32
, BX_LF_INSTR_SUB_SBB32(temp_CF
));
206 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EdGdM(bxInstruction_c
*i
)
208 Bit32u op1_32
, op2_32
, diff_32
;
210 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
212 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
213 op2_32
= BX_READ_32BIT_REG(i
->nnn());
214 diff_32
= op1_32
- op2_32
;
215 write_RMW_virtual_dword(diff_32
);
217 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
220 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GdEdR(bxInstruction_c
*i
)
222 Bit32u op1_32
, op2_32
, diff_32
;
224 op1_32
= BX_READ_32BIT_REG(i
->nnn());
225 op2_32
= BX_READ_32BIT_REG(i
->rm());
226 diff_32
= op1_32
- op2_32
;
227 BX_WRITE_32BIT_REGZ(i
->nnn(), diff_32
);
229 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
232 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EAXId(bxInstruction_c
*i
)
234 Bit32u op1_32
, op2_32
, diff_32
;
238 diff_32
= op1_32
- op2_32
;
241 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
244 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EdGdM(bxInstruction_c
*i
)
246 Bit32u op1_32
, op2_32
, diff_32
;
248 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
250 op1_32
= read_virtual_dword(i
->seg(), eaddr
);
251 op2_32
= BX_READ_32BIT_REG(i
->nnn());
252 diff_32
= op1_32
- op2_32
;
254 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
257 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_GdEdR(bxInstruction_c
*i
)
259 Bit32u op1_32
, op2_32
, diff_32
;
261 op1_32
= BX_READ_32BIT_REG(i
->nnn());
262 op2_32
= BX_READ_32BIT_REG(i
->rm());
263 diff_32
= op1_32
- op2_32
;
265 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
268 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EAXId(bxInstruction_c
*i
)
270 Bit32u op1_32
, op2_32
, diff_32
;
274 diff_32
= op1_32
- op2_32
;
276 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
279 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CWDE(bxInstruction_c
*i
)
281 /* CWDE: no flags are effected */
282 Bit32u tmp
= (Bit16s
) AX
;
286 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CDQ(bxInstruction_c
*i
)
288 /* CDQ: no flags are affected */
289 if (EAX
& 0x80000000) {
297 // Some info on the opcodes at {0F,A6} and {0F,A7}
298 // On 386 steps A0-B0:
301 // On 486 steps A0-B0:
302 // {OF,A6} = CMPXCHG 8
303 // {OF,A7} = CMPXCHG 16|32
305 // On 486 >= B steps, and further processors, the
306 // CMPXCHG instructions were moved to opcodes:
307 // {OF,B0} = CMPXCHG 8
308 // {OF,B1} = CMPXCHG 16|32
310 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_XBTS(bxInstruction_c
*i
)
312 BX_INFO(("CMPXCHG_XBTS: Generate #UD exception"));
313 exception(BX_UD_EXCEPTION
, 0, 0);
316 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_IBTS(bxInstruction_c
*i
)
318 BX_INFO(("CMPXCHG_IBTS: Generate #UD exception"));
319 exception(BX_UD_EXCEPTION
, 0, 0);
322 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EdGdM(bxInstruction_c
*i
)
324 #if BX_CPU_LEVEL >= 4
325 Bit32u op1_32
, op2_32
, sum_32
;
327 /* XADD dst(r/m), src(r)
328 * temp <-- src + dst | sum = op2 + op1
329 * src <-- dst | op2 = op1
330 * dst <-- tmp | op1 = sum
333 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
335 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
336 op2_32
= BX_READ_32BIT_REG(i
->nnn());
337 sum_32
= op1_32
+ op2_32
;
338 write_RMW_virtual_dword(sum_32
);
340 /* and write destination into source */
341 BX_WRITE_32BIT_REGZ(i
->nnn(), op1_32
);
343 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
345 BX_INFO (("XADD_EdGd not supported for cpulevel <= 3"));
346 exception(BX_UD_EXCEPTION
, 0, 0);
350 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EdGdR(bxInstruction_c
*i
)
352 #if BX_CPU_LEVEL >= 4
353 Bit32u op1_32
, op2_32
, sum_32
;
355 /* XADD dst(r/m), src(r)
356 * temp <-- src + dst | sum = op2 + op1
357 * src <-- dst | op2 = op1
358 * dst <-- tmp | op1 = sum
361 op1_32
= BX_READ_32BIT_REG(i
->rm());
362 op2_32
= BX_READ_32BIT_REG(i
->nnn());
363 sum_32
= op1_32
+ op2_32
;
365 // and write destination into source
366 // Note: if both op1 & op2 are registers, the last one written
367 // should be the sum, as op1 & op2 may be the same register.
368 // For example: XADD AL, AL
369 BX_WRITE_32BIT_REGZ(i
->nnn(), op1_32
);
370 BX_WRITE_32BIT_REGZ(i
->rm(), sum_32
);
372 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
374 BX_INFO (("XADD_EdGd not supported for cpulevel <= 3"));
375 exception(BX_UD_EXCEPTION
, 0, 0);
379 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EdIdM(bxInstruction_c
*i
)
381 Bit32u op1_32
, op2_32
, sum_32
;
383 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
385 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
387 sum_32
= op1_32
+ op2_32
;
388 write_RMW_virtual_dword(sum_32
);
390 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
393 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EdIdR(bxInstruction_c
*i
)
395 Bit32u op1_32
, op2_32
, sum_32
;
397 op1_32
= BX_READ_32BIT_REG(i
->rm());
399 sum_32
= op1_32
+ op2_32
;
401 BX_WRITE_32BIT_REGZ(i
->rm(), sum_32
);
403 SET_FLAGS_OSZAPC_ADD_32(op1_32
, op2_32
, sum_32
);
406 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EdIdM(bxInstruction_c
*i
)
408 bx_bool temp_CF
= getB_CF();
410 Bit32u op1_32
, op2_32
= i
->Id(), sum_32
;
412 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
414 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
415 sum_32
= op1_32
+ op2_32
+ temp_CF
;
416 write_RMW_virtual_dword(sum_32
);
418 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, sum_32
, BX_LF_INSTR_ADD_ADC32(temp_CF
));
421 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EdIdR(bxInstruction_c
*i
)
423 bx_bool temp_CF
= getB_CF();
425 Bit32u op1_32
, op2_32
= i
->Id(), sum_32
;
427 op1_32
= BX_READ_32BIT_REG(i
->rm());
428 sum_32
= op1_32
+ op2_32
+ temp_CF
;
429 BX_WRITE_32BIT_REGZ(i
->rm(), sum_32
);
431 SET_FLAGS_OSZAPC_32(op1_32
, op2_32
, sum_32
, BX_LF_INSTR_ADD_ADC32(temp_CF
));
434 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EdIdM(bxInstruction_c
*i
)
436 Bit32u op1_32
, op2_32
= i
->Id(), diff_32
;
438 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
440 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
441 diff_32
= op1_32
- op2_32
;
442 write_RMW_virtual_dword(diff_32
);
444 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
447 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EdIdR(bxInstruction_c
*i
)
449 Bit32u op1_32
, op2_32
= i
->Id(), diff_32
;
451 op1_32
= BX_READ_32BIT_REG(i
->rm());
452 diff_32
= op1_32
- op2_32
;
453 BX_WRITE_32BIT_REGZ(i
->rm(), diff_32
);
455 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
458 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EdIdM(bxInstruction_c
*i
)
460 Bit32u op1_32
, op2_32
, diff_32
;
462 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
464 op1_32
= read_virtual_dword(i
->seg(), eaddr
);
466 diff_32
= op1_32
- op2_32
;
468 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
471 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EdIdR(bxInstruction_c
*i
)
473 Bit32u op1_32
, op2_32
, diff_32
;
475 op1_32
= BX_READ_32BIT_REG(i
->rm());
477 diff_32
= op1_32
- op2_32
;
479 SET_FLAGS_OSZAPC_SUB_32(op1_32
, op2_32
, diff_32
);
482 void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EdM(bxInstruction_c
*i
)
486 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
488 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
489 op1_32
= - (Bit32s
)(op1_32
);
490 write_RMW_virtual_dword(op1_32
);
492 SET_FLAGS_OSZAPC_RESULT_32(op1_32
, BX_LF_INSTR_NEG32
);
495 void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EdR(bxInstruction_c
*i
)
497 Bit32u op1_32
= BX_READ_32BIT_REG(i
->rm());
498 op1_32
= - (Bit32s
)(op1_32
);
499 BX_WRITE_32BIT_REGZ(i
->rm(), op1_32
);
501 SET_FLAGS_OSZAPC_RESULT_32(op1_32
, BX_LF_INSTR_NEG32
);
504 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INC_EdM(bxInstruction_c
*i
)
508 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
510 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
512 write_RMW_virtual_dword(op1_32
);
514 SET_FLAGS_OSZAPC_INC_32(op1_32
);
517 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DEC_EdM(bxInstruction_c
*i
)
521 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
523 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
525 write_RMW_virtual_dword(op1_32
);
527 SET_FLAGS_OSZAPC_DEC_32(op1_32
);
530 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EdGdM(bxInstruction_c
*i
)
532 #if BX_CPU_LEVEL >= 4
533 Bit32u op1_32
, op2_32
, diff_32
;
535 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
537 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
538 diff_32
= EAX
- op1_32
;
539 SET_FLAGS_OSZAPC_SUB_32(EAX
, op1_32
, diff_32
);
541 if (diff_32
== 0) { // if accumulator == dest
543 op2_32
= BX_READ_32BIT_REG(i
->nnn());
544 write_RMW_virtual_dword(op2_32
);
547 // accumulator <-- dest
551 BX_INFO(("CMPXCHG_EdGd: not supported for cpulevel <= 3"));
552 exception(BX_UD_EXCEPTION
, 0, 0);
556 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EdGdR(bxInstruction_c
*i
)
558 #if BX_CPU_LEVEL >= 4
559 Bit32u op1_32
, op2_32
, diff_32
;
561 op1_32
= BX_READ_32BIT_REG(i
->rm());
562 diff_32
= EAX
- op1_32
;
563 SET_FLAGS_OSZAPC_SUB_32(EAX
, op1_32
, diff_32
);
565 if (diff_32
== 0) { // if accumulator == dest
567 op2_32
= BX_READ_32BIT_REG(i
->nnn());
568 BX_WRITE_32BIT_REGZ(i
->rm(), op2_32
);
571 // accumulator <-- dest
575 BX_INFO(("CMPXCHG_EdGd: not supported for cpulevel <= 3"));
576 exception(BX_UD_EXCEPTION
, 0, 0);
580 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG8B(bxInstruction_c
*i
)
582 #if BX_CPU_LEVEL >= 5
583 Bit64u op1_64
, op2_64
;
585 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
587 // check write permission for following write
588 op1_64
= read_RMW_virtual_qword(i
->seg(), eaddr
);
589 op2_64
= ((Bit64u
) EDX
<< 32) | EAX
;
591 if (op1_64
== op2_64
) { // if accumulator == dest
592 // dest <-- src (ECX:EBX)
593 op2_64
= ((Bit64u
) ECX
<< 32) | EBX
;
594 write_RMW_virtual_qword(op2_64
);
598 // accumulator <-- dest
599 RAX
= GET32L(op1_64
);
600 RDX
= GET32H(op1_64
);
605 BX_INFO(("CMPXCHG8B: not supported for cpulevel <= 4"));
606 exception(BX_UD_EXCEPTION
, 0, 0);