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