1 /////////////////////////////////////////////////////////////////////////
2 // $Id: arith8.cc 13466 2018-02-16 07:57:32Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2001-2018  The Bochs Project
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
20 /////////////////////////////////////////////////////////////////////////
21 
22 #define NEED_CPU_REG_SHORTCUTS 1
23 #include "bochs.h"
24 #include "cpu.h"
25 #define LOG_THIS BX_CPU_THIS_PTR
26 
ADD_EbGbM(bxInstruction_c * i)27 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EbGbM(bxInstruction_c *i)
28 {
29   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
30 
31   Bit32u op1 = read_RMW_virtual_byte(i->seg(), eaddr);
32   Bit32u op2 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
33   Bit32u sum = op1 + op2;
34 
35   write_RMW_linear_byte(sum);
36 
37   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
38 
39   BX_NEXT_INSTR(i);
40 }
41 
ADD_GbEbR(bxInstruction_c * i)42 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_GbEbR(bxInstruction_c *i)
43 {
44   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
45   Bit32u op2 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
46   Bit32u sum = op1 + op2;
47 
48   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
49 
50   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
51 
52   BX_NEXT_INSTR(i);
53 }
54 
ADD_GbEbM(bxInstruction_c * i)55 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_GbEbM(bxInstruction_c *i)
56 {
57   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
58 
59   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
60   Bit32u op2 = read_virtual_byte(i->seg(), eaddr);
61   Bit32u sum = op1 + op2;
62 
63   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
64 
65   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
66 
67   BX_NEXT_INSTR(i);
68 }
69 
ADC_EbGbM(bxInstruction_c * i)70 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EbGbM(bxInstruction_c *i)
71 {
72   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
73 
74   Bit32u op1 = read_RMW_virtual_byte(i->seg(), eaddr);
75   Bit32u op2 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
76   Bit32u sum = op1 + op2 + getB_CF();
77 
78   write_RMW_linear_byte(sum);
79 
80   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
81 
82   BX_NEXT_INSTR(i);
83 }
84 
ADC_GbEbR(bxInstruction_c * i)85 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_GbEbR(bxInstruction_c *i)
86 {
87   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
88   Bit32u op2 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
89   Bit32u sum = op1 + op2 + getB_CF();
90 
91   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
92 
93   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
94 
95   BX_NEXT_INSTR(i);
96 }
97 
ADC_GbEbM(bxInstruction_c * i)98 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_GbEbM(bxInstruction_c *i)
99 {
100   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
101 
102   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
103   Bit32u op2 = read_virtual_byte(i->seg(), eaddr);
104   Bit32u sum = op1 + op2 + getB_CF();
105 
106   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
107 
108   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
109 
110   BX_NEXT_INSTR(i);
111 }
112 
SBB_EbGbM(bxInstruction_c * i)113 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EbGbM(bxInstruction_c *i)
114 {
115   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
116 
117   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
118   Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
119   Bit32u diff_8 = op1_8 - (op2_8 + getB_CF());
120 
121   write_RMW_linear_byte(diff_8);
122 
123   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
124 
125   BX_NEXT_INSTR(i);
126 }
127 
SBB_GbEbR(bxInstruction_c * i)128 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_GbEbR(bxInstruction_c *i)
129 {
130   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
131   Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
132   Bit32u diff_8 = op1_8 - (op2_8 + getB_CF());
133 
134   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), diff_8);
135 
136   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
137 
138   BX_NEXT_INSTR(i);
139 }
140 
SBB_GbEbM(bxInstruction_c * i)141 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_GbEbM(bxInstruction_c *i)
142 {
143   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
144 
145   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
146   Bit32u op2_8 = read_virtual_byte(i->seg(), eaddr);
147   Bit32u diff_8 = op1_8 - (op2_8 + getB_CF());
148 
149   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), diff_8);
150 
151   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
152 
153   BX_NEXT_INSTR(i);
154 }
155 
SBB_EbIbM(bxInstruction_c * i)156 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EbIbM(bxInstruction_c *i)
157 {
158   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
159 
160   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
161   Bit32u op2_8 = i->Ib();
162   Bit32u diff_8 = op1_8 - (op2_8 + getB_CF());
163   write_RMW_linear_byte(diff_8);
164 
165   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
166 
167   BX_NEXT_INSTR(i);
168 }
169 
SBB_EbIbR(bxInstruction_c * i)170 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EbIbR(bxInstruction_c *i)
171 {
172   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
173   Bit32u op2_8 = i->Ib();
174   Bit32u diff_8 = op1_8 - (op2_8 + getB_CF());
175   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), diff_8);
176 
177   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
178 
179   BX_NEXT_INSTR(i);
180 }
181 
SUB_EbGbM(bxInstruction_c * i)182 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EbGbM(bxInstruction_c *i)
183 {
184   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
185 
186   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
187   Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
188   Bit32u diff_8 = op1_8 - op2_8;
189 
190   write_RMW_linear_byte(diff_8);
191 
192   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
193 
194   BX_NEXT_INSTR(i);
195 }
196 
SUB_GbEbR(bxInstruction_c * i)197 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GbEbR(bxInstruction_c *i)
198 {
199   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
200   Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
201   Bit32u diff_8 = op1_8 - op2_8;
202 
203   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), diff_8);
204 
205   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
206 
207   BX_NEXT_INSTR(i);
208 }
209 
SUB_GbEbM(bxInstruction_c * i)210 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GbEbM(bxInstruction_c *i)
211 {
212   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
213 
214   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
215   Bit32u op2_8 = read_virtual_byte(i->seg(), eaddr);
216   Bit32u diff_8 = op1_8 - op2_8;
217 
218   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), diff_8);
219 
220   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
221 
222   BX_NEXT_INSTR(i);
223 }
224 
CMP_EbGbM(bxInstruction_c * i)225 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EbGbM(bxInstruction_c *i)
226 {
227   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
228 
229   Bit32u op1_8 = read_virtual_byte(i->seg(), eaddr);
230   Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
231   Bit32u diff_8 = op1_8 - op2_8;
232 
233   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
234 
235   BX_NEXT_INSTR(i);
236 }
237 
CMP_GbEbR(bxInstruction_c * i)238 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_GbEbR(bxInstruction_c *i)
239 {
240   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
241   Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
242   Bit32u diff_8 = op1_8 - op2_8;
243 
244   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
245 
246   BX_NEXT_INSTR(i);
247 }
248 
CMP_GbEbM(bxInstruction_c * i)249 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_GbEbM(bxInstruction_c *i)
250 {
251   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
252 
253   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
254   Bit32u op2_8 = read_virtual_byte(i->seg(), eaddr);
255   Bit32u diff_8 = op1_8 - op2_8;
256 
257   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
258 
259   BX_NEXT_INSTR(i);
260 }
261 
XADD_EbGbM(bxInstruction_c * i)262 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EbGbM(bxInstruction_c *i)
263 {
264   /* XADD dst(r/m8), src(r8)
265    * temp <-- src + dst         | sum = op2 + op1
266    * src  <-- dst               | op2 = op1
267    * dst  <-- tmp               | op1 = sum
268    */
269 
270   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
271 
272   Bit32u op1 = read_RMW_virtual_byte(i->seg(), eaddr);
273   Bit32u op2 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
274   Bit32u sum = op1 + op2;
275 
276   write_RMW_linear_byte(sum);
277 
278   /* and write destination into source */
279   BX_WRITE_8BIT_REGx(i->src(), i->extend8bitL(), op1);
280 
281   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
282 
283   BX_NEXT_INSTR(i);
284 }
285 
XADD_EbGbR(bxInstruction_c * i)286 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EbGbR(bxInstruction_c *i)
287 {
288   /* XADD dst(r/m8), src(r8)
289    * temp <-- src + dst         | sum = op2 + op1
290    * src  <-- dst               | op2 = op1
291    * dst  <-- tmp               | op1 = sum
292    */
293 
294   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
295   Bit32u op2 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
296   Bit32u sum = op1 + op2;
297 
298   // and write destination into source
299   // Note: if both op1 & op2 are registers, the last one written
300   //       should be the sum, as op1 & op2 may be the same register.
301   //       For example:  XADD AL, AL
302   BX_WRITE_8BIT_REGx(i->src(), i->extend8bitL(), op1);
303   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
304 
305   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
306 
307   BX_NEXT_INSTR(i);
308 }
309 
ADD_EbIbM(bxInstruction_c * i)310 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EbIbM(bxInstruction_c *i)
311 {
312   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
313 
314   Bit32u op1 = read_RMW_virtual_byte(i->seg(), eaddr);
315   Bit32u op2 = i->Ib();
316   Bit32u sum = op1 + op2;
317 
318   write_RMW_linear_byte(sum);
319 
320   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
321 
322   BX_NEXT_INSTR(i);
323 }
324 
ADD_EbIbR(bxInstruction_c * i)325 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EbIbR(bxInstruction_c *i)
326 {
327   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
328   Bit32u op2 = i->Ib();
329   Bit32u sum = op1 + op2;
330 
331   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
332 
333   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
334 
335   BX_NEXT_INSTR(i);
336 }
337 
ADC_EbIbM(bxInstruction_c * i)338 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EbIbM(bxInstruction_c *i)
339 {
340   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
341 
342   Bit32u op1 = read_RMW_virtual_byte(i->seg(), eaddr);
343   Bit32u op2 = i->Ib();
344   Bit32u sum = op1 + op2 + getB_CF();
345 
346   write_RMW_linear_byte(sum);
347 
348   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
349 
350   BX_NEXT_INSTR(i);
351 }
352 
ADC_EbIbR(bxInstruction_c * i)353 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EbIbR(bxInstruction_c *i)
354 {
355   Bit32u op1 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
356   Bit32u op2 = i->Ib();
357   Bit32u sum = op1 + op2 + getB_CF();
358 
359   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), sum);
360 
361   SET_FLAGS_OSZAPC_ADD_8(op1, op2, sum);
362 
363   BX_NEXT_INSTR(i);
364 }
365 
SUB_EbIbM(bxInstruction_c * i)366 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EbIbM(bxInstruction_c *i)
367 {
368   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
369 
370   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
371   Bit32u op2_8 = i->Ib();
372   Bit32u diff_8 = op1_8 - op2_8;
373 
374   write_RMW_linear_byte(diff_8);
375 
376   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
377 
378   BX_NEXT_INSTR(i);
379 }
380 
SUB_EbIbR(bxInstruction_c * i)381 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EbIbR(bxInstruction_c *i)
382 {
383   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
384   Bit32u op2_8 = i->Ib();
385   Bit32u diff_8 = op1_8 - op2_8;
386 
387   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), diff_8);
388 
389   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
390 
391   BX_NEXT_INSTR(i);
392 }
393 
CMP_EbIbM(bxInstruction_c * i)394 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EbIbM(bxInstruction_c *i)
395 {
396   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
397 
398   Bit32u op1_8 = read_virtual_byte(i->seg(), eaddr);
399   Bit32u op2_8 = i->Ib();
400   Bit32u diff_8 = op1_8 - op2_8;
401 
402   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
403 
404   BX_NEXT_INSTR(i);
405 }
406 
CMP_EbIbR(bxInstruction_c * i)407 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EbIbR(bxInstruction_c *i)
408 {
409   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
410   Bit32u op2_8 = i->Ib();
411   Bit32u diff_8 = op1_8 - op2_8;
412 
413   SET_FLAGS_OSZAPC_SUB_8(op1_8, op2_8, diff_8);
414 
415   BX_NEXT_INSTR(i);
416 }
417 
NEG_EbM(bxInstruction_c * i)418 void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EbM(bxInstruction_c *i)
419 {
420   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
421 
422   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
423   op1_8 = - (Bit8s)(op1_8);
424   write_RMW_linear_byte(op1_8);
425 
426   SET_FLAGS_OSZAPC_SUB_8(0, 0 - op1_8, op1_8);
427 
428   BX_NEXT_INSTR(i);
429 }
430 
NEG_EbR(bxInstruction_c * i)431 void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EbR(bxInstruction_c *i)
432 {
433   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
434   op1_8 = - (Bit8s)(op1_8);
435   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), op1_8);
436 
437   SET_FLAGS_OSZAPC_SUB_8(0, 0 - op1_8, op1_8);
438 
439   BX_NEXT_INSTR(i);
440 }
441 
INC_EbM(bxInstruction_c * i)442 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INC_EbM(bxInstruction_c *i)
443 {
444   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
445 
446   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
447   op1_8++;
448   write_RMW_linear_byte(op1_8);
449 
450   SET_FLAGS_OSZAP_ADD_8(op1_8 - 1, 0, op1_8);
451 
452   BX_NEXT_INSTR(i);
453 }
454 
INC_EbR(bxInstruction_c * i)455 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INC_EbR(bxInstruction_c *i)
456 {
457   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
458   op1_8++;
459   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), op1_8);
460 
461   SET_FLAGS_OSZAP_ADD_8(op1_8 - 1, 0, op1_8);
462 
463   BX_NEXT_INSTR(i);
464 }
465 
DEC_EbM(bxInstruction_c * i)466 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DEC_EbM(bxInstruction_c *i)
467 {
468   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
469 
470   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
471   op1_8--;
472   write_RMW_linear_byte(op1_8);
473 
474   SET_FLAGS_OSZAP_SUB_8(op1_8 + 1, 0, op1_8);
475 
476   BX_NEXT_INSTR(i);
477 }
478 
DEC_EbR(bxInstruction_c * i)479 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DEC_EbR(bxInstruction_c *i)
480 {
481   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
482   op1_8--;
483   BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), op1_8);
484 
485   SET_FLAGS_OSZAP_SUB_8(op1_8 + 1, 0, op1_8);
486 
487   BX_NEXT_INSTR(i);
488 }
489 
CMPXCHG_EbGbM(bxInstruction_c * i)490 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EbGbM(bxInstruction_c *i)
491 {
492   bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
493 
494   Bit32u op1_8 = read_RMW_virtual_byte(i->seg(), eaddr);
495   Bit32u diff_8 = AL - op1_8;
496 
497   SET_FLAGS_OSZAPC_SUB_8(AL, op1_8, diff_8);
498 
499   if (diff_8 == 0) {  // if accumulator == dest
500     // dest <-- src
501     Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
502     write_RMW_linear_byte(op2_8);
503   }
504   else {
505     // accumulator <-- dest
506     write_RMW_linear_byte(op1_8);
507     AL = op1_8;
508   }
509 
510   BX_NEXT_INSTR(i);
511 }
512 
CMPXCHG_EbGbR(bxInstruction_c * i)513 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EbGbR(bxInstruction_c *i)
514 {
515   Bit32u op1_8 = BX_READ_8BIT_REGx(i->dst(), i->extend8bitL());
516   Bit32u diff_8 = AL - op1_8;
517 
518   SET_FLAGS_OSZAPC_SUB_8(AL, op1_8, diff_8);
519 
520   if (diff_8 == 0) {  // if accumulator == dest
521     // dest <-- src
522     Bit32u op2_8 = BX_READ_8BIT_REGx(i->src(), i->extend8bitL());
523     BX_WRITE_8BIT_REGx(i->dst(), i->extend8bitL(), op2_8);
524   }
525   else {
526     // accumulator <-- dest
527     AL = op1_8;
528   }
529 
530   BX_NEXT_INSTR(i);
531 }
532