- compilation fixes for MSVC toolkit 2003
[bochs-mirror.git] / cpu / arith32.cc
blobc56f6f9010f8a9e0a3ad4e6e826366c8bb6bfe03
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: arith32.cc,v 1.82 2008/08/09 21:05:05 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
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
29 #include "bochs.h"
30 #include "cpu.h"
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.
35 #define RAX EAX
36 #define RDX EDX
37 #endif
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;
84 op1_32 = EAX;
85 sum_32 = op1_32 + op2_32;
86 RAX = sum_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;
127 op1_32 = EAX;
128 sum_32 = op1_32 + op2_32 + temp_CF;
129 RAX = sum_32;
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;
170 op1_32 = EAX;
171 op2_32 = i->Id();
172 diff_32 = op1_32 - (op2_32 + temp_CF);
173 RAX = diff_32;
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;
236 op1_32 = EAX;
237 op2_32 = i->Id();
238 diff_32 = op1_32 - op2_32;
239 RAX = diff_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;
272 op1_32 = EAX;
273 op2_32 = i->Id();
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;
283 RAX = tmp;
286 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CDQ(bxInstruction_c *i)
288 /* CDQ: no flags are affected */
289 if (EAX & 0x80000000) {
290 RDX = 0xFFFFFFFF;
292 else {
293 RDX = 0x00000000;
297 // Some info on the opcodes at {0F,A6} and {0F,A7}
298 // On 386 steps A0-B0:
299 // {OF,A6} = XBTS
300 // {OF,A7} = IBTS
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);
344 #else
345 BX_INFO (("XADD_EdGd not supported for cpulevel <= 3"));
346 exception(BX_UD_EXCEPTION, 0, 0);
347 #endif
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);
373 #else
374 BX_INFO (("XADD_EdGd not supported for cpulevel <= 3"));
375 exception(BX_UD_EXCEPTION, 0, 0);
376 #endif
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);
386 op2_32 = i->Id();
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());
398 op2_32 = i->Id();
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);
465 op2_32 = i->Id();
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());
476 op2_32 = i->Id();
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)
484 Bit32u op1_32;
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)
506 Bit32u op1_32;
508 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
510 op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
511 op1_32++;
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)
519 Bit32u op1_32;
521 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
523 op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
524 op1_32--;
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
542 // dest <-- src
543 op2_32 = BX_READ_32BIT_REG(i->nnn());
544 write_RMW_virtual_dword(op2_32);
546 else {
547 // accumulator <-- dest
548 RAX = op1_32;
550 #else
551 BX_INFO(("CMPXCHG_EdGd: not supported for cpulevel <= 3"));
552 exception(BX_UD_EXCEPTION, 0, 0);
553 #endif
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
566 // dest <-- src
567 op2_32 = BX_READ_32BIT_REG(i->nnn());
568 BX_WRITE_32BIT_REGZ(i->rm(), op2_32);
570 else {
571 // accumulator <-- dest
572 RAX = op1_32;
574 #else
575 BX_INFO(("CMPXCHG_EdGd: not supported for cpulevel <= 3"));
576 exception(BX_UD_EXCEPTION, 0, 0);
577 #endif
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);
595 assert_ZF();
597 else {
598 // accumulator <-- dest
599 RAX = GET32L(op1_64);
600 RDX = GET32H(op1_64);
601 clear_ZF();
604 #else
605 BX_INFO(("CMPXCHG8B: not supported for cpulevel <= 4"));
606 exception(BX_UD_EXCEPTION, 0, 0);
607 #endif