1 /////////////////////////////////////////////////////////////////////////
2 // $Id: arith16.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
INC_EwR(bxInstruction_c * i)27 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INC_EwR(bxInstruction_c *i)
28 {
29 Bit32u rx = ++BX_READ_16BIT_REG(i->dst());
30 SET_FLAGS_OSZAP_ADD_16(rx - 1, 0, rx);
31
32 BX_NEXT_INSTR(i);
33 }
34
DEC_EwR(bxInstruction_c * i)35 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DEC_EwR(bxInstruction_c *i)
36 {
37 Bit32u rx = --BX_READ_16BIT_REG(i->dst());
38 SET_FLAGS_OSZAP_SUB_16(rx + 1, 0, rx);
39
40 BX_NEXT_INSTR(i);
41 }
42
ADD_EwGwM(bxInstruction_c * i)43 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EwGwM(bxInstruction_c *i)
44 {
45 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
46
47 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
48 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
49 Bit32u sum_16 = op1_16 + op2_16;
50
51 write_RMW_linear_word(sum_16);
52
53 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
54
55 BX_NEXT_INSTR(i);
56 }
57
ADD_GwEwR(bxInstruction_c * i)58 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_GwEwR(bxInstruction_c *i)
59 {
60 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
61 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
62 Bit32u sum_16 = op1_16 + op2_16;
63
64 BX_WRITE_16BIT_REG(i->dst(), sum_16);
65
66 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
67
68 BX_NEXT_INSTR(i);
69 }
70
ADD_GwEwM(bxInstruction_c * i)71 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_GwEwM(bxInstruction_c *i)
72 {
73 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
74
75 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
76 Bit32u op2_16 = read_virtual_word(i->seg(), eaddr);
77 Bit32u sum_16 = op1_16 + op2_16;
78
79 BX_WRITE_16BIT_REG(i->dst(), sum_16);
80
81 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
82
83 BX_NEXT_INSTR(i);
84 }
85
ADC_EwGwM(bxInstruction_c * i)86 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EwGwM(bxInstruction_c *i)
87 {
88 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
89
90 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
91 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
92 Bit32u sum_16 = op1_16 + op2_16 + getB_CF();
93
94 write_RMW_linear_word(sum_16);
95
96 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
97
98 BX_NEXT_INSTR(i);
99 }
100
ADC_GwEwR(bxInstruction_c * i)101 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_GwEwR(bxInstruction_c *i)
102 {
103 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
104 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
105 Bit32u sum_16 = op1_16 + op2_16 + getB_CF();
106
107 BX_WRITE_16BIT_REG(i->dst(), sum_16);
108
109 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
110
111 BX_NEXT_INSTR(i);
112 }
113
ADC_GwEwM(bxInstruction_c * i)114 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_GwEwM(bxInstruction_c *i)
115 {
116 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
117
118 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
119 Bit32u op2_16 = read_virtual_word(i->seg(), eaddr);
120 Bit32u sum_16 = op1_16 + op2_16 + getB_CF();
121
122 BX_WRITE_16BIT_REG(i->dst(), sum_16);
123
124 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
125
126 BX_NEXT_INSTR(i);
127 }
128
SBB_EwGwM(bxInstruction_c * i)129 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EwGwM(bxInstruction_c *i)
130 {
131 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
132
133 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
134 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
135 Bit32u diff_16 = op1_16 - (op2_16 + getB_CF());
136
137 write_RMW_linear_word(diff_16);
138
139 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
140
141 BX_NEXT_INSTR(i);
142 }
143
SBB_GwEwR(bxInstruction_c * i)144 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_GwEwR(bxInstruction_c *i)
145 {
146 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
147 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
148 Bit32u diff_16 = op1_16 - (op2_16 + getB_CF());
149
150 BX_WRITE_16BIT_REG(i->dst(), diff_16);
151
152 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
153
154 BX_NEXT_INSTR(i);
155 }
156
SBB_GwEwM(bxInstruction_c * i)157 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_GwEwM(bxInstruction_c *i)
158 {
159 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
160
161 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
162 Bit32u op2_16 = read_virtual_word(i->seg(), eaddr);
163 Bit32u diff_16 = op1_16 - (op2_16 + getB_CF());
164
165 BX_WRITE_16BIT_REG(i->dst(), diff_16);
166
167 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
168
169 BX_NEXT_INSTR(i);
170 }
171
SBB_EwIwM(bxInstruction_c * i)172 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EwIwM(bxInstruction_c *i)
173 {
174 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
175
176 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
177 Bit32u op2_16 = i->Iw();
178 Bit32u diff_16 = op1_16 - (op2_16 + getB_CF());
179
180 write_RMW_linear_word(diff_16);
181
182 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
183
184 BX_NEXT_INSTR(i);
185 }
186
SBB_EwIwR(bxInstruction_c * i)187 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EwIwR(bxInstruction_c *i)
188 {
189 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
190 Bit32u op2_16 = i->Iw();
191 Bit32u diff_16 = op1_16 - (op2_16 + getB_CF());
192
193 BX_WRITE_16BIT_REG(i->dst(), diff_16);
194
195 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
196
197 BX_NEXT_INSTR(i);
198 }
199
SUB_EwGwM(bxInstruction_c * i)200 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EwGwM(bxInstruction_c *i)
201 {
202 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
203
204 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
205 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
206 Bit32u diff_16 = op1_16 - op2_16;
207
208 write_RMW_linear_word(diff_16);
209
210 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
211
212 BX_NEXT_INSTR(i);
213 }
214
SUB_GwEwR(bxInstruction_c * i)215 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GwEwR(bxInstruction_c *i)
216 {
217 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
218 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
219 Bit32u diff_16 = op1_16 - op2_16;
220
221 BX_WRITE_16BIT_REG(i->dst(), diff_16);
222
223 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
224
225 BX_NEXT_INSTR(i);
226 }
227
SUB_GwEwM(bxInstruction_c * i)228 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GwEwM(bxInstruction_c *i)
229 {
230 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
231
232 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
233 Bit32u op2_16 = read_virtual_word(i->seg(), eaddr);
234 Bit32u diff_16 = op1_16 - op2_16;
235
236 BX_WRITE_16BIT_REG(i->dst(), diff_16);
237
238 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
239
240 BX_NEXT_INSTR(i);
241 }
242
CMP_EwGwM(bxInstruction_c * i)243 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EwGwM(bxInstruction_c *i)
244 {
245 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
246
247 Bit32u op1_16 = read_virtual_word(i->seg(), eaddr);
248 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
249 Bit32u diff_16 = op1_16 - op2_16;
250
251 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
252
253 BX_NEXT_INSTR(i);
254 }
255
CMP_GwEwR(bxInstruction_c * i)256 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_GwEwR(bxInstruction_c *i)
257 {
258 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
259 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
260 Bit32u diff_16 = op1_16 - op2_16;
261
262 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
263
264 BX_NEXT_INSTR(i);
265 }
266
CMP_GwEwM(bxInstruction_c * i)267 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_GwEwM(bxInstruction_c *i)
268 {
269 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
270
271 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
272 Bit32u op2_16 = read_virtual_word(i->seg(), eaddr);
273 Bit32u diff_16 = op1_16 - op2_16;
274
275 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
276
277 BX_NEXT_INSTR(i);
278 }
279
CBW(bxInstruction_c * i)280 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CBW(bxInstruction_c *i)
281 {
282 /* CBW: no flags are effected */
283 AX = (Bit8s) AL;
284
285 BX_NEXT_INSTR(i);
286 }
287
CWD(bxInstruction_c * i)288 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CWD(bxInstruction_c *i)
289 {
290 /* CWD: no flags are affected */
291 if (AX & 0x8000) {
292 DX = 0xFFFF;
293 }
294 else {
295 DX = 0x0000;
296 }
297
298 BX_NEXT_INSTR(i);
299 }
300
XADD_EwGwM(bxInstruction_c * i)301 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EwGwM(bxInstruction_c *i)
302 {
303 /* XADD dst(r/m), src(r)
304 * temp <-- src + dst | sum = op2 + op1
305 * src <-- dst | op2 = op1
306 * dst <-- tmp | op1 = sum
307 */
308
309 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
310
311 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
312 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
313 Bit32u sum_16 = op1_16 + op2_16;
314
315 write_RMW_linear_word(sum_16);
316
317 /* and write destination into source */
318 BX_WRITE_16BIT_REG(i->src(), op1_16);
319
320 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
321
322 BX_NEXT_INSTR(i);
323 }
324
XADD_EwGwR(bxInstruction_c * i)325 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EwGwR(bxInstruction_c *i)
326 {
327 /* XADD dst(r/m), src(r)
328 * temp <-- src + dst | sum = op2 + op1
329 * src <-- dst | op2 = op1
330 * dst <-- tmp | op1 = sum
331 */
332
333 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
334 Bit32u op2_16 = BX_READ_16BIT_REG(i->src());
335 Bit32u sum_16 = op1_16 + op2_16;
336
337 // and write destination into source
338 // Note: if both op1 & op2 are registers, the last one written
339 // should be the sum, as op1 & op2 may be the same register.
340 // For example: XADD AL, AL
341 BX_WRITE_16BIT_REG(i->src(), op1_16);
342 BX_WRITE_16BIT_REG(i->dst(), sum_16);
343
344 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
345
346 BX_NEXT_INSTR(i);
347 }
348
ADD_EwIwM(bxInstruction_c * i)349 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EwIwM(bxInstruction_c *i)
350 {
351 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
352
353 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
354 Bit32u op2_16 = i->Iw();
355 Bit32u sum_16 = op1_16 + op2_16;
356
357 write_RMW_linear_word(sum_16);
358
359 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
360
361 BX_NEXT_INSTR(i);
362 }
363
ADD_EwIwR(bxInstruction_c * i)364 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EwIwR(bxInstruction_c *i)
365 {
366 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
367 Bit32u op2_16 = i->Iw();
368 Bit32u sum_16 = op1_16 + op2_16;
369 BX_WRITE_16BIT_REG(i->dst(), sum_16);
370
371 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
372
373 BX_NEXT_INSTR(i);
374 }
375
ADC_EwIwM(bxInstruction_c * i)376 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EwIwM(bxInstruction_c *i)
377 {
378 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
379
380 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
381 Bit32u op2_16 = i->Iw();
382 Bit32u sum_16 = op1_16 + op2_16 + getB_CF();
383
384 write_RMW_linear_word(sum_16);
385
386 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
387
388 BX_NEXT_INSTR(i);
389 }
390
ADC_EwIwR(bxInstruction_c * i)391 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EwIwR(bxInstruction_c *i)
392 {
393 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
394 Bit32u op2_16 = i->Iw();
395 Bit32u sum_16 = op1_16 + op2_16 + getB_CF();
396
397 BX_WRITE_16BIT_REG(i->dst(), sum_16);
398
399 SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
400
401 BX_NEXT_INSTR(i);
402 }
403
SUB_EwIwM(bxInstruction_c * i)404 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EwIwM(bxInstruction_c *i)
405 {
406 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
407
408 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
409 Bit32u op2_16 = i->Iw();
410 Bit32u diff_16 = op1_16 - op2_16;
411
412 write_RMW_linear_word(diff_16);
413
414 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
415
416 BX_NEXT_INSTR(i);
417 }
418
SUB_EwIwR(bxInstruction_c * i)419 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EwIwR(bxInstruction_c *i)
420 {
421 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
422 Bit32u op2_16 = i->Iw();
423 Bit32u diff_16 = op1_16 - op2_16;
424
425 BX_WRITE_16BIT_REG(i->dst(), diff_16);
426
427 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
428
429 BX_NEXT_INSTR(i);
430 }
431
CMP_EwIwM(bxInstruction_c * i)432 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EwIwM(bxInstruction_c *i)
433 {
434 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
435
436 Bit32u op1_16 = read_virtual_word(i->seg(), eaddr);
437 Bit32u op2_16 = i->Iw();
438 Bit32u diff_16 = op1_16 - op2_16;
439
440 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
441
442 BX_NEXT_INSTR(i);
443 }
444
CMP_EwIwR(bxInstruction_c * i)445 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMP_EwIwR(bxInstruction_c *i)
446 {
447 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
448 Bit32u op2_16 = i->Iw();
449 Bit32u diff_16 = op1_16 - op2_16;
450
451 SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
452
453 BX_NEXT_INSTR(i);
454 }
455
NEG_EwM(bxInstruction_c * i)456 void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EwM(bxInstruction_c *i)
457 {
458 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
459
460 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
461 op1_16 = 0 - (Bit32s)(Bit16s)(op1_16);
462 write_RMW_linear_word(op1_16);
463
464 SET_FLAGS_OSZAPC_SUB_16(0, 0 - op1_16, op1_16);
465
466 BX_NEXT_INSTR(i);
467 }
468
NEG_EwR(bxInstruction_c * i)469 void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EwR(bxInstruction_c *i)
470 {
471 Bit32u op1_16 = BX_READ_16BIT_REG(i->dst());
472 op1_16 = 0 - (Bit32s)(Bit16s)(op1_16);
473 BX_WRITE_16BIT_REG(i->dst(), op1_16);
474
475 SET_FLAGS_OSZAPC_SUB_16(0, 0 - op1_16, op1_16);
476
477 BX_NEXT_INSTR(i);
478 }
479
INC_EwM(bxInstruction_c * i)480 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INC_EwM(bxInstruction_c *i)
481 {
482 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
483
484 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
485 op1_16++;
486 write_RMW_linear_word(op1_16);
487
488 SET_FLAGS_OSZAP_ADD_16(op1_16 - 1, 0, op1_16);
489
490 BX_NEXT_INSTR(i);
491 }
492
DEC_EwM(bxInstruction_c * i)493 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DEC_EwM(bxInstruction_c *i)
494 {
495 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
496
497 Bit32u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
498 op1_16--;
499 write_RMW_linear_word(op1_16);
500
501 SET_FLAGS_OSZAP_SUB_16(op1_16 + 1, 0, op1_16);
502
503 BX_NEXT_INSTR(i);
504 }
505
CMPXCHG_EwGwM(bxInstruction_c * i)506 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EwGwM(bxInstruction_c *i)
507 {
508 bx_address eaddr = BX_CPU_RESOLVE_ADDR(i);
509
510 Bit16u op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
511 Bit16u diff_16 = AX - op1_16;
512
513 SET_FLAGS_OSZAPC_SUB_16(AX, op1_16, diff_16);
514
515 if (diff_16 == 0) { // if accumulator == dest
516 // dest <-- src
517 write_RMW_linear_word(BX_READ_16BIT_REG(i->src()));
518 }
519 else {
520 // accumulator <-- dest
521 write_RMW_linear_word(op1_16);
522 AX = op1_16;
523 }
524
525 BX_NEXT_INSTR(i);
526 }
527
CMPXCHG_EwGwR(bxInstruction_c * i)528 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EwGwR(bxInstruction_c *i)
529 {
530 Bit16u op1_16 = BX_READ_16BIT_REG(i->dst());
531 Bit16u diff_16 = AX - op1_16;
532
533 SET_FLAGS_OSZAPC_SUB_16(AX, op1_16, diff_16);
534
535 if (diff_16 == 0) { // if accumulator == dest
536 // dest <-- src
537 BX_WRITE_16BIT_REG(i->dst(), BX_READ_16BIT_REG(i->src()));
538 }
539 else {
540 // accumulator <-- dest
541 AX = op1_16;
542 }
543
544 BX_NEXT_INSTR(i);
545 }
546