1 /****************************************************************************
2 *
3 * Realmode X86 Emulator Library
4 *
5 * Copyright (C) 1991-2004 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
8 *
9 * ========================================================================
10 *
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
20 *
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
28 *
29 * ========================================================================
30 *
31 * Language: ANSI C
32 * Environment: Any
33 * Developer: Kendall Bennett
34 *
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 processor instructions.
37 *
38 * There are approximately 250 subroutines in here, which correspond
39 * to the 256 byte-"opcodes" found on the 8086. The table which
40 * dispatches this is found in the files optab.[ch].
41 *
42 * Each opcode proc has a comment preceeding it which gives it's table
43 * address. Several opcodes are missing (undefined) in the table.
44 *
45 * Each proc includes information for decoding (DECODE_PRINTF and
46 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47 * functions (START_OF_INSTR, END_OF_INSTR).
48 *
49 * Many of the procedures are *VERY* similar in coding. This has
50 * allowed for a very large amount of code to be generated in a fairly
51 * short amount of time (i.e. cut, paste, and modify). The result is
52 * that much of the code below could have been folded into subroutines
53 * for a large reduction in size of this file. The downside would be
54 * that there would be a penalty in execution speed. The file could
55 * also have been *MUCH* larger by inlining certain functions which
56 * were called. This could have resulted even faster execution. The
57 * prime directive I used to decide whether to inline the code or to
58 * modularize it, was basically: 1) no unnecessary subroutine calls,
59 * 2) no routines more than about 200 lines in size, and 3) modularize
60 * any code that I might not get right the first time. The fetch_*
61 * subroutines fall into the latter category. The The decode_* fall
62 * into the second category. The coding of the "switch(mod){ .... }"
63 * in many of the subroutines below falls into the first category.
64 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
65 * subroutines are an especially glaring case of the third guideline.
66 * Since so much of the code is cloned from other modules (compare
67 * opcode #00 to opcode #01), making the basic operations subroutine
68 * calls is especially important; otherwise mistakes in coding an
69 * "add" would represent a nightmare in maintenance.
70 *
71 ****************************************************************************/
72
73 #include "x86emu/x86emui.h"
74
75 /*----------------------------- Implementation ----------------------------*/
76
77 /****************************************************************************
78 PARAMETERS:
79 op1 - Instruction op code
80
81 REMARKS:
82 Handles illegal opcodes.
83 ****************************************************************************/
x86emuOp_illegal_op(u8 op1)84 void x86emuOp_illegal_op(
85 u8 op1)
86 {
87 START_OF_INSTR();
88 if (M.x86.R_SP != 0) {
89 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90 TRACE_REGS();
91 DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92 M.x86.R_CS, M.x86.R_IP-1,op1));
93 HALT_SYS();
94 }
95 else {
96 /* If we get here, it means the stack pointer is back to zero
97 * so we are just returning from an emulator service call
98 * so therte is no need to display an error message. We trap
99 * the emulator with an 0xF1 opcode to finish the service
100 * call.
101 */
102 X86EMU_halt_sys();
103 }
104 END_OF_INSTR();
105 }
106
107 /****************************************************************************
108 REMARKS:
109 Handles opcode 0x00
110 ****************************************************************************/
x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED (op1))111 void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
112 {
113 int mod, rl, rh;
114 uint destoffset;
115 u8 *destreg, *srcreg;
116 u8 destval;
117
118 START_OF_INSTR();
119 DECODE_PRINTF("ADD\t");
120 FETCH_DECODE_MODRM(mod, rh, rl);
121 switch (mod) {
122 case 0:
123 destoffset = decode_rm00_address(rl);
124 DECODE_PRINTF(",");
125 destval = fetch_data_byte(destoffset);
126 srcreg = DECODE_RM_BYTE_REGISTER(rh);
127 DECODE_PRINTF("\n");
128 TRACE_AND_STEP();
129 destval = add_byte(destval, *srcreg);
130 store_data_byte(destoffset, destval);
131 break;
132 case 1:
133 destoffset = decode_rm01_address(rl);
134 DECODE_PRINTF(",");
135 destval = fetch_data_byte(destoffset);
136 srcreg = DECODE_RM_BYTE_REGISTER(rh);
137 DECODE_PRINTF("\n");
138 TRACE_AND_STEP();
139 destval = add_byte(destval, *srcreg);
140 store_data_byte(destoffset, destval);
141 break;
142 case 2:
143 destoffset = decode_rm10_address(rl);
144 DECODE_PRINTF(",");
145 destval = fetch_data_byte(destoffset);
146 srcreg = DECODE_RM_BYTE_REGISTER(rh);
147 DECODE_PRINTF("\n");
148 TRACE_AND_STEP();
149 destval = add_byte(destval, *srcreg);
150 store_data_byte(destoffset, destval);
151 break;
152 case 3: /* register to register */
153 destreg = DECODE_RM_BYTE_REGISTER(rl);
154 DECODE_PRINTF(",");
155 srcreg = DECODE_RM_BYTE_REGISTER(rh);
156 DECODE_PRINTF("\n");
157 TRACE_AND_STEP();
158 *destreg = add_byte(*destreg, *srcreg);
159 break;
160 }
161 DECODE_CLEAR_SEGOVR();
162 END_OF_INSTR();
163 }
164
165 /****************************************************************************
166 REMARKS:
167 Handles opcode 0x01
168 ****************************************************************************/
x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED (op1))169 void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
170 {
171 int mod, rl, rh;
172 uint destoffset;
173
174 START_OF_INSTR();
175 DECODE_PRINTF("ADD\t");
176 FETCH_DECODE_MODRM(mod, rh, rl);
177 switch (mod) {
178 case 0:
179 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
180 u32 destval;
181 u32 *srcreg;
182
183 destoffset = decode_rm00_address(rl);
184 DECODE_PRINTF(",");
185 destval = fetch_data_long(destoffset);
186 srcreg = DECODE_RM_LONG_REGISTER(rh);
187 DECODE_PRINTF("\n");
188 TRACE_AND_STEP();
189 destval = add_long(destval, *srcreg);
190 store_data_long(destoffset, destval);
191 } else {
192 u16 destval;
193 u16 *srcreg;
194
195 destoffset = decode_rm00_address(rl);
196 DECODE_PRINTF(",");
197 destval = fetch_data_word(destoffset);
198 srcreg = DECODE_RM_WORD_REGISTER(rh);
199 DECODE_PRINTF("\n");
200 TRACE_AND_STEP();
201 destval = add_word(destval, *srcreg);
202 store_data_word(destoffset, destval);
203 }
204 break;
205 case 1:
206 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
207 u32 destval;
208 u32 *srcreg;
209
210 destoffset = decode_rm01_address(rl);
211 DECODE_PRINTF(",");
212 destval = fetch_data_long(destoffset);
213 srcreg = DECODE_RM_LONG_REGISTER(rh);
214 DECODE_PRINTF("\n");
215 TRACE_AND_STEP();
216 destval = add_long(destval, *srcreg);
217 store_data_long(destoffset, destval);
218 } else {
219 u16 destval;
220 u16 *srcreg;
221
222 destoffset = decode_rm01_address(rl);
223 DECODE_PRINTF(",");
224 destval = fetch_data_word(destoffset);
225 srcreg = DECODE_RM_WORD_REGISTER(rh);
226 DECODE_PRINTF("\n");
227 TRACE_AND_STEP();
228 destval = add_word(destval, *srcreg);
229 store_data_word(destoffset, destval);
230 }
231 break;
232 case 2:
233 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
234 u32 destval;
235 u32 *srcreg;
236
237 destoffset = decode_rm10_address(rl);
238 DECODE_PRINTF(",");
239 destval = fetch_data_long(destoffset);
240 srcreg = DECODE_RM_LONG_REGISTER(rh);
241 DECODE_PRINTF("\n");
242 TRACE_AND_STEP();
243 destval = add_long(destval, *srcreg);
244 store_data_long(destoffset, destval);
245 } else {
246 u16 destval;
247 u16 *srcreg;
248
249 destoffset = decode_rm10_address(rl);
250 DECODE_PRINTF(",");
251 destval = fetch_data_word(destoffset);
252 srcreg = DECODE_RM_WORD_REGISTER(rh);
253 DECODE_PRINTF("\n");
254 TRACE_AND_STEP();
255 destval = add_word(destval, *srcreg);
256 store_data_word(destoffset, destval);
257 }
258 break;
259 case 3: /* register to register */
260 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
261 u32 *destreg,*srcreg;
262
263 destreg = DECODE_RM_LONG_REGISTER(rl);
264 DECODE_PRINTF(",");
265 srcreg = DECODE_RM_LONG_REGISTER(rh);
266 DECODE_PRINTF("\n");
267 TRACE_AND_STEP();
268 *destreg = add_long(*destreg, *srcreg);
269 } else {
270 u16 *destreg,*srcreg;
271
272 destreg = DECODE_RM_WORD_REGISTER(rl);
273 DECODE_PRINTF(",");
274 srcreg = DECODE_RM_WORD_REGISTER(rh);
275 DECODE_PRINTF("\n");
276 TRACE_AND_STEP();
277 *destreg = add_word(*destreg, *srcreg);
278 }
279 break;
280 }
281 DECODE_CLEAR_SEGOVR();
282 END_OF_INSTR();
283 }
284
285 /****************************************************************************
286 REMARKS:
287 Handles opcode 0x02
288 ****************************************************************************/
x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED (op1))289 void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
290 {
291 int mod, rl, rh;
292 u8 *destreg, *srcreg;
293 uint srcoffset;
294 u8 srcval;
295
296 START_OF_INSTR();
297 DECODE_PRINTF("ADD\t");
298 FETCH_DECODE_MODRM(mod, rh, rl);
299 switch (mod) {
300 case 0:
301 destreg = DECODE_RM_BYTE_REGISTER(rh);
302 DECODE_PRINTF(",");
303 srcoffset = decode_rm00_address(rl);
304 srcval = fetch_data_byte(srcoffset);
305 DECODE_PRINTF("\n");
306 TRACE_AND_STEP();
307 *destreg = add_byte(*destreg, srcval);
308 break;
309 case 1:
310 destreg = DECODE_RM_BYTE_REGISTER(rh);
311 DECODE_PRINTF(",");
312 srcoffset = decode_rm01_address(rl);
313 srcval = fetch_data_byte(srcoffset);
314 DECODE_PRINTF("\n");
315 TRACE_AND_STEP();
316 *destreg = add_byte(*destreg, srcval);
317 break;
318 case 2:
319 destreg = DECODE_RM_BYTE_REGISTER(rh);
320 DECODE_PRINTF(",");
321 srcoffset = decode_rm10_address(rl);
322 srcval = fetch_data_byte(srcoffset);
323 DECODE_PRINTF("\n");
324 TRACE_AND_STEP();
325 *destreg = add_byte(*destreg, srcval);
326 break;
327 case 3: /* register to register */
328 destreg = DECODE_RM_BYTE_REGISTER(rh);
329 DECODE_PRINTF(",");
330 srcreg = DECODE_RM_BYTE_REGISTER(rl);
331 DECODE_PRINTF("\n");
332 TRACE_AND_STEP();
333 *destreg = add_byte(*destreg, *srcreg);
334 break;
335 }
336 DECODE_CLEAR_SEGOVR();
337 END_OF_INSTR();
338 }
339
340 /****************************************************************************
341 REMARKS:
342 Handles opcode 0x03
343 ****************************************************************************/
x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED (op1))344 void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
345 {
346 int mod, rl, rh;
347 uint srcoffset;
348
349 START_OF_INSTR();
350 DECODE_PRINTF("ADD\t");
351 FETCH_DECODE_MODRM(mod, rh, rl);
352 switch (mod) {
353 case 0:
354 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
355 u32 *destreg;
356 u32 srcval;
357
358 destreg = DECODE_RM_LONG_REGISTER(rh);
359 DECODE_PRINTF(",");
360 srcoffset = decode_rm00_address(rl);
361 srcval = fetch_data_long(srcoffset);
362 DECODE_PRINTF("\n");
363 TRACE_AND_STEP();
364 *destreg = add_long(*destreg, srcval);
365 } else {
366 u16 *destreg;
367 u16 srcval;
368
369 destreg = DECODE_RM_WORD_REGISTER(rh);
370 DECODE_PRINTF(",");
371 srcoffset = decode_rm00_address(rl);
372 srcval = fetch_data_word(srcoffset);
373 DECODE_PRINTF("\n");
374 TRACE_AND_STEP();
375 *destreg = add_word(*destreg, srcval);
376 }
377 break;
378 case 1:
379 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
380 u32 *destreg;
381 u32 srcval;
382
383 destreg = DECODE_RM_LONG_REGISTER(rh);
384 DECODE_PRINTF(",");
385 srcoffset = decode_rm01_address(rl);
386 srcval = fetch_data_long(srcoffset);
387 DECODE_PRINTF("\n");
388 TRACE_AND_STEP();
389 *destreg = add_long(*destreg, srcval);
390 } else {
391 u16 *destreg;
392 u16 srcval;
393
394 destreg = DECODE_RM_WORD_REGISTER(rh);
395 DECODE_PRINTF(",");
396 srcoffset = decode_rm01_address(rl);
397 srcval = fetch_data_word(srcoffset);
398 DECODE_PRINTF("\n");
399 TRACE_AND_STEP();
400 *destreg = add_word(*destreg, srcval);
401 }
402 break;
403 case 2:
404 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
405 u32 *destreg;
406 u32 srcval;
407
408 destreg = DECODE_RM_LONG_REGISTER(rh);
409 DECODE_PRINTF(",");
410 srcoffset = decode_rm10_address(rl);
411 srcval = fetch_data_long(srcoffset);
412 DECODE_PRINTF("\n");
413 TRACE_AND_STEP();
414 *destreg = add_long(*destreg, srcval);
415 } else {
416 u16 *destreg;
417 u16 srcval;
418
419 destreg = DECODE_RM_WORD_REGISTER(rh);
420 DECODE_PRINTF(",");
421 srcoffset = decode_rm10_address(rl);
422 srcval = fetch_data_word(srcoffset);
423 DECODE_PRINTF("\n");
424 TRACE_AND_STEP();
425 *destreg = add_word(*destreg, srcval);
426 }
427 break;
428 case 3: /* register to register */
429 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
430 u32 *destreg,*srcreg;
431
432 destreg = DECODE_RM_LONG_REGISTER(rh);
433 DECODE_PRINTF(",");
434 srcreg = DECODE_RM_LONG_REGISTER(rl);
435 DECODE_PRINTF("\n");
436 TRACE_AND_STEP();
437 *destreg = add_long(*destreg, *srcreg);
438 } else {
439 u16 *destreg,*srcreg;
440
441 destreg = DECODE_RM_WORD_REGISTER(rh);
442 DECODE_PRINTF(",");
443 srcreg = DECODE_RM_WORD_REGISTER(rl);
444 DECODE_PRINTF("\n");
445 TRACE_AND_STEP();
446 *destreg = add_word(*destreg, *srcreg);
447 }
448 break;
449 }
450 DECODE_CLEAR_SEGOVR();
451 END_OF_INSTR();
452 }
453
454 /****************************************************************************
455 REMARKS:
456 Handles opcode 0x04
457 ****************************************************************************/
x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED (op1))458 void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
459 {
460 u8 srcval;
461
462 START_OF_INSTR();
463 DECODE_PRINTF("ADD\tAL,");
464 srcval = fetch_byte_imm();
465 DECODE_PRINTF2("%x\n", srcval);
466 TRACE_AND_STEP();
467 M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
468 DECODE_CLEAR_SEGOVR();
469 END_OF_INSTR();
470 }
471
472 /****************************************************************************
473 REMARKS:
474 Handles opcode 0x05
475 ****************************************************************************/
x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED (op1))476 void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
477 {
478 u32 srcval;
479
480 START_OF_INSTR();
481 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
482 DECODE_PRINTF("ADD\tEAX,");
483 srcval = fetch_long_imm();
484 } else {
485 DECODE_PRINTF("ADD\tAX,");
486 srcval = fetch_word_imm();
487 }
488 DECODE_PRINTF2("%x\n", srcval);
489 TRACE_AND_STEP();
490 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
491 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
492 } else {
493 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
494 }
495 DECODE_CLEAR_SEGOVR();
496 END_OF_INSTR();
497 }
498
499 /****************************************************************************
500 REMARKS:
501 Handles opcode 0x06
502 ****************************************************************************/
x86emuOp_push_ES(u8 X86EMU_UNUSED (op1))503 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
504 {
505 START_OF_INSTR();
506 DECODE_PRINTF("PUSH\tES\n");
507 TRACE_AND_STEP();
508 push_word(M.x86.R_ES);
509 DECODE_CLEAR_SEGOVR();
510 END_OF_INSTR();
511 }
512
513 /****************************************************************************
514 REMARKS:
515 Handles opcode 0x07
516 ****************************************************************************/
x86emuOp_pop_ES(u8 X86EMU_UNUSED (op1))517 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
518 {
519 START_OF_INSTR();
520 DECODE_PRINTF("POP\tES\n");
521 TRACE_AND_STEP();
522 M.x86.R_ES = pop_word();
523 DECODE_CLEAR_SEGOVR();
524 END_OF_INSTR();
525 }
526
527 /****************************************************************************
528 REMARKS:
529 Handles opcode 0x08
530 ****************************************************************************/
x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED (op1))531 void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
532 {
533 int mod, rl, rh;
534 u8 *destreg, *srcreg;
535 uint destoffset;
536 u8 destval;
537
538 START_OF_INSTR();
539 DECODE_PRINTF("OR\t");
540 FETCH_DECODE_MODRM(mod, rh, rl);
541 switch (mod) {
542 case 0:
543 destoffset = decode_rm00_address(rl);
544 DECODE_PRINTF(",");
545 destval = fetch_data_byte(destoffset);
546 srcreg = DECODE_RM_BYTE_REGISTER(rh);
547 DECODE_PRINTF("\n");
548 TRACE_AND_STEP();
549 destval = or_byte(destval, *srcreg);
550 store_data_byte(destoffset, destval);
551 break;
552 case 1:
553 destoffset = decode_rm01_address(rl);
554 DECODE_PRINTF(",");
555 destval = fetch_data_byte(destoffset);
556 srcreg = DECODE_RM_BYTE_REGISTER(rh);
557 DECODE_PRINTF("\n");
558 TRACE_AND_STEP();
559 destval = or_byte(destval, *srcreg);
560 store_data_byte(destoffset, destval);
561 break;
562 case 2:
563 destoffset = decode_rm10_address(rl);
564 DECODE_PRINTF(",");
565 destval = fetch_data_byte(destoffset);
566 srcreg = DECODE_RM_BYTE_REGISTER(rh);
567 DECODE_PRINTF("\n");
568 TRACE_AND_STEP();
569 destval = or_byte(destval, *srcreg);
570 store_data_byte(destoffset, destval);
571 break;
572 case 3: /* register to register */
573 destreg = DECODE_RM_BYTE_REGISTER(rl);
574 DECODE_PRINTF(",");
575 srcreg = DECODE_RM_BYTE_REGISTER(rh);
576 DECODE_PRINTF("\n");
577 TRACE_AND_STEP();
578 *destreg = or_byte(*destreg, *srcreg);
579 break;
580 }
581 DECODE_CLEAR_SEGOVR();
582 END_OF_INSTR();
583 }
584
585 /****************************************************************************
586 REMARKS:
587 Handles opcode 0x09
588 ****************************************************************************/
x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED (op1))589 void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
590 {
591 int mod, rl, rh;
592 uint destoffset;
593
594 START_OF_INSTR();
595 DECODE_PRINTF("OR\t");
596 FETCH_DECODE_MODRM(mod, rh, rl);
597 switch (mod) {
598 case 0:
599 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
600 u32 destval;
601 u32 *srcreg;
602
603 destoffset = decode_rm00_address(rl);
604 DECODE_PRINTF(",");
605 destval = fetch_data_long(destoffset);
606 srcreg = DECODE_RM_LONG_REGISTER(rh);
607 DECODE_PRINTF("\n");
608 TRACE_AND_STEP();
609 destval = or_long(destval, *srcreg);
610 store_data_long(destoffset, destval);
611 } else {
612 u16 destval;
613 u16 *srcreg;
614
615 destoffset = decode_rm00_address(rl);
616 DECODE_PRINTF(",");
617 destval = fetch_data_word(destoffset);
618 srcreg = DECODE_RM_WORD_REGISTER(rh);
619 DECODE_PRINTF("\n");
620 TRACE_AND_STEP();
621 destval = or_word(destval, *srcreg);
622 store_data_word(destoffset, destval);
623 }
624 break;
625 case 1:
626 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
627 u32 destval;
628 u32 *srcreg;
629
630 destoffset = decode_rm01_address(rl);
631 DECODE_PRINTF(",");
632 destval = fetch_data_long(destoffset);
633 srcreg = DECODE_RM_LONG_REGISTER(rh);
634 DECODE_PRINTF("\n");
635 TRACE_AND_STEP();
636 destval = or_long(destval, *srcreg);
637 store_data_long(destoffset, destval);
638 } else {
639 u16 destval;
640 u16 *srcreg;
641
642 destoffset = decode_rm01_address(rl);
643 DECODE_PRINTF(",");
644 destval = fetch_data_word(destoffset);
645 srcreg = DECODE_RM_WORD_REGISTER(rh);
646 DECODE_PRINTF("\n");
647 TRACE_AND_STEP();
648 destval = or_word(destval, *srcreg);
649 store_data_word(destoffset, destval);
650 }
651 break;
652 case 2:
653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
654 u32 destval;
655 u32 *srcreg;
656
657 destoffset = decode_rm10_address(rl);
658 DECODE_PRINTF(",");
659 destval = fetch_data_long(destoffset);
660 srcreg = DECODE_RM_LONG_REGISTER(rh);
661 DECODE_PRINTF("\n");
662 TRACE_AND_STEP();
663 destval = or_long(destval, *srcreg);
664 store_data_long(destoffset, destval);
665 } else {
666 u16 destval;
667 u16 *srcreg;
668
669 destoffset = decode_rm10_address(rl);
670 DECODE_PRINTF(",");
671 destval = fetch_data_word(destoffset);
672 srcreg = DECODE_RM_WORD_REGISTER(rh);
673 DECODE_PRINTF("\n");
674 TRACE_AND_STEP();
675 destval = or_word(destval, *srcreg);
676 store_data_word(destoffset, destval);
677 }
678 break;
679 case 3: /* register to register */
680 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
681 u32 *destreg,*srcreg;
682
683 destreg = DECODE_RM_LONG_REGISTER(rl);
684 DECODE_PRINTF(",");
685 srcreg = DECODE_RM_LONG_REGISTER(rh);
686 DECODE_PRINTF("\n");
687 TRACE_AND_STEP();
688 *destreg = or_long(*destreg, *srcreg);
689 } else {
690 u16 *destreg,*srcreg;
691
692 destreg = DECODE_RM_WORD_REGISTER(rl);
693 DECODE_PRINTF(",");
694 srcreg = DECODE_RM_WORD_REGISTER(rh);
695 DECODE_PRINTF("\n");
696 TRACE_AND_STEP();
697 *destreg = or_word(*destreg, *srcreg);
698 }
699 break;
700 }
701 DECODE_CLEAR_SEGOVR();
702 END_OF_INSTR();
703 }
704
705 /****************************************************************************
706 REMARKS:
707 Handles opcode 0x0a
708 ****************************************************************************/
x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED (op1))709 void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
710 {
711 int mod, rl, rh;
712 u8 *destreg, *srcreg;
713 uint srcoffset;
714 u8 srcval;
715
716 START_OF_INSTR();
717 DECODE_PRINTF("OR\t");
718 FETCH_DECODE_MODRM(mod, rh, rl);
719 switch (mod) {
720 case 0:
721 destreg = DECODE_RM_BYTE_REGISTER(rh);
722 DECODE_PRINTF(",");
723 srcoffset = decode_rm00_address(rl);
724 srcval = fetch_data_byte(srcoffset);
725 DECODE_PRINTF("\n");
726 TRACE_AND_STEP();
727 *destreg = or_byte(*destreg, srcval);
728 break;
729 case 1:
730 destreg = DECODE_RM_BYTE_REGISTER(rh);
731 DECODE_PRINTF(",");
732 srcoffset = decode_rm01_address(rl);
733 srcval = fetch_data_byte(srcoffset);
734 DECODE_PRINTF("\n");
735 TRACE_AND_STEP();
736 *destreg = or_byte(*destreg, srcval);
737 break;
738 case 2:
739 destreg = DECODE_RM_BYTE_REGISTER(rh);
740 DECODE_PRINTF(",");
741 srcoffset = decode_rm10_address(rl);
742 srcval = fetch_data_byte(srcoffset);
743 DECODE_PRINTF("\n");
744 TRACE_AND_STEP();
745 *destreg = or_byte(*destreg, srcval);
746 break;
747 case 3: /* register to register */
748 destreg = DECODE_RM_BYTE_REGISTER(rh);
749 DECODE_PRINTF(",");
750 srcreg = DECODE_RM_BYTE_REGISTER(rl);
751 DECODE_PRINTF("\n");
752 TRACE_AND_STEP();
753 *destreg = or_byte(*destreg, *srcreg);
754 break;
755 }
756 DECODE_CLEAR_SEGOVR();
757 END_OF_INSTR();
758 }
759
760 /****************************************************************************
761 REMARKS:
762 Handles opcode 0x0b
763 ****************************************************************************/
x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED (op1))764 void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
765 {
766 int mod, rl, rh;
767 uint srcoffset;
768
769 START_OF_INSTR();
770 DECODE_PRINTF("OR\t");
771 FETCH_DECODE_MODRM(mod, rh, rl);
772 switch (mod) {
773 case 0:
774 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
775 u32 *destreg;
776 u32 srcval;
777
778 destreg = DECODE_RM_LONG_REGISTER(rh);
779 DECODE_PRINTF(",");
780 srcoffset = decode_rm00_address(rl);
781 srcval = fetch_data_long(srcoffset);
782 DECODE_PRINTF("\n");
783 TRACE_AND_STEP();
784 *destreg = or_long(*destreg, srcval);
785 } else {
786 u16 *destreg;
787 u16 srcval;
788
789 destreg = DECODE_RM_WORD_REGISTER(rh);
790 DECODE_PRINTF(",");
791 srcoffset = decode_rm00_address(rl);
792 srcval = fetch_data_word(srcoffset);
793 DECODE_PRINTF("\n");
794 TRACE_AND_STEP();
795 *destreg = or_word(*destreg, srcval);
796 }
797 break;
798 case 1:
799 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
800 u32 *destreg;
801 u32 srcval;
802
803 destreg = DECODE_RM_LONG_REGISTER(rh);
804 DECODE_PRINTF(",");
805 srcoffset = decode_rm01_address(rl);
806 srcval = fetch_data_long(srcoffset);
807 DECODE_PRINTF("\n");
808 TRACE_AND_STEP();
809 *destreg = or_long(*destreg, srcval);
810 } else {
811 u16 *destreg;
812 u16 srcval;
813
814 destreg = DECODE_RM_WORD_REGISTER(rh);
815 DECODE_PRINTF(",");
816 srcoffset = decode_rm01_address(rl);
817 srcval = fetch_data_word(srcoffset);
818 DECODE_PRINTF("\n");
819 TRACE_AND_STEP();
820 *destreg = or_word(*destreg, srcval);
821 }
822 break;
823 case 2:
824 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
825 u32 *destreg;
826 u32 srcval;
827
828 destreg = DECODE_RM_LONG_REGISTER(rh);
829 DECODE_PRINTF(",");
830 srcoffset = decode_rm10_address(rl);
831 srcval = fetch_data_long(srcoffset);
832 DECODE_PRINTF("\n");
833 TRACE_AND_STEP();
834 *destreg = or_long(*destreg, srcval);
835 } else {
836 u16 *destreg;
837 u16 srcval;
838
839 destreg = DECODE_RM_WORD_REGISTER(rh);
840 DECODE_PRINTF(",");
841 srcoffset = decode_rm10_address(rl);
842 srcval = fetch_data_word(srcoffset);
843 DECODE_PRINTF("\n");
844 TRACE_AND_STEP();
845 *destreg = or_word(*destreg, srcval);
846 }
847 break;
848 case 3: /* register to register */
849 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
850 u32 *destreg,*srcreg;
851
852 destreg = DECODE_RM_LONG_REGISTER(rh);
853 DECODE_PRINTF(",");
854 srcreg = DECODE_RM_LONG_REGISTER(rl);
855 DECODE_PRINTF("\n");
856 TRACE_AND_STEP();
857 *destreg = or_long(*destreg, *srcreg);
858 } else {
859 u16 *destreg,*srcreg;
860
861 destreg = DECODE_RM_WORD_REGISTER(rh);
862 DECODE_PRINTF(",");
863 srcreg = DECODE_RM_WORD_REGISTER(rl);
864 DECODE_PRINTF("\n");
865 TRACE_AND_STEP();
866 *destreg = or_word(*destreg, *srcreg);
867 }
868 break;
869 }
870 DECODE_CLEAR_SEGOVR();
871 END_OF_INSTR();
872 }
873
874 /****************************************************************************
875 REMARKS:
876 Handles opcode 0x0c
877 ****************************************************************************/
x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED (op1))878 void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
879 {
880 u8 srcval;
881
882 START_OF_INSTR();
883 DECODE_PRINTF("OR\tAL,");
884 srcval = fetch_byte_imm();
885 DECODE_PRINTF2("%x\n", srcval);
886 TRACE_AND_STEP();
887 M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
888 DECODE_CLEAR_SEGOVR();
889 END_OF_INSTR();
890 }
891
892 /****************************************************************************
893 REMARKS:
894 Handles opcode 0x0d
895 ****************************************************************************/
x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED (op1))896 void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
897 {
898 u32 srcval;
899
900 START_OF_INSTR();
901 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
902 DECODE_PRINTF("OR\tEAX,");
903 srcval = fetch_long_imm();
904 } else {
905 DECODE_PRINTF("OR\tAX,");
906 srcval = fetch_word_imm();
907 }
908 DECODE_PRINTF2("%x\n", srcval);
909 TRACE_AND_STEP();
910 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
911 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
912 } else {
913 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
914 }
915 DECODE_CLEAR_SEGOVR();
916 END_OF_INSTR();
917 }
918
919 /****************************************************************************
920 REMARKS:
921 Handles opcode 0x0e
922 ****************************************************************************/
x86emuOp_push_CS(u8 X86EMU_UNUSED (op1))923 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
924 {
925 START_OF_INSTR();
926 DECODE_PRINTF("PUSH\tCS\n");
927 TRACE_AND_STEP();
928 push_word(M.x86.R_CS);
929 DECODE_CLEAR_SEGOVR();
930 END_OF_INSTR();
931 }
932
933 /****************************************************************************
934 REMARKS:
935 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
936 ****************************************************************************/
x86emuOp_two_byte(u8 X86EMU_UNUSED (op1))937 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
938 {
939 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
940 INC_DECODED_INST_LEN(1);
941 (*x86emu_optab2[op2])(op2);
942 }
943
944 /****************************************************************************
945 REMARKS:
946 Handles opcode 0x10
947 ****************************************************************************/
x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED (op1))948 void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
949 {
950 int mod, rl, rh;
951 u8 *destreg, *srcreg;
952 uint destoffset;
953 u8 destval;
954
955 START_OF_INSTR();
956 DECODE_PRINTF("ADC\t");
957 FETCH_DECODE_MODRM(mod, rh, rl);
958 switch (mod) {
959 case 0:
960 destoffset = decode_rm00_address(rl);
961 DECODE_PRINTF(",");
962 destval = fetch_data_byte(destoffset);
963 srcreg = DECODE_RM_BYTE_REGISTER(rh);
964 DECODE_PRINTF("\n");
965 TRACE_AND_STEP();
966 destval = adc_byte(destval, *srcreg);
967 store_data_byte(destoffset, destval);
968 break;
969 case 1:
970 destoffset = decode_rm01_address(rl);
971 DECODE_PRINTF(",");
972 destval = fetch_data_byte(destoffset);
973 srcreg = DECODE_RM_BYTE_REGISTER(rh);
974 DECODE_PRINTF("\n");
975 TRACE_AND_STEP();
976 destval = adc_byte(destval, *srcreg);
977 store_data_byte(destoffset, destval);
978 break;
979 case 2:
980 destoffset = decode_rm10_address(rl);
981 DECODE_PRINTF(",");
982 destval = fetch_data_byte(destoffset);
983 srcreg = DECODE_RM_BYTE_REGISTER(rh);
984 DECODE_PRINTF("\n");
985 TRACE_AND_STEP();
986 destval = adc_byte(destval, *srcreg);
987 store_data_byte(destoffset, destval);
988 break;
989 case 3: /* register to register */
990 destreg = DECODE_RM_BYTE_REGISTER(rl);
991 DECODE_PRINTF(",");
992 srcreg = DECODE_RM_BYTE_REGISTER(rh);
993 DECODE_PRINTF("\n");
994 TRACE_AND_STEP();
995 *destreg = adc_byte(*destreg, *srcreg);
996 break;
997 }
998 DECODE_CLEAR_SEGOVR();
999 END_OF_INSTR();
1000 }
1001
1002 /****************************************************************************
1003 REMARKS:
1004 Handles opcode 0x11
1005 ****************************************************************************/
x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED (op1))1006 void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1007 {
1008 int mod, rl, rh;
1009 uint destoffset;
1010
1011 START_OF_INSTR();
1012 DECODE_PRINTF("ADC\t");
1013 FETCH_DECODE_MODRM(mod, rh, rl);
1014 switch (mod) {
1015 case 0:
1016 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1017 u32 destval;
1018 u32 *srcreg;
1019
1020 destoffset = decode_rm00_address(rl);
1021 DECODE_PRINTF(",");
1022 destval = fetch_data_long(destoffset);
1023 srcreg = DECODE_RM_LONG_REGISTER(rh);
1024 DECODE_PRINTF("\n");
1025 TRACE_AND_STEP();
1026 destval = adc_long(destval, *srcreg);
1027 store_data_long(destoffset, destval);
1028 } else {
1029 u16 destval;
1030 u16 *srcreg;
1031
1032 destoffset = decode_rm00_address(rl);
1033 DECODE_PRINTF(",");
1034 destval = fetch_data_word(destoffset);
1035 srcreg = DECODE_RM_WORD_REGISTER(rh);
1036 DECODE_PRINTF("\n");
1037 TRACE_AND_STEP();
1038 destval = adc_word(destval, *srcreg);
1039 store_data_word(destoffset, destval);
1040 }
1041 break;
1042 case 1:
1043 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1044 u32 destval;
1045 u32 *srcreg;
1046
1047 destoffset = decode_rm01_address(rl);
1048 DECODE_PRINTF(",");
1049 destval = fetch_data_long(destoffset);
1050 srcreg = DECODE_RM_LONG_REGISTER(rh);
1051 DECODE_PRINTF("\n");
1052 TRACE_AND_STEP();
1053 destval = adc_long(destval, *srcreg);
1054 store_data_long(destoffset, destval);
1055 } else {
1056 u16 destval;
1057 u16 *srcreg;
1058
1059 destoffset = decode_rm01_address(rl);
1060 DECODE_PRINTF(",");
1061 destval = fetch_data_word(destoffset);
1062 srcreg = DECODE_RM_WORD_REGISTER(rh);
1063 DECODE_PRINTF("\n");
1064 TRACE_AND_STEP();
1065 destval = adc_word(destval, *srcreg);
1066 store_data_word(destoffset, destval);
1067 }
1068 break;
1069 case 2:
1070 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1071 u32 destval;
1072 u32 *srcreg;
1073
1074 destoffset = decode_rm10_address(rl);
1075 DECODE_PRINTF(",");
1076 destval = fetch_data_long(destoffset);
1077 srcreg = DECODE_RM_LONG_REGISTER(rh);
1078 DECODE_PRINTF("\n");
1079 TRACE_AND_STEP();
1080 destval = adc_long(destval, *srcreg);
1081 store_data_long(destoffset, destval);
1082 } else {
1083 u16 destval;
1084 u16 *srcreg;
1085
1086 destoffset = decode_rm10_address(rl);
1087 DECODE_PRINTF(",");
1088 destval = fetch_data_word(destoffset);
1089 srcreg = DECODE_RM_WORD_REGISTER(rh);
1090 DECODE_PRINTF("\n");
1091 TRACE_AND_STEP();
1092 destval = adc_word(destval, *srcreg);
1093 store_data_word(destoffset, destval);
1094 }
1095 break;
1096 case 3: /* register to register */
1097 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1098 u32 *destreg,*srcreg;
1099
1100 destreg = DECODE_RM_LONG_REGISTER(rl);
1101 DECODE_PRINTF(",");
1102 srcreg = DECODE_RM_LONG_REGISTER(rh);
1103 DECODE_PRINTF("\n");
1104 TRACE_AND_STEP();
1105 *destreg = adc_long(*destreg, *srcreg);
1106 } else {
1107 u16 *destreg,*srcreg;
1108
1109 destreg = DECODE_RM_WORD_REGISTER(rl);
1110 DECODE_PRINTF(",");
1111 srcreg = DECODE_RM_WORD_REGISTER(rh);
1112 DECODE_PRINTF("\n");
1113 TRACE_AND_STEP();
1114 *destreg = adc_word(*destreg, *srcreg);
1115 }
1116 break;
1117 }
1118 DECODE_CLEAR_SEGOVR();
1119 END_OF_INSTR();
1120 }
1121
1122 /****************************************************************************
1123 REMARKS:
1124 Handles opcode 0x12
1125 ****************************************************************************/
x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED (op1))1126 void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1127 {
1128 int mod, rl, rh;
1129 u8 *destreg, *srcreg;
1130 uint srcoffset;
1131 u8 srcval;
1132
1133 START_OF_INSTR();
1134 DECODE_PRINTF("ADC\t");
1135 FETCH_DECODE_MODRM(mod, rh, rl);
1136 switch (mod) {
1137 case 0:
1138 destreg = DECODE_RM_BYTE_REGISTER(rh);
1139 DECODE_PRINTF(",");
1140 srcoffset = decode_rm00_address(rl);
1141 srcval = fetch_data_byte(srcoffset);
1142 DECODE_PRINTF("\n");
1143 TRACE_AND_STEP();
1144 *destreg = adc_byte(*destreg, srcval);
1145 break;
1146 case 1:
1147 destreg = DECODE_RM_BYTE_REGISTER(rh);
1148 DECODE_PRINTF(",");
1149 srcoffset = decode_rm01_address(rl);
1150 srcval = fetch_data_byte(srcoffset);
1151 DECODE_PRINTF("\n");
1152 TRACE_AND_STEP();
1153 *destreg = adc_byte(*destreg, srcval);
1154 break;
1155 case 2:
1156 destreg = DECODE_RM_BYTE_REGISTER(rh);
1157 DECODE_PRINTF(",");
1158 srcoffset = decode_rm10_address(rl);
1159 srcval = fetch_data_byte(srcoffset);
1160 DECODE_PRINTF("\n");
1161 TRACE_AND_STEP();
1162 *destreg = adc_byte(*destreg, srcval);
1163 break;
1164 case 3: /* register to register */
1165 destreg = DECODE_RM_BYTE_REGISTER(rh);
1166 DECODE_PRINTF(",");
1167 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1168 DECODE_PRINTF("\n");
1169 TRACE_AND_STEP();
1170 *destreg = adc_byte(*destreg, *srcreg);
1171 break;
1172 }
1173 DECODE_CLEAR_SEGOVR();
1174 END_OF_INSTR();
1175 }
1176
1177 /****************************************************************************
1178 REMARKS:
1179 Handles opcode 0x13
1180 ****************************************************************************/
x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED (op1))1181 void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1182 {
1183 int mod, rl, rh;
1184 uint srcoffset;
1185
1186 START_OF_INSTR();
1187 DECODE_PRINTF("ADC\t");
1188 FETCH_DECODE_MODRM(mod, rh, rl);
1189 switch (mod) {
1190 case 0:
1191 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1192 u32 *destreg;
1193 u32 srcval;
1194
1195 destreg = DECODE_RM_LONG_REGISTER(rh);
1196 DECODE_PRINTF(",");
1197 srcoffset = decode_rm00_address(rl);
1198 srcval = fetch_data_long(srcoffset);
1199 DECODE_PRINTF("\n");
1200 TRACE_AND_STEP();
1201 *destreg = adc_long(*destreg, srcval);
1202 } else {
1203 u16 *destreg;
1204 u16 srcval;
1205
1206 destreg = DECODE_RM_WORD_REGISTER(rh);
1207 DECODE_PRINTF(",");
1208 srcoffset = decode_rm00_address(rl);
1209 srcval = fetch_data_word(srcoffset);
1210 DECODE_PRINTF("\n");
1211 TRACE_AND_STEP();
1212 *destreg = adc_word(*destreg, srcval);
1213 }
1214 break;
1215 case 1:
1216 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1217 u32 *destreg;
1218 u32 srcval;
1219
1220 destreg = DECODE_RM_LONG_REGISTER(rh);
1221 DECODE_PRINTF(",");
1222 srcoffset = decode_rm01_address(rl);
1223 srcval = fetch_data_long(srcoffset);
1224 DECODE_PRINTF("\n");
1225 TRACE_AND_STEP();
1226 *destreg = adc_long(*destreg, srcval);
1227 } else {
1228 u16 *destreg;
1229 u16 srcval;
1230
1231 destreg = DECODE_RM_WORD_REGISTER(rh);
1232 DECODE_PRINTF(",");
1233 srcoffset = decode_rm01_address(rl);
1234 srcval = fetch_data_word(srcoffset);
1235 DECODE_PRINTF("\n");
1236 TRACE_AND_STEP();
1237 *destreg = adc_word(*destreg, srcval);
1238 }
1239 break;
1240 case 2:
1241 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1242 u32 *destreg;
1243 u32 srcval;
1244
1245 destreg = DECODE_RM_LONG_REGISTER(rh);
1246 DECODE_PRINTF(",");
1247 srcoffset = decode_rm10_address(rl);
1248 srcval = fetch_data_long(srcoffset);
1249 DECODE_PRINTF("\n");
1250 TRACE_AND_STEP();
1251 *destreg = adc_long(*destreg, srcval);
1252 } else {
1253 u16 *destreg;
1254 u16 srcval;
1255
1256 destreg = DECODE_RM_WORD_REGISTER(rh);
1257 DECODE_PRINTF(",");
1258 srcoffset = decode_rm10_address(rl);
1259 srcval = fetch_data_word(srcoffset);
1260 DECODE_PRINTF("\n");
1261 TRACE_AND_STEP();
1262 *destreg = adc_word(*destreg, srcval);
1263 }
1264 break;
1265 case 3: /* register to register */
1266 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1267 u32 *destreg,*srcreg;
1268
1269 destreg = DECODE_RM_LONG_REGISTER(rh);
1270 DECODE_PRINTF(",");
1271 srcreg = DECODE_RM_LONG_REGISTER(rl);
1272 DECODE_PRINTF("\n");
1273 TRACE_AND_STEP();
1274 *destreg = adc_long(*destreg, *srcreg);
1275 } else {
1276 u16 *destreg,*srcreg;
1277
1278 destreg = DECODE_RM_WORD_REGISTER(rh);
1279 DECODE_PRINTF(",");
1280 srcreg = DECODE_RM_WORD_REGISTER(rl);
1281 DECODE_PRINTF("\n");
1282 TRACE_AND_STEP();
1283 *destreg = adc_word(*destreg, *srcreg);
1284 }
1285 break;
1286 }
1287 DECODE_CLEAR_SEGOVR();
1288 END_OF_INSTR();
1289 }
1290
1291 /****************************************************************************
1292 REMARKS:
1293 Handles opcode 0x14
1294 ****************************************************************************/
x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1295 void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1296 {
1297 u8 srcval;
1298
1299 START_OF_INSTR();
1300 DECODE_PRINTF("ADC\tAL,");
1301 srcval = fetch_byte_imm();
1302 DECODE_PRINTF2("%x\n", srcval);
1303 TRACE_AND_STEP();
1304 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1305 DECODE_CLEAR_SEGOVR();
1306 END_OF_INSTR();
1307 }
1308
1309 /****************************************************************************
1310 REMARKS:
1311 Handles opcode 0x15
1312 ****************************************************************************/
x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED (op1))1313 void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1314 {
1315 u32 srcval;
1316
1317 START_OF_INSTR();
1318 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1319 DECODE_PRINTF("ADC\tEAX,");
1320 srcval = fetch_long_imm();
1321 } else {
1322 DECODE_PRINTF("ADC\tAX,");
1323 srcval = fetch_word_imm();
1324 }
1325 DECODE_PRINTF2("%x\n", srcval);
1326 TRACE_AND_STEP();
1327 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1328 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1329 } else {
1330 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1331 }
1332 DECODE_CLEAR_SEGOVR();
1333 END_OF_INSTR();
1334 }
1335
1336 /****************************************************************************
1337 REMARKS:
1338 Handles opcode 0x16
1339 ****************************************************************************/
x86emuOp_push_SS(u8 X86EMU_UNUSED (op1))1340 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1341 {
1342 START_OF_INSTR();
1343 DECODE_PRINTF("PUSH\tSS\n");
1344 TRACE_AND_STEP();
1345 push_word(M.x86.R_SS);
1346 DECODE_CLEAR_SEGOVR();
1347 END_OF_INSTR();
1348 }
1349
1350 /****************************************************************************
1351 REMARKS:
1352 Handles opcode 0x17
1353 ****************************************************************************/
x86emuOp_pop_SS(u8 X86EMU_UNUSED (op1))1354 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1355 {
1356 START_OF_INSTR();
1357 DECODE_PRINTF("POP\tSS\n");
1358 TRACE_AND_STEP();
1359 M.x86.R_SS = pop_word();
1360 DECODE_CLEAR_SEGOVR();
1361 END_OF_INSTR();
1362 }
1363
1364 /****************************************************************************
1365 REMARKS:
1366 Handles opcode 0x18
1367 ****************************************************************************/
x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED (op1))1368 void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1369 {
1370 int mod, rl, rh;
1371 u8 *destreg, *srcreg;
1372 uint destoffset;
1373 u8 destval;
1374
1375 START_OF_INSTR();
1376 DECODE_PRINTF("SBB\t");
1377 FETCH_DECODE_MODRM(mod, rh, rl);
1378 switch (mod) {
1379 case 0:
1380 destoffset = decode_rm00_address(rl);
1381 DECODE_PRINTF(",");
1382 destval = fetch_data_byte(destoffset);
1383 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1384 DECODE_PRINTF("\n");
1385 TRACE_AND_STEP();
1386 destval = sbb_byte(destval, *srcreg);
1387 store_data_byte(destoffset, destval);
1388 break;
1389 case 1:
1390 destoffset = decode_rm01_address(rl);
1391 DECODE_PRINTF(",");
1392 destval = fetch_data_byte(destoffset);
1393 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1394 DECODE_PRINTF("\n");
1395 TRACE_AND_STEP();
1396 destval = sbb_byte(destval, *srcreg);
1397 store_data_byte(destoffset, destval);
1398 break;
1399 case 2:
1400 destoffset = decode_rm10_address(rl);
1401 DECODE_PRINTF(",");
1402 destval = fetch_data_byte(destoffset);
1403 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1404 DECODE_PRINTF("\n");
1405 TRACE_AND_STEP();
1406 destval = sbb_byte(destval, *srcreg);
1407 store_data_byte(destoffset, destval);
1408 break;
1409 case 3: /* register to register */
1410 destreg = DECODE_RM_BYTE_REGISTER(rl);
1411 DECODE_PRINTF(",");
1412 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1413 DECODE_PRINTF("\n");
1414 TRACE_AND_STEP();
1415 *destreg = sbb_byte(*destreg, *srcreg);
1416 break;
1417 }
1418 DECODE_CLEAR_SEGOVR();
1419 END_OF_INSTR();
1420 }
1421
1422 /****************************************************************************
1423 REMARKS:
1424 Handles opcode 0x19
1425 ****************************************************************************/
x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED (op1))1426 void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1427 {
1428 int mod, rl, rh;
1429 uint destoffset;
1430
1431 START_OF_INSTR();
1432 DECODE_PRINTF("SBB\t");
1433 FETCH_DECODE_MODRM(mod, rh, rl);
1434 switch (mod) {
1435 case 0:
1436 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1437 u32 destval;
1438 u32 *srcreg;
1439
1440 destoffset = decode_rm00_address(rl);
1441 DECODE_PRINTF(",");
1442 destval = fetch_data_long(destoffset);
1443 srcreg = DECODE_RM_LONG_REGISTER(rh);
1444 DECODE_PRINTF("\n");
1445 TRACE_AND_STEP();
1446 destval = sbb_long(destval, *srcreg);
1447 store_data_long(destoffset, destval);
1448 } else {
1449 u16 destval;
1450 u16 *srcreg;
1451
1452 destoffset = decode_rm00_address(rl);
1453 DECODE_PRINTF(",");
1454 destval = fetch_data_word(destoffset);
1455 srcreg = DECODE_RM_WORD_REGISTER(rh);
1456 DECODE_PRINTF("\n");
1457 TRACE_AND_STEP();
1458 destval = sbb_word(destval, *srcreg);
1459 store_data_word(destoffset, destval);
1460 }
1461 break;
1462 case 1:
1463 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1464 u32 destval;
1465 u32 *srcreg;
1466
1467 destoffset = decode_rm01_address(rl);
1468 DECODE_PRINTF(",");
1469 destval = fetch_data_long(destoffset);
1470 srcreg = DECODE_RM_LONG_REGISTER(rh);
1471 DECODE_PRINTF("\n");
1472 TRACE_AND_STEP();
1473 destval = sbb_long(destval, *srcreg);
1474 store_data_long(destoffset, destval);
1475 } else {
1476 u16 destval;
1477 u16 *srcreg;
1478
1479 destoffset = decode_rm01_address(rl);
1480 DECODE_PRINTF(",");
1481 destval = fetch_data_word(destoffset);
1482 srcreg = DECODE_RM_WORD_REGISTER(rh);
1483 DECODE_PRINTF("\n");
1484 TRACE_AND_STEP();
1485 destval = sbb_word(destval, *srcreg);
1486 store_data_word(destoffset, destval);
1487 }
1488 break;
1489 case 2:
1490 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1491 u32 destval;
1492 u32 *srcreg;
1493
1494 destoffset = decode_rm10_address(rl);
1495 DECODE_PRINTF(",");
1496 destval = fetch_data_long(destoffset);
1497 srcreg = DECODE_RM_LONG_REGISTER(rh);
1498 DECODE_PRINTF("\n");
1499 TRACE_AND_STEP();
1500 destval = sbb_long(destval, *srcreg);
1501 store_data_long(destoffset, destval);
1502 } else {
1503 u16 destval;
1504 u16 *srcreg;
1505
1506 destoffset = decode_rm10_address(rl);
1507 DECODE_PRINTF(",");
1508 destval = fetch_data_word(destoffset);
1509 srcreg = DECODE_RM_WORD_REGISTER(rh);
1510 DECODE_PRINTF("\n");
1511 TRACE_AND_STEP();
1512 destval = sbb_word(destval, *srcreg);
1513 store_data_word(destoffset, destval);
1514 }
1515 break;
1516 case 3: /* register to register */
1517 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1518 u32 *destreg,*srcreg;
1519
1520 destreg = DECODE_RM_LONG_REGISTER(rl);
1521 DECODE_PRINTF(",");
1522 srcreg = DECODE_RM_LONG_REGISTER(rh);
1523 DECODE_PRINTF("\n");
1524 TRACE_AND_STEP();
1525 *destreg = sbb_long(*destreg, *srcreg);
1526 } else {
1527 u16 *destreg,*srcreg;
1528
1529 destreg = DECODE_RM_WORD_REGISTER(rl);
1530 DECODE_PRINTF(",");
1531 srcreg = DECODE_RM_WORD_REGISTER(rh);
1532 DECODE_PRINTF("\n");
1533 TRACE_AND_STEP();
1534 *destreg = sbb_word(*destreg, *srcreg);
1535 }
1536 break;
1537 }
1538 DECODE_CLEAR_SEGOVR();
1539 END_OF_INSTR();
1540 }
1541
1542 /****************************************************************************
1543 REMARKS:
1544 Handles opcode 0x1a
1545 ****************************************************************************/
x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED (op1))1546 void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1547 {
1548 int mod, rl, rh;
1549 u8 *destreg, *srcreg;
1550 uint srcoffset;
1551 u8 srcval;
1552
1553 START_OF_INSTR();
1554 DECODE_PRINTF("SBB\t");
1555 FETCH_DECODE_MODRM(mod, rh, rl);
1556 switch (mod) {
1557 case 0:
1558 destreg = DECODE_RM_BYTE_REGISTER(rh);
1559 DECODE_PRINTF(",");
1560 srcoffset = decode_rm00_address(rl);
1561 srcval = fetch_data_byte(srcoffset);
1562 DECODE_PRINTF("\n");
1563 TRACE_AND_STEP();
1564 *destreg = sbb_byte(*destreg, srcval);
1565 break;
1566 case 1:
1567 destreg = DECODE_RM_BYTE_REGISTER(rh);
1568 DECODE_PRINTF(",");
1569 srcoffset = decode_rm01_address(rl);
1570 srcval = fetch_data_byte(srcoffset);
1571 DECODE_PRINTF("\n");
1572 TRACE_AND_STEP();
1573 *destreg = sbb_byte(*destreg, srcval);
1574 break;
1575 case 2:
1576 destreg = DECODE_RM_BYTE_REGISTER(rh);
1577 DECODE_PRINTF(",");
1578 srcoffset = decode_rm10_address(rl);
1579 srcval = fetch_data_byte(srcoffset);
1580 DECODE_PRINTF("\n");
1581 TRACE_AND_STEP();
1582 *destreg = sbb_byte(*destreg, srcval);
1583 break;
1584 case 3: /* register to register */
1585 destreg = DECODE_RM_BYTE_REGISTER(rh);
1586 DECODE_PRINTF(",");
1587 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1588 DECODE_PRINTF("\n");
1589 TRACE_AND_STEP();
1590 *destreg = sbb_byte(*destreg, *srcreg);
1591 break;
1592 }
1593 DECODE_CLEAR_SEGOVR();
1594 END_OF_INSTR();
1595 }
1596
1597 /****************************************************************************
1598 REMARKS:
1599 Handles opcode 0x1b
1600 ****************************************************************************/
x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED (op1))1601 void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1602 {
1603 int mod, rl, rh;
1604 uint srcoffset;
1605
1606 START_OF_INSTR();
1607 DECODE_PRINTF("SBB\t");
1608 FETCH_DECODE_MODRM(mod, rh, rl);
1609 switch (mod) {
1610 case 0:
1611 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1612 u32 *destreg;
1613 u32 srcval;
1614
1615 destreg = DECODE_RM_LONG_REGISTER(rh);
1616 DECODE_PRINTF(",");
1617 srcoffset = decode_rm00_address(rl);
1618 srcval = fetch_data_long(srcoffset);
1619 DECODE_PRINTF("\n");
1620 TRACE_AND_STEP();
1621 *destreg = sbb_long(*destreg, srcval);
1622 } else {
1623 u16 *destreg;
1624 u16 srcval;
1625
1626 destreg = DECODE_RM_WORD_REGISTER(rh);
1627 DECODE_PRINTF(",");
1628 srcoffset = decode_rm00_address(rl);
1629 srcval = fetch_data_word(srcoffset);
1630 DECODE_PRINTF("\n");
1631 TRACE_AND_STEP();
1632 *destreg = sbb_word(*destreg, srcval);
1633 }
1634 break;
1635 case 1:
1636 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1637 u32 *destreg;
1638 u32 srcval;
1639
1640 destreg = DECODE_RM_LONG_REGISTER(rh);
1641 DECODE_PRINTF(",");
1642 srcoffset = decode_rm01_address(rl);
1643 srcval = fetch_data_long(srcoffset);
1644 DECODE_PRINTF("\n");
1645 TRACE_AND_STEP();
1646 *destreg = sbb_long(*destreg, srcval);
1647 } else {
1648 u16 *destreg;
1649 u16 srcval;
1650
1651 destreg = DECODE_RM_WORD_REGISTER(rh);
1652 DECODE_PRINTF(",");
1653 srcoffset = decode_rm01_address(rl);
1654 srcval = fetch_data_word(srcoffset);
1655 DECODE_PRINTF("\n");
1656 TRACE_AND_STEP();
1657 *destreg = sbb_word(*destreg, srcval);
1658 }
1659 break;
1660 case 2:
1661 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1662 u32 *destreg;
1663 u32 srcval;
1664
1665 destreg = DECODE_RM_LONG_REGISTER(rh);
1666 DECODE_PRINTF(",");
1667 srcoffset = decode_rm10_address(rl);
1668 srcval = fetch_data_long(srcoffset);
1669 DECODE_PRINTF("\n");
1670 TRACE_AND_STEP();
1671 *destreg = sbb_long(*destreg, srcval);
1672 } else {
1673 u16 *destreg;
1674 u16 srcval;
1675
1676 destreg = DECODE_RM_WORD_REGISTER(rh);
1677 DECODE_PRINTF(",");
1678 srcoffset = decode_rm10_address(rl);
1679 srcval = fetch_data_word(srcoffset);
1680 DECODE_PRINTF("\n");
1681 TRACE_AND_STEP();
1682 *destreg = sbb_word(*destreg, srcval);
1683 }
1684 break;
1685 case 3: /* register to register */
1686 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1687 u32 *destreg,*srcreg;
1688
1689 destreg = DECODE_RM_LONG_REGISTER(rh);
1690 DECODE_PRINTF(",");
1691 srcreg = DECODE_RM_LONG_REGISTER(rl);
1692 DECODE_PRINTF("\n");
1693 TRACE_AND_STEP();
1694 *destreg = sbb_long(*destreg, *srcreg);
1695 } else {
1696 u16 *destreg,*srcreg;
1697
1698 destreg = DECODE_RM_WORD_REGISTER(rh);
1699 DECODE_PRINTF(",");
1700 srcreg = DECODE_RM_WORD_REGISTER(rl);
1701 DECODE_PRINTF("\n");
1702 TRACE_AND_STEP();
1703 *destreg = sbb_word(*destreg, *srcreg);
1704 }
1705 break;
1706 }
1707 DECODE_CLEAR_SEGOVR();
1708 END_OF_INSTR();
1709 }
1710
1711 /****************************************************************************
1712 REMARKS:
1713 Handles opcode 0x1c
1714 ****************************************************************************/
x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1715 void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1716 {
1717 u8 srcval;
1718
1719 START_OF_INSTR();
1720 DECODE_PRINTF("SBB\tAL,");
1721 srcval = fetch_byte_imm();
1722 DECODE_PRINTF2("%x\n", srcval);
1723 TRACE_AND_STEP();
1724 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1725 DECODE_CLEAR_SEGOVR();
1726 END_OF_INSTR();
1727 }
1728
1729 /****************************************************************************
1730 REMARKS:
1731 Handles opcode 0x1d
1732 ****************************************************************************/
x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED (op1))1733 void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1734 {
1735 u32 srcval;
1736
1737 START_OF_INSTR();
1738 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1739 DECODE_PRINTF("SBB\tEAX,");
1740 srcval = fetch_long_imm();
1741 } else {
1742 DECODE_PRINTF("SBB\tAX,");
1743 srcval = fetch_word_imm();
1744 }
1745 DECODE_PRINTF2("%x\n", srcval);
1746 TRACE_AND_STEP();
1747 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1748 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1749 } else {
1750 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1751 }
1752 DECODE_CLEAR_SEGOVR();
1753 END_OF_INSTR();
1754 }
1755
1756 /****************************************************************************
1757 REMARKS:
1758 Handles opcode 0x1e
1759 ****************************************************************************/
x86emuOp_push_DS(u8 X86EMU_UNUSED (op1))1760 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1761 {
1762 START_OF_INSTR();
1763 DECODE_PRINTF("PUSH\tDS\n");
1764 TRACE_AND_STEP();
1765 push_word(M.x86.R_DS);
1766 DECODE_CLEAR_SEGOVR();
1767 END_OF_INSTR();
1768 }
1769
1770 /****************************************************************************
1771 REMARKS:
1772 Handles opcode 0x1f
1773 ****************************************************************************/
x86emuOp_pop_DS(u8 X86EMU_UNUSED (op1))1774 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1775 {
1776 START_OF_INSTR();
1777 DECODE_PRINTF("POP\tDS\n");
1778 TRACE_AND_STEP();
1779 M.x86.R_DS = pop_word();
1780 DECODE_CLEAR_SEGOVR();
1781 END_OF_INSTR();
1782 }
1783
1784 /****************************************************************************
1785 REMARKS:
1786 Handles opcode 0x20
1787 ****************************************************************************/
x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED (op1))1788 void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1789 {
1790 int mod, rl, rh;
1791 u8 *destreg, *srcreg;
1792 uint destoffset;
1793 u8 destval;
1794
1795 START_OF_INSTR();
1796 DECODE_PRINTF("AND\t");
1797 FETCH_DECODE_MODRM(mod, rh, rl);
1798
1799 switch (mod) {
1800 case 0:
1801 destoffset = decode_rm00_address(rl);
1802 DECODE_PRINTF(",");
1803 destval = fetch_data_byte(destoffset);
1804 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1805 DECODE_PRINTF("\n");
1806 TRACE_AND_STEP();
1807 destval = and_byte(destval, *srcreg);
1808 store_data_byte(destoffset, destval);
1809 break;
1810
1811 case 1:
1812 destoffset = decode_rm01_address(rl);
1813 DECODE_PRINTF(",");
1814 destval = fetch_data_byte(destoffset);
1815 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1816 DECODE_PRINTF("\n");
1817 TRACE_AND_STEP();
1818 destval = and_byte(destval, *srcreg);
1819 store_data_byte(destoffset, destval);
1820 break;
1821
1822 case 2:
1823 destoffset = decode_rm10_address(rl);
1824 DECODE_PRINTF(",");
1825 destval = fetch_data_byte(destoffset);
1826 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1827 DECODE_PRINTF("\n");
1828 TRACE_AND_STEP();
1829 destval = and_byte(destval, *srcreg);
1830 store_data_byte(destoffset, destval);
1831 break;
1832
1833 case 3: /* register to register */
1834 destreg = DECODE_RM_BYTE_REGISTER(rl);
1835 DECODE_PRINTF(",");
1836 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1837 DECODE_PRINTF("\n");
1838 TRACE_AND_STEP();
1839 *destreg = and_byte(*destreg, *srcreg);
1840 break;
1841 }
1842 DECODE_CLEAR_SEGOVR();
1843 END_OF_INSTR();
1844 }
1845
1846 /****************************************************************************
1847 REMARKS:
1848 Handles opcode 0x21
1849 ****************************************************************************/
x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED (op1))1850 void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1851 {
1852 int mod, rl, rh;
1853 uint destoffset;
1854
1855 START_OF_INSTR();
1856 DECODE_PRINTF("AND\t");
1857 FETCH_DECODE_MODRM(mod, rh, rl);
1858 switch (mod) {
1859 case 0:
1860 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1861 u32 destval;
1862 u32 *srcreg;
1863
1864 destoffset = decode_rm00_address(rl);
1865 DECODE_PRINTF(",");
1866 destval = fetch_data_long(destoffset);
1867 srcreg = DECODE_RM_LONG_REGISTER(rh);
1868 DECODE_PRINTF("\n");
1869 TRACE_AND_STEP();
1870 destval = and_long(destval, *srcreg);
1871 store_data_long(destoffset, destval);
1872 } else {
1873 u16 destval;
1874 u16 *srcreg;
1875
1876 destoffset = decode_rm00_address(rl);
1877 DECODE_PRINTF(",");
1878 destval = fetch_data_word(destoffset);
1879 srcreg = DECODE_RM_WORD_REGISTER(rh);
1880 DECODE_PRINTF("\n");
1881 TRACE_AND_STEP();
1882 destval = and_word(destval, *srcreg);
1883 store_data_word(destoffset, destval);
1884 }
1885 break;
1886 case 1:
1887 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1888 u32 destval;
1889 u32 *srcreg;
1890
1891 destoffset = decode_rm01_address(rl);
1892 DECODE_PRINTF(",");
1893 destval = fetch_data_long(destoffset);
1894 srcreg = DECODE_RM_LONG_REGISTER(rh);
1895 DECODE_PRINTF("\n");
1896 TRACE_AND_STEP();
1897 destval = and_long(destval, *srcreg);
1898 store_data_long(destoffset, destval);
1899 } else {
1900 u16 destval;
1901 u16 *srcreg;
1902
1903 destoffset = decode_rm01_address(rl);
1904 DECODE_PRINTF(",");
1905 destval = fetch_data_word(destoffset);
1906 srcreg = DECODE_RM_WORD_REGISTER(rh);
1907 DECODE_PRINTF("\n");
1908 TRACE_AND_STEP();
1909 destval = and_word(destval, *srcreg);
1910 store_data_word(destoffset, destval);
1911 }
1912 break;
1913 case 2:
1914 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1915 u32 destval;
1916 u32 *srcreg;
1917
1918 destoffset = decode_rm10_address(rl);
1919 DECODE_PRINTF(",");
1920 destval = fetch_data_long(destoffset);
1921 srcreg = DECODE_RM_LONG_REGISTER(rh);
1922 DECODE_PRINTF("\n");
1923 TRACE_AND_STEP();
1924 destval = and_long(destval, *srcreg);
1925 store_data_long(destoffset, destval);
1926 } else {
1927 u16 destval;
1928 u16 *srcreg;
1929
1930 destoffset = decode_rm10_address(rl);
1931 DECODE_PRINTF(",");
1932 destval = fetch_data_word(destoffset);
1933 srcreg = DECODE_RM_WORD_REGISTER(rh);
1934 DECODE_PRINTF("\n");
1935 TRACE_AND_STEP();
1936 destval = and_word(destval, *srcreg);
1937 store_data_word(destoffset, destval);
1938 }
1939 break;
1940 case 3: /* register to register */
1941 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1942 u32 *destreg,*srcreg;
1943
1944 destreg = DECODE_RM_LONG_REGISTER(rl);
1945 DECODE_PRINTF(",");
1946 srcreg = DECODE_RM_LONG_REGISTER(rh);
1947 DECODE_PRINTF("\n");
1948 TRACE_AND_STEP();
1949 *destreg = and_long(*destreg, *srcreg);
1950 } else {
1951 u16 *destreg,*srcreg;
1952
1953 destreg = DECODE_RM_WORD_REGISTER(rl);
1954 DECODE_PRINTF(",");
1955 srcreg = DECODE_RM_WORD_REGISTER(rh);
1956 DECODE_PRINTF("\n");
1957 TRACE_AND_STEP();
1958 *destreg = and_word(*destreg, *srcreg);
1959 }
1960 break;
1961 }
1962 DECODE_CLEAR_SEGOVR();
1963 END_OF_INSTR();
1964 }
1965
1966 /****************************************************************************
1967 REMARKS:
1968 Handles opcode 0x22
1969 ****************************************************************************/
x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED (op1))1970 void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1971 {
1972 int mod, rl, rh;
1973 u8 *destreg, *srcreg;
1974 uint srcoffset;
1975 u8 srcval;
1976
1977 START_OF_INSTR();
1978 DECODE_PRINTF("AND\t");
1979 FETCH_DECODE_MODRM(mod, rh, rl);
1980 switch (mod) {
1981 case 0:
1982 destreg = DECODE_RM_BYTE_REGISTER(rh);
1983 DECODE_PRINTF(",");
1984 srcoffset = decode_rm00_address(rl);
1985 srcval = fetch_data_byte(srcoffset);
1986 DECODE_PRINTF("\n");
1987 TRACE_AND_STEP();
1988 *destreg = and_byte(*destreg, srcval);
1989 break;
1990 case 1:
1991 destreg = DECODE_RM_BYTE_REGISTER(rh);
1992 DECODE_PRINTF(",");
1993 srcoffset = decode_rm01_address(rl);
1994 srcval = fetch_data_byte(srcoffset);
1995 DECODE_PRINTF("\n");
1996 TRACE_AND_STEP();
1997 *destreg = and_byte(*destreg, srcval);
1998 break;
1999 case 2:
2000 destreg = DECODE_RM_BYTE_REGISTER(rh);
2001 DECODE_PRINTF(",");
2002 srcoffset = decode_rm10_address(rl);
2003 srcval = fetch_data_byte(srcoffset);
2004 DECODE_PRINTF("\n");
2005 TRACE_AND_STEP();
2006 *destreg = and_byte(*destreg, srcval);
2007 break;
2008 case 3: /* register to register */
2009 destreg = DECODE_RM_BYTE_REGISTER(rh);
2010 DECODE_PRINTF(",");
2011 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2012 DECODE_PRINTF("\n");
2013 TRACE_AND_STEP();
2014 *destreg = and_byte(*destreg, *srcreg);
2015 break;
2016 }
2017 DECODE_CLEAR_SEGOVR();
2018 END_OF_INSTR();
2019 }
2020
2021 /****************************************************************************
2022 REMARKS:
2023 Handles opcode 0x23
2024 ****************************************************************************/
x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED (op1))2025 void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2026 {
2027 int mod, rl, rh;
2028 uint srcoffset;
2029
2030 START_OF_INSTR();
2031 DECODE_PRINTF("AND\t");
2032 FETCH_DECODE_MODRM(mod, rh, rl);
2033 switch (mod) {
2034 case 0:
2035 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2036 u32 *destreg;
2037 u32 srcval;
2038
2039 destreg = DECODE_RM_LONG_REGISTER(rh);
2040 DECODE_PRINTF(",");
2041 srcoffset = decode_rm00_address(rl);
2042 srcval = fetch_data_long(srcoffset);
2043 DECODE_PRINTF("\n");
2044 TRACE_AND_STEP();
2045 *destreg = and_long(*destreg, srcval);
2046 } else {
2047 u16 *destreg;
2048 u16 srcval;
2049
2050 destreg = DECODE_RM_WORD_REGISTER(rh);
2051 DECODE_PRINTF(",");
2052 srcoffset = decode_rm00_address(rl);
2053 srcval = fetch_data_word(srcoffset);
2054 DECODE_PRINTF("\n");
2055 TRACE_AND_STEP();
2056 *destreg = and_word(*destreg, srcval);
2057 }
2058 break;
2059 case 1:
2060 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2061 u32 *destreg;
2062 u32 srcval;
2063
2064 destreg = DECODE_RM_LONG_REGISTER(rh);
2065 DECODE_PRINTF(",");
2066 srcoffset = decode_rm01_address(rl);
2067 srcval = fetch_data_long(srcoffset);
2068 DECODE_PRINTF("\n");
2069 TRACE_AND_STEP();
2070 *destreg = and_long(*destreg, srcval);
2071 break;
2072 } else {
2073 u16 *destreg;
2074 u16 srcval;
2075
2076 destreg = DECODE_RM_WORD_REGISTER(rh);
2077 DECODE_PRINTF(",");
2078 srcoffset = decode_rm01_address(rl);
2079 srcval = fetch_data_word(srcoffset);
2080 DECODE_PRINTF("\n");
2081 TRACE_AND_STEP();
2082 *destreg = and_word(*destreg, srcval);
2083 break;
2084 }
2085 case 2:
2086 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2087 u32 *destreg;
2088 u32 srcval;
2089
2090 destreg = DECODE_RM_LONG_REGISTER(rh);
2091 DECODE_PRINTF(",");
2092 srcoffset = decode_rm10_address(rl);
2093 srcval = fetch_data_long(srcoffset);
2094 DECODE_PRINTF("\n");
2095 TRACE_AND_STEP();
2096 *destreg = and_long(*destreg, srcval);
2097 } else {
2098 u16 *destreg;
2099 u16 srcval;
2100
2101 destreg = DECODE_RM_WORD_REGISTER(rh);
2102 DECODE_PRINTF(",");
2103 srcoffset = decode_rm10_address(rl);
2104 srcval = fetch_data_word(srcoffset);
2105 DECODE_PRINTF("\n");
2106 TRACE_AND_STEP();
2107 *destreg = and_word(*destreg, srcval);
2108 }
2109 break;
2110 case 3: /* register to register */
2111 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2112 u32 *destreg,*srcreg;
2113
2114 destreg = DECODE_RM_LONG_REGISTER(rh);
2115 DECODE_PRINTF(",");
2116 srcreg = DECODE_RM_LONG_REGISTER(rl);
2117 DECODE_PRINTF("\n");
2118 TRACE_AND_STEP();
2119 *destreg = and_long(*destreg, *srcreg);
2120 } else {
2121 u16 *destreg,*srcreg;
2122
2123 destreg = DECODE_RM_WORD_REGISTER(rh);
2124 DECODE_PRINTF(",");
2125 srcreg = DECODE_RM_WORD_REGISTER(rl);
2126 DECODE_PRINTF("\n");
2127 TRACE_AND_STEP();
2128 *destreg = and_word(*destreg, *srcreg);
2129 }
2130 break;
2131 }
2132 DECODE_CLEAR_SEGOVR();
2133 END_OF_INSTR();
2134 }
2135
2136 /****************************************************************************
2137 REMARKS:
2138 Handles opcode 0x24
2139 ****************************************************************************/
x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2140 void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2141 {
2142 u8 srcval;
2143
2144 START_OF_INSTR();
2145 DECODE_PRINTF("AND\tAL,");
2146 srcval = fetch_byte_imm();
2147 DECODE_PRINTF2("%x\n", srcval);
2148 TRACE_AND_STEP();
2149 M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2150 DECODE_CLEAR_SEGOVR();
2151 END_OF_INSTR();
2152 }
2153
2154 /****************************************************************************
2155 REMARKS:
2156 Handles opcode 0x25
2157 ****************************************************************************/
x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED (op1))2158 void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2159 {
2160 u32 srcval;
2161
2162 START_OF_INSTR();
2163 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2164 DECODE_PRINTF("AND\tEAX,");
2165 srcval = fetch_long_imm();
2166 } else {
2167 DECODE_PRINTF("AND\tAX,");
2168 srcval = fetch_word_imm();
2169 }
2170 DECODE_PRINTF2("%x\n", srcval);
2171 TRACE_AND_STEP();
2172 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2173 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2174 } else {
2175 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2176 }
2177 DECODE_CLEAR_SEGOVR();
2178 END_OF_INSTR();
2179 }
2180
2181 /****************************************************************************
2182 REMARKS:
2183 Handles opcode 0x26
2184 ****************************************************************************/
x86emuOp_segovr_ES(u8 X86EMU_UNUSED (op1))2185 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2186 {
2187 START_OF_INSTR();
2188 DECODE_PRINTF("ES:\n");
2189 TRACE_AND_STEP();
2190 M.x86.mode |= SYSMODE_SEGOVR_ES;
2191 /*
2192 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2193 * opcode subroutines we do not want to do this.
2194 */
2195 END_OF_INSTR();
2196 }
2197
2198 /****************************************************************************
2199 REMARKS:
2200 Handles opcode 0x27
2201 ****************************************************************************/
x86emuOp_daa(u8 X86EMU_UNUSED (op1))2202 void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2203 {
2204 START_OF_INSTR();
2205 DECODE_PRINTF("DAA\n");
2206 TRACE_AND_STEP();
2207 M.x86.R_AL = daa_byte(M.x86.R_AL);
2208 DECODE_CLEAR_SEGOVR();
2209 END_OF_INSTR();
2210 }
2211
2212 /****************************************************************************
2213 REMARKS:
2214 Handles opcode 0x28
2215 ****************************************************************************/
x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED (op1))2216 void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2217 {
2218 int mod, rl, rh;
2219 u8 *destreg, *srcreg;
2220 uint destoffset;
2221 u8 destval;
2222
2223 START_OF_INSTR();
2224 DECODE_PRINTF("SUB\t");
2225 FETCH_DECODE_MODRM(mod, rh, rl);
2226 switch (mod) {
2227 case 0:
2228 destoffset = decode_rm00_address(rl);
2229 DECODE_PRINTF(",");
2230 destval = fetch_data_byte(destoffset);
2231 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2232 DECODE_PRINTF("\n");
2233 TRACE_AND_STEP();
2234 destval = sub_byte(destval, *srcreg);
2235 store_data_byte(destoffset, destval);
2236 break;
2237 case 1:
2238 destoffset = decode_rm01_address(rl);
2239 DECODE_PRINTF(",");
2240 destval = fetch_data_byte(destoffset);
2241 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2242 DECODE_PRINTF("\n");
2243 TRACE_AND_STEP();
2244 destval = sub_byte(destval, *srcreg);
2245 store_data_byte(destoffset, destval);
2246 break;
2247 case 2:
2248 destoffset = decode_rm10_address(rl);
2249 DECODE_PRINTF(",");
2250 destval = fetch_data_byte(destoffset);
2251 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2252 DECODE_PRINTF("\n");
2253 TRACE_AND_STEP();
2254 destval = sub_byte(destval, *srcreg);
2255 store_data_byte(destoffset, destval);
2256 break;
2257 case 3: /* register to register */
2258 destreg = DECODE_RM_BYTE_REGISTER(rl);
2259 DECODE_PRINTF(",");
2260 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2261 DECODE_PRINTF("\n");
2262 TRACE_AND_STEP();
2263 *destreg = sub_byte(*destreg, *srcreg);
2264 break;
2265 }
2266 DECODE_CLEAR_SEGOVR();
2267 END_OF_INSTR();
2268 }
2269
2270 /****************************************************************************
2271 REMARKS:
2272 Handles opcode 0x29
2273 ****************************************************************************/
x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED (op1))2274 void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2275 {
2276 int mod, rl, rh;
2277 uint destoffset;
2278
2279 START_OF_INSTR();
2280 DECODE_PRINTF("SUB\t");
2281 FETCH_DECODE_MODRM(mod, rh, rl);
2282 switch (mod) {
2283 case 0:
2284 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2285 u32 destval;
2286 u32 *srcreg;
2287
2288 destoffset = decode_rm00_address(rl);
2289 DECODE_PRINTF(",");
2290 destval = fetch_data_long(destoffset);
2291 srcreg = DECODE_RM_LONG_REGISTER(rh);
2292 DECODE_PRINTF("\n");
2293 TRACE_AND_STEP();
2294 destval = sub_long(destval, *srcreg);
2295 store_data_long(destoffset, destval);
2296 } else {
2297 u16 destval;
2298 u16 *srcreg;
2299
2300 destoffset = decode_rm00_address(rl);
2301 DECODE_PRINTF(",");
2302 destval = fetch_data_word(destoffset);
2303 srcreg = DECODE_RM_WORD_REGISTER(rh);
2304 DECODE_PRINTF("\n");
2305 TRACE_AND_STEP();
2306 destval = sub_word(destval, *srcreg);
2307 store_data_word(destoffset, destval);
2308 }
2309 break;
2310 case 1:
2311 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2312 u32 destval;
2313 u32 *srcreg;
2314
2315 destoffset = decode_rm01_address(rl);
2316 DECODE_PRINTF(",");
2317 destval = fetch_data_long(destoffset);
2318 srcreg = DECODE_RM_LONG_REGISTER(rh);
2319 DECODE_PRINTF("\n");
2320 TRACE_AND_STEP();
2321 destval = sub_long(destval, *srcreg);
2322 store_data_long(destoffset, destval);
2323 } else {
2324 u16 destval;
2325 u16 *srcreg;
2326
2327 destoffset = decode_rm01_address(rl);
2328 DECODE_PRINTF(",");
2329 destval = fetch_data_word(destoffset);
2330 srcreg = DECODE_RM_WORD_REGISTER(rh);
2331 DECODE_PRINTF("\n");
2332 TRACE_AND_STEP();
2333 destval = sub_word(destval, *srcreg);
2334 store_data_word(destoffset, destval);
2335 }
2336 break;
2337 case 2:
2338 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2339 u32 destval;
2340 u32 *srcreg;
2341
2342 destoffset = decode_rm10_address(rl);
2343 DECODE_PRINTF(",");
2344 destval = fetch_data_long(destoffset);
2345 srcreg = DECODE_RM_LONG_REGISTER(rh);
2346 DECODE_PRINTF("\n");
2347 TRACE_AND_STEP();
2348 destval = sub_long(destval, *srcreg);
2349 store_data_long(destoffset, destval);
2350 } else {
2351 u16 destval;
2352 u16 *srcreg;
2353
2354 destoffset = decode_rm10_address(rl);
2355 DECODE_PRINTF(",");
2356 destval = fetch_data_word(destoffset);
2357 srcreg = DECODE_RM_WORD_REGISTER(rh);
2358 DECODE_PRINTF("\n");
2359 TRACE_AND_STEP();
2360 destval = sub_word(destval, *srcreg);
2361 store_data_word(destoffset, destval);
2362 }
2363 break;
2364 case 3: /* register to register */
2365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2366 u32 *destreg,*srcreg;
2367
2368 destreg = DECODE_RM_LONG_REGISTER(rl);
2369 DECODE_PRINTF(",");
2370 srcreg = DECODE_RM_LONG_REGISTER(rh);
2371 DECODE_PRINTF("\n");
2372 TRACE_AND_STEP();
2373 *destreg = sub_long(*destreg, *srcreg);
2374 } else {
2375 u16 *destreg,*srcreg;
2376
2377 destreg = DECODE_RM_WORD_REGISTER(rl);
2378 DECODE_PRINTF(",");
2379 srcreg = DECODE_RM_WORD_REGISTER(rh);
2380 DECODE_PRINTF("\n");
2381 TRACE_AND_STEP();
2382 *destreg = sub_word(*destreg, *srcreg);
2383 }
2384 break;
2385 }
2386 DECODE_CLEAR_SEGOVR();
2387 END_OF_INSTR();
2388 }
2389
2390 /****************************************************************************
2391 REMARKS:
2392 Handles opcode 0x2a
2393 ****************************************************************************/
x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED (op1))2394 void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2395 {
2396 int mod, rl, rh;
2397 u8 *destreg, *srcreg;
2398 uint srcoffset;
2399 u8 srcval;
2400
2401 START_OF_INSTR();
2402 DECODE_PRINTF("SUB\t");
2403 FETCH_DECODE_MODRM(mod, rh, rl);
2404 switch (mod) {
2405 case 0:
2406 destreg = DECODE_RM_BYTE_REGISTER(rh);
2407 DECODE_PRINTF(",");
2408 srcoffset = decode_rm00_address(rl);
2409 srcval = fetch_data_byte(srcoffset);
2410 DECODE_PRINTF("\n");
2411 TRACE_AND_STEP();
2412 *destreg = sub_byte(*destreg, srcval);
2413 break;
2414 case 1:
2415 destreg = DECODE_RM_BYTE_REGISTER(rh);
2416 DECODE_PRINTF(",");
2417 srcoffset = decode_rm01_address(rl);
2418 srcval = fetch_data_byte(srcoffset);
2419 DECODE_PRINTF("\n");
2420 TRACE_AND_STEP();
2421 *destreg = sub_byte(*destreg, srcval);
2422 break;
2423 case 2:
2424 destreg = DECODE_RM_BYTE_REGISTER(rh);
2425 DECODE_PRINTF(",");
2426 srcoffset = decode_rm10_address(rl);
2427 srcval = fetch_data_byte(srcoffset);
2428 DECODE_PRINTF("\n");
2429 TRACE_AND_STEP();
2430 *destreg = sub_byte(*destreg, srcval);
2431 break;
2432 case 3: /* register to register */
2433 destreg = DECODE_RM_BYTE_REGISTER(rh);
2434 DECODE_PRINTF(",");
2435 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2436 DECODE_PRINTF("\n");
2437 TRACE_AND_STEP();
2438 *destreg = sub_byte(*destreg, *srcreg);
2439 break;
2440 }
2441 DECODE_CLEAR_SEGOVR();
2442 END_OF_INSTR();
2443 }
2444
2445 /****************************************************************************
2446 REMARKS:
2447 Handles opcode 0x2b
2448 ****************************************************************************/
x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED (op1))2449 void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2450 {
2451 int mod, rl, rh;
2452 uint srcoffset;
2453
2454 START_OF_INSTR();
2455 DECODE_PRINTF("SUB\t");
2456 FETCH_DECODE_MODRM(mod, rh, rl);
2457 switch (mod) {
2458 case 0:
2459 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2460 u32 *destreg;
2461 u32 srcval;
2462
2463 destreg = DECODE_RM_LONG_REGISTER(rh);
2464 DECODE_PRINTF(",");
2465 srcoffset = decode_rm00_address(rl);
2466 srcval = fetch_data_long(srcoffset);
2467 DECODE_PRINTF("\n");
2468 TRACE_AND_STEP();
2469 *destreg = sub_long(*destreg, srcval);
2470 } else {
2471 u16 *destreg;
2472 u16 srcval;
2473
2474 destreg = DECODE_RM_WORD_REGISTER(rh);
2475 DECODE_PRINTF(",");
2476 srcoffset = decode_rm00_address(rl);
2477 srcval = fetch_data_word(srcoffset);
2478 DECODE_PRINTF("\n");
2479 TRACE_AND_STEP();
2480 *destreg = sub_word(*destreg, srcval);
2481 }
2482 break;
2483 case 1:
2484 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2485 u32 *destreg;
2486 u32 srcval;
2487
2488 destreg = DECODE_RM_LONG_REGISTER(rh);
2489 DECODE_PRINTF(",");
2490 srcoffset = decode_rm01_address(rl);
2491 srcval = fetch_data_long(srcoffset);
2492 DECODE_PRINTF("\n");
2493 TRACE_AND_STEP();
2494 *destreg = sub_long(*destreg, srcval);
2495 } else {
2496 u16 *destreg;
2497 u16 srcval;
2498
2499 destreg = DECODE_RM_WORD_REGISTER(rh);
2500 DECODE_PRINTF(",");
2501 srcoffset = decode_rm01_address(rl);
2502 srcval = fetch_data_word(srcoffset);
2503 DECODE_PRINTF("\n");
2504 TRACE_AND_STEP();
2505 *destreg = sub_word(*destreg, srcval);
2506 }
2507 break;
2508 case 2:
2509 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2510 u32 *destreg;
2511 u32 srcval;
2512
2513 destreg = DECODE_RM_LONG_REGISTER(rh);
2514 DECODE_PRINTF(",");
2515 srcoffset = decode_rm10_address(rl);
2516 srcval = fetch_data_long(srcoffset);
2517 DECODE_PRINTF("\n");
2518 TRACE_AND_STEP();
2519 *destreg = sub_long(*destreg, srcval);
2520 } else {
2521 u16 *destreg;
2522 u16 srcval;
2523
2524 destreg = DECODE_RM_WORD_REGISTER(rh);
2525 DECODE_PRINTF(",");
2526 srcoffset = decode_rm10_address(rl);
2527 srcval = fetch_data_word(srcoffset);
2528 DECODE_PRINTF("\n");
2529 TRACE_AND_STEP();
2530 *destreg = sub_word(*destreg, srcval);
2531 }
2532 break;
2533 case 3: /* register to register */
2534 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2535 u32 *destreg,*srcreg;
2536
2537 destreg = DECODE_RM_LONG_REGISTER(rh);
2538 DECODE_PRINTF(",");
2539 srcreg = DECODE_RM_LONG_REGISTER(rl);
2540 DECODE_PRINTF("\n");
2541 TRACE_AND_STEP();
2542 *destreg = sub_long(*destreg, *srcreg);
2543 } else {
2544 u16 *destreg,*srcreg;
2545
2546 destreg = DECODE_RM_WORD_REGISTER(rh);
2547 DECODE_PRINTF(",");
2548 srcreg = DECODE_RM_WORD_REGISTER(rl);
2549 DECODE_PRINTF("\n");
2550 TRACE_AND_STEP();
2551 *destreg = sub_word(*destreg, *srcreg);
2552 }
2553 break;
2554 }
2555 DECODE_CLEAR_SEGOVR();
2556 END_OF_INSTR();
2557 }
2558
2559 /****************************************************************************
2560 REMARKS:
2561 Handles opcode 0x2c
2562 ****************************************************************************/
x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2563 void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2564 {
2565 u8 srcval;
2566
2567 START_OF_INSTR();
2568 DECODE_PRINTF("SUB\tAL,");
2569 srcval = fetch_byte_imm();
2570 DECODE_PRINTF2("%x\n", srcval);
2571 TRACE_AND_STEP();
2572 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2573 DECODE_CLEAR_SEGOVR();
2574 END_OF_INSTR();
2575 }
2576
2577 /****************************************************************************
2578 REMARKS:
2579 Handles opcode 0x2d
2580 ****************************************************************************/
x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED (op1))2581 void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2582 {
2583 u32 srcval;
2584
2585 START_OF_INSTR();
2586 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2587 DECODE_PRINTF("SUB\tEAX,");
2588 srcval = fetch_long_imm();
2589 } else {
2590 DECODE_PRINTF("SUB\tAX,");
2591 srcval = fetch_word_imm();
2592 }
2593 DECODE_PRINTF2("%x\n", srcval);
2594 TRACE_AND_STEP();
2595 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2596 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2597 } else {
2598 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2599 }
2600 DECODE_CLEAR_SEGOVR();
2601 END_OF_INSTR();
2602 }
2603
2604 /****************************************************************************
2605 REMARKS:
2606 Handles opcode 0x2e
2607 ****************************************************************************/
x86emuOp_segovr_CS(u8 X86EMU_UNUSED (op1))2608 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2609 {
2610 START_OF_INSTR();
2611 DECODE_PRINTF("CS:\n");
2612 TRACE_AND_STEP();
2613 M.x86.mode |= SYSMODE_SEGOVR_CS;
2614 /* note no DECODE_CLEAR_SEGOVR here. */
2615 END_OF_INSTR();
2616 }
2617
2618 /****************************************************************************
2619 REMARKS:
2620 Handles opcode 0x2f
2621 ****************************************************************************/
x86emuOp_das(u8 X86EMU_UNUSED (op1))2622 void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2623 {
2624 START_OF_INSTR();
2625 DECODE_PRINTF("DAS\n");
2626 TRACE_AND_STEP();
2627 M.x86.R_AL = das_byte(M.x86.R_AL);
2628 DECODE_CLEAR_SEGOVR();
2629 END_OF_INSTR();
2630 }
2631
2632 /****************************************************************************
2633 REMARKS:
2634 Handles opcode 0x30
2635 ****************************************************************************/
x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED (op1))2636 void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2637 {
2638 int mod, rl, rh;
2639 u8 *destreg, *srcreg;
2640 uint destoffset;
2641 u8 destval;
2642
2643 START_OF_INSTR();
2644 DECODE_PRINTF("XOR\t");
2645 FETCH_DECODE_MODRM(mod, rh, rl);
2646 switch (mod) {
2647 case 0:
2648 destoffset = decode_rm00_address(rl);
2649 DECODE_PRINTF(",");
2650 destval = fetch_data_byte(destoffset);
2651 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2652 DECODE_PRINTF("\n");
2653 TRACE_AND_STEP();
2654 destval = xor_byte(destval, *srcreg);
2655 store_data_byte(destoffset, destval);
2656 break;
2657 case 1:
2658 destoffset = decode_rm01_address(rl);
2659 DECODE_PRINTF(",");
2660 destval = fetch_data_byte(destoffset);
2661 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2662 DECODE_PRINTF("\n");
2663 TRACE_AND_STEP();
2664 destval = xor_byte(destval, *srcreg);
2665 store_data_byte(destoffset, destval);
2666 break;
2667 case 2:
2668 destoffset = decode_rm10_address(rl);
2669 DECODE_PRINTF(",");
2670 destval = fetch_data_byte(destoffset);
2671 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2672 DECODE_PRINTF("\n");
2673 TRACE_AND_STEP();
2674 destval = xor_byte(destval, *srcreg);
2675 store_data_byte(destoffset, destval);
2676 break;
2677 case 3: /* register to register */
2678 destreg = DECODE_RM_BYTE_REGISTER(rl);
2679 DECODE_PRINTF(",");
2680 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2681 DECODE_PRINTF("\n");
2682 TRACE_AND_STEP();
2683 *destreg = xor_byte(*destreg, *srcreg);
2684 break;
2685 }
2686 DECODE_CLEAR_SEGOVR();
2687 END_OF_INSTR();
2688 }
2689
2690 /****************************************************************************
2691 REMARKS:
2692 Handles opcode 0x31
2693 ****************************************************************************/
x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED (op1))2694 void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2695 {
2696 int mod, rl, rh;
2697 uint destoffset;
2698
2699 START_OF_INSTR();
2700 DECODE_PRINTF("XOR\t");
2701 FETCH_DECODE_MODRM(mod, rh, rl);
2702 switch (mod) {
2703 case 0:
2704 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2705 u32 destval;
2706 u32 *srcreg;
2707
2708 destoffset = decode_rm00_address(rl);
2709 DECODE_PRINTF(",");
2710 destval = fetch_data_long(destoffset);
2711 srcreg = DECODE_RM_LONG_REGISTER(rh);
2712 DECODE_PRINTF("\n");
2713 TRACE_AND_STEP();
2714 destval = xor_long(destval, *srcreg);
2715 store_data_long(destoffset, destval);
2716 } else {
2717 u16 destval;
2718 u16 *srcreg;
2719
2720 destoffset = decode_rm00_address(rl);
2721 DECODE_PRINTF(",");
2722 destval = fetch_data_word(destoffset);
2723 srcreg = DECODE_RM_WORD_REGISTER(rh);
2724 DECODE_PRINTF("\n");
2725 TRACE_AND_STEP();
2726 destval = xor_word(destval, *srcreg);
2727 store_data_word(destoffset, destval);
2728 }
2729 break;
2730 case 1:
2731 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2732 u32 destval;
2733 u32 *srcreg;
2734
2735 destoffset = decode_rm01_address(rl);
2736 DECODE_PRINTF(",");
2737 destval = fetch_data_long(destoffset);
2738 srcreg = DECODE_RM_LONG_REGISTER(rh);
2739 DECODE_PRINTF("\n");
2740 TRACE_AND_STEP();
2741 destval = xor_long(destval, *srcreg);
2742 store_data_long(destoffset, destval);
2743 } else {
2744 u16 destval;
2745 u16 *srcreg;
2746
2747 destoffset = decode_rm01_address(rl);
2748 DECODE_PRINTF(",");
2749 destval = fetch_data_word(destoffset);
2750 srcreg = DECODE_RM_WORD_REGISTER(rh);
2751 DECODE_PRINTF("\n");
2752 TRACE_AND_STEP();
2753 destval = xor_word(destval, *srcreg);
2754 store_data_word(destoffset, destval);
2755 }
2756 break;
2757 case 2:
2758 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2759 u32 destval;
2760 u32 *srcreg;
2761
2762 destoffset = decode_rm10_address(rl);
2763 DECODE_PRINTF(",");
2764 destval = fetch_data_long(destoffset);
2765 srcreg = DECODE_RM_LONG_REGISTER(rh);
2766 DECODE_PRINTF("\n");
2767 TRACE_AND_STEP();
2768 destval = xor_long(destval, *srcreg);
2769 store_data_long(destoffset, destval);
2770 } else {
2771 u16 destval;
2772 u16 *srcreg;
2773
2774 destoffset = decode_rm10_address(rl);
2775 DECODE_PRINTF(",");
2776 destval = fetch_data_word(destoffset);
2777 srcreg = DECODE_RM_WORD_REGISTER(rh);
2778 DECODE_PRINTF("\n");
2779 TRACE_AND_STEP();
2780 destval = xor_word(destval, *srcreg);
2781 store_data_word(destoffset, destval);
2782 }
2783 break;
2784 case 3: /* register to register */
2785 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2786 u32 *destreg,*srcreg;
2787
2788 destreg = DECODE_RM_LONG_REGISTER(rl);
2789 DECODE_PRINTF(",");
2790 srcreg = DECODE_RM_LONG_REGISTER(rh);
2791 DECODE_PRINTF("\n");
2792 TRACE_AND_STEP();
2793 *destreg = xor_long(*destreg, *srcreg);
2794 } else {
2795 u16 *destreg,*srcreg;
2796
2797 destreg = DECODE_RM_WORD_REGISTER(rl);
2798 DECODE_PRINTF(",");
2799 srcreg = DECODE_RM_WORD_REGISTER(rh);
2800 DECODE_PRINTF("\n");
2801 TRACE_AND_STEP();
2802 *destreg = xor_word(*destreg, *srcreg);
2803 }
2804 break;
2805 }
2806 DECODE_CLEAR_SEGOVR();
2807 END_OF_INSTR();
2808 }
2809
2810 /****************************************************************************
2811 REMARKS:
2812 Handles opcode 0x32
2813 ****************************************************************************/
x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED (op1))2814 void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2815 {
2816 int mod, rl, rh;
2817 u8 *destreg, *srcreg;
2818 uint srcoffset;
2819 u8 srcval;
2820
2821 START_OF_INSTR();
2822 DECODE_PRINTF("XOR\t");
2823 FETCH_DECODE_MODRM(mod, rh, rl);
2824 switch (mod) {
2825 case 0:
2826 destreg = DECODE_RM_BYTE_REGISTER(rh);
2827 DECODE_PRINTF(",");
2828 srcoffset = decode_rm00_address(rl);
2829 srcval = fetch_data_byte(srcoffset);
2830 DECODE_PRINTF("\n");
2831 TRACE_AND_STEP();
2832 *destreg = xor_byte(*destreg, srcval);
2833 break;
2834 case 1:
2835 destreg = DECODE_RM_BYTE_REGISTER(rh);
2836 DECODE_PRINTF(",");
2837 srcoffset = decode_rm01_address(rl);
2838 srcval = fetch_data_byte(srcoffset);
2839 DECODE_PRINTF("\n");
2840 TRACE_AND_STEP();
2841 *destreg = xor_byte(*destreg, srcval);
2842 break;
2843 case 2:
2844 destreg = DECODE_RM_BYTE_REGISTER(rh);
2845 DECODE_PRINTF(",");
2846 srcoffset = decode_rm10_address(rl);
2847 srcval = fetch_data_byte(srcoffset);
2848 DECODE_PRINTF("\n");
2849 TRACE_AND_STEP();
2850 *destreg = xor_byte(*destreg, srcval);
2851 break;
2852 case 3: /* register to register */
2853 destreg = DECODE_RM_BYTE_REGISTER(rh);
2854 DECODE_PRINTF(",");
2855 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2856 DECODE_PRINTF("\n");
2857 TRACE_AND_STEP();
2858 *destreg = xor_byte(*destreg, *srcreg);
2859 break;
2860 }
2861 DECODE_CLEAR_SEGOVR();
2862 END_OF_INSTR();
2863 }
2864
2865 /****************************************************************************
2866 REMARKS:
2867 Handles opcode 0x33
2868 ****************************************************************************/
x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED (op1))2869 void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2870 {
2871 int mod, rl, rh;
2872 uint srcoffset;
2873
2874 START_OF_INSTR();
2875 DECODE_PRINTF("XOR\t");
2876 FETCH_DECODE_MODRM(mod, rh, rl);
2877 switch (mod) {
2878 case 0:
2879 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2880 u32 *destreg;
2881 u32 srcval;
2882
2883 destreg = DECODE_RM_LONG_REGISTER(rh);
2884 DECODE_PRINTF(",");
2885 srcoffset = decode_rm00_address(rl);
2886 srcval = fetch_data_long(srcoffset);
2887 DECODE_PRINTF("\n");
2888 TRACE_AND_STEP();
2889 *destreg = xor_long(*destreg, srcval);
2890 } else {
2891 u16 *destreg;
2892 u16 srcval;
2893
2894 destreg = DECODE_RM_WORD_REGISTER(rh);
2895 DECODE_PRINTF(",");
2896 srcoffset = decode_rm00_address(rl);
2897 srcval = fetch_data_word(srcoffset);
2898 DECODE_PRINTF("\n");
2899 TRACE_AND_STEP();
2900 *destreg = xor_word(*destreg, srcval);
2901 }
2902 break;
2903 case 1:
2904 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2905 u32 *destreg;
2906 u32 srcval;
2907
2908 destreg = DECODE_RM_LONG_REGISTER(rh);
2909 DECODE_PRINTF(",");
2910 srcoffset = decode_rm01_address(rl);
2911 srcval = fetch_data_long(srcoffset);
2912 DECODE_PRINTF("\n");
2913 TRACE_AND_STEP();
2914 *destreg = xor_long(*destreg, srcval);
2915 } else {
2916 u16 *destreg;
2917 u16 srcval;
2918
2919 destreg = DECODE_RM_WORD_REGISTER(rh);
2920 DECODE_PRINTF(",");
2921 srcoffset = decode_rm01_address(rl);
2922 srcval = fetch_data_word(srcoffset);
2923 DECODE_PRINTF("\n");
2924 TRACE_AND_STEP();
2925 *destreg = xor_word(*destreg, srcval);
2926 }
2927 break;
2928 case 2:
2929 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2930 u32 *destreg;
2931 u32 srcval;
2932
2933 destreg = DECODE_RM_LONG_REGISTER(rh);
2934 DECODE_PRINTF(",");
2935 srcoffset = decode_rm10_address(rl);
2936 srcval = fetch_data_long(srcoffset);
2937 DECODE_PRINTF("\n");
2938 TRACE_AND_STEP();
2939 *destreg = xor_long(*destreg, srcval);
2940 } else {
2941 u16 *destreg;
2942 u16 srcval;
2943
2944 destreg = DECODE_RM_WORD_REGISTER(rh);
2945 DECODE_PRINTF(",");
2946 srcoffset = decode_rm10_address(rl);
2947 srcval = fetch_data_word(srcoffset);
2948 DECODE_PRINTF("\n");
2949 TRACE_AND_STEP();
2950 *destreg = xor_word(*destreg, srcval);
2951 }
2952 break;
2953 case 3: /* register to register */
2954 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2955 u32 *destreg,*srcreg;
2956
2957 destreg = DECODE_RM_LONG_REGISTER(rh);
2958 DECODE_PRINTF(",");
2959 srcreg = DECODE_RM_LONG_REGISTER(rl);
2960 DECODE_PRINTF("\n");
2961 TRACE_AND_STEP();
2962 *destreg = xor_long(*destreg, *srcreg);
2963 } else {
2964 u16 *destreg,*srcreg;
2965
2966 destreg = DECODE_RM_WORD_REGISTER(rh);
2967 DECODE_PRINTF(",");
2968 srcreg = DECODE_RM_WORD_REGISTER(rl);
2969 DECODE_PRINTF("\n");
2970 TRACE_AND_STEP();
2971 *destreg = xor_word(*destreg, *srcreg);
2972 }
2973 break;
2974 }
2975 DECODE_CLEAR_SEGOVR();
2976 END_OF_INSTR();
2977 }
2978
2979 /****************************************************************************
2980 REMARKS:
2981 Handles opcode 0x34
2982 ****************************************************************************/
x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2983 void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2984 {
2985 u8 srcval;
2986
2987 START_OF_INSTR();
2988 DECODE_PRINTF("XOR\tAL,");
2989 srcval = fetch_byte_imm();
2990 DECODE_PRINTF2("%x\n", srcval);
2991 TRACE_AND_STEP();
2992 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2993 DECODE_CLEAR_SEGOVR();
2994 END_OF_INSTR();
2995 }
2996
2997 /****************************************************************************
2998 REMARKS:
2999 Handles opcode 0x35
3000 ****************************************************************************/
x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED (op1))3001 void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3002 {
3003 u32 srcval;
3004
3005 START_OF_INSTR();
3006 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3007 DECODE_PRINTF("XOR\tEAX,");
3008 srcval = fetch_long_imm();
3009 } else {
3010 DECODE_PRINTF("XOR\tAX,");
3011 srcval = fetch_word_imm();
3012 }
3013 DECODE_PRINTF2("%x\n", srcval);
3014 TRACE_AND_STEP();
3015 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3016 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3017 } else {
3018 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3019 }
3020 DECODE_CLEAR_SEGOVR();
3021 END_OF_INSTR();
3022 }
3023
3024 /****************************************************************************
3025 REMARKS:
3026 Handles opcode 0x36
3027 ****************************************************************************/
x86emuOp_segovr_SS(u8 X86EMU_UNUSED (op1))3028 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3029 {
3030 START_OF_INSTR();
3031 DECODE_PRINTF("SS:\n");
3032 TRACE_AND_STEP();
3033 M.x86.mode |= SYSMODE_SEGOVR_SS;
3034 /* no DECODE_CLEAR_SEGOVR ! */
3035 END_OF_INSTR();
3036 }
3037
3038 /****************************************************************************
3039 REMARKS:
3040 Handles opcode 0x37
3041 ****************************************************************************/
x86emuOp_aaa(u8 X86EMU_UNUSED (op1))3042 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3043 {
3044 START_OF_INSTR();
3045 DECODE_PRINTF("AAA\n");
3046 TRACE_AND_STEP();
3047 M.x86.R_AX = aaa_word(M.x86.R_AX);
3048 DECODE_CLEAR_SEGOVR();
3049 END_OF_INSTR();
3050 }
3051
3052 /****************************************************************************
3053 REMARKS:
3054 Handles opcode 0x38
3055 ****************************************************************************/
x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED (op1))3056 void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3057 {
3058 int mod, rl, rh;
3059 uint destoffset;
3060 u8 *destreg, *srcreg;
3061 u8 destval;
3062
3063 START_OF_INSTR();
3064 DECODE_PRINTF("CMP\t");
3065 FETCH_DECODE_MODRM(mod, rh, rl);
3066 switch (mod) {
3067 case 0:
3068 destoffset = decode_rm00_address(rl);
3069 DECODE_PRINTF(",");
3070 destval = fetch_data_byte(destoffset);
3071 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3072 DECODE_PRINTF("\n");
3073 TRACE_AND_STEP();
3074 cmp_byte(destval, *srcreg);
3075 break;
3076 case 1:
3077 destoffset = decode_rm01_address(rl);
3078 DECODE_PRINTF(",");
3079 destval = fetch_data_byte(destoffset);
3080 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3081 DECODE_PRINTF("\n");
3082 TRACE_AND_STEP();
3083 cmp_byte(destval, *srcreg);
3084 break;
3085 case 2:
3086 destoffset = decode_rm10_address(rl);
3087 DECODE_PRINTF(",");
3088 destval = fetch_data_byte(destoffset);
3089 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3090 DECODE_PRINTF("\n");
3091 TRACE_AND_STEP();
3092 cmp_byte(destval, *srcreg);
3093 break;
3094 case 3: /* register to register */
3095 destreg = DECODE_RM_BYTE_REGISTER(rl);
3096 DECODE_PRINTF(",");
3097 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3098 DECODE_PRINTF("\n");
3099 TRACE_AND_STEP();
3100 cmp_byte(*destreg, *srcreg);
3101 break;
3102 }
3103 DECODE_CLEAR_SEGOVR();
3104 END_OF_INSTR();
3105 }
3106
3107 /****************************************************************************
3108 REMARKS:
3109 Handles opcode 0x39
3110 ****************************************************************************/
x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED (op1))3111 void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3112 {
3113 int mod, rl, rh;
3114 uint destoffset;
3115
3116 START_OF_INSTR();
3117 DECODE_PRINTF("CMP\t");
3118 FETCH_DECODE_MODRM(mod, rh, rl);
3119 switch (mod) {
3120 case 0:
3121 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3122 u32 destval;
3123 u32 *srcreg;
3124
3125 destoffset = decode_rm00_address(rl);
3126 DECODE_PRINTF(",");
3127 destval = fetch_data_long(destoffset);
3128 srcreg = DECODE_RM_LONG_REGISTER(rh);
3129 DECODE_PRINTF("\n");
3130 TRACE_AND_STEP();
3131 cmp_long(destval, *srcreg);
3132 } else {
3133 u16 destval;
3134 u16 *srcreg;
3135
3136 destoffset = decode_rm00_address(rl);
3137 DECODE_PRINTF(",");
3138 destval = fetch_data_word(destoffset);
3139 srcreg = DECODE_RM_WORD_REGISTER(rh);
3140 DECODE_PRINTF("\n");
3141 TRACE_AND_STEP();
3142 cmp_word(destval, *srcreg);
3143 }
3144 break;
3145 case 1:
3146 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3147 u32 destval;
3148 u32 *srcreg;
3149
3150 destoffset = decode_rm01_address(rl);
3151 DECODE_PRINTF(",");
3152 destval = fetch_data_long(destoffset);
3153 srcreg = DECODE_RM_LONG_REGISTER(rh);
3154 DECODE_PRINTF("\n");
3155 TRACE_AND_STEP();
3156 cmp_long(destval, *srcreg);
3157 } else {
3158 u16 destval;
3159 u16 *srcreg;
3160
3161 destoffset = decode_rm01_address(rl);
3162 DECODE_PRINTF(",");
3163 destval = fetch_data_word(destoffset);
3164 srcreg = DECODE_RM_WORD_REGISTER(rh);
3165 DECODE_PRINTF("\n");
3166 TRACE_AND_STEP();
3167 cmp_word(destval, *srcreg);
3168 }
3169 break;
3170 case 2:
3171 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3172 u32 destval;
3173 u32 *srcreg;
3174
3175 destoffset = decode_rm10_address(rl);
3176 DECODE_PRINTF(",");
3177 destval = fetch_data_long(destoffset);
3178 srcreg = DECODE_RM_LONG_REGISTER(rh);
3179 DECODE_PRINTF("\n");
3180 TRACE_AND_STEP();
3181 cmp_long(destval, *srcreg);
3182 } else {
3183 u16 destval;
3184 u16 *srcreg;
3185
3186 destoffset = decode_rm10_address(rl);
3187 DECODE_PRINTF(",");
3188 destval = fetch_data_word(destoffset);
3189 srcreg = DECODE_RM_WORD_REGISTER(rh);
3190 DECODE_PRINTF("\n");
3191 TRACE_AND_STEP();
3192 cmp_word(destval, *srcreg);
3193 }
3194 break;
3195 case 3: /* register to register */
3196 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3197 u32 *destreg,*srcreg;
3198
3199 destreg = DECODE_RM_LONG_REGISTER(rl);
3200 DECODE_PRINTF(",");
3201 srcreg = DECODE_RM_LONG_REGISTER(rh);
3202 DECODE_PRINTF("\n");
3203 TRACE_AND_STEP();
3204 cmp_long(*destreg, *srcreg);
3205 } else {
3206 u16 *destreg,*srcreg;
3207
3208 destreg = DECODE_RM_WORD_REGISTER(rl);
3209 DECODE_PRINTF(",");
3210 srcreg = DECODE_RM_WORD_REGISTER(rh);
3211 DECODE_PRINTF("\n");
3212 TRACE_AND_STEP();
3213 cmp_word(*destreg, *srcreg);
3214 }
3215 break;
3216 }
3217 DECODE_CLEAR_SEGOVR();
3218 END_OF_INSTR();
3219 }
3220
3221 /****************************************************************************
3222 REMARKS:
3223 Handles opcode 0x3a
3224 ****************************************************************************/
x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED (op1))3225 void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3226 {
3227 int mod, rl, rh;
3228 u8 *destreg, *srcreg;
3229 uint srcoffset;
3230 u8 srcval;
3231
3232 START_OF_INSTR();
3233 DECODE_PRINTF("CMP\t");
3234 FETCH_DECODE_MODRM(mod, rh, rl);
3235 switch (mod) {
3236 case 0:
3237 destreg = DECODE_RM_BYTE_REGISTER(rh);
3238 DECODE_PRINTF(",");
3239 srcoffset = decode_rm00_address(rl);
3240 srcval = fetch_data_byte(srcoffset);
3241 DECODE_PRINTF("\n");
3242 TRACE_AND_STEP();
3243 cmp_byte(*destreg, srcval);
3244 break;
3245 case 1:
3246 destreg = DECODE_RM_BYTE_REGISTER(rh);
3247 DECODE_PRINTF(",");
3248 srcoffset = decode_rm01_address(rl);
3249 srcval = fetch_data_byte(srcoffset);
3250 DECODE_PRINTF("\n");
3251 TRACE_AND_STEP();
3252 cmp_byte(*destreg, srcval);
3253 break;
3254 case 2:
3255 destreg = DECODE_RM_BYTE_REGISTER(rh);
3256 DECODE_PRINTF(",");
3257 srcoffset = decode_rm10_address(rl);
3258 srcval = fetch_data_byte(srcoffset);
3259 DECODE_PRINTF("\n");
3260 TRACE_AND_STEP();
3261 cmp_byte(*destreg, srcval);
3262 break;
3263 case 3: /* register to register */
3264 destreg = DECODE_RM_BYTE_REGISTER(rh);
3265 DECODE_PRINTF(",");
3266 srcreg = DECODE_RM_BYTE_REGISTER(rl);
3267 DECODE_PRINTF("\n");
3268 TRACE_AND_STEP();
3269 cmp_byte(*destreg, *srcreg);
3270 break;
3271 }
3272 DECODE_CLEAR_SEGOVR();
3273 END_OF_INSTR();
3274 }
3275
3276 /****************************************************************************
3277 REMARKS:
3278 Handles opcode 0x3b
3279 ****************************************************************************/
x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED (op1))3280 void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3281 {
3282 int mod, rl, rh;
3283 uint srcoffset;
3284
3285 START_OF_INSTR();
3286 DECODE_PRINTF("CMP\t");
3287 FETCH_DECODE_MODRM(mod, rh, rl);
3288 switch (mod) {
3289 case 0:
3290 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3291 u32 *destreg;
3292 u32 srcval;
3293
3294 destreg = DECODE_RM_LONG_REGISTER(rh);
3295 DECODE_PRINTF(",");
3296 srcoffset = decode_rm00_address(rl);
3297 srcval = fetch_data_long(srcoffset);
3298 DECODE_PRINTF("\n");
3299 TRACE_AND_STEP();
3300 cmp_long(*destreg, srcval);
3301 } else {
3302 u16 *destreg;
3303 u16 srcval;
3304
3305 destreg = DECODE_RM_WORD_REGISTER(rh);
3306 DECODE_PRINTF(",");
3307 srcoffset = decode_rm00_address(rl);
3308 srcval = fetch_data_word(srcoffset);
3309 DECODE_PRINTF("\n");
3310 TRACE_AND_STEP();
3311 cmp_word(*destreg, srcval);
3312 }
3313 break;
3314 case 1:
3315 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3316 u32 *destreg;
3317 u32 srcval;
3318
3319 destreg = DECODE_RM_LONG_REGISTER(rh);
3320 DECODE_PRINTF(",");
3321 srcoffset = decode_rm01_address(rl);
3322 srcval = fetch_data_long(srcoffset);
3323 DECODE_PRINTF("\n");
3324 TRACE_AND_STEP();
3325 cmp_long(*destreg, srcval);
3326 } else {
3327 u16 *destreg;
3328 u16 srcval;
3329
3330 destreg = DECODE_RM_WORD_REGISTER(rh);
3331 DECODE_PRINTF(",");
3332 srcoffset = decode_rm01_address(rl);
3333 srcval = fetch_data_word(srcoffset);
3334 DECODE_PRINTF("\n");
3335 TRACE_AND_STEP();
3336 cmp_word(*destreg, srcval);
3337 }
3338 break;
3339 case 2:
3340 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3341 u32 *destreg;
3342 u32 srcval;
3343
3344 destreg = DECODE_RM_LONG_REGISTER(rh);
3345 DECODE_PRINTF(",");
3346 srcoffset = decode_rm10_address(rl);
3347 srcval = fetch_data_long(srcoffset);
3348 DECODE_PRINTF("\n");
3349 TRACE_AND_STEP();
3350 cmp_long(*destreg, srcval);
3351 } else {
3352 u16 *destreg;
3353 u16 srcval;
3354
3355 destreg = DECODE_RM_WORD_REGISTER(rh);
3356 DECODE_PRINTF(",");
3357 srcoffset = decode_rm10_address(rl);
3358 srcval = fetch_data_word(srcoffset);
3359 DECODE_PRINTF("\n");
3360 TRACE_AND_STEP();
3361 cmp_word(*destreg, srcval);
3362 }
3363 break;
3364 case 3: /* register to register */
3365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3366 u32 *destreg,*srcreg;
3367
3368 destreg = DECODE_RM_LONG_REGISTER(rh);
3369 DECODE_PRINTF(",");
3370 srcreg = DECODE_RM_LONG_REGISTER(rl);
3371 DECODE_PRINTF("\n");
3372 TRACE_AND_STEP();
3373 cmp_long(*destreg, *srcreg);
3374 } else {
3375 u16 *destreg,*srcreg;
3376
3377 destreg = DECODE_RM_WORD_REGISTER(rh);
3378 DECODE_PRINTF(",");
3379 srcreg = DECODE_RM_WORD_REGISTER(rl);
3380 DECODE_PRINTF("\n");
3381 TRACE_AND_STEP();
3382 cmp_word(*destreg, *srcreg);
3383 }
3384 break;
3385 }
3386 DECODE_CLEAR_SEGOVR();
3387 END_OF_INSTR();
3388 }
3389
3390 /****************************************************************************
3391 REMARKS:
3392 Handles opcode 0x3c
3393 ****************************************************************************/
x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3394 void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3395 {
3396 u8 srcval;
3397
3398 START_OF_INSTR();
3399 DECODE_PRINTF("CMP\tAL,");
3400 srcval = fetch_byte_imm();
3401 DECODE_PRINTF2("%x\n", srcval);
3402 TRACE_AND_STEP();
3403 cmp_byte(M.x86.R_AL, srcval);
3404 DECODE_CLEAR_SEGOVR();
3405 END_OF_INSTR();
3406 }
3407
3408 /****************************************************************************
3409 REMARKS:
3410 Handles opcode 0x3d
3411 ****************************************************************************/
x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED (op1))3412 void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3413 {
3414 u32 srcval;
3415
3416 START_OF_INSTR();
3417 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3418 DECODE_PRINTF("CMP\tEAX,");
3419 srcval = fetch_long_imm();
3420 } else {
3421 DECODE_PRINTF("CMP\tAX,");
3422 srcval = fetch_word_imm();
3423 }
3424 DECODE_PRINTF2("%x\n", srcval);
3425 TRACE_AND_STEP();
3426 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3427 cmp_long(M.x86.R_EAX, srcval);
3428 } else {
3429 cmp_word(M.x86.R_AX, (u16)srcval);
3430 }
3431 DECODE_CLEAR_SEGOVR();
3432 END_OF_INSTR();
3433 }
3434
3435 /****************************************************************************
3436 REMARKS:
3437 Handles opcode 0x3e
3438 ****************************************************************************/
x86emuOp_segovr_DS(u8 X86EMU_UNUSED (op1))3439 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3440 {
3441 START_OF_INSTR();
3442 DECODE_PRINTF("DS:\n");
3443 TRACE_AND_STEP();
3444 M.x86.mode |= SYSMODE_SEGOVR_DS;
3445 /* NO DECODE_CLEAR_SEGOVR! */
3446 END_OF_INSTR();
3447 }
3448
3449 /****************************************************************************
3450 REMARKS:
3451 Handles opcode 0x3f
3452 ****************************************************************************/
x86emuOp_aas(u8 X86EMU_UNUSED (op1))3453 void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3454 {
3455 START_OF_INSTR();
3456 DECODE_PRINTF("AAS\n");
3457 TRACE_AND_STEP();
3458 M.x86.R_AX = aas_word(M.x86.R_AX);
3459 DECODE_CLEAR_SEGOVR();
3460 END_OF_INSTR();
3461 }
3462
3463 /****************************************************************************
3464 REMARKS:
3465 Handles opcode 0x40
3466 ****************************************************************************/
x86emuOp_inc_AX(u8 X86EMU_UNUSED (op1))3467 void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3468 {
3469 START_OF_INSTR();
3470 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3471 DECODE_PRINTF("INC\tEAX\n");
3472 } else {
3473 DECODE_PRINTF("INC\tAX\n");
3474 }
3475 TRACE_AND_STEP();
3476 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3477 M.x86.R_EAX = inc_long(M.x86.R_EAX);
3478 } else {
3479 M.x86.R_AX = inc_word(M.x86.R_AX);
3480 }
3481 DECODE_CLEAR_SEGOVR();
3482 END_OF_INSTR();
3483 }
3484
3485 /****************************************************************************
3486 REMARKS:
3487 Handles opcode 0x41
3488 ****************************************************************************/
x86emuOp_inc_CX(u8 X86EMU_UNUSED (op1))3489 void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3490 {
3491 START_OF_INSTR();
3492 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3493 DECODE_PRINTF("INC\tECX\n");
3494 } else {
3495 DECODE_PRINTF("INC\tCX\n");
3496 }
3497 TRACE_AND_STEP();
3498 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3499 M.x86.R_ECX = inc_long(M.x86.R_ECX);
3500 } else {
3501 M.x86.R_CX = inc_word(M.x86.R_CX);
3502 }
3503 DECODE_CLEAR_SEGOVR();
3504 END_OF_INSTR();
3505 }
3506
3507 /****************************************************************************
3508 REMARKS:
3509 Handles opcode 0x42
3510 ****************************************************************************/
x86emuOp_inc_DX(u8 X86EMU_UNUSED (op1))3511 void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3512 {
3513 START_OF_INSTR();
3514 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3515 DECODE_PRINTF("INC\tEDX\n");
3516 } else {
3517 DECODE_PRINTF("INC\tDX\n");
3518 }
3519 TRACE_AND_STEP();
3520 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3521 M.x86.R_EDX = inc_long(M.x86.R_EDX);
3522 } else {
3523 M.x86.R_DX = inc_word(M.x86.R_DX);
3524 }
3525 DECODE_CLEAR_SEGOVR();
3526 END_OF_INSTR();
3527 }
3528
3529 /****************************************************************************
3530 REMARKS:
3531 Handles opcode 0x43
3532 ****************************************************************************/
x86emuOp_inc_BX(u8 X86EMU_UNUSED (op1))3533 void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3534 {
3535 START_OF_INSTR();
3536 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3537 DECODE_PRINTF("INC\tEBX\n");
3538 } else {
3539 DECODE_PRINTF("INC\tBX\n");
3540 }
3541 TRACE_AND_STEP();
3542 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3543 M.x86.R_EBX = inc_long(M.x86.R_EBX);
3544 } else {
3545 M.x86.R_BX = inc_word(M.x86.R_BX);
3546 }
3547 DECODE_CLEAR_SEGOVR();
3548 END_OF_INSTR();
3549 }
3550
3551 /****************************************************************************
3552 REMARKS:
3553 Handles opcode 0x44
3554 ****************************************************************************/
x86emuOp_inc_SP(u8 X86EMU_UNUSED (op1))3555 void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3556 {
3557 START_OF_INSTR();
3558 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559 DECODE_PRINTF("INC\tESP\n");
3560 } else {
3561 DECODE_PRINTF("INC\tSP\n");
3562 }
3563 TRACE_AND_STEP();
3564 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3565 M.x86.R_ESP = inc_long(M.x86.R_ESP);
3566 } else {
3567 M.x86.R_SP = inc_word(M.x86.R_SP);
3568 }
3569 DECODE_CLEAR_SEGOVR();
3570 END_OF_INSTR();
3571 }
3572
3573 /****************************************************************************
3574 REMARKS:
3575 Handles opcode 0x45
3576 ****************************************************************************/
x86emuOp_inc_BP(u8 X86EMU_UNUSED (op1))3577 void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3578 {
3579 START_OF_INSTR();
3580 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3581 DECODE_PRINTF("INC\tEBP\n");
3582 } else {
3583 DECODE_PRINTF("INC\tBP\n");
3584 }
3585 TRACE_AND_STEP();
3586 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3587 M.x86.R_EBP = inc_long(M.x86.R_EBP);
3588 } else {
3589 M.x86.R_BP = inc_word(M.x86.R_BP);
3590 }
3591 DECODE_CLEAR_SEGOVR();
3592 END_OF_INSTR();
3593 }
3594
3595 /****************************************************************************
3596 REMARKS:
3597 Handles opcode 0x46
3598 ****************************************************************************/
x86emuOp_inc_SI(u8 X86EMU_UNUSED (op1))3599 void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3600 {
3601 START_OF_INSTR();
3602 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3603 DECODE_PRINTF("INC\tESI\n");
3604 } else {
3605 DECODE_PRINTF("INC\tSI\n");
3606 }
3607 TRACE_AND_STEP();
3608 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3609 M.x86.R_ESI = inc_long(M.x86.R_ESI);
3610 } else {
3611 M.x86.R_SI = inc_word(M.x86.R_SI);
3612 }
3613 DECODE_CLEAR_SEGOVR();
3614 END_OF_INSTR();
3615 }
3616
3617 /****************************************************************************
3618 REMARKS:
3619 Handles opcode 0x47
3620 ****************************************************************************/
x86emuOp_inc_DI(u8 X86EMU_UNUSED (op1))3621 void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3622 {
3623 START_OF_INSTR();
3624 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3625 DECODE_PRINTF("INC\tEDI\n");
3626 } else {
3627 DECODE_PRINTF("INC\tDI\n");
3628 }
3629 TRACE_AND_STEP();
3630 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3631 M.x86.R_EDI = inc_long(M.x86.R_EDI);
3632 } else {
3633 M.x86.R_DI = inc_word(M.x86.R_DI);
3634 }
3635 DECODE_CLEAR_SEGOVR();
3636 END_OF_INSTR();
3637 }
3638
3639 /****************************************************************************
3640 REMARKS:
3641 Handles opcode 0x48
3642 ****************************************************************************/
x86emuOp_dec_AX(u8 X86EMU_UNUSED (op1))3643 void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3644 {
3645 START_OF_INSTR();
3646 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3647 DECODE_PRINTF("DEC\tEAX\n");
3648 } else {
3649 DECODE_PRINTF("DEC\tAX\n");
3650 }
3651 TRACE_AND_STEP();
3652 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3653 M.x86.R_EAX = dec_long(M.x86.R_EAX);
3654 } else {
3655 M.x86.R_AX = dec_word(M.x86.R_AX);
3656 }
3657 DECODE_CLEAR_SEGOVR();
3658 END_OF_INSTR();
3659 }
3660
3661 /****************************************************************************
3662 REMARKS:
3663 Handles opcode 0x49
3664 ****************************************************************************/
x86emuOp_dec_CX(u8 X86EMU_UNUSED (op1))3665 void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3666 {
3667 START_OF_INSTR();
3668 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3669 DECODE_PRINTF("DEC\tECX\n");
3670 } else {
3671 DECODE_PRINTF("DEC\tCX\n");
3672 }
3673 TRACE_AND_STEP();
3674 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3675 M.x86.R_ECX = dec_long(M.x86.R_ECX);
3676 } else {
3677 M.x86.R_CX = dec_word(M.x86.R_CX);
3678 }
3679 DECODE_CLEAR_SEGOVR();
3680 END_OF_INSTR();
3681 }
3682
3683 /****************************************************************************
3684 REMARKS:
3685 Handles opcode 0x4a
3686 ****************************************************************************/
x86emuOp_dec_DX(u8 X86EMU_UNUSED (op1))3687 void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3688 {
3689 START_OF_INSTR();
3690 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3691 DECODE_PRINTF("DEC\tEDX\n");
3692 } else {
3693 DECODE_PRINTF("DEC\tDX\n");
3694 }
3695 TRACE_AND_STEP();
3696 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3697 M.x86.R_EDX = dec_long(M.x86.R_EDX);
3698 } else {
3699 M.x86.R_DX = dec_word(M.x86.R_DX);
3700 }
3701 DECODE_CLEAR_SEGOVR();
3702 END_OF_INSTR();
3703 }
3704
3705 /****************************************************************************
3706 REMARKS:
3707 Handles opcode 0x4b
3708 ****************************************************************************/
x86emuOp_dec_BX(u8 X86EMU_UNUSED (op1))3709 void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3710 {
3711 START_OF_INSTR();
3712 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3713 DECODE_PRINTF("DEC\tEBX\n");
3714 } else {
3715 DECODE_PRINTF("DEC\tBX\n");
3716 }
3717 TRACE_AND_STEP();
3718 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3719 M.x86.R_EBX = dec_long(M.x86.R_EBX);
3720 } else {
3721 M.x86.R_BX = dec_word(M.x86.R_BX);
3722 }
3723 DECODE_CLEAR_SEGOVR();
3724 END_OF_INSTR();
3725 }
3726
3727 /****************************************************************************
3728 REMARKS:
3729 Handles opcode 0x4c
3730 ****************************************************************************/
x86emuOp_dec_SP(u8 X86EMU_UNUSED (op1))3731 void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3732 {
3733 START_OF_INSTR();
3734 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3735 DECODE_PRINTF("DEC\tESP\n");
3736 } else {
3737 DECODE_PRINTF("DEC\tSP\n");
3738 }
3739 TRACE_AND_STEP();
3740 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3741 M.x86.R_ESP = dec_long(M.x86.R_ESP);
3742 } else {
3743 M.x86.R_SP = dec_word(M.x86.R_SP);
3744 }
3745 DECODE_CLEAR_SEGOVR();
3746 END_OF_INSTR();
3747 }
3748
3749 /****************************************************************************
3750 REMARKS:
3751 Handles opcode 0x4d
3752 ****************************************************************************/
x86emuOp_dec_BP(u8 X86EMU_UNUSED (op1))3753 void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3754 {
3755 START_OF_INSTR();
3756 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3757 DECODE_PRINTF("DEC\tEBP\n");
3758 } else {
3759 DECODE_PRINTF("DEC\tBP\n");
3760 }
3761 TRACE_AND_STEP();
3762 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3763 M.x86.R_EBP = dec_long(M.x86.R_EBP);
3764 } else {
3765 M.x86.R_BP = dec_word(M.x86.R_BP);
3766 }
3767 DECODE_CLEAR_SEGOVR();
3768 END_OF_INSTR();
3769 }
3770
3771 /****************************************************************************
3772 REMARKS:
3773 Handles opcode 0x4e
3774 ****************************************************************************/
x86emuOp_dec_SI(u8 X86EMU_UNUSED (op1))3775 void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3776 {
3777 START_OF_INSTR();
3778 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3779 DECODE_PRINTF("DEC\tESI\n");
3780 } else {
3781 DECODE_PRINTF("DEC\tSI\n");
3782 }
3783 TRACE_AND_STEP();
3784 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3785 M.x86.R_ESI = dec_long(M.x86.R_ESI);
3786 } else {
3787 M.x86.R_SI = dec_word(M.x86.R_SI);
3788 }
3789 DECODE_CLEAR_SEGOVR();
3790 END_OF_INSTR();
3791 }
3792
3793 /****************************************************************************
3794 REMARKS:
3795 Handles opcode 0x4f
3796 ****************************************************************************/
x86emuOp_dec_DI(u8 X86EMU_UNUSED (op1))3797 void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3798 {
3799 START_OF_INSTR();
3800 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3801 DECODE_PRINTF("DEC\tEDI\n");
3802 } else {
3803 DECODE_PRINTF("DEC\tDI\n");
3804 }
3805 TRACE_AND_STEP();
3806 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3807 M.x86.R_EDI = dec_long(M.x86.R_EDI);
3808 } else {
3809 M.x86.R_DI = dec_word(M.x86.R_DI);
3810 }
3811 DECODE_CLEAR_SEGOVR();
3812 END_OF_INSTR();
3813 }
3814
3815 /****************************************************************************
3816 REMARKS:
3817 Handles opcode 0x50
3818 ****************************************************************************/
x86emuOp_push_AX(u8 X86EMU_UNUSED (op1))3819 void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3820 {
3821 START_OF_INSTR();
3822 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3823 DECODE_PRINTF("PUSH\tEAX\n");
3824 } else {
3825 DECODE_PRINTF("PUSH\tAX\n");
3826 }
3827 TRACE_AND_STEP();
3828 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3829 push_long(M.x86.R_EAX);
3830 } else {
3831 push_word(M.x86.R_AX);
3832 }
3833 DECODE_CLEAR_SEGOVR();
3834 END_OF_INSTR();
3835 }
3836
3837 /****************************************************************************
3838 REMARKS:
3839 Handles opcode 0x51
3840 ****************************************************************************/
x86emuOp_push_CX(u8 X86EMU_UNUSED (op1))3841 void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3842 {
3843 START_OF_INSTR();
3844 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3845 DECODE_PRINTF("PUSH\tECX\n");
3846 } else {
3847 DECODE_PRINTF("PUSH\tCX\n");
3848 }
3849 TRACE_AND_STEP();
3850 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3851 push_long(M.x86.R_ECX);
3852 } else {
3853 push_word(M.x86.R_CX);
3854 }
3855 DECODE_CLEAR_SEGOVR();
3856 END_OF_INSTR();
3857 }
3858
3859 /****************************************************************************
3860 REMARKS:
3861 Handles opcode 0x52
3862 ****************************************************************************/
x86emuOp_push_DX(u8 X86EMU_UNUSED (op1))3863 void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3864 {
3865 START_OF_INSTR();
3866 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867 DECODE_PRINTF("PUSH\tEDX\n");
3868 } else {
3869 DECODE_PRINTF("PUSH\tDX\n");
3870 }
3871 TRACE_AND_STEP();
3872 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3873 push_long(M.x86.R_EDX);
3874 } else {
3875 push_word(M.x86.R_DX);
3876 }
3877 DECODE_CLEAR_SEGOVR();
3878 END_OF_INSTR();
3879 }
3880
3881 /****************************************************************************
3882 REMARKS:
3883 Handles opcode 0x53
3884 ****************************************************************************/
x86emuOp_push_BX(u8 X86EMU_UNUSED (op1))3885 void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3886 {
3887 START_OF_INSTR();
3888 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3889 DECODE_PRINTF("PUSH\tEBX\n");
3890 } else {
3891 DECODE_PRINTF("PUSH\tBX\n");
3892 }
3893 TRACE_AND_STEP();
3894 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3895 push_long(M.x86.R_EBX);
3896 } else {
3897 push_word(M.x86.R_BX);
3898 }
3899 DECODE_CLEAR_SEGOVR();
3900 END_OF_INSTR();
3901 }
3902
3903 /****************************************************************************
3904 REMARKS:
3905 Handles opcode 0x54
3906 ****************************************************************************/
x86emuOp_push_SP(u8 X86EMU_UNUSED (op1))3907 void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3908 {
3909 START_OF_INSTR();
3910 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3911 DECODE_PRINTF("PUSH\tESP\n");
3912 } else {
3913 DECODE_PRINTF("PUSH\tSP\n");
3914 }
3915 TRACE_AND_STEP();
3916 /* Always push (E)SP, since we are emulating an i386 and above
3917 * processor. This is necessary as some BIOS'es use this to check
3918 * what type of processor is in the system.
3919 */
3920 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3921 push_long(M.x86.R_ESP);
3922 } else {
3923 push_word((u16)(M.x86.R_SP));
3924 }
3925 DECODE_CLEAR_SEGOVR();
3926 END_OF_INSTR();
3927 }
3928
3929 /****************************************************************************
3930 REMARKS:
3931 Handles opcode 0x55
3932 ****************************************************************************/
x86emuOp_push_BP(u8 X86EMU_UNUSED (op1))3933 void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3934 {
3935 START_OF_INSTR();
3936 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3937 DECODE_PRINTF("PUSH\tEBP\n");
3938 } else {
3939 DECODE_PRINTF("PUSH\tBP\n");
3940 }
3941 TRACE_AND_STEP();
3942 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3943 push_long(M.x86.R_EBP);
3944 } else {
3945 push_word(M.x86.R_BP);
3946 }
3947 DECODE_CLEAR_SEGOVR();
3948 END_OF_INSTR();
3949 }
3950
3951 /****************************************************************************
3952 REMARKS:
3953 Handles opcode 0x56
3954 ****************************************************************************/
x86emuOp_push_SI(u8 X86EMU_UNUSED (op1))3955 void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3956 {
3957 START_OF_INSTR();
3958 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3959 DECODE_PRINTF("PUSH\tESI\n");
3960 } else {
3961 DECODE_PRINTF("PUSH\tSI\n");
3962 }
3963 TRACE_AND_STEP();
3964 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3965 push_long(M.x86.R_ESI);
3966 } else {
3967 push_word(M.x86.R_SI);
3968 }
3969 DECODE_CLEAR_SEGOVR();
3970 END_OF_INSTR();
3971 }
3972
3973 /****************************************************************************
3974 REMARKS:
3975 Handles opcode 0x57
3976 ****************************************************************************/
x86emuOp_push_DI(u8 X86EMU_UNUSED (op1))3977 void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3978 {
3979 START_OF_INSTR();
3980 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3981 DECODE_PRINTF("PUSH\tEDI\n");
3982 } else {
3983 DECODE_PRINTF("PUSH\tDI\n");
3984 }
3985 TRACE_AND_STEP();
3986 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3987 push_long(M.x86.R_EDI);
3988 } else {
3989 push_word(M.x86.R_DI);
3990 }
3991 DECODE_CLEAR_SEGOVR();
3992 END_OF_INSTR();
3993 }
3994
3995 /****************************************************************************
3996 REMARKS:
3997 Handles opcode 0x58
3998 ****************************************************************************/
x86emuOp_pop_AX(u8 X86EMU_UNUSED (op1))3999 void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4000 {
4001 START_OF_INSTR();
4002 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4003 DECODE_PRINTF("POP\tEAX\n");
4004 } else {
4005 DECODE_PRINTF("POP\tAX\n");
4006 }
4007 TRACE_AND_STEP();
4008 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4009 M.x86.R_EAX = pop_long();
4010 } else {
4011 M.x86.R_AX = pop_word();
4012 }
4013 DECODE_CLEAR_SEGOVR();
4014 END_OF_INSTR();
4015 }
4016
4017 /****************************************************************************
4018 REMARKS:
4019 Handles opcode 0x59
4020 ****************************************************************************/
x86emuOp_pop_CX(u8 X86EMU_UNUSED (op1))4021 void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4022 {
4023 START_OF_INSTR();
4024 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4025 DECODE_PRINTF("POP\tECX\n");
4026 } else {
4027 DECODE_PRINTF("POP\tCX\n");
4028 }
4029 TRACE_AND_STEP();
4030 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4031 M.x86.R_ECX = pop_long();
4032 } else {
4033 M.x86.R_CX = pop_word();
4034 }
4035 DECODE_CLEAR_SEGOVR();
4036 END_OF_INSTR();
4037 }
4038
4039 /****************************************************************************
4040 REMARKS:
4041 Handles opcode 0x5a
4042 ****************************************************************************/
x86emuOp_pop_DX(u8 X86EMU_UNUSED (op1))4043 void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4044 {
4045 START_OF_INSTR();
4046 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4047 DECODE_PRINTF("POP\tEDX\n");
4048 } else {
4049 DECODE_PRINTF("POP\tDX\n");
4050 }
4051 TRACE_AND_STEP();
4052 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4053 M.x86.R_EDX = pop_long();
4054 } else {
4055 M.x86.R_DX = pop_word();
4056 }
4057 DECODE_CLEAR_SEGOVR();
4058 END_OF_INSTR();
4059 }
4060
4061 /****************************************************************************
4062 REMARKS:
4063 Handles opcode 0x5b
4064 ****************************************************************************/
x86emuOp_pop_BX(u8 X86EMU_UNUSED (op1))4065 void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4066 {
4067 START_OF_INSTR();
4068 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4069 DECODE_PRINTF("POP\tEBX\n");
4070 } else {
4071 DECODE_PRINTF("POP\tBX\n");
4072 }
4073 TRACE_AND_STEP();
4074 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4075 M.x86.R_EBX = pop_long();
4076 } else {
4077 M.x86.R_BX = pop_word();
4078 }
4079 DECODE_CLEAR_SEGOVR();
4080 END_OF_INSTR();
4081 }
4082
4083 /****************************************************************************
4084 REMARKS:
4085 Handles opcode 0x5c
4086 ****************************************************************************/
x86emuOp_pop_SP(u8 X86EMU_UNUSED (op1))4087 void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4088 {
4089 START_OF_INSTR();
4090 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4091 DECODE_PRINTF("POP\tESP\n");
4092 } else {
4093 DECODE_PRINTF("POP\tSP\n");
4094 }
4095 TRACE_AND_STEP();
4096 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4097 M.x86.R_ESP = pop_long();
4098 } else {
4099 M.x86.R_SP = pop_word();
4100 }
4101 DECODE_CLEAR_SEGOVR();
4102 END_OF_INSTR();
4103 }
4104
4105 /****************************************************************************
4106 REMARKS:
4107 Handles opcode 0x5d
4108 ****************************************************************************/
x86emuOp_pop_BP(u8 X86EMU_UNUSED (op1))4109 void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4110 {
4111 START_OF_INSTR();
4112 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4113 DECODE_PRINTF("POP\tEBP\n");
4114 } else {
4115 DECODE_PRINTF("POP\tBP\n");
4116 }
4117 TRACE_AND_STEP();
4118 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4119 M.x86.R_EBP = pop_long();
4120 } else {
4121 M.x86.R_BP = pop_word();
4122 }
4123 DECODE_CLEAR_SEGOVR();
4124 END_OF_INSTR();
4125 }
4126
4127 /****************************************************************************
4128 REMARKS:
4129 Handles opcode 0x5e
4130 ****************************************************************************/
x86emuOp_pop_SI(u8 X86EMU_UNUSED (op1))4131 void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4132 {
4133 START_OF_INSTR();
4134 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4135 DECODE_PRINTF("POP\tESI\n");
4136 } else {
4137 DECODE_PRINTF("POP\tSI\n");
4138 }
4139 TRACE_AND_STEP();
4140 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4141 M.x86.R_ESI = pop_long();
4142 } else {
4143 M.x86.R_SI = pop_word();
4144 }
4145 DECODE_CLEAR_SEGOVR();
4146 END_OF_INSTR();
4147 }
4148
4149 /****************************************************************************
4150 REMARKS:
4151 Handles opcode 0x5f
4152 ****************************************************************************/
x86emuOp_pop_DI(u8 X86EMU_UNUSED (op1))4153 void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4154 {
4155 START_OF_INSTR();
4156 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4157 DECODE_PRINTF("POP\tEDI\n");
4158 } else {
4159 DECODE_PRINTF("POP\tDI\n");
4160 }
4161 TRACE_AND_STEP();
4162 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4163 M.x86.R_EDI = pop_long();
4164 } else {
4165 M.x86.R_DI = pop_word();
4166 }
4167 DECODE_CLEAR_SEGOVR();
4168 END_OF_INSTR();
4169 }
4170
4171 /****************************************************************************
4172 REMARKS:
4173 Handles opcode 0x60
4174 ****************************************************************************/
x86emuOp_push_all(u8 X86EMU_UNUSED (op1))4175 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4176 {
4177 START_OF_INSTR();
4178 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4179 DECODE_PRINTF("PUSHAD\n");
4180 } else {
4181 DECODE_PRINTF("PUSHA\n");
4182 }
4183 TRACE_AND_STEP();
4184 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4185 u32 old_sp = M.x86.R_ESP;
4186
4187 push_long(M.x86.R_EAX);
4188 push_long(M.x86.R_ECX);
4189 push_long(M.x86.R_EDX);
4190 push_long(M.x86.R_EBX);
4191 push_long(old_sp);
4192 push_long(M.x86.R_EBP);
4193 push_long(M.x86.R_ESI);
4194 push_long(M.x86.R_EDI);
4195 } else {
4196 u16 old_sp = M.x86.R_SP;
4197
4198 push_word(M.x86.R_AX);
4199 push_word(M.x86.R_CX);
4200 push_word(M.x86.R_DX);
4201 push_word(M.x86.R_BX);
4202 push_word(old_sp);
4203 push_word(M.x86.R_BP);
4204 push_word(M.x86.R_SI);
4205 push_word(M.x86.R_DI);
4206 }
4207 DECODE_CLEAR_SEGOVR();
4208 END_OF_INSTR();
4209 }
4210
4211 /****************************************************************************
4212 REMARKS:
4213 Handles opcode 0x61
4214 ****************************************************************************/
x86emuOp_pop_all(u8 X86EMU_UNUSED (op1))4215 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4216 {
4217 START_OF_INSTR();
4218 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4219 DECODE_PRINTF("POPAD\n");
4220 } else {
4221 DECODE_PRINTF("POPA\n");
4222 }
4223 TRACE_AND_STEP();
4224 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4225 M.x86.R_EDI = pop_long();
4226 M.x86.R_ESI = pop_long();
4227 M.x86.R_EBP = pop_long();
4228 M.x86.R_ESP += 4; /* skip ESP */
4229 M.x86.R_EBX = pop_long();
4230 M.x86.R_EDX = pop_long();
4231 M.x86.R_ECX = pop_long();
4232 M.x86.R_EAX = pop_long();
4233 } else {
4234 M.x86.R_DI = pop_word();
4235 M.x86.R_SI = pop_word();
4236 M.x86.R_BP = pop_word();
4237 M.x86.R_SP += 2; /* skip SP */
4238 M.x86.R_BX = pop_word();
4239 M.x86.R_DX = pop_word();
4240 M.x86.R_CX = pop_word();
4241 M.x86.R_AX = pop_word();
4242 }
4243 DECODE_CLEAR_SEGOVR();
4244 END_OF_INSTR();
4245 }
4246
4247 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4248 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4249
4250 /****************************************************************************
4251 REMARKS:
4252 Handles opcode 0x64
4253 ****************************************************************************/
x86emuOp_segovr_FS(u8 X86EMU_UNUSED (op1))4254 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4255 {
4256 START_OF_INSTR();
4257 DECODE_PRINTF("FS:\n");
4258 TRACE_AND_STEP();
4259 M.x86.mode |= SYSMODE_SEGOVR_FS;
4260 /*
4261 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4262 * opcode subroutines we do not want to do this.
4263 */
4264 END_OF_INSTR();
4265 }
4266
4267 /****************************************************************************
4268 REMARKS:
4269 Handles opcode 0x65
4270 ****************************************************************************/
x86emuOp_segovr_GS(u8 X86EMU_UNUSED (op1))4271 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4272 {
4273 START_OF_INSTR();
4274 DECODE_PRINTF("GS:\n");
4275 TRACE_AND_STEP();
4276 M.x86.mode |= SYSMODE_SEGOVR_GS;
4277 /*
4278 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4279 * opcode subroutines we do not want to do this.
4280 */
4281 END_OF_INSTR();
4282 }
4283
4284 /****************************************************************************
4285 REMARKS:
4286 Handles opcode 0x66 - prefix for 32-bit register
4287 ****************************************************************************/
x86emuOp_prefix_data(u8 X86EMU_UNUSED (op1))4288 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4289 {
4290 START_OF_INSTR();
4291 DECODE_PRINTF("DATA:\n");
4292 TRACE_AND_STEP();
4293 M.x86.mode |= SYSMODE_PREFIX_DATA;
4294 /* note no DECODE_CLEAR_SEGOVR here. */
4295 END_OF_INSTR();
4296 }
4297
4298 /****************************************************************************
4299 REMARKS:
4300 Handles opcode 0x67 - prefix for 32-bit address
4301 ****************************************************************************/
x86emuOp_prefix_addr(u8 X86EMU_UNUSED (op1))4302 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4303 {
4304 START_OF_INSTR();
4305 DECODE_PRINTF("ADDR:\n");
4306 TRACE_AND_STEP();
4307 M.x86.mode |= SYSMODE_PREFIX_ADDR;
4308 /* note no DECODE_CLEAR_SEGOVR here. */
4309 END_OF_INSTR();
4310 }
4311
4312 /****************************************************************************
4313 REMARKS:
4314 Handles opcode 0x68
4315 ****************************************************************************/
x86emuOp_push_word_IMM(u8 X86EMU_UNUSED (op1))4316 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4317 {
4318 u32 imm;
4319
4320 START_OF_INSTR();
4321 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4322 imm = fetch_long_imm();
4323 } else {
4324 imm = fetch_word_imm();
4325 }
4326 DECODE_PRINTF2("PUSH\t%x\n", imm);
4327 TRACE_AND_STEP();
4328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4329 push_long(imm);
4330 } else {
4331 push_word((u16)imm);
4332 }
4333 DECODE_CLEAR_SEGOVR();
4334 END_OF_INSTR();
4335 }
4336
4337 /****************************************************************************
4338 REMARKS:
4339 Handles opcode 0x69
4340 ****************************************************************************/
x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED (op1))4341 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4342 {
4343 int mod, rl, rh;
4344 uint srcoffset;
4345
4346 START_OF_INSTR();
4347 DECODE_PRINTF("IMUL\t");
4348 FETCH_DECODE_MODRM(mod, rh, rl);
4349 switch (mod) {
4350 case 0:
4351 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4352 u32 *destreg;
4353 u32 srcval;
4354 u32 res_lo,res_hi;
4355 s32 imm;
4356
4357 destreg = DECODE_RM_LONG_REGISTER(rh);
4358 DECODE_PRINTF(",");
4359 srcoffset = decode_rm00_address(rl);
4360 srcval = fetch_data_long(srcoffset);
4361 imm = fetch_long_imm();
4362 DECODE_PRINTF2(",%d\n", (s32)imm);
4363 TRACE_AND_STEP();
4364 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4365 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4366 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4367 CLEAR_FLAG(F_CF);
4368 CLEAR_FLAG(F_OF);
4369 } else {
4370 SET_FLAG(F_CF);
4371 SET_FLAG(F_OF);
4372 }
4373 *destreg = (u32)res_lo;
4374 } else {
4375 u16 *destreg;
4376 u16 srcval;
4377 u32 res;
4378 s16 imm;
4379
4380 destreg = DECODE_RM_WORD_REGISTER(rh);
4381 DECODE_PRINTF(",");
4382 srcoffset = decode_rm00_address(rl);
4383 srcval = fetch_data_word(srcoffset);
4384 imm = fetch_word_imm();
4385 DECODE_PRINTF2(",%d\n", (s32)imm);
4386 TRACE_AND_STEP();
4387 res = (s16)srcval * (s16)imm;
4388 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4389 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4390 CLEAR_FLAG(F_CF);
4391 CLEAR_FLAG(F_OF);
4392 } else {
4393 SET_FLAG(F_CF);
4394 SET_FLAG(F_OF);
4395 }
4396 *destreg = (u16)res;
4397 }
4398 break;
4399 case 1:
4400 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4401 u32 *destreg;
4402 u32 srcval;
4403 u32 res_lo,res_hi;
4404 s32 imm;
4405
4406 destreg = DECODE_RM_LONG_REGISTER(rh);
4407 DECODE_PRINTF(",");
4408 srcoffset = decode_rm01_address(rl);
4409 srcval = fetch_data_long(srcoffset);
4410 imm = fetch_long_imm();
4411 DECODE_PRINTF2(",%d\n", (s32)imm);
4412 TRACE_AND_STEP();
4413 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4414 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4415 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4416 CLEAR_FLAG(F_CF);
4417 CLEAR_FLAG(F_OF);
4418 } else {
4419 SET_FLAG(F_CF);
4420 SET_FLAG(F_OF);
4421 }
4422 *destreg = (u32)res_lo;
4423 } else {
4424 u16 *destreg;
4425 u16 srcval;
4426 u32 res;
4427 s16 imm;
4428
4429 destreg = DECODE_RM_WORD_REGISTER(rh);
4430 DECODE_PRINTF(",");
4431 srcoffset = decode_rm01_address(rl);
4432 srcval = fetch_data_word(srcoffset);
4433 imm = fetch_word_imm();
4434 DECODE_PRINTF2(",%d\n", (s32)imm);
4435 TRACE_AND_STEP();
4436 res = (s16)srcval * (s16)imm;
4437 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4438 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4439 CLEAR_FLAG(F_CF);
4440 CLEAR_FLAG(F_OF);
4441 } else {
4442 SET_FLAG(F_CF);
4443 SET_FLAG(F_OF);
4444 }
4445 *destreg = (u16)res;
4446 }
4447 break;
4448 case 2:
4449 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4450 u32 *destreg;
4451 u32 srcval;
4452 u32 res_lo,res_hi;
4453 s32 imm;
4454
4455 destreg = DECODE_RM_LONG_REGISTER(rh);
4456 DECODE_PRINTF(",");
4457 srcoffset = decode_rm10_address(rl);
4458 srcval = fetch_data_long(srcoffset);
4459 imm = fetch_long_imm();
4460 DECODE_PRINTF2(",%d\n", (s32)imm);
4461 TRACE_AND_STEP();
4462 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4463 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4464 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4465 CLEAR_FLAG(F_CF);
4466 CLEAR_FLAG(F_OF);
4467 } else {
4468 SET_FLAG(F_CF);
4469 SET_FLAG(F_OF);
4470 }
4471 *destreg = (u32)res_lo;
4472 } else {
4473 u16 *destreg;
4474 u16 srcval;
4475 u32 res;
4476 s16 imm;
4477
4478 destreg = DECODE_RM_WORD_REGISTER(rh);
4479 DECODE_PRINTF(",");
4480 srcoffset = decode_rm10_address(rl);
4481 srcval = fetch_data_word(srcoffset);
4482 imm = fetch_word_imm();
4483 DECODE_PRINTF2(",%d\n", (s32)imm);
4484 TRACE_AND_STEP();
4485 res = (s16)srcval * (s16)imm;
4486 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4487 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4488 CLEAR_FLAG(F_CF);
4489 CLEAR_FLAG(F_OF);
4490 } else {
4491 SET_FLAG(F_CF);
4492 SET_FLAG(F_OF);
4493 }
4494 *destreg = (u16)res;
4495 }
4496 break;
4497 case 3: /* register to register */
4498 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4499 u32 *destreg,*srcreg;
4500 u32 res_lo,res_hi;
4501 s32 imm;
4502
4503 destreg = DECODE_RM_LONG_REGISTER(rh);
4504 DECODE_PRINTF(",");
4505 srcreg = DECODE_RM_LONG_REGISTER(rl);
4506 imm = fetch_long_imm();
4507 DECODE_PRINTF2(",%d\n", (s32)imm);
4508 TRACE_AND_STEP();
4509 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4510 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4511 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4512 CLEAR_FLAG(F_CF);
4513 CLEAR_FLAG(F_OF);
4514 } else {
4515 SET_FLAG(F_CF);
4516 SET_FLAG(F_OF);
4517 }
4518 *destreg = (u32)res_lo;
4519 } else {
4520 u16 *destreg,*srcreg;
4521 u32 res;
4522 s16 imm;
4523
4524 destreg = DECODE_RM_WORD_REGISTER(rh);
4525 DECODE_PRINTF(",");
4526 srcreg = DECODE_RM_WORD_REGISTER(rl);
4527 imm = fetch_word_imm();
4528 DECODE_PRINTF2(",%d\n", (s32)imm);
4529 TRACE_AND_STEP();
4530 res = (s16)*srcreg * (s16)imm;
4531 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4532 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4533 CLEAR_FLAG(F_CF);
4534 CLEAR_FLAG(F_OF);
4535 } else {
4536 SET_FLAG(F_CF);
4537 SET_FLAG(F_OF);
4538 }
4539 *destreg = (u16)res;
4540 }
4541 break;
4542 }
4543 DECODE_CLEAR_SEGOVR();
4544 END_OF_INSTR();
4545 }
4546
4547 /****************************************************************************
4548 REMARKS:
4549 Handles opcode 0x6a
4550 ****************************************************************************/
x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED (op1))4551 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4552 {
4553 s16 imm;
4554
4555 START_OF_INSTR();
4556 imm = (s8)fetch_byte_imm();
4557 DECODE_PRINTF2("PUSH\t%d\n", imm);
4558 TRACE_AND_STEP();
4559 push_word(imm);
4560 DECODE_CLEAR_SEGOVR();
4561 END_OF_INSTR();
4562 }
4563
4564 /****************************************************************************
4565 REMARKS:
4566 Handles opcode 0x6b
4567 ****************************************************************************/
x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED (op1))4568 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4569 {
4570 int mod, rl, rh;
4571 uint srcoffset;
4572 s8 imm;
4573
4574 START_OF_INSTR();
4575 DECODE_PRINTF("IMUL\t");
4576 FETCH_DECODE_MODRM(mod, rh, rl);
4577 switch (mod) {
4578 case 0:
4579 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4580 u32 *destreg;
4581 u32 srcval;
4582 u32 res_lo,res_hi;
4583
4584 destreg = DECODE_RM_LONG_REGISTER(rh);
4585 DECODE_PRINTF(",");
4586 srcoffset = decode_rm00_address(rl);
4587 srcval = fetch_data_long(srcoffset);
4588 imm = fetch_byte_imm();
4589 DECODE_PRINTF2(",%d\n", (s32)imm);
4590 TRACE_AND_STEP();
4591 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4592 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4593 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4594 CLEAR_FLAG(F_CF);
4595 CLEAR_FLAG(F_OF);
4596 } else {
4597 SET_FLAG(F_CF);
4598 SET_FLAG(F_OF);
4599 }
4600 *destreg = (u32)res_lo;
4601 } else {
4602 u16 *destreg;
4603 u16 srcval;
4604 u32 res;
4605
4606 destreg = DECODE_RM_WORD_REGISTER(rh);
4607 DECODE_PRINTF(",");
4608 srcoffset = decode_rm00_address(rl);
4609 srcval = fetch_data_word(srcoffset);
4610 imm = fetch_byte_imm();
4611 DECODE_PRINTF2(",%d\n", (s32)imm);
4612 TRACE_AND_STEP();
4613 res = (s16)srcval * (s16)imm;
4614 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4615 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4616 CLEAR_FLAG(F_CF);
4617 CLEAR_FLAG(F_OF);
4618 } else {
4619 SET_FLAG(F_CF);
4620 SET_FLAG(F_OF);
4621 }
4622 *destreg = (u16)res;
4623 }
4624 break;
4625 case 1:
4626 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4627 u32 *destreg;
4628 u32 srcval;
4629 u32 res_lo,res_hi;
4630
4631 destreg = DECODE_RM_LONG_REGISTER(rh);
4632 DECODE_PRINTF(",");
4633 srcoffset = decode_rm01_address(rl);
4634 srcval = fetch_data_long(srcoffset);
4635 imm = fetch_byte_imm();
4636 DECODE_PRINTF2(",%d\n", (s32)imm);
4637 TRACE_AND_STEP();
4638 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4639 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4640 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4641 CLEAR_FLAG(F_CF);
4642 CLEAR_FLAG(F_OF);
4643 } else {
4644 SET_FLAG(F_CF);
4645 SET_FLAG(F_OF);
4646 }
4647 *destreg = (u32)res_lo;
4648 } else {
4649 u16 *destreg;
4650 u16 srcval;
4651 u32 res;
4652
4653 destreg = DECODE_RM_WORD_REGISTER(rh);
4654 DECODE_PRINTF(",");
4655 srcoffset = decode_rm01_address(rl);
4656 srcval = fetch_data_word(srcoffset);
4657 imm = fetch_byte_imm();
4658 DECODE_PRINTF2(",%d\n", (s32)imm);
4659 TRACE_AND_STEP();
4660 res = (s16)srcval * (s16)imm;
4661 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4662 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4663 CLEAR_FLAG(F_CF);
4664 CLEAR_FLAG(F_OF);
4665 } else {
4666 SET_FLAG(F_CF);
4667 SET_FLAG(F_OF);
4668 }
4669 *destreg = (u16)res;
4670 }
4671 break;
4672 case 2:
4673 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4674 u32 *destreg;
4675 u32 srcval;
4676 u32 res_lo,res_hi;
4677
4678 destreg = DECODE_RM_LONG_REGISTER(rh);
4679 DECODE_PRINTF(",");
4680 srcoffset = decode_rm10_address(rl);
4681 srcval = fetch_data_long(srcoffset);
4682 imm = fetch_byte_imm();
4683 DECODE_PRINTF2(",%d\n", (s32)imm);
4684 TRACE_AND_STEP();
4685 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4686 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4687 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4688 CLEAR_FLAG(F_CF);
4689 CLEAR_FLAG(F_OF);
4690 } else {
4691 SET_FLAG(F_CF);
4692 SET_FLAG(F_OF);
4693 }
4694 *destreg = (u32)res_lo;
4695 } else {
4696 u16 *destreg;
4697 u16 srcval;
4698 u32 res;
4699
4700 destreg = DECODE_RM_WORD_REGISTER(rh);
4701 DECODE_PRINTF(",");
4702 srcoffset = decode_rm10_address(rl);
4703 srcval = fetch_data_word(srcoffset);
4704 imm = fetch_byte_imm();
4705 DECODE_PRINTF2(",%d\n", (s32)imm);
4706 TRACE_AND_STEP();
4707 res = (s16)srcval * (s16)imm;
4708 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4709 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4710 CLEAR_FLAG(F_CF);
4711 CLEAR_FLAG(F_OF);
4712 } else {
4713 SET_FLAG(F_CF);
4714 SET_FLAG(F_OF);
4715 }
4716 *destreg = (u16)res;
4717 }
4718 break;
4719 case 3: /* register to register */
4720 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4721 u32 *destreg,*srcreg;
4722 u32 res_lo,res_hi;
4723
4724 destreg = DECODE_RM_LONG_REGISTER(rh);
4725 DECODE_PRINTF(",");
4726 srcreg = DECODE_RM_LONG_REGISTER(rl);
4727 imm = fetch_byte_imm();
4728 DECODE_PRINTF2(",%d\n", (s32)imm);
4729 TRACE_AND_STEP();
4730 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4731 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4732 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4733 CLEAR_FLAG(F_CF);
4734 CLEAR_FLAG(F_OF);
4735 } else {
4736 SET_FLAG(F_CF);
4737 SET_FLAG(F_OF);
4738 }
4739 *destreg = (u32)res_lo;
4740 } else {
4741 u16 *destreg,*srcreg;
4742 u32 res;
4743
4744 destreg = DECODE_RM_WORD_REGISTER(rh);
4745 DECODE_PRINTF(",");
4746 srcreg = DECODE_RM_WORD_REGISTER(rl);
4747 imm = fetch_byte_imm();
4748 DECODE_PRINTF2(",%d\n", (s32)imm);
4749 TRACE_AND_STEP();
4750 res = (s16)*srcreg * (s16)imm;
4751 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4752 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4753 CLEAR_FLAG(F_CF);
4754 CLEAR_FLAG(F_OF);
4755 } else {
4756 SET_FLAG(F_CF);
4757 SET_FLAG(F_OF);
4758 }
4759 *destreg = (u16)res;
4760 }
4761 break;
4762 }
4763 DECODE_CLEAR_SEGOVR();
4764 END_OF_INSTR();
4765 }
4766
4767 /****************************************************************************
4768 REMARKS:
4769 Handles opcode 0x6c
4770 ****************************************************************************/
x86emuOp_ins_byte(u8 X86EMU_UNUSED (op1))4771 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4772 {
4773 START_OF_INSTR();
4774 DECODE_PRINTF("INSB\n");
4775 ins(1);
4776 TRACE_AND_STEP();
4777 DECODE_CLEAR_SEGOVR();
4778 END_OF_INSTR();
4779 }
4780
4781 /****************************************************************************
4782 REMARKS:
4783 Handles opcode 0x6d
4784 ****************************************************************************/
x86emuOp_ins_word(u8 X86EMU_UNUSED (op1))4785 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4786 {
4787 START_OF_INSTR();
4788 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4789 DECODE_PRINTF("INSD\n");
4790 ins(4);
4791 } else {
4792 DECODE_PRINTF("INSW\n");
4793 ins(2);
4794 }
4795 TRACE_AND_STEP();
4796 DECODE_CLEAR_SEGOVR();
4797 END_OF_INSTR();
4798 }
4799
4800 /****************************************************************************
4801 REMARKS:
4802 Handles opcode 0x6e
4803 ****************************************************************************/
x86emuOp_outs_byte(u8 X86EMU_UNUSED (op1))4804 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4805 {
4806 START_OF_INSTR();
4807 DECODE_PRINTF("OUTSB\n");
4808 outs(1);
4809 TRACE_AND_STEP();
4810 DECODE_CLEAR_SEGOVR();
4811 END_OF_INSTR();
4812 }
4813
4814 /****************************************************************************
4815 REMARKS:
4816 Handles opcode 0x6f
4817 ****************************************************************************/
x86emuOp_outs_word(u8 X86EMU_UNUSED (op1))4818 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4819 {
4820 START_OF_INSTR();
4821 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822 DECODE_PRINTF("OUTSD\n");
4823 outs(4);
4824 } else {
4825 DECODE_PRINTF("OUTSW\n");
4826 outs(2);
4827 }
4828 TRACE_AND_STEP();
4829 DECODE_CLEAR_SEGOVR();
4830 END_OF_INSTR();
4831 }
4832
4833 /****************************************************************************
4834 REMARKS:
4835 Handles opcode 0x70
4836 ****************************************************************************/
x86emuOp_jump_near_O(u8 X86EMU_UNUSED (op1))4837 void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4838 {
4839 s8 offset;
4840 u16 target;
4841
4842 /* jump to byte offset if overflow flag is set */
4843 START_OF_INSTR();
4844 DECODE_PRINTF("JO\t");
4845 offset = (s8)fetch_byte_imm();
4846 target = (u16)(M.x86.R_IP + (s16)offset);
4847 DECODE_PRINTF2("%x\n", target);
4848 TRACE_AND_STEP();
4849 if (ACCESS_FLAG(F_OF))
4850 M.x86.R_IP = target;
4851 DECODE_CLEAR_SEGOVR();
4852 END_OF_INSTR();
4853 }
4854
4855 /****************************************************************************
4856 REMARKS:
4857 Handles opcode 0x71
4858 ****************************************************************************/
x86emuOp_jump_near_NO(u8 X86EMU_UNUSED (op1))4859 void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4860 {
4861 s8 offset;
4862 u16 target;
4863
4864 /* jump to byte offset if overflow is not set */
4865 START_OF_INSTR();
4866 DECODE_PRINTF("JNO\t");
4867 offset = (s8)fetch_byte_imm();
4868 target = (u16)(M.x86.R_IP + (s16)offset);
4869 DECODE_PRINTF2("%x\n", target);
4870 TRACE_AND_STEP();
4871 if (!ACCESS_FLAG(F_OF))
4872 M.x86.R_IP = target;
4873 DECODE_CLEAR_SEGOVR();
4874 END_OF_INSTR();
4875 }
4876
4877 /****************************************************************************
4878 REMARKS:
4879 Handles opcode 0x72
4880 ****************************************************************************/
x86emuOp_jump_near_B(u8 X86EMU_UNUSED (op1))4881 void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4882 {
4883 s8 offset;
4884 u16 target;
4885
4886 /* jump to byte offset if carry flag is set. */
4887 START_OF_INSTR();
4888 DECODE_PRINTF("JB\t");
4889 offset = (s8)fetch_byte_imm();
4890 target = (u16)(M.x86.R_IP + (s16)offset);
4891 DECODE_PRINTF2("%x\n", target);
4892 TRACE_AND_STEP();
4893 if (ACCESS_FLAG(F_CF))
4894 M.x86.R_IP = target;
4895 DECODE_CLEAR_SEGOVR();
4896 END_OF_INSTR();
4897 }
4898
4899 /****************************************************************************
4900 REMARKS:
4901 Handles opcode 0x73
4902 ****************************************************************************/
x86emuOp_jump_near_NB(u8 X86EMU_UNUSED (op1))4903 void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4904 {
4905 s8 offset;
4906 u16 target;
4907
4908 /* jump to byte offset if carry flag is clear. */
4909 START_OF_INSTR();
4910 DECODE_PRINTF("JNB\t");
4911 offset = (s8)fetch_byte_imm();
4912 target = (u16)(M.x86.R_IP + (s16)offset);
4913 DECODE_PRINTF2("%x\n", target);
4914 TRACE_AND_STEP();
4915 if (!ACCESS_FLAG(F_CF))
4916 M.x86.R_IP = target;
4917 DECODE_CLEAR_SEGOVR();
4918 END_OF_INSTR();
4919 }
4920
4921 /****************************************************************************
4922 REMARKS:
4923 Handles opcode 0x74
4924 ****************************************************************************/
x86emuOp_jump_near_Z(u8 X86EMU_UNUSED (op1))4925 void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4926 {
4927 s8 offset;
4928 u16 target;
4929
4930 /* jump to byte offset if zero flag is set. */
4931 START_OF_INSTR();
4932 DECODE_PRINTF("JZ\t");
4933 offset = (s8)fetch_byte_imm();
4934 target = (u16)(M.x86.R_IP + (s16)offset);
4935 DECODE_PRINTF2("%x\n", target);
4936 TRACE_AND_STEP();
4937 if (ACCESS_FLAG(F_ZF))
4938 M.x86.R_IP = target;
4939 DECODE_CLEAR_SEGOVR();
4940 END_OF_INSTR();
4941 }
4942
4943 /****************************************************************************
4944 REMARKS:
4945 Handles opcode 0x75
4946 ****************************************************************************/
x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED (op1))4947 void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4948 {
4949 s8 offset;
4950 u16 target;
4951
4952 /* jump to byte offset if zero flag is clear. */
4953 START_OF_INSTR();
4954 DECODE_PRINTF("JNZ\t");
4955 offset = (s8)fetch_byte_imm();
4956 target = (u16)(M.x86.R_IP + (s16)offset);
4957 DECODE_PRINTF2("%x\n", target);
4958 TRACE_AND_STEP();
4959 if (!ACCESS_FLAG(F_ZF))
4960 M.x86.R_IP = target;
4961 DECODE_CLEAR_SEGOVR();
4962 END_OF_INSTR();
4963 }
4964
4965 /****************************************************************************
4966 REMARKS:
4967 Handles opcode 0x76
4968 ****************************************************************************/
x86emuOp_jump_near_BE(u8 X86EMU_UNUSED (op1))4969 void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4970 {
4971 s8 offset;
4972 u16 target;
4973
4974 /* jump to byte offset if carry flag is set or if the zero
4975 flag is set. */
4976 START_OF_INSTR();
4977 DECODE_PRINTF("JBE\t");
4978 offset = (s8)fetch_byte_imm();
4979 target = (u16)(M.x86.R_IP + (s16)offset);
4980 DECODE_PRINTF2("%x\n", target);
4981 TRACE_AND_STEP();
4982 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4983 M.x86.R_IP = target;
4984 DECODE_CLEAR_SEGOVR();
4985 END_OF_INSTR();
4986 }
4987
4988 /****************************************************************************
4989 REMARKS:
4990 Handles opcode 0x77
4991 ****************************************************************************/
x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED (op1))4992 void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4993 {
4994 s8 offset;
4995 u16 target;
4996
4997 /* jump to byte offset if carry flag is clear and if the zero
4998 flag is clear */
4999 START_OF_INSTR();
5000 DECODE_PRINTF("JNBE\t");
5001 offset = (s8)fetch_byte_imm();
5002 target = (u16)(M.x86.R_IP + (s16)offset);
5003 DECODE_PRINTF2("%x\n", target);
5004 TRACE_AND_STEP();
5005 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5006 M.x86.R_IP = target;
5007 DECODE_CLEAR_SEGOVR();
5008 END_OF_INSTR();
5009 }
5010
5011 /****************************************************************************
5012 REMARKS:
5013 Handles opcode 0x78
5014 ****************************************************************************/
x86emuOp_jump_near_S(u8 X86EMU_UNUSED (op1))5015 void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5016 {
5017 s8 offset;
5018 u16 target;
5019
5020 /* jump to byte offset if sign flag is set */
5021 START_OF_INSTR();
5022 DECODE_PRINTF("JS\t");
5023 offset = (s8)fetch_byte_imm();
5024 target = (u16)(M.x86.R_IP + (s16)offset);
5025 DECODE_PRINTF2("%x\n", target);
5026 TRACE_AND_STEP();
5027 if (ACCESS_FLAG(F_SF))
5028 M.x86.R_IP = target;
5029 DECODE_CLEAR_SEGOVR();
5030 END_OF_INSTR();
5031 }
5032
5033 /****************************************************************************
5034 REMARKS:
5035 Handles opcode 0x79
5036 ****************************************************************************/
x86emuOp_jump_near_NS(u8 X86EMU_UNUSED (op1))5037 void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5038 {
5039 s8 offset;
5040 u16 target;
5041
5042 /* jump to byte offset if sign flag is clear */
5043 START_OF_INSTR();
5044 DECODE_PRINTF("JNS\t");
5045 offset = (s8)fetch_byte_imm();
5046 target = (u16)(M.x86.R_IP + (s16)offset);
5047 DECODE_PRINTF2("%x\n", target);
5048 TRACE_AND_STEP();
5049 if (!ACCESS_FLAG(F_SF))
5050 M.x86.R_IP = target;
5051 DECODE_CLEAR_SEGOVR();
5052 END_OF_INSTR();
5053 }
5054
5055 /****************************************************************************
5056 REMARKS:
5057 Handles opcode 0x7a
5058 ****************************************************************************/
x86emuOp_jump_near_P(u8 X86EMU_UNUSED (op1))5059 void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5060 {
5061 s8 offset;
5062 u16 target;
5063
5064 /* jump to byte offset if parity flag is set (even parity) */
5065 START_OF_INSTR();
5066 DECODE_PRINTF("JP\t");
5067 offset = (s8)fetch_byte_imm();
5068 target = (u16)(M.x86.R_IP + (s16)offset);
5069 DECODE_PRINTF2("%x\n", target);
5070 TRACE_AND_STEP();
5071 if (ACCESS_FLAG(F_PF))
5072 M.x86.R_IP = target;
5073 DECODE_CLEAR_SEGOVR();
5074 END_OF_INSTR();
5075 }
5076
5077 /****************************************************************************
5078 REMARKS:
5079 Handles opcode 0x7b
5080 ****************************************************************************/
x86emuOp_jump_near_NP(u8 X86EMU_UNUSED (op1))5081 void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5082 {
5083 s8 offset;
5084 u16 target;
5085
5086 /* jump to byte offset if parity flag is clear (odd parity) */
5087 START_OF_INSTR();
5088 DECODE_PRINTF("JNP\t");
5089 offset = (s8)fetch_byte_imm();
5090 target = (u16)(M.x86.R_IP + (s16)offset);
5091 DECODE_PRINTF2("%x\n", target);
5092 TRACE_AND_STEP();
5093 if (!ACCESS_FLAG(F_PF))
5094 M.x86.R_IP = target;
5095 DECODE_CLEAR_SEGOVR();
5096 END_OF_INSTR();
5097 }
5098
5099 /****************************************************************************
5100 REMARKS:
5101 Handles opcode 0x7c
5102 ****************************************************************************/
x86emuOp_jump_near_L(u8 X86EMU_UNUSED (op1))5103 void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5104 {
5105 s8 offset;
5106 u16 target;
5107 int sf, of;
5108
5109 /* jump to byte offset if sign flag not equal to overflow flag. */
5110 START_OF_INSTR();
5111 DECODE_PRINTF("JL\t");
5112 offset = (s8)fetch_byte_imm();
5113 target = (u16)(M.x86.R_IP + (s16)offset);
5114 DECODE_PRINTF2("%x\n", target);
5115 TRACE_AND_STEP();
5116 sf = ACCESS_FLAG(F_SF) != 0;
5117 of = ACCESS_FLAG(F_OF) != 0;
5118 if (sf ^ of)
5119 M.x86.R_IP = target;
5120 DECODE_CLEAR_SEGOVR();
5121 END_OF_INSTR();
5122 }
5123
5124 /****************************************************************************
5125 REMARKS:
5126 Handles opcode 0x7d
5127 ****************************************************************************/
x86emuOp_jump_near_NL(u8 X86EMU_UNUSED (op1))5128 void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5129 {
5130 s8 offset;
5131 u16 target;
5132 int sf, of;
5133
5134 /* jump to byte offset if sign flag not equal to overflow flag. */
5135 START_OF_INSTR();
5136 DECODE_PRINTF("JNL\t");
5137 offset = (s8)fetch_byte_imm();
5138 target = (u16)(M.x86.R_IP + (s16)offset);
5139 DECODE_PRINTF2("%x\n", target);
5140 TRACE_AND_STEP();
5141 sf = ACCESS_FLAG(F_SF) != 0;
5142 of = ACCESS_FLAG(F_OF) != 0;
5143 /* note: inverse of above, but using == instead of xor. */
5144 if (sf == of)
5145 M.x86.R_IP = target;
5146 DECODE_CLEAR_SEGOVR();
5147 END_OF_INSTR();
5148 }
5149
5150 /****************************************************************************
5151 REMARKS:
5152 Handles opcode 0x7e
5153 ****************************************************************************/
x86emuOp_jump_near_LE(u8 X86EMU_UNUSED (op1))5154 void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5155 {
5156 s8 offset;
5157 u16 target;
5158 int sf, of;
5159
5160 /* jump to byte offset if sign flag not equal to overflow flag
5161 or the zero flag is set */
5162 START_OF_INSTR();
5163 DECODE_PRINTF("JLE\t");
5164 offset = (s8)fetch_byte_imm();
5165 target = (u16)(M.x86.R_IP + (s16)offset);
5166 DECODE_PRINTF2("%x\n", target);
5167 TRACE_AND_STEP();
5168 sf = ACCESS_FLAG(F_SF) != 0;
5169 of = ACCESS_FLAG(F_OF) != 0;
5170 if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5171 M.x86.R_IP = target;
5172 DECODE_CLEAR_SEGOVR();
5173 END_OF_INSTR();
5174 }
5175
5176 /****************************************************************************
5177 REMARKS:
5178 Handles opcode 0x7f
5179 ****************************************************************************/
x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED (op1))5180 void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5181 {
5182 s8 offset;
5183 u16 target;
5184 int sf, of;
5185
5186 /* jump to byte offset if sign flag equal to overflow flag.
5187 and the zero flag is clear */
5188 START_OF_INSTR();
5189 DECODE_PRINTF("JNLE\t");
5190 offset = (s8)fetch_byte_imm();
5191 target = (u16)(M.x86.R_IP + (s16)offset);
5192 DECODE_PRINTF2("%x\n", target);
5193 TRACE_AND_STEP();
5194 sf = ACCESS_FLAG(F_SF) != 0;
5195 of = ACCESS_FLAG(F_OF) != 0;
5196 if ((sf == of) && !ACCESS_FLAG(F_ZF))
5197 M.x86.R_IP = target;
5198 DECODE_CLEAR_SEGOVR();
5199 END_OF_INSTR();
5200 }
5201
5202 static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5203 {
5204 add_byte, /* 00 */
5205 or_byte, /* 01 */
5206 adc_byte, /* 02 */
5207 sbb_byte, /* 03 */
5208 and_byte, /* 04 */
5209 sub_byte, /* 05 */
5210 xor_byte, /* 06 */
5211 cmp_byte, /* 07 */
5212 };
5213
5214 /****************************************************************************
5215 REMARKS:
5216 Handles opcode 0x80
5217 ****************************************************************************/
x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5218 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5219 {
5220 int mod, rl, rh;
5221 u8 *destreg;
5222 uint destoffset;
5223 u8 imm;
5224 u8 destval;
5225
5226 /*
5227 * Weirdo special case instruction format. Part of the opcode
5228 * held below in "RH". Doubly nested case would result, except
5229 * that the decoded instruction
5230 */
5231 START_OF_INSTR();
5232 FETCH_DECODE_MODRM(mod, rh, rl);
5233 #ifdef DEBUG
5234 if (DEBUG_DECODE()) {
5235 /* XXX DECODE_PRINTF may be changed to something more
5236 general, so that it is important to leave the strings
5237 in the same format, even though the result is that the
5238 above test is done twice. */
5239
5240 switch (rh) {
5241 case 0:
5242 DECODE_PRINTF("ADD\t");
5243 break;
5244 case 1:
5245 DECODE_PRINTF("OR\t");
5246 break;
5247 case 2:
5248 DECODE_PRINTF("ADC\t");
5249 break;
5250 case 3:
5251 DECODE_PRINTF("SBB\t");
5252 break;
5253 case 4:
5254 DECODE_PRINTF("AND\t");
5255 break;
5256 case 5:
5257 DECODE_PRINTF("SUB\t");
5258 break;
5259 case 6:
5260 DECODE_PRINTF("XOR\t");
5261 break;
5262 case 7:
5263 DECODE_PRINTF("CMP\t");
5264 break;
5265 }
5266 }
5267 #endif
5268 /* know operation, decode the mod byte to find the addressing
5269 mode. */
5270 switch (mod) {
5271 case 0:
5272 DECODE_PRINTF("BYTE PTR ");
5273 destoffset = decode_rm00_address(rl);
5274 DECODE_PRINTF(",");
5275 destval = fetch_data_byte(destoffset);
5276 imm = fetch_byte_imm();
5277 DECODE_PRINTF2("%x\n", imm);
5278 TRACE_AND_STEP();
5279 destval = (*opc80_byte_operation[rh]) (destval, imm);
5280 if (rh != 7)
5281 store_data_byte(destoffset, destval);
5282 break;
5283 case 1:
5284 DECODE_PRINTF("BYTE PTR ");
5285 destoffset = decode_rm01_address(rl);
5286 DECODE_PRINTF(",");
5287 destval = fetch_data_byte(destoffset);
5288 imm = fetch_byte_imm();
5289 DECODE_PRINTF2("%x\n", imm);
5290 TRACE_AND_STEP();
5291 destval = (*opc80_byte_operation[rh]) (destval, imm);
5292 if (rh != 7)
5293 store_data_byte(destoffset, destval);
5294 break;
5295 case 2:
5296 DECODE_PRINTF("BYTE PTR ");
5297 destoffset = decode_rm10_address(rl);
5298 DECODE_PRINTF(",");
5299 destval = fetch_data_byte(destoffset);
5300 imm = fetch_byte_imm();
5301 DECODE_PRINTF2("%x\n", imm);
5302 TRACE_AND_STEP();
5303 destval = (*opc80_byte_operation[rh]) (destval, imm);
5304 if (rh != 7)
5305 store_data_byte(destoffset, destval);
5306 break;
5307 case 3: /* register to register */
5308 destreg = DECODE_RM_BYTE_REGISTER(rl);
5309 DECODE_PRINTF(",");
5310 imm = fetch_byte_imm();
5311 DECODE_PRINTF2("%x\n", imm);
5312 TRACE_AND_STEP();
5313 destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5314 if (rh != 7)
5315 *destreg = destval;
5316 break;
5317 }
5318 DECODE_CLEAR_SEGOVR();
5319 END_OF_INSTR();
5320 }
5321
5322 static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5323 {
5324 add_word, /*00 */
5325 or_word, /*01 */
5326 adc_word, /*02 */
5327 sbb_word, /*03 */
5328 and_word, /*04 */
5329 sub_word, /*05 */
5330 xor_word, /*06 */
5331 cmp_word, /*07 */
5332 };
5333
5334 static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5335 {
5336 add_long, /*00 */
5337 or_long, /*01 */
5338 adc_long, /*02 */
5339 sbb_long, /*03 */
5340 and_long, /*04 */
5341 sub_long, /*05 */
5342 xor_long, /*06 */
5343 cmp_long, /*07 */
5344 };
5345
5346 /****************************************************************************
5347 REMARKS:
5348 Handles opcode 0x81
5349 ****************************************************************************/
x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED (op1))5350 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5351 {
5352 int mod, rl, rh;
5353 uint destoffset;
5354
5355 /*
5356 * Weirdo special case instruction format. Part of the opcode
5357 * held below in "RH". Doubly nested case would result, except
5358 * that the decoded instruction
5359 */
5360 START_OF_INSTR();
5361 FETCH_DECODE_MODRM(mod, rh, rl);
5362 #ifdef DEBUG
5363 if (DEBUG_DECODE()) {
5364 /* XXX DECODE_PRINTF may be changed to something more
5365 general, so that it is important to leave the strings
5366 in the same format, even though the result is that the
5367 above test is done twice. */
5368
5369 switch (rh) {
5370 case 0:
5371 DECODE_PRINTF("ADD\t");
5372 break;
5373 case 1:
5374 DECODE_PRINTF("OR\t");
5375 break;
5376 case 2:
5377 DECODE_PRINTF("ADC\t");
5378 break;
5379 case 3:
5380 DECODE_PRINTF("SBB\t");
5381 break;
5382 case 4:
5383 DECODE_PRINTF("AND\t");
5384 break;
5385 case 5:
5386 DECODE_PRINTF("SUB\t");
5387 break;
5388 case 6:
5389 DECODE_PRINTF("XOR\t");
5390 break;
5391 case 7:
5392 DECODE_PRINTF("CMP\t");
5393 break;
5394 }
5395 }
5396 #endif
5397 /*
5398 * Know operation, decode the mod byte to find the addressing
5399 * mode.
5400 */
5401 switch (mod) {
5402 case 0:
5403 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5404 u32 destval,imm;
5405
5406 DECODE_PRINTF("DWORD PTR ");
5407 destoffset = decode_rm00_address(rl);
5408 DECODE_PRINTF(",");
5409 destval = fetch_data_long(destoffset);
5410 imm = fetch_long_imm();
5411 DECODE_PRINTF2("%x\n", imm);
5412 TRACE_AND_STEP();
5413 destval = (*opc81_long_operation[rh]) (destval, imm);
5414 if (rh != 7)
5415 store_data_long(destoffset, destval);
5416 } else {
5417 u16 destval,imm;
5418
5419 DECODE_PRINTF("WORD PTR ");
5420 destoffset = decode_rm00_address(rl);
5421 DECODE_PRINTF(",");
5422 destval = fetch_data_word(destoffset);
5423 imm = fetch_word_imm();
5424 DECODE_PRINTF2("%x\n", imm);
5425 TRACE_AND_STEP();
5426 destval = (*opc81_word_operation[rh]) (destval, imm);
5427 if (rh != 7)
5428 store_data_word(destoffset, destval);
5429 }
5430 break;
5431 case 1:
5432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5433 u32 destval,imm;
5434
5435 DECODE_PRINTF("DWORD PTR ");
5436 destoffset = decode_rm01_address(rl);
5437 DECODE_PRINTF(",");
5438 destval = fetch_data_long(destoffset);
5439 imm = fetch_long_imm();
5440 DECODE_PRINTF2("%x\n", imm);
5441 TRACE_AND_STEP();
5442 destval = (*opc81_long_operation[rh]) (destval, imm);
5443 if (rh != 7)
5444 store_data_long(destoffset, destval);
5445 } else {
5446 u16 destval,imm;
5447
5448 DECODE_PRINTF("WORD PTR ");
5449 destoffset = decode_rm01_address(rl);
5450 DECODE_PRINTF(",");
5451 destval = fetch_data_word(destoffset);
5452 imm = fetch_word_imm();
5453 DECODE_PRINTF2("%x\n", imm);
5454 TRACE_AND_STEP();
5455 destval = (*opc81_word_operation[rh]) (destval, imm);
5456 if (rh != 7)
5457 store_data_word(destoffset, destval);
5458 }
5459 break;
5460 case 2:
5461 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5462 u32 destval,imm;
5463
5464 DECODE_PRINTF("DWORD PTR ");
5465 destoffset = decode_rm10_address(rl);
5466 DECODE_PRINTF(",");
5467 destval = fetch_data_long(destoffset);
5468 imm = fetch_long_imm();
5469 DECODE_PRINTF2("%x\n", imm);
5470 TRACE_AND_STEP();
5471 destval = (*opc81_long_operation[rh]) (destval, imm);
5472 if (rh != 7)
5473 store_data_long(destoffset, destval);
5474 } else {
5475 u16 destval,imm;
5476
5477 DECODE_PRINTF("WORD PTR ");
5478 destoffset = decode_rm10_address(rl);
5479 DECODE_PRINTF(",");
5480 destval = fetch_data_word(destoffset);
5481 imm = fetch_word_imm();
5482 DECODE_PRINTF2("%x\n", imm);
5483 TRACE_AND_STEP();
5484 destval = (*opc81_word_operation[rh]) (destval, imm);
5485 if (rh != 7)
5486 store_data_word(destoffset, destval);
5487 }
5488 break;
5489 case 3: /* register to register */
5490 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5491 u32 *destreg;
5492 u32 destval,imm;
5493
5494 destreg = DECODE_RM_LONG_REGISTER(rl);
5495 DECODE_PRINTF(",");
5496 imm = fetch_long_imm();
5497 DECODE_PRINTF2("%x\n", imm);
5498 TRACE_AND_STEP();
5499 destval = (*opc81_long_operation[rh]) (*destreg, imm);
5500 if (rh != 7)
5501 *destreg = destval;
5502 } else {
5503 u16 *destreg;
5504 u16 destval,imm;
5505
5506 destreg = DECODE_RM_WORD_REGISTER(rl);
5507 DECODE_PRINTF(",");
5508 imm = fetch_word_imm();
5509 DECODE_PRINTF2("%x\n", imm);
5510 TRACE_AND_STEP();
5511 destval = (*opc81_word_operation[rh]) (*destreg, imm);
5512 if (rh != 7)
5513 *destreg = destval;
5514 }
5515 break;
5516 }
5517 DECODE_CLEAR_SEGOVR();
5518 END_OF_INSTR();
5519 }
5520
5521 static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5522 {
5523 add_byte, /*00 */
5524 or_byte, /*01 *//*YYY UNUSED ???? */
5525 adc_byte, /*02 */
5526 sbb_byte, /*03 */
5527 and_byte, /*04 *//*YYY UNUSED ???? */
5528 sub_byte, /*05 */
5529 xor_byte, /*06 *//*YYY UNUSED ???? */
5530 cmp_byte, /*07 */
5531 };
5532
5533 /****************************************************************************
5534 REMARKS:
5535 Handles opcode 0x82
5536 ****************************************************************************/
x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5537 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5538 {
5539 int mod, rl, rh;
5540 u8 *destreg;
5541 uint destoffset;
5542 u8 imm;
5543 u8 destval;
5544
5545 /*
5546 * Weirdo special case instruction format. Part of the opcode
5547 * held below in "RH". Doubly nested case would result, except
5548 * that the decoded instruction Similar to opcode 81, except that
5549 * the immediate byte is sign extended to a word length.
5550 */
5551 START_OF_INSTR();
5552 FETCH_DECODE_MODRM(mod, rh, rl);
5553 #ifdef DEBUG
5554 if (DEBUG_DECODE()) {
5555 /* XXX DECODE_PRINTF may be changed to something more
5556 general, so that it is important to leave the strings
5557 in the same format, even though the result is that the
5558 above test is done twice. */
5559 switch (rh) {
5560 case 0:
5561 DECODE_PRINTF("ADD\t");
5562 break;
5563 case 1:
5564 DECODE_PRINTF("OR\t");
5565 break;
5566 case 2:
5567 DECODE_PRINTF("ADC\t");
5568 break;
5569 case 3:
5570 DECODE_PRINTF("SBB\t");
5571 break;
5572 case 4:
5573 DECODE_PRINTF("AND\t");
5574 break;
5575 case 5:
5576 DECODE_PRINTF("SUB\t");
5577 break;
5578 case 6:
5579 DECODE_PRINTF("XOR\t");
5580 break;
5581 case 7:
5582 DECODE_PRINTF("CMP\t");
5583 break;
5584 }
5585 }
5586 #endif
5587 /* know operation, decode the mod byte to find the addressing
5588 mode. */
5589 switch (mod) {
5590 case 0:
5591 DECODE_PRINTF("BYTE PTR ");
5592 destoffset = decode_rm00_address(rl);
5593 destval = fetch_data_byte(destoffset);
5594 imm = fetch_byte_imm();
5595 DECODE_PRINTF2(",%x\n", imm);
5596 TRACE_AND_STEP();
5597 destval = (*opc82_byte_operation[rh]) (destval, imm);
5598 if (rh != 7)
5599 store_data_byte(destoffset, destval);
5600 break;
5601 case 1:
5602 DECODE_PRINTF("BYTE PTR ");
5603 destoffset = decode_rm01_address(rl);
5604 destval = fetch_data_byte(destoffset);
5605 imm = fetch_byte_imm();
5606 DECODE_PRINTF2(",%x\n", imm);
5607 TRACE_AND_STEP();
5608 destval = (*opc82_byte_operation[rh]) (destval, imm);
5609 if (rh != 7)
5610 store_data_byte(destoffset, destval);
5611 break;
5612 case 2:
5613 DECODE_PRINTF("BYTE PTR ");
5614 destoffset = decode_rm10_address(rl);
5615 destval = fetch_data_byte(destoffset);
5616 imm = fetch_byte_imm();
5617 DECODE_PRINTF2(",%x\n", imm);
5618 TRACE_AND_STEP();
5619 destval = (*opc82_byte_operation[rh]) (destval, imm);
5620 if (rh != 7)
5621 store_data_byte(destoffset, destval);
5622 break;
5623 case 3: /* register to register */
5624 destreg = DECODE_RM_BYTE_REGISTER(rl);
5625 imm = fetch_byte_imm();
5626 DECODE_PRINTF2(",%x\n", imm);
5627 TRACE_AND_STEP();
5628 destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5629 if (rh != 7)
5630 *destreg = destval;
5631 break;
5632 }
5633 DECODE_CLEAR_SEGOVR();
5634 END_OF_INSTR();
5635 }
5636
5637 static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5638 {
5639 add_word, /*00 */
5640 or_word, /*01 *//*YYY UNUSED ???? */
5641 adc_word, /*02 */
5642 sbb_word, /*03 */
5643 and_word, /*04 *//*YYY UNUSED ???? */
5644 sub_word, /*05 */
5645 xor_word, /*06 *//*YYY UNUSED ???? */
5646 cmp_word, /*07 */
5647 };
5648
5649 static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5650 {
5651 add_long, /*00 */
5652 or_long, /*01 *//*YYY UNUSED ???? */
5653 adc_long, /*02 */
5654 sbb_long, /*03 */
5655 and_long, /*04 *//*YYY UNUSED ???? */
5656 sub_long, /*05 */
5657 xor_long, /*06 *//*YYY UNUSED ???? */
5658 cmp_long, /*07 */
5659 };
5660
5661 /****************************************************************************
5662 REMARKS:
5663 Handles opcode 0x83
5664 ****************************************************************************/
x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED (op1))5665 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5666 {
5667 int mod, rl, rh;
5668 uint destoffset;
5669
5670 /*
5671 * Weirdo special case instruction format. Part of the opcode
5672 * held below in "RH". Doubly nested case would result, except
5673 * that the decoded instruction Similar to opcode 81, except that
5674 * the immediate byte is sign extended to a word length.
5675 */
5676 START_OF_INSTR();
5677 FETCH_DECODE_MODRM(mod, rh, rl);
5678 #ifdef DEBUG
5679 if (DEBUG_DECODE()) {
5680 /* XXX DECODE_PRINTF may be changed to something more
5681 general, so that it is important to leave the strings
5682 in the same format, even though the result is that the
5683 above test is done twice. */
5684 switch (rh) {
5685 case 0:
5686 DECODE_PRINTF("ADD\t");
5687 break;
5688 case 1:
5689 DECODE_PRINTF("OR\t");
5690 break;
5691 case 2:
5692 DECODE_PRINTF("ADC\t");
5693 break;
5694 case 3:
5695 DECODE_PRINTF("SBB\t");
5696 break;
5697 case 4:
5698 DECODE_PRINTF("AND\t");
5699 break;
5700 case 5:
5701 DECODE_PRINTF("SUB\t");
5702 break;
5703 case 6:
5704 DECODE_PRINTF("XOR\t");
5705 break;
5706 case 7:
5707 DECODE_PRINTF("CMP\t");
5708 break;
5709 }
5710 }
5711 #endif
5712 /* know operation, decode the mod byte to find the addressing
5713 mode. */
5714 switch (mod) {
5715 case 0:
5716 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5717 u32 destval,imm;
5718
5719 DECODE_PRINTF("DWORD PTR ");
5720 destoffset = decode_rm00_address(rl);
5721 destval = fetch_data_long(destoffset);
5722 imm = (s8) fetch_byte_imm();
5723 DECODE_PRINTF2(",%x\n", imm);
5724 TRACE_AND_STEP();
5725 destval = (*opc83_long_operation[rh]) (destval, imm);
5726 if (rh != 7)
5727 store_data_long(destoffset, destval);
5728 } else {
5729 u16 destval,imm;
5730
5731 DECODE_PRINTF("WORD PTR ");
5732 destoffset = decode_rm00_address(rl);
5733 destval = fetch_data_word(destoffset);
5734 imm = (s8) fetch_byte_imm();
5735 DECODE_PRINTF2(",%x\n", imm);
5736 TRACE_AND_STEP();
5737 destval = (*opc83_word_operation[rh]) (destval, imm);
5738 if (rh != 7)
5739 store_data_word(destoffset, destval);
5740 }
5741 break;
5742 case 1:
5743 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5744 u32 destval,imm;
5745
5746 DECODE_PRINTF("DWORD PTR ");
5747 destoffset = decode_rm01_address(rl);
5748 destval = fetch_data_long(destoffset);
5749 imm = (s8) fetch_byte_imm();
5750 DECODE_PRINTF2(",%x\n", imm);
5751 TRACE_AND_STEP();
5752 destval = (*opc83_long_operation[rh]) (destval, imm);
5753 if (rh != 7)
5754 store_data_long(destoffset, destval);
5755 } else {
5756 u16 destval,imm;
5757
5758 DECODE_PRINTF("WORD PTR ");
5759 destoffset = decode_rm01_address(rl);
5760 destval = fetch_data_word(destoffset);
5761 imm = (s8) fetch_byte_imm();
5762 DECODE_PRINTF2(",%x\n", imm);
5763 TRACE_AND_STEP();
5764 destval = (*opc83_word_operation[rh]) (destval, imm);
5765 if (rh != 7)
5766 store_data_word(destoffset, destval);
5767 }
5768 break;
5769 case 2:
5770 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5771 u32 destval,imm;
5772
5773 DECODE_PRINTF("DWORD PTR ");
5774 destoffset = decode_rm10_address(rl);
5775 destval = fetch_data_long(destoffset);
5776 imm = (s8) fetch_byte_imm();
5777 DECODE_PRINTF2(",%x\n", imm);
5778 TRACE_AND_STEP();
5779 destval = (*opc83_long_operation[rh]) (destval, imm);
5780 if (rh != 7)
5781 store_data_long(destoffset, destval);
5782 } else {
5783 u16 destval,imm;
5784
5785 DECODE_PRINTF("WORD PTR ");
5786 destoffset = decode_rm10_address(rl);
5787 destval = fetch_data_word(destoffset);
5788 imm = (s8) fetch_byte_imm();
5789 DECODE_PRINTF2(",%x\n", imm);
5790 TRACE_AND_STEP();
5791 destval = (*opc83_word_operation[rh]) (destval, imm);
5792 if (rh != 7)
5793 store_data_word(destoffset, destval);
5794 }
5795 break;
5796 case 3: /* register to register */
5797 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5798 u32 *destreg;
5799 u32 destval,imm;
5800
5801 destreg = DECODE_RM_LONG_REGISTER(rl);
5802 imm = (s8) fetch_byte_imm();
5803 DECODE_PRINTF2(",%x\n", imm);
5804 TRACE_AND_STEP();
5805 destval = (*opc83_long_operation[rh]) (*destreg, imm);
5806 if (rh != 7)
5807 *destreg = destval;
5808 } else {
5809 u16 *destreg;
5810 u16 destval,imm;
5811
5812 destreg = DECODE_RM_WORD_REGISTER(rl);
5813 imm = (s8) fetch_byte_imm();
5814 DECODE_PRINTF2(",%x\n", imm);
5815 TRACE_AND_STEP();
5816 destval = (*opc83_word_operation[rh]) (*destreg, imm);
5817 if (rh != 7)
5818 *destreg = destval;
5819 }
5820 break;
5821 }
5822 DECODE_CLEAR_SEGOVR();
5823 END_OF_INSTR();
5824 }
5825
5826 /****************************************************************************
5827 REMARKS:
5828 Handles opcode 0x84
5829 ****************************************************************************/
x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED (op1))5830 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5831 {
5832 int mod, rl, rh;
5833 u8 *destreg, *srcreg;
5834 uint destoffset;
5835 u8 destval;
5836
5837 START_OF_INSTR();
5838 DECODE_PRINTF("TEST\t");
5839 FETCH_DECODE_MODRM(mod, rh, rl);
5840 switch (mod) {
5841 case 0:
5842 destoffset = decode_rm00_address(rl);
5843 DECODE_PRINTF(",");
5844 destval = fetch_data_byte(destoffset);
5845 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5846 DECODE_PRINTF("\n");
5847 TRACE_AND_STEP();
5848 test_byte(destval, *srcreg);
5849 break;
5850 case 1:
5851 destoffset = decode_rm01_address(rl);
5852 DECODE_PRINTF(",");
5853 destval = fetch_data_byte(destoffset);
5854 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5855 DECODE_PRINTF("\n");
5856 TRACE_AND_STEP();
5857 test_byte(destval, *srcreg);
5858 break;
5859 case 2:
5860 destoffset = decode_rm10_address(rl);
5861 DECODE_PRINTF(",");
5862 destval = fetch_data_byte(destoffset);
5863 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5864 DECODE_PRINTF("\n");
5865 TRACE_AND_STEP();
5866 test_byte(destval, *srcreg);
5867 break;
5868 case 3: /* register to register */
5869 destreg = DECODE_RM_BYTE_REGISTER(rl);
5870 DECODE_PRINTF(",");
5871 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5872 DECODE_PRINTF("\n");
5873 TRACE_AND_STEP();
5874 test_byte(*destreg, *srcreg);
5875 break;
5876 }
5877 DECODE_CLEAR_SEGOVR();
5878 END_OF_INSTR();
5879 }
5880
5881 /****************************************************************************
5882 REMARKS:
5883 Handles opcode 0x85
5884 ****************************************************************************/
x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED (op1))5885 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5886 {
5887 int mod, rl, rh;
5888 uint destoffset;
5889
5890 START_OF_INSTR();
5891 DECODE_PRINTF("TEST\t");
5892 FETCH_DECODE_MODRM(mod, rh, rl);
5893 switch (mod) {
5894 case 0:
5895 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5896 u32 destval;
5897 u32 *srcreg;
5898
5899 destoffset = decode_rm00_address(rl);
5900 DECODE_PRINTF(",");
5901 destval = fetch_data_long(destoffset);
5902 srcreg = DECODE_RM_LONG_REGISTER(rh);
5903 DECODE_PRINTF("\n");
5904 TRACE_AND_STEP();
5905 test_long(destval, *srcreg);
5906 } else {
5907 u16 destval;
5908 u16 *srcreg;
5909
5910 destoffset = decode_rm00_address(rl);
5911 DECODE_PRINTF(",");
5912 destval = fetch_data_word(destoffset);
5913 srcreg = DECODE_RM_WORD_REGISTER(rh);
5914 DECODE_PRINTF("\n");
5915 TRACE_AND_STEP();
5916 test_word(destval, *srcreg);
5917 }
5918 break;
5919 case 1:
5920 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5921 u32 destval;
5922 u32 *srcreg;
5923
5924 destoffset = decode_rm01_address(rl);
5925 DECODE_PRINTF(",");
5926 destval = fetch_data_long(destoffset);
5927 srcreg = DECODE_RM_LONG_REGISTER(rh);
5928 DECODE_PRINTF("\n");
5929 TRACE_AND_STEP();
5930 test_long(destval, *srcreg);
5931 } else {
5932 u16 destval;
5933 u16 *srcreg;
5934
5935 destoffset = decode_rm01_address(rl);
5936 DECODE_PRINTF(",");
5937 destval = fetch_data_word(destoffset);
5938 srcreg = DECODE_RM_WORD_REGISTER(rh);
5939 DECODE_PRINTF("\n");
5940 TRACE_AND_STEP();
5941 test_word(destval, *srcreg);
5942 }
5943 break;
5944 case 2:
5945 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5946 u32 destval;
5947 u32 *srcreg;
5948
5949 destoffset = decode_rm10_address(rl);
5950 DECODE_PRINTF(",");
5951 destval = fetch_data_long(destoffset);
5952 srcreg = DECODE_RM_LONG_REGISTER(rh);
5953 DECODE_PRINTF("\n");
5954 TRACE_AND_STEP();
5955 test_long(destval, *srcreg);
5956 } else {
5957 u16 destval;
5958 u16 *srcreg;
5959
5960 destoffset = decode_rm10_address(rl);
5961 DECODE_PRINTF(",");
5962 destval = fetch_data_word(destoffset);
5963 srcreg = DECODE_RM_WORD_REGISTER(rh);
5964 DECODE_PRINTF("\n");
5965 TRACE_AND_STEP();
5966 test_word(destval, *srcreg);
5967 }
5968 break;
5969 case 3: /* register to register */
5970 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5971 u32 *destreg,*srcreg;
5972
5973 destreg = DECODE_RM_LONG_REGISTER(rl);
5974 DECODE_PRINTF(",");
5975 srcreg = DECODE_RM_LONG_REGISTER(rh);
5976 DECODE_PRINTF("\n");
5977 TRACE_AND_STEP();
5978 test_long(*destreg, *srcreg);
5979 } else {
5980 u16 *destreg,*srcreg;
5981
5982 destreg = DECODE_RM_WORD_REGISTER(rl);
5983 DECODE_PRINTF(",");
5984 srcreg = DECODE_RM_WORD_REGISTER(rh);
5985 DECODE_PRINTF("\n");
5986 TRACE_AND_STEP();
5987 test_word(*destreg, *srcreg);
5988 }
5989 break;
5990 }
5991 DECODE_CLEAR_SEGOVR();
5992 END_OF_INSTR();
5993 }
5994
5995 /****************************************************************************
5996 REMARKS:
5997 Handles opcode 0x86
5998 ****************************************************************************/
x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED (op1))5999 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6000 {
6001 int mod, rl, rh;
6002 u8 *destreg, *srcreg;
6003 uint destoffset;
6004 u8 destval;
6005 u8 tmp;
6006
6007 START_OF_INSTR();
6008 DECODE_PRINTF("XCHG\t");
6009 FETCH_DECODE_MODRM(mod, rh, rl);
6010 switch (mod) {
6011 case 0:
6012 destoffset = decode_rm00_address(rl);
6013 DECODE_PRINTF(",");
6014 destval = fetch_data_byte(destoffset);
6015 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6016 DECODE_PRINTF("\n");
6017 TRACE_AND_STEP();
6018 tmp = *srcreg;
6019 *srcreg = destval;
6020 destval = tmp;
6021 store_data_byte(destoffset, destval);
6022 break;
6023 case 1:
6024 destoffset = decode_rm01_address(rl);
6025 DECODE_PRINTF(",");
6026 destval = fetch_data_byte(destoffset);
6027 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6028 DECODE_PRINTF("\n");
6029 TRACE_AND_STEP();
6030 tmp = *srcreg;
6031 *srcreg = destval;
6032 destval = tmp;
6033 store_data_byte(destoffset, destval);
6034 break;
6035 case 2:
6036 destoffset = decode_rm10_address(rl);
6037 DECODE_PRINTF(",");
6038 destval = fetch_data_byte(destoffset);
6039 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6040 DECODE_PRINTF("\n");
6041 TRACE_AND_STEP();
6042 tmp = *srcreg;
6043 *srcreg = destval;
6044 destval = tmp;
6045 store_data_byte(destoffset, destval);
6046 break;
6047 case 3: /* register to register */
6048 destreg = DECODE_RM_BYTE_REGISTER(rl);
6049 DECODE_PRINTF(",");
6050 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6051 DECODE_PRINTF("\n");
6052 TRACE_AND_STEP();
6053 tmp = *srcreg;
6054 *srcreg = *destreg;
6055 *destreg = tmp;
6056 break;
6057 }
6058 DECODE_CLEAR_SEGOVR();
6059 END_OF_INSTR();
6060 }
6061
6062 /****************************************************************************
6063 REMARKS:
6064 Handles opcode 0x87
6065 ****************************************************************************/
x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED (op1))6066 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6067 {
6068 int mod, rl, rh;
6069 uint destoffset;
6070
6071 START_OF_INSTR();
6072 DECODE_PRINTF("XCHG\t");
6073 FETCH_DECODE_MODRM(mod, rh, rl);
6074 switch (mod) {
6075 case 0:
6076 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6077 u32 *srcreg;
6078 u32 destval,tmp;
6079
6080 destoffset = decode_rm00_address(rl);
6081 DECODE_PRINTF(",");
6082 destval = fetch_data_long(destoffset);
6083 srcreg = DECODE_RM_LONG_REGISTER(rh);
6084 DECODE_PRINTF("\n");
6085 TRACE_AND_STEP();
6086 tmp = *srcreg;
6087 *srcreg = destval;
6088 destval = tmp;
6089 store_data_long(destoffset, destval);
6090 } else {
6091 u16 *srcreg;
6092 u16 destval,tmp;
6093
6094 destoffset = decode_rm00_address(rl);
6095 DECODE_PRINTF(",");
6096 destval = fetch_data_word(destoffset);
6097 srcreg = DECODE_RM_WORD_REGISTER(rh);
6098 DECODE_PRINTF("\n");
6099 TRACE_AND_STEP();
6100 tmp = *srcreg;
6101 *srcreg = destval;
6102 destval = tmp;
6103 store_data_word(destoffset, destval);
6104 }
6105 break;
6106 case 1:
6107 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6108 u32 *srcreg;
6109 u32 destval,tmp;
6110
6111 destoffset = decode_rm01_address(rl);
6112 DECODE_PRINTF(",");
6113 destval = fetch_data_long(destoffset);
6114 srcreg = DECODE_RM_LONG_REGISTER(rh);
6115 DECODE_PRINTF("\n");
6116 TRACE_AND_STEP();
6117 tmp = *srcreg;
6118 *srcreg = destval;
6119 destval = tmp;
6120 store_data_long(destoffset, destval);
6121 } else {
6122 u16 *srcreg;
6123 u16 destval,tmp;
6124
6125 destoffset = decode_rm01_address(rl);
6126 DECODE_PRINTF(",");
6127 destval = fetch_data_word(destoffset);
6128 srcreg = DECODE_RM_WORD_REGISTER(rh);
6129 DECODE_PRINTF("\n");
6130 TRACE_AND_STEP();
6131 tmp = *srcreg;
6132 *srcreg = destval;
6133 destval = tmp;
6134 store_data_word(destoffset, destval);
6135 }
6136 break;
6137 case 2:
6138 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6139 u32 *srcreg;
6140 u32 destval,tmp;
6141
6142 destoffset = decode_rm10_address(rl);
6143 DECODE_PRINTF(",");
6144 destval = fetch_data_long(destoffset);
6145 srcreg = DECODE_RM_LONG_REGISTER(rh);
6146 DECODE_PRINTF("\n");
6147 TRACE_AND_STEP();
6148 tmp = *srcreg;
6149 *srcreg = destval;
6150 destval = tmp;
6151 store_data_long(destoffset, destval);
6152 } else {
6153 u16 *srcreg;
6154 u16 destval,tmp;
6155
6156 destoffset = decode_rm10_address(rl);
6157 DECODE_PRINTF(",");
6158 destval = fetch_data_word(destoffset);
6159 srcreg = DECODE_RM_WORD_REGISTER(rh);
6160 DECODE_PRINTF("\n");
6161 TRACE_AND_STEP();
6162 tmp = *srcreg;
6163 *srcreg = destval;
6164 destval = tmp;
6165 store_data_word(destoffset, destval);
6166 }
6167 break;
6168 case 3: /* register to register */
6169 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6170 u32 *destreg,*srcreg;
6171 u32 tmp;
6172
6173 destreg = DECODE_RM_LONG_REGISTER(rl);
6174 DECODE_PRINTF(",");
6175 srcreg = DECODE_RM_LONG_REGISTER(rh);
6176 DECODE_PRINTF("\n");
6177 TRACE_AND_STEP();
6178 tmp = *srcreg;
6179 *srcreg = *destreg;
6180 *destreg = tmp;
6181 } else {
6182 u16 *destreg,*srcreg;
6183 u16 tmp;
6184
6185 destreg = DECODE_RM_WORD_REGISTER(rl);
6186 DECODE_PRINTF(",");
6187 srcreg = DECODE_RM_WORD_REGISTER(rh);
6188 DECODE_PRINTF("\n");
6189 TRACE_AND_STEP();
6190 tmp = *srcreg;
6191 *srcreg = *destreg;
6192 *destreg = tmp;
6193 }
6194 break;
6195 }
6196 DECODE_CLEAR_SEGOVR();
6197 END_OF_INSTR();
6198 }
6199
6200 /****************************************************************************
6201 REMARKS:
6202 Handles opcode 0x88
6203 ****************************************************************************/
x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED (op1))6204 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6205 {
6206 int mod, rl, rh;
6207 u8 *destreg, *srcreg;
6208 uint destoffset;
6209
6210 START_OF_INSTR();
6211 DECODE_PRINTF("MOV\t");
6212 FETCH_DECODE_MODRM(mod, rh, rl);
6213 switch (mod) {
6214 case 0:
6215 destoffset = decode_rm00_address(rl);
6216 DECODE_PRINTF(",");
6217 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6218 DECODE_PRINTF("\n");
6219 TRACE_AND_STEP();
6220 store_data_byte(destoffset, *srcreg);
6221 break;
6222 case 1:
6223 destoffset = decode_rm01_address(rl);
6224 DECODE_PRINTF(",");
6225 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6226 DECODE_PRINTF("\n");
6227 TRACE_AND_STEP();
6228 store_data_byte(destoffset, *srcreg);
6229 break;
6230 case 2:
6231 destoffset = decode_rm10_address(rl);
6232 DECODE_PRINTF(",");
6233 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6234 DECODE_PRINTF("\n");
6235 TRACE_AND_STEP();
6236 store_data_byte(destoffset, *srcreg);
6237 break;
6238 case 3: /* register to register */
6239 destreg = DECODE_RM_BYTE_REGISTER(rl);
6240 DECODE_PRINTF(",");
6241 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6242 DECODE_PRINTF("\n");
6243 TRACE_AND_STEP();
6244 *destreg = *srcreg;
6245 break;
6246 }
6247 DECODE_CLEAR_SEGOVR();
6248 END_OF_INSTR();
6249 }
6250
6251 /****************************************************************************
6252 REMARKS:
6253 Handles opcode 0x89
6254 ****************************************************************************/
x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED (op1))6255 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6256 {
6257 int mod, rl, rh;
6258 uint destoffset;
6259
6260 START_OF_INSTR();
6261 DECODE_PRINTF("MOV\t");
6262 FETCH_DECODE_MODRM(mod, rh, rl);
6263 switch (mod) {
6264 case 0:
6265 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6266 u32 *srcreg;
6267
6268 destoffset = decode_rm00_address(rl);
6269 DECODE_PRINTF(",");
6270 srcreg = DECODE_RM_LONG_REGISTER(rh);
6271 DECODE_PRINTF("\n");
6272 TRACE_AND_STEP();
6273 store_data_long(destoffset, *srcreg);
6274 } else {
6275 u16 *srcreg;
6276
6277 destoffset = decode_rm00_address(rl);
6278 DECODE_PRINTF(",");
6279 srcreg = DECODE_RM_WORD_REGISTER(rh);
6280 DECODE_PRINTF("\n");
6281 TRACE_AND_STEP();
6282 store_data_word(destoffset, *srcreg);
6283 }
6284 break;
6285 case 1:
6286 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6287 u32 *srcreg;
6288
6289 destoffset = decode_rm01_address(rl);
6290 DECODE_PRINTF(",");
6291 srcreg = DECODE_RM_LONG_REGISTER(rh);
6292 DECODE_PRINTF("\n");
6293 TRACE_AND_STEP();
6294 store_data_long(destoffset, *srcreg);
6295 } else {
6296 u16 *srcreg;
6297
6298 destoffset = decode_rm01_address(rl);
6299 DECODE_PRINTF(",");
6300 srcreg = DECODE_RM_WORD_REGISTER(rh);
6301 DECODE_PRINTF("\n");
6302 TRACE_AND_STEP();
6303 store_data_word(destoffset, *srcreg);
6304 }
6305 break;
6306 case 2:
6307 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6308 u32 *srcreg;
6309
6310 destoffset = decode_rm10_address(rl);
6311 DECODE_PRINTF(",");
6312 srcreg = DECODE_RM_LONG_REGISTER(rh);
6313 DECODE_PRINTF("\n");
6314 TRACE_AND_STEP();
6315 store_data_long(destoffset, *srcreg);
6316 } else {
6317 u16 *srcreg;
6318
6319 destoffset = decode_rm10_address(rl);
6320 DECODE_PRINTF(",");
6321 srcreg = DECODE_RM_WORD_REGISTER(rh);
6322 DECODE_PRINTF("\n");
6323 TRACE_AND_STEP();
6324 store_data_word(destoffset, *srcreg);
6325 }
6326 break;
6327 case 3: /* register to register */
6328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6329 u32 *destreg,*srcreg;
6330
6331 destreg = DECODE_RM_LONG_REGISTER(rl);
6332 DECODE_PRINTF(",");
6333 srcreg = DECODE_RM_LONG_REGISTER(rh);
6334 DECODE_PRINTF("\n");
6335 TRACE_AND_STEP();
6336 *destreg = *srcreg;
6337 } else {
6338 u16 *destreg,*srcreg;
6339
6340 destreg = DECODE_RM_WORD_REGISTER(rl);
6341 DECODE_PRINTF(",");
6342 srcreg = DECODE_RM_WORD_REGISTER(rh);
6343 DECODE_PRINTF("\n");
6344 TRACE_AND_STEP();
6345 *destreg = *srcreg;
6346 }
6347 break;
6348 }
6349 DECODE_CLEAR_SEGOVR();
6350 END_OF_INSTR();
6351 }
6352
6353 /****************************************************************************
6354 REMARKS:
6355 Handles opcode 0x8a
6356 ****************************************************************************/
x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED (op1))6357 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6358 {
6359 int mod, rl, rh;
6360 u8 *destreg, *srcreg;
6361 uint srcoffset;
6362 u8 srcval;
6363
6364 START_OF_INSTR();
6365 DECODE_PRINTF("MOV\t");
6366 FETCH_DECODE_MODRM(mod, rh, rl);
6367 switch (mod) {
6368 case 0:
6369 destreg = DECODE_RM_BYTE_REGISTER(rh);
6370 DECODE_PRINTF(",");
6371 srcoffset = decode_rm00_address(rl);
6372 srcval = fetch_data_byte(srcoffset);
6373 DECODE_PRINTF("\n");
6374 TRACE_AND_STEP();
6375 *destreg = srcval;
6376 break;
6377 case 1:
6378 destreg = DECODE_RM_BYTE_REGISTER(rh);
6379 DECODE_PRINTF(",");
6380 srcoffset = decode_rm01_address(rl);
6381 srcval = fetch_data_byte(srcoffset);
6382 DECODE_PRINTF("\n");
6383 TRACE_AND_STEP();
6384 *destreg = srcval;
6385 break;
6386 case 2:
6387 destreg = DECODE_RM_BYTE_REGISTER(rh);
6388 DECODE_PRINTF(",");
6389 srcoffset = decode_rm10_address(rl);
6390 srcval = fetch_data_byte(srcoffset);
6391 DECODE_PRINTF("\n");
6392 TRACE_AND_STEP();
6393 *destreg = srcval;
6394 break;
6395 case 3: /* register to register */
6396 destreg = DECODE_RM_BYTE_REGISTER(rh);
6397 DECODE_PRINTF(",");
6398 srcreg = DECODE_RM_BYTE_REGISTER(rl);
6399 DECODE_PRINTF("\n");
6400 TRACE_AND_STEP();
6401 *destreg = *srcreg;
6402 break;
6403 }
6404 DECODE_CLEAR_SEGOVR();
6405 END_OF_INSTR();
6406 }
6407
6408 /****************************************************************************
6409 REMARKS:
6410 Handles opcode 0x8b
6411 ****************************************************************************/
x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED (op1))6412 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6413 {
6414 int mod, rl, rh;
6415 uint srcoffset;
6416
6417 START_OF_INSTR();
6418 DECODE_PRINTF("MOV\t");
6419 FETCH_DECODE_MODRM(mod, rh, rl);
6420 switch (mod) {
6421 case 0:
6422 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6423 u32 *destreg;
6424 u32 srcval;
6425
6426 destreg = DECODE_RM_LONG_REGISTER(rh);
6427 DECODE_PRINTF(",");
6428 srcoffset = decode_rm00_address(rl);
6429 srcval = fetch_data_long(srcoffset);
6430 DECODE_PRINTF("\n");
6431 TRACE_AND_STEP();
6432 *destreg = srcval;
6433 } else {
6434 u16 *destreg;
6435 u16 srcval;
6436
6437 destreg = DECODE_RM_WORD_REGISTER(rh);
6438 DECODE_PRINTF(",");
6439 srcoffset = decode_rm00_address(rl);
6440 srcval = fetch_data_word(srcoffset);
6441 DECODE_PRINTF("\n");
6442 TRACE_AND_STEP();
6443 *destreg = srcval;
6444 }
6445 break;
6446 case 1:
6447 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6448 u32 *destreg;
6449 u32 srcval;
6450
6451 destreg = DECODE_RM_LONG_REGISTER(rh);
6452 DECODE_PRINTF(",");
6453 srcoffset = decode_rm01_address(rl);
6454 srcval = fetch_data_long(srcoffset);
6455 DECODE_PRINTF("\n");
6456 TRACE_AND_STEP();
6457 *destreg = srcval;
6458 } else {
6459 u16 *destreg;
6460 u16 srcval;
6461
6462 destreg = DECODE_RM_WORD_REGISTER(rh);
6463 DECODE_PRINTF(",");
6464 srcoffset = decode_rm01_address(rl);
6465 srcval = fetch_data_word(srcoffset);
6466 DECODE_PRINTF("\n");
6467 TRACE_AND_STEP();
6468 *destreg = srcval;
6469 }
6470 break;
6471 case 2:
6472 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6473 u32 *destreg;
6474 u32 srcval;
6475
6476 destreg = DECODE_RM_LONG_REGISTER(rh);
6477 DECODE_PRINTF(",");
6478 srcoffset = decode_rm10_address(rl);
6479 srcval = fetch_data_long(srcoffset);
6480 DECODE_PRINTF("\n");
6481 TRACE_AND_STEP();
6482 *destreg = srcval;
6483 } else {
6484 u16 *destreg;
6485 u16 srcval;
6486
6487 destreg = DECODE_RM_WORD_REGISTER(rh);
6488 DECODE_PRINTF(",");
6489 srcoffset = decode_rm10_address(rl);
6490 srcval = fetch_data_word(srcoffset);
6491 DECODE_PRINTF("\n");
6492 TRACE_AND_STEP();
6493 *destreg = srcval;
6494 }
6495 break;
6496 case 3: /* register to register */
6497 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6498 u32 *destreg, *srcreg;
6499
6500 destreg = DECODE_RM_LONG_REGISTER(rh);
6501 DECODE_PRINTF(",");
6502 srcreg = DECODE_RM_LONG_REGISTER(rl);
6503 DECODE_PRINTF("\n");
6504 TRACE_AND_STEP();
6505 *destreg = *srcreg;
6506 } else {
6507 u16 *destreg, *srcreg;
6508
6509 destreg = DECODE_RM_WORD_REGISTER(rh);
6510 DECODE_PRINTF(",");
6511 srcreg = DECODE_RM_WORD_REGISTER(rl);
6512 DECODE_PRINTF("\n");
6513 TRACE_AND_STEP();
6514 *destreg = *srcreg;
6515 }
6516 break;
6517 }
6518 DECODE_CLEAR_SEGOVR();
6519 END_OF_INSTR();
6520 }
6521
6522 /****************************************************************************
6523 REMARKS:
6524 Handles opcode 0x8c
6525 ****************************************************************************/
x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED (op1))6526 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6527 {
6528 int mod, rl, rh;
6529 u16 *destreg, *srcreg;
6530 uint destoffset;
6531 u16 destval;
6532
6533 START_OF_INSTR();
6534 DECODE_PRINTF("MOV\t");
6535 FETCH_DECODE_MODRM(mod, rh, rl);
6536 switch (mod) {
6537 case 0:
6538 destoffset = decode_rm00_address(rl);
6539 DECODE_PRINTF(",");
6540 srcreg = decode_rm_seg_register(rh);
6541 DECODE_PRINTF("\n");
6542 TRACE_AND_STEP();
6543 destval = *srcreg;
6544 store_data_word(destoffset, destval);
6545 break;
6546 case 1:
6547 destoffset = decode_rm01_address(rl);
6548 DECODE_PRINTF(",");
6549 srcreg = decode_rm_seg_register(rh);
6550 DECODE_PRINTF("\n");
6551 TRACE_AND_STEP();
6552 destval = *srcreg;
6553 store_data_word(destoffset, destval);
6554 break;
6555 case 2:
6556 destoffset = decode_rm10_address(rl);
6557 DECODE_PRINTF(",");
6558 srcreg = decode_rm_seg_register(rh);
6559 DECODE_PRINTF("\n");
6560 TRACE_AND_STEP();
6561 destval = *srcreg;
6562 store_data_word(destoffset, destval);
6563 break;
6564 case 3: /* register to register */
6565 destreg = DECODE_RM_WORD_REGISTER(rl);
6566 DECODE_PRINTF(",");
6567 srcreg = decode_rm_seg_register(rh);
6568 DECODE_PRINTF("\n");
6569 TRACE_AND_STEP();
6570 *destreg = *srcreg;
6571 break;
6572 }
6573 DECODE_CLEAR_SEGOVR();
6574 END_OF_INSTR();
6575 }
6576
6577 /****************************************************************************
6578 REMARKS:
6579 Handles opcode 0x8d
6580 ****************************************************************************/
x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED (op1))6581 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6582 {
6583 int mod, rl, rh;
6584 u16 *srcreg;
6585 uint destoffset;
6586
6587 /*
6588 * TODO: Need to handle address size prefix!
6589 *
6590 * lea eax,[eax+ebx*2] ??
6591 */
6592
6593 START_OF_INSTR();
6594 DECODE_PRINTF("LEA\t");
6595 FETCH_DECODE_MODRM(mod, rh, rl);
6596 switch (mod) {
6597 case 0:
6598 srcreg = DECODE_RM_WORD_REGISTER(rh);
6599 DECODE_PRINTF(",");
6600 destoffset = decode_rm00_address(rl);
6601 DECODE_PRINTF("\n");
6602 TRACE_AND_STEP();
6603 *srcreg = (u16)destoffset;
6604 break;
6605 case 1:
6606 srcreg = DECODE_RM_WORD_REGISTER(rh);
6607 DECODE_PRINTF(",");
6608 destoffset = decode_rm01_address(rl);
6609 DECODE_PRINTF("\n");
6610 TRACE_AND_STEP();
6611 *srcreg = (u16)destoffset;
6612 break;
6613 case 2:
6614 srcreg = DECODE_RM_WORD_REGISTER(rh);
6615 DECODE_PRINTF(",");
6616 destoffset = decode_rm10_address(rl);
6617 DECODE_PRINTF("\n");
6618 TRACE_AND_STEP();
6619 *srcreg = (u16)destoffset;
6620 break;
6621 case 3: /* register to register */
6622 /* undefined. Do nothing. */
6623 break;
6624 }
6625 DECODE_CLEAR_SEGOVR();
6626 END_OF_INSTR();
6627 }
6628
6629 /****************************************************************************
6630 REMARKS:
6631 Handles opcode 0x8e
6632 ****************************************************************************/
x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED (op1))6633 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6634 {
6635 int mod, rl, rh;
6636 u16 *destreg, *srcreg;
6637 uint srcoffset;
6638 u16 srcval;
6639
6640 START_OF_INSTR();
6641 DECODE_PRINTF("MOV\t");
6642 FETCH_DECODE_MODRM(mod, rh, rl);
6643 switch (mod) {
6644 case 0:
6645 destreg = decode_rm_seg_register(rh);
6646 DECODE_PRINTF(",");
6647 srcoffset = decode_rm00_address(rl);
6648 srcval = fetch_data_word(srcoffset);
6649 DECODE_PRINTF("\n");
6650 TRACE_AND_STEP();
6651 *destreg = srcval;
6652 break;
6653 case 1:
6654 destreg = decode_rm_seg_register(rh);
6655 DECODE_PRINTF(",");
6656 srcoffset = decode_rm01_address(rl);
6657 srcval = fetch_data_word(srcoffset);
6658 DECODE_PRINTF("\n");
6659 TRACE_AND_STEP();
6660 *destreg = srcval;
6661 break;
6662 case 2:
6663 destreg = decode_rm_seg_register(rh);
6664 DECODE_PRINTF(",");
6665 srcoffset = decode_rm10_address(rl);
6666 srcval = fetch_data_word(srcoffset);
6667 DECODE_PRINTF("\n");
6668 TRACE_AND_STEP();
6669 *destreg = srcval;
6670 break;
6671 case 3: /* register to register */
6672 destreg = decode_rm_seg_register(rh);
6673 DECODE_PRINTF(",");
6674 srcreg = DECODE_RM_WORD_REGISTER(rl);
6675 DECODE_PRINTF("\n");
6676 TRACE_AND_STEP();
6677 *destreg = *srcreg;
6678 break;
6679 }
6680 /*
6681 * Clean up, and reset all the R_xSP pointers to the correct
6682 * locations. This is about 3x too much overhead (doing all the
6683 * segreg ptrs when only one is needed, but this instruction
6684 * *cannot* be that common, and this isn't too much work anyway.
6685 */
6686 DECODE_CLEAR_SEGOVR();
6687 END_OF_INSTR();
6688 }
6689
6690 /****************************************************************************
6691 REMARKS:
6692 Handles opcode 0x8f
6693 ****************************************************************************/
x86emuOp_pop_RM(u8 X86EMU_UNUSED (op1))6694 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6695 {
6696 int mod, rl, rh;
6697 uint destoffset;
6698
6699 START_OF_INSTR();
6700 DECODE_PRINTF("POP\t");
6701 FETCH_DECODE_MODRM(mod, rh, rl);
6702 if (rh != 0) {
6703 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6704 HALT_SYS();
6705 }
6706 switch (mod) {
6707 case 0:
6708 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6709 u32 destval;
6710
6711 destoffset = decode_rm00_address(rl);
6712 DECODE_PRINTF("\n");
6713 TRACE_AND_STEP();
6714 destval = pop_long();
6715 store_data_long(destoffset, destval);
6716 } else {
6717 u16 destval;
6718
6719 destoffset = decode_rm00_address(rl);
6720 DECODE_PRINTF("\n");
6721 TRACE_AND_STEP();
6722 destval = pop_word();
6723 store_data_word(destoffset, destval);
6724 }
6725 break;
6726 case 1:
6727 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6728 u32 destval;
6729
6730 destoffset = decode_rm01_address(rl);
6731 DECODE_PRINTF("\n");
6732 TRACE_AND_STEP();
6733 destval = pop_long();
6734 store_data_long(destoffset, destval);
6735 } else {
6736 u16 destval;
6737
6738 destoffset = decode_rm01_address(rl);
6739 DECODE_PRINTF("\n");
6740 TRACE_AND_STEP();
6741 destval = pop_word();
6742 store_data_word(destoffset, destval);
6743 }
6744 break;
6745 case 2:
6746 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6747 u32 destval;
6748
6749 destoffset = decode_rm10_address(rl);
6750 DECODE_PRINTF("\n");
6751 TRACE_AND_STEP();
6752 destval = pop_long();
6753 store_data_long(destoffset, destval);
6754 } else {
6755 u16 destval;
6756
6757 destoffset = decode_rm10_address(rl);
6758 DECODE_PRINTF("\n");
6759 TRACE_AND_STEP();
6760 destval = pop_word();
6761 store_data_word(destoffset, destval);
6762 }
6763 break;
6764 case 3: /* register to register */
6765 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6766 u32 *destreg;
6767
6768 destreg = DECODE_RM_LONG_REGISTER(rl);
6769 DECODE_PRINTF("\n");
6770 TRACE_AND_STEP();
6771 *destreg = pop_long();
6772 } else {
6773 u16 *destreg;
6774
6775 destreg = DECODE_RM_WORD_REGISTER(rl);
6776 DECODE_PRINTF("\n");
6777 TRACE_AND_STEP();
6778 *destreg = pop_word();
6779 }
6780 break;
6781 }
6782 DECODE_CLEAR_SEGOVR();
6783 END_OF_INSTR();
6784 }
6785
6786 /****************************************************************************
6787 REMARKS:
6788 Handles opcode 0x90
6789 ****************************************************************************/
x86emuOp_nop(u8 X86EMU_UNUSED (op1))6790 void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6791 {
6792 START_OF_INSTR();
6793 DECODE_PRINTF("NOP\n");
6794 TRACE_AND_STEP();
6795 DECODE_CLEAR_SEGOVR();
6796 END_OF_INSTR();
6797 }
6798
6799 /****************************************************************************
6800 REMARKS:
6801 Handles opcode 0x91
6802 ****************************************************************************/
x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED (op1))6803 void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6804 {
6805 u32 tmp;
6806
6807 START_OF_INSTR();
6808 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6809 DECODE_PRINTF("XCHG\tEAX,ECX\n");
6810 } else {
6811 DECODE_PRINTF("XCHG\tAX,CX\n");
6812 }
6813 TRACE_AND_STEP();
6814 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6815 tmp = M.x86.R_EAX;
6816 M.x86.R_EAX = M.x86.R_ECX;
6817 M.x86.R_ECX = tmp;
6818 } else {
6819 tmp = M.x86.R_AX;
6820 M.x86.R_AX = M.x86.R_CX;
6821 M.x86.R_CX = (u16)tmp;
6822 }
6823 DECODE_CLEAR_SEGOVR();
6824 END_OF_INSTR();
6825 }
6826
6827 /****************************************************************************
6828 REMARKS:
6829 Handles opcode 0x92
6830 ****************************************************************************/
x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED (op1))6831 void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6832 {
6833 u32 tmp;
6834
6835 START_OF_INSTR();
6836 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6837 DECODE_PRINTF("XCHG\tEAX,EDX\n");
6838 } else {
6839 DECODE_PRINTF("XCHG\tAX,DX\n");
6840 }
6841 TRACE_AND_STEP();
6842 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6843 tmp = M.x86.R_EAX;
6844 M.x86.R_EAX = M.x86.R_EDX;
6845 M.x86.R_EDX = tmp;
6846 } else {
6847 tmp = M.x86.R_AX;
6848 M.x86.R_AX = M.x86.R_DX;
6849 M.x86.R_DX = (u16)tmp;
6850 }
6851 DECODE_CLEAR_SEGOVR();
6852 END_OF_INSTR();
6853 }
6854
6855 /****************************************************************************
6856 REMARKS:
6857 Handles opcode 0x93
6858 ****************************************************************************/
x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED (op1))6859 void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6860 {
6861 u32 tmp;
6862
6863 START_OF_INSTR();
6864 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6865 DECODE_PRINTF("XCHG\tEAX,EBX\n");
6866 } else {
6867 DECODE_PRINTF("XCHG\tAX,BX\n");
6868 }
6869 TRACE_AND_STEP();
6870 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6871 tmp = M.x86.R_EAX;
6872 M.x86.R_EAX = M.x86.R_EBX;
6873 M.x86.R_EBX = tmp;
6874 } else {
6875 tmp = M.x86.R_AX;
6876 M.x86.R_AX = M.x86.R_BX;
6877 M.x86.R_BX = (u16)tmp;
6878 }
6879 DECODE_CLEAR_SEGOVR();
6880 END_OF_INSTR();
6881 }
6882
6883 /****************************************************************************
6884 REMARKS:
6885 Handles opcode 0x94
6886 ****************************************************************************/
x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED (op1))6887 void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6888 {
6889 u32 tmp;
6890
6891 START_OF_INSTR();
6892 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6893 DECODE_PRINTF("XCHG\tEAX,ESP\n");
6894 } else {
6895 DECODE_PRINTF("XCHG\tAX,SP\n");
6896 }
6897 TRACE_AND_STEP();
6898 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6899 tmp = M.x86.R_EAX;
6900 M.x86.R_EAX = M.x86.R_ESP;
6901 M.x86.R_ESP = tmp;
6902 } else {
6903 tmp = M.x86.R_AX;
6904 M.x86.R_AX = M.x86.R_SP;
6905 M.x86.R_SP = (u16)tmp;
6906 }
6907 DECODE_CLEAR_SEGOVR();
6908 END_OF_INSTR();
6909 }
6910
6911 /****************************************************************************
6912 REMARKS:
6913 Handles opcode 0x95
6914 ****************************************************************************/
x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED (op1))6915 void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6916 {
6917 u32 tmp;
6918
6919 START_OF_INSTR();
6920 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6921 DECODE_PRINTF("XCHG\tEAX,EBP\n");
6922 } else {
6923 DECODE_PRINTF("XCHG\tAX,BP\n");
6924 }
6925 TRACE_AND_STEP();
6926 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6927 tmp = M.x86.R_EAX;
6928 M.x86.R_EAX = M.x86.R_EBP;
6929 M.x86.R_EBP = tmp;
6930 } else {
6931 tmp = M.x86.R_AX;
6932 M.x86.R_AX = M.x86.R_BP;
6933 M.x86.R_BP = (u16)tmp;
6934 }
6935 DECODE_CLEAR_SEGOVR();
6936 END_OF_INSTR();
6937 }
6938
6939 /****************************************************************************
6940 REMARKS:
6941 Handles opcode 0x96
6942 ****************************************************************************/
x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED (op1))6943 void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6944 {
6945 u32 tmp;
6946
6947 START_OF_INSTR();
6948 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6949 DECODE_PRINTF("XCHG\tEAX,ESI\n");
6950 } else {
6951 DECODE_PRINTF("XCHG\tAX,SI\n");
6952 }
6953 TRACE_AND_STEP();
6954 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6955 tmp = M.x86.R_EAX;
6956 M.x86.R_EAX = M.x86.R_ESI;
6957 M.x86.R_ESI = tmp;
6958 } else {
6959 tmp = M.x86.R_AX;
6960 M.x86.R_AX = M.x86.R_SI;
6961 M.x86.R_SI = (u16)tmp;
6962 }
6963 DECODE_CLEAR_SEGOVR();
6964 END_OF_INSTR();
6965 }
6966
6967 /****************************************************************************
6968 REMARKS:
6969 Handles opcode 0x97
6970 ****************************************************************************/
x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED (op1))6971 void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6972 {
6973 u32 tmp;
6974
6975 START_OF_INSTR();
6976 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6977 DECODE_PRINTF("XCHG\tEAX,EDI\n");
6978 } else {
6979 DECODE_PRINTF("XCHG\tAX,DI\n");
6980 }
6981 TRACE_AND_STEP();
6982 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6983 tmp = M.x86.R_EAX;
6984 M.x86.R_EAX = M.x86.R_EDI;
6985 M.x86.R_EDI = tmp;
6986 } else {
6987 tmp = M.x86.R_AX;
6988 M.x86.R_AX = M.x86.R_DI;
6989 M.x86.R_DI = (u16)tmp;
6990 }
6991 DECODE_CLEAR_SEGOVR();
6992 END_OF_INSTR();
6993 }
6994
6995 /****************************************************************************
6996 REMARKS:
6997 Handles opcode 0x98
6998 ****************************************************************************/
x86emuOp_cbw(u8 X86EMU_UNUSED (op1))6999 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7000 {
7001 START_OF_INSTR();
7002 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7003 DECODE_PRINTF("CWDE\n");
7004 } else {
7005 DECODE_PRINTF("CBW\n");
7006 }
7007 TRACE_AND_STEP();
7008 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7009 if (M.x86.R_AX & 0x8000) {
7010 M.x86.R_EAX |= 0xffff0000;
7011 } else {
7012 M.x86.R_EAX &= 0x0000ffff;
7013 }
7014 } else {
7015 if (M.x86.R_AL & 0x80) {
7016 M.x86.R_AH = 0xff;
7017 } else {
7018 M.x86.R_AH = 0x0;
7019 }
7020 }
7021 DECODE_CLEAR_SEGOVR();
7022 END_OF_INSTR();
7023 }
7024
7025 /****************************************************************************
7026 REMARKS:
7027 Handles opcode 0x99
7028 ****************************************************************************/
x86emuOp_cwd(u8 X86EMU_UNUSED (op1))7029 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7030 {
7031 START_OF_INSTR();
7032 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7033 DECODE_PRINTF("CDQ\n");
7034 } else {
7035 DECODE_PRINTF("CWD\n");
7036 }
7037 DECODE_PRINTF("CWD\n");
7038 TRACE_AND_STEP();
7039 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7040 if (M.x86.R_EAX & 0x80000000) {
7041 M.x86.R_EDX = 0xffffffff;
7042 } else {
7043 M.x86.R_EDX = 0x0;
7044 }
7045 } else {
7046 if (M.x86.R_AX & 0x8000) {
7047 M.x86.R_DX = 0xffff;
7048 } else {
7049 M.x86.R_DX = 0x0;
7050 }
7051 }
7052 DECODE_CLEAR_SEGOVR();
7053 END_OF_INSTR();
7054 }
7055
7056 /****************************************************************************
7057 REMARKS:
7058 Handles opcode 0x9a
7059 ****************************************************************************/
x86emuOp_call_far_IMM(u8 X86EMU_UNUSED (op1))7060 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7061 {
7062 u16 farseg, faroff;
7063
7064 START_OF_INSTR();
7065 DECODE_PRINTF("CALL\t");
7066 faroff = fetch_word_imm();
7067 farseg = fetch_word_imm();
7068 DECODE_PRINTF2("%04x:", farseg);
7069 DECODE_PRINTF2("%04x\n", faroff);
7070 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7071
7072 /* XXX
7073 *
7074 * Hooked interrupt vectors calling into our "BIOS" will cause
7075 * problems unless all intersegment stuff is checked for BIOS
7076 * access. Check needed here. For moment, let it alone.
7077 */
7078 TRACE_AND_STEP();
7079 push_word(M.x86.R_CS);
7080 M.x86.R_CS = farseg;
7081 push_word(M.x86.R_IP);
7082 M.x86.R_IP = faroff;
7083 DECODE_CLEAR_SEGOVR();
7084 END_OF_INSTR();
7085 }
7086
7087 /****************************************************************************
7088 REMARKS:
7089 Handles opcode 0x9b
7090 ****************************************************************************/
x86emuOp_wait(u8 X86EMU_UNUSED (op1))7091 void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7092 {
7093 START_OF_INSTR();
7094 DECODE_PRINTF("WAIT");
7095 TRACE_AND_STEP();
7096 /* NADA. */
7097 DECODE_CLEAR_SEGOVR();
7098 END_OF_INSTR();
7099 }
7100
7101 /****************************************************************************
7102 REMARKS:
7103 Handles opcode 0x9c
7104 ****************************************************************************/
x86emuOp_pushf_word(u8 X86EMU_UNUSED (op1))7105 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7106 {
7107 u32 flags;
7108
7109 START_OF_INSTR();
7110 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7111 DECODE_PRINTF("PUSHFD\n");
7112 } else {
7113 DECODE_PRINTF("PUSHF\n");
7114 }
7115 TRACE_AND_STEP();
7116
7117 /* clear out *all* bits not representing flags, and turn on real bits */
7118 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7119 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7120 push_long(flags);
7121 } else {
7122 push_word((u16)flags);
7123 }
7124 DECODE_CLEAR_SEGOVR();
7125 END_OF_INSTR();
7126 }
7127
7128 /****************************************************************************
7129 REMARKS:
7130 Handles opcode 0x9d
7131 ****************************************************************************/
x86emuOp_popf_word(u8 X86EMU_UNUSED (op1))7132 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7133 {
7134 START_OF_INSTR();
7135 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7136 DECODE_PRINTF("POPFD\n");
7137 } else {
7138 DECODE_PRINTF("POPF\n");
7139 }
7140 TRACE_AND_STEP();
7141 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7142 M.x86.R_EFLG = pop_long();
7143 } else {
7144 M.x86.R_FLG = pop_word();
7145 }
7146 DECODE_CLEAR_SEGOVR();
7147 END_OF_INSTR();
7148 }
7149
7150 /****************************************************************************
7151 REMARKS:
7152 Handles opcode 0x9e
7153 ****************************************************************************/
x86emuOp_sahf(u8 X86EMU_UNUSED (op1))7154 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7155 {
7156 START_OF_INSTR();
7157 DECODE_PRINTF("SAHF\n");
7158 TRACE_AND_STEP();
7159 /* clear the lower bits of the flag register */
7160 M.x86.R_FLG &= 0xffffff00;
7161 /* or in the AH register into the flags register */
7162 M.x86.R_FLG |= M.x86.R_AH;
7163 DECODE_CLEAR_SEGOVR();
7164 END_OF_INSTR();
7165 }
7166
7167 /****************************************************************************
7168 REMARKS:
7169 Handles opcode 0x9f
7170 ****************************************************************************/
x86emuOp_lahf(u8 X86EMU_UNUSED (op1))7171 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7172 {
7173 START_OF_INSTR();
7174 DECODE_PRINTF("LAHF\n");
7175 TRACE_AND_STEP();
7176 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7177 /*undocumented TC++ behavior??? Nope. It's documented, but
7178 you have too look real hard to notice it. */
7179 M.x86.R_AH |= 0x2;
7180 DECODE_CLEAR_SEGOVR();
7181 END_OF_INSTR();
7182 }
7183
7184 /****************************************************************************
7185 REMARKS:
7186 Handles opcode 0xa0
7187 ****************************************************************************/
x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED (op1))7188 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7189 {
7190 u16 offset;
7191
7192 START_OF_INSTR();
7193 DECODE_PRINTF("MOV\tAL,");
7194 offset = fetch_word_imm();
7195 DECODE_PRINTF2("[%04x]\n", offset);
7196 TRACE_AND_STEP();
7197 M.x86.R_AL = fetch_data_byte(offset);
7198 DECODE_CLEAR_SEGOVR();
7199 END_OF_INSTR();
7200 }
7201
7202 /****************************************************************************
7203 REMARKS:
7204 Handles opcode 0xa1
7205 ****************************************************************************/
x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED (op1))7206 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7207 {
7208 u16 offset;
7209
7210 START_OF_INSTR();
7211 offset = fetch_word_imm();
7212 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7213 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7214 } else {
7215 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7216 }
7217 TRACE_AND_STEP();
7218 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7219 M.x86.R_EAX = fetch_data_long(offset);
7220 } else {
7221 M.x86.R_AX = fetch_data_word(offset);
7222 }
7223 DECODE_CLEAR_SEGOVR();
7224 END_OF_INSTR();
7225 }
7226
7227 /****************************************************************************
7228 REMARKS:
7229 Handles opcode 0xa2
7230 ****************************************************************************/
x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED (op1))7231 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7232 {
7233 u16 offset;
7234
7235 START_OF_INSTR();
7236 DECODE_PRINTF("MOV\t");
7237 offset = fetch_word_imm();
7238 DECODE_PRINTF2("[%04x],AL\n", offset);
7239 TRACE_AND_STEP();
7240 store_data_byte(offset, M.x86.R_AL);
7241 DECODE_CLEAR_SEGOVR();
7242 END_OF_INSTR();
7243 }
7244
7245 /****************************************************************************
7246 REMARKS:
7247 Handles opcode 0xa3
7248 ****************************************************************************/
x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED (op1))7249 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7250 {
7251 u16 offset;
7252
7253 START_OF_INSTR();
7254 offset = fetch_word_imm();
7255 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7256 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7257 } else {
7258 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7259 }
7260 TRACE_AND_STEP();
7261 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7262 store_data_long(offset, M.x86.R_EAX);
7263 } else {
7264 store_data_word(offset, M.x86.R_AX);
7265 }
7266 DECODE_CLEAR_SEGOVR();
7267 END_OF_INSTR();
7268 }
7269
7270 /****************************************************************************
7271 REMARKS:
7272 Handles opcode 0xa4
7273 ****************************************************************************/
x86emuOp_movs_byte(u8 X86EMU_UNUSED (op1))7274 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7275 {
7276 u8 val;
7277 u32 count;
7278 int inc;
7279
7280 START_OF_INSTR();
7281 DECODE_PRINTF("MOVS\tBYTE\n");
7282 if (ACCESS_FLAG(F_DF)) /* down */
7283 inc = -1;
7284 else
7285 inc = 1;
7286 TRACE_AND_STEP();
7287 count = 1;
7288 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7289 /* dont care whether REPE or REPNE */
7290 /* move them until CX is ZERO. */
7291 count = M.x86.R_CX;
7292 M.x86.R_CX = 0;
7293 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7294 }
7295 while (count--) {
7296 val = fetch_data_byte(M.x86.R_SI);
7297 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7298 M.x86.R_SI += inc;
7299 M.x86.R_DI += inc;
7300 }
7301 DECODE_CLEAR_SEGOVR();
7302 END_OF_INSTR();
7303 }
7304
7305 /****************************************************************************
7306 REMARKS:
7307 Handles opcode 0xa5
7308 ****************************************************************************/
x86emuOp_movs_word(u8 X86EMU_UNUSED (op1))7309 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7310 {
7311 u32 val;
7312 int inc;
7313 u32 count;
7314
7315 START_OF_INSTR();
7316 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7317 DECODE_PRINTF("MOVS\tDWORD\n");
7318 if (ACCESS_FLAG(F_DF)) /* down */
7319 inc = -4;
7320 else
7321 inc = 4;
7322 } else {
7323 DECODE_PRINTF("MOVS\tWORD\n");
7324 if (ACCESS_FLAG(F_DF)) /* down */
7325 inc = -2;
7326 else
7327 inc = 2;
7328 }
7329 TRACE_AND_STEP();
7330 count = 1;
7331 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7332 /* dont care whether REPE or REPNE */
7333 /* move them until CX is ZERO. */
7334 count = M.x86.R_CX;
7335 M.x86.R_CX = 0;
7336 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7337 }
7338 while (count--) {
7339 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7340 val = fetch_data_long(M.x86.R_SI);
7341 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7342 } else {
7343 val = fetch_data_word(M.x86.R_SI);
7344 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7345 }
7346 M.x86.R_SI += inc;
7347 M.x86.R_DI += inc;
7348 }
7349 DECODE_CLEAR_SEGOVR();
7350 END_OF_INSTR();
7351 }
7352
7353 /****************************************************************************
7354 REMARKS:
7355 Handles opcode 0xa6
7356 ****************************************************************************/
x86emuOp_cmps_byte(u8 X86EMU_UNUSED (op1))7357 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7358 {
7359 s8 val1, val2;
7360 int inc;
7361
7362 START_OF_INSTR();
7363 DECODE_PRINTF("CMPS\tBYTE\n");
7364 TRACE_AND_STEP();
7365 if (ACCESS_FLAG(F_DF)) /* down */
7366 inc = -1;
7367 else
7368 inc = 1;
7369
7370 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7371 /* REPE */
7372 /* move them until CX is ZERO. */
7373 while (M.x86.R_CX != 0) {
7374 val1 = fetch_data_byte(M.x86.R_SI);
7375 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7376 cmp_byte(val1, val2);
7377 M.x86.R_CX -= 1;
7378 M.x86.R_SI += inc;
7379 M.x86.R_DI += inc;
7380 if (ACCESS_FLAG(F_ZF) == 0)
7381 break;
7382 }
7383 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7384 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7385 /* REPNE */
7386 /* move them until CX is ZERO. */
7387 while (M.x86.R_CX != 0) {
7388 val1 = fetch_data_byte(M.x86.R_SI);
7389 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7390 cmp_byte(val1, val2);
7391 M.x86.R_CX -= 1;
7392 M.x86.R_SI += inc;
7393 M.x86.R_DI += inc;
7394 if (ACCESS_FLAG(F_ZF))
7395 break; /* zero flag set means equal */
7396 }
7397 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7398 } else {
7399 val1 = fetch_data_byte(M.x86.R_SI);
7400 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7401 cmp_byte(val1, val2);
7402 M.x86.R_SI += inc;
7403 M.x86.R_DI += inc;
7404 }
7405 DECODE_CLEAR_SEGOVR();
7406 END_OF_INSTR();
7407 }
7408
7409 /****************************************************************************
7410 REMARKS:
7411 Handles opcode 0xa7
7412 ****************************************************************************/
x86emuOp_cmps_word(u8 X86EMU_UNUSED (op1))7413 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7414 {
7415 u32 val1,val2;
7416 int inc;
7417
7418 START_OF_INSTR();
7419 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7420 DECODE_PRINTF("CMPS\tDWORD\n");
7421 if (ACCESS_FLAG(F_DF)) /* down */
7422 inc = -4;
7423 else
7424 inc = 4;
7425 } else {
7426 DECODE_PRINTF("CMPS\tWORD\n");
7427 if (ACCESS_FLAG(F_DF)) /* down */
7428 inc = -2;
7429 else
7430 inc = 2;
7431 }
7432 TRACE_AND_STEP();
7433 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7434 /* REPE */
7435 /* move them until CX is ZERO. */
7436 while (M.x86.R_CX != 0) {
7437 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7438 val1 = fetch_data_long(M.x86.R_SI);
7439 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7440 cmp_long(val1, val2);
7441 } else {
7442 val1 = fetch_data_word(M.x86.R_SI);
7443 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7444 cmp_word((u16)val1, (u16)val2);
7445 }
7446 M.x86.R_CX -= 1;
7447 M.x86.R_SI += inc;
7448 M.x86.R_DI += inc;
7449 if (ACCESS_FLAG(F_ZF) == 0)
7450 break;
7451 }
7452 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7453 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7454 /* REPNE */
7455 /* move them until CX is ZERO. */
7456 while (M.x86.R_CX != 0) {
7457 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7458 val1 = fetch_data_long(M.x86.R_SI);
7459 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7460 cmp_long(val1, val2);
7461 } else {
7462 val1 = fetch_data_word(M.x86.R_SI);
7463 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7464 cmp_word((u16)val1, (u16)val2);
7465 }
7466 M.x86.R_CX -= 1;
7467 M.x86.R_SI += inc;
7468 M.x86.R_DI += inc;
7469 if (ACCESS_FLAG(F_ZF))
7470 break; /* zero flag set means equal */
7471 }
7472 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7473 } else {
7474 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7475 val1 = fetch_data_long(M.x86.R_SI);
7476 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7477 cmp_long(val1, val2);
7478 } else {
7479 val1 = fetch_data_word(M.x86.R_SI);
7480 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7481 cmp_word((u16)val1, (u16)val2);
7482 }
7483 M.x86.R_SI += inc;
7484 M.x86.R_DI += inc;
7485 }
7486 DECODE_CLEAR_SEGOVR();
7487 END_OF_INSTR();
7488 }
7489
7490 /****************************************************************************
7491 REMARKS:
7492 Handles opcode 0xa8
7493 ****************************************************************************/
x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED (op1))7494 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7495 {
7496 int imm;
7497
7498 START_OF_INSTR();
7499 DECODE_PRINTF("TEST\tAL,");
7500 imm = fetch_byte_imm();
7501 DECODE_PRINTF2("%04x\n", imm);
7502 TRACE_AND_STEP();
7503 test_byte(M.x86.R_AL, (u8)imm);
7504 DECODE_CLEAR_SEGOVR();
7505 END_OF_INSTR();
7506 }
7507
7508 /****************************************************************************
7509 REMARKS:
7510 Handles opcode 0xa9
7511 ****************************************************************************/
x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED (op1))7512 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7513 {
7514 u32 srcval;
7515
7516 START_OF_INSTR();
7517 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7518 DECODE_PRINTF("TEST\tEAX,");
7519 srcval = fetch_long_imm();
7520 } else {
7521 DECODE_PRINTF("TEST\tAX,");
7522 srcval = fetch_word_imm();
7523 }
7524 DECODE_PRINTF2("%x\n", srcval);
7525 TRACE_AND_STEP();
7526 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7527 test_long(M.x86.R_EAX, srcval);
7528 } else {
7529 test_word(M.x86.R_AX, (u16)srcval);
7530 }
7531 DECODE_CLEAR_SEGOVR();
7532 END_OF_INSTR();
7533 }
7534
7535 /****************************************************************************
7536 REMARKS:
7537 Handles opcode 0xaa
7538 ****************************************************************************/
x86emuOp_stos_byte(u8 X86EMU_UNUSED (op1))7539 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7540 {
7541 int inc;
7542
7543 START_OF_INSTR();
7544 DECODE_PRINTF("STOS\tBYTE\n");
7545 if (ACCESS_FLAG(F_DF)) /* down */
7546 inc = -1;
7547 else
7548 inc = 1;
7549 TRACE_AND_STEP();
7550 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7551 /* dont care whether REPE or REPNE */
7552 /* move them until CX is ZERO. */
7553 while (M.x86.R_CX != 0) {
7554 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7555 M.x86.R_CX -= 1;
7556 M.x86.R_DI += inc;
7557 }
7558 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7559 } else {
7560 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7561 M.x86.R_DI += inc;
7562 }
7563 DECODE_CLEAR_SEGOVR();
7564 END_OF_INSTR();
7565 }
7566
7567 /****************************************************************************
7568 REMARKS:
7569 Handles opcode 0xab
7570 ****************************************************************************/
x86emuOp_stos_word(u8 X86EMU_UNUSED (op1))7571 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7572 {
7573 int inc;
7574 u32 count;
7575
7576 START_OF_INSTR();
7577 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7578 DECODE_PRINTF("STOS\tDWORD\n");
7579 if (ACCESS_FLAG(F_DF)) /* down */
7580 inc = -4;
7581 else
7582 inc = 4;
7583 } else {
7584 DECODE_PRINTF("STOS\tWORD\n");
7585 if (ACCESS_FLAG(F_DF)) /* down */
7586 inc = -2;
7587 else
7588 inc = 2;
7589 }
7590 TRACE_AND_STEP();
7591 count = 1;
7592 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7593 /* dont care whether REPE or REPNE */
7594 /* move them until CX is ZERO. */
7595 count = M.x86.R_CX;
7596 M.x86.R_CX = 0;
7597 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7598 }
7599 while (count--) {
7600 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7601 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7602 } else {
7603 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7604 }
7605 M.x86.R_DI += inc;
7606 }
7607 DECODE_CLEAR_SEGOVR();
7608 END_OF_INSTR();
7609 }
7610
7611 /****************************************************************************
7612 REMARKS:
7613 Handles opcode 0xac
7614 ****************************************************************************/
x86emuOp_lods_byte(u8 X86EMU_UNUSED (op1))7615 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7616 {
7617 int inc;
7618
7619 START_OF_INSTR();
7620 DECODE_PRINTF("LODS\tBYTE\n");
7621 TRACE_AND_STEP();
7622 if (ACCESS_FLAG(F_DF)) /* down */
7623 inc = -1;
7624 else
7625 inc = 1;
7626 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7627 /* dont care whether REPE or REPNE */
7628 /* move them until CX is ZERO. */
7629 while (M.x86.R_CX != 0) {
7630 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7631 M.x86.R_CX -= 1;
7632 M.x86.R_SI += inc;
7633 }
7634 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7635 } else {
7636 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7637 M.x86.R_SI += inc;
7638 }
7639 DECODE_CLEAR_SEGOVR();
7640 END_OF_INSTR();
7641 }
7642
7643 /****************************************************************************
7644 REMARKS:
7645 Handles opcode 0xad
7646 ****************************************************************************/
x86emuOp_lods_word(u8 X86EMU_UNUSED (op1))7647 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7648 {
7649 int inc;
7650 u32 count;
7651
7652 START_OF_INSTR();
7653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7654 DECODE_PRINTF("LODS\tDWORD\n");
7655 if (ACCESS_FLAG(F_DF)) /* down */
7656 inc = -4;
7657 else
7658 inc = 4;
7659 } else {
7660 DECODE_PRINTF("LODS\tWORD\n");
7661 if (ACCESS_FLAG(F_DF)) /* down */
7662 inc = -2;
7663 else
7664 inc = 2;
7665 }
7666 TRACE_AND_STEP();
7667 count = 1;
7668 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7669 /* dont care whether REPE or REPNE */
7670 /* move them until CX is ZERO. */
7671 count = M.x86.R_CX;
7672 M.x86.R_CX = 0;
7673 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7674 }
7675 while (count--) {
7676 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7677 M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7678 } else {
7679 M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7680 }
7681 M.x86.R_SI += inc;
7682 }
7683 DECODE_CLEAR_SEGOVR();
7684 END_OF_INSTR();
7685 }
7686
7687 /****************************************************************************
7688 REMARKS:
7689 Handles opcode 0xae
7690 ****************************************************************************/
x86emuOp_scas_byte(u8 X86EMU_UNUSED (op1))7691 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7692 {
7693 s8 val2;
7694 int inc;
7695
7696 START_OF_INSTR();
7697 DECODE_PRINTF("SCAS\tBYTE\n");
7698 TRACE_AND_STEP();
7699 if (ACCESS_FLAG(F_DF)) /* down */
7700 inc = -1;
7701 else
7702 inc = 1;
7703 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7704 /* REPE */
7705 /* move them until CX is ZERO. */
7706 while (M.x86.R_CX != 0) {
7707 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7708 cmp_byte(M.x86.R_AL, val2);
7709 M.x86.R_CX -= 1;
7710 M.x86.R_DI += inc;
7711 if (ACCESS_FLAG(F_ZF) == 0)
7712 break;
7713 }
7714 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7715 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7716 /* REPNE */
7717 /* move them until CX is ZERO. */
7718 while (M.x86.R_CX != 0) {
7719 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7720 cmp_byte(M.x86.R_AL, val2);
7721 M.x86.R_CX -= 1;
7722 M.x86.R_DI += inc;
7723 if (ACCESS_FLAG(F_ZF))
7724 break; /* zero flag set means equal */
7725 }
7726 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7727 } else {
7728 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7729 cmp_byte(M.x86.R_AL, val2);
7730 M.x86.R_DI += inc;
7731 }
7732 DECODE_CLEAR_SEGOVR();
7733 END_OF_INSTR();
7734 }
7735
7736 /****************************************************************************
7737 REMARKS:
7738 Handles opcode 0xaf
7739 ****************************************************************************/
x86emuOp_scas_word(u8 X86EMU_UNUSED (op1))7740 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7741 {
7742 int inc;
7743 u32 val;
7744
7745 START_OF_INSTR();
7746 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7747 DECODE_PRINTF("SCAS\tDWORD\n");
7748 if (ACCESS_FLAG(F_DF)) /* down */
7749 inc = -4;
7750 else
7751 inc = 4;
7752 } else {
7753 DECODE_PRINTF("SCAS\tWORD\n");
7754 if (ACCESS_FLAG(F_DF)) /* down */
7755 inc = -2;
7756 else
7757 inc = 2;
7758 }
7759 TRACE_AND_STEP();
7760 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7761 /* REPE */
7762 /* move them until CX is ZERO. */
7763 while (M.x86.R_CX != 0) {
7764 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7765 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7766 cmp_long(M.x86.R_EAX, val);
7767 } else {
7768 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7769 cmp_word(M.x86.R_AX, (u16)val);
7770 }
7771 M.x86.R_CX -= 1;
7772 M.x86.R_DI += inc;
7773 if (ACCESS_FLAG(F_ZF) == 0)
7774 break;
7775 }
7776 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7777 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7778 /* REPNE */
7779 /* move them until CX is ZERO. */
7780 while (M.x86.R_CX != 0) {
7781 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7782 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7783 cmp_long(M.x86.R_EAX, val);
7784 } else {
7785 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7786 cmp_word(M.x86.R_AX, (u16)val);
7787 }
7788 M.x86.R_CX -= 1;
7789 M.x86.R_DI += inc;
7790 if (ACCESS_FLAG(F_ZF))
7791 break; /* zero flag set means equal */
7792 }
7793 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7794 } else {
7795 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7796 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7797 cmp_long(M.x86.R_EAX, val);
7798 } else {
7799 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7800 cmp_word(M.x86.R_AX, (u16)val);
7801 }
7802 M.x86.R_DI += inc;
7803 }
7804 DECODE_CLEAR_SEGOVR();
7805 END_OF_INSTR();
7806 }
7807
7808 /****************************************************************************
7809 REMARKS:
7810 Handles opcode 0xb0
7811 ****************************************************************************/
x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED (op1))7812 void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7813 {
7814 u8 imm;
7815
7816 START_OF_INSTR();
7817 DECODE_PRINTF("MOV\tAL,");
7818 imm = fetch_byte_imm();
7819 DECODE_PRINTF2("%x\n", imm);
7820 TRACE_AND_STEP();
7821 M.x86.R_AL = imm;
7822 DECODE_CLEAR_SEGOVR();
7823 END_OF_INSTR();
7824 }
7825
7826 /****************************************************************************
7827 REMARKS:
7828 Handles opcode 0xb1
7829 ****************************************************************************/
x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED (op1))7830 void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7831 {
7832 u8 imm;
7833
7834 START_OF_INSTR();
7835 DECODE_PRINTF("MOV\tCL,");
7836 imm = fetch_byte_imm();
7837 DECODE_PRINTF2("%x\n", imm);
7838 TRACE_AND_STEP();
7839 M.x86.R_CL = imm;
7840 DECODE_CLEAR_SEGOVR();
7841 END_OF_INSTR();
7842 }
7843
7844 /****************************************************************************
7845 REMARKS:
7846 Handles opcode 0xb2
7847 ****************************************************************************/
x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED (op1))7848 void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7849 {
7850 u8 imm;
7851
7852 START_OF_INSTR();
7853 DECODE_PRINTF("MOV\tDL,");
7854 imm = fetch_byte_imm();
7855 DECODE_PRINTF2("%x\n", imm);
7856 TRACE_AND_STEP();
7857 M.x86.R_DL = imm;
7858 DECODE_CLEAR_SEGOVR();
7859 END_OF_INSTR();
7860 }
7861
7862 /****************************************************************************
7863 REMARKS:
7864 Handles opcode 0xb3
7865 ****************************************************************************/
x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED (op1))7866 void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7867 {
7868 u8 imm;
7869
7870 START_OF_INSTR();
7871 DECODE_PRINTF("MOV\tBL,");
7872 imm = fetch_byte_imm();
7873 DECODE_PRINTF2("%x\n", imm);
7874 TRACE_AND_STEP();
7875 M.x86.R_BL = imm;
7876 DECODE_CLEAR_SEGOVR();
7877 END_OF_INSTR();
7878 }
7879
7880 /****************************************************************************
7881 REMARKS:
7882 Handles opcode 0xb4
7883 ****************************************************************************/
x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED (op1))7884 void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7885 {
7886 u8 imm;
7887
7888 START_OF_INSTR();
7889 DECODE_PRINTF("MOV\tAH,");
7890 imm = fetch_byte_imm();
7891 DECODE_PRINTF2("%x\n", imm);
7892 TRACE_AND_STEP();
7893 M.x86.R_AH = imm;
7894 DECODE_CLEAR_SEGOVR();
7895 END_OF_INSTR();
7896 }
7897
7898 /****************************************************************************
7899 REMARKS:
7900 Handles opcode 0xb5
7901 ****************************************************************************/
x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED (op1))7902 void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7903 {
7904 u8 imm;
7905
7906 START_OF_INSTR();
7907 DECODE_PRINTF("MOV\tCH,");
7908 imm = fetch_byte_imm();
7909 DECODE_PRINTF2("%x\n", imm);
7910 TRACE_AND_STEP();
7911 M.x86.R_CH = imm;
7912 DECODE_CLEAR_SEGOVR();
7913 END_OF_INSTR();
7914 }
7915
7916 /****************************************************************************
7917 REMARKS:
7918 Handles opcode 0xb6
7919 ****************************************************************************/
x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED (op1))7920 void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7921 {
7922 u8 imm;
7923
7924 START_OF_INSTR();
7925 DECODE_PRINTF("MOV\tDH,");
7926 imm = fetch_byte_imm();
7927 DECODE_PRINTF2("%x\n", imm);
7928 TRACE_AND_STEP();
7929 M.x86.R_DH = imm;
7930 DECODE_CLEAR_SEGOVR();
7931 END_OF_INSTR();
7932 }
7933
7934 /****************************************************************************
7935 REMARKS:
7936 Handles opcode 0xb7
7937 ****************************************************************************/
x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED (op1))7938 void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7939 {
7940 u8 imm;
7941
7942 START_OF_INSTR();
7943 DECODE_PRINTF("MOV\tBH,");
7944 imm = fetch_byte_imm();
7945 DECODE_PRINTF2("%x\n", imm);
7946 TRACE_AND_STEP();
7947 M.x86.R_BH = imm;
7948 DECODE_CLEAR_SEGOVR();
7949 END_OF_INSTR();
7950 }
7951
7952 /****************************************************************************
7953 REMARKS:
7954 Handles opcode 0xb8
7955 ****************************************************************************/
x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED (op1))7956 void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7957 {
7958 u32 srcval;
7959 START_OF_INSTR();
7960 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7961 DECODE_PRINTF("MOV\tEAX,");
7962 srcval = fetch_long_imm();
7963 } else {
7964 DECODE_PRINTF("MOV\tAX,");
7965 srcval = fetch_word_imm();
7966 }
7967 DECODE_PRINTF2("%x\n", srcval);
7968 TRACE_AND_STEP();
7969 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7970 M.x86.R_EAX = srcval;
7971 } else {
7972 M.x86.R_AX = (u16)srcval;
7973 }
7974 DECODE_CLEAR_SEGOVR();
7975 END_OF_INSTR();
7976 }
7977
7978 /****************************************************************************
7979 REMARKS:
7980 Handles opcode 0xb9
7981 ****************************************************************************/
x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED (op1))7982 void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7983 {
7984 u32 srcval;
7985
7986 START_OF_INSTR();
7987 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7988 DECODE_PRINTF("MOV\tECX,");
7989 srcval = fetch_long_imm();
7990 } else {
7991 DECODE_PRINTF("MOV\tCX,");
7992 srcval = fetch_word_imm();
7993 }
7994 DECODE_PRINTF2("%x\n", srcval);
7995 TRACE_AND_STEP();
7996 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7997 M.x86.R_ECX = srcval;
7998 } else {
7999 M.x86.R_CX = (u16)srcval;
8000 }
8001 DECODE_CLEAR_SEGOVR();
8002 END_OF_INSTR();
8003 }
8004
8005 /****************************************************************************
8006 REMARKS:
8007 Handles opcode 0xba
8008 ****************************************************************************/
x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED (op1))8009 void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8010 {
8011 u32 srcval;
8012
8013 START_OF_INSTR();
8014 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8015 DECODE_PRINTF("MOV\tEDX,");
8016 srcval = fetch_long_imm();
8017 } else {
8018 DECODE_PRINTF("MOV\tDX,");
8019 srcval = fetch_word_imm();
8020 }
8021 DECODE_PRINTF2("%x\n", srcval);
8022 TRACE_AND_STEP();
8023 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8024 M.x86.R_EDX = srcval;
8025 } else {
8026 M.x86.R_DX = (u16)srcval;
8027 }
8028 DECODE_CLEAR_SEGOVR();
8029 END_OF_INSTR();
8030 }
8031
8032 /****************************************************************************
8033 REMARKS:
8034 Handles opcode 0xbb
8035 ****************************************************************************/
x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED (op1))8036 void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8037 {
8038 u32 srcval;
8039
8040 START_OF_INSTR();
8041 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8042 DECODE_PRINTF("MOV\tEBX,");
8043 srcval = fetch_long_imm();
8044 } else {
8045 DECODE_PRINTF("MOV\tBX,");
8046 srcval = fetch_word_imm();
8047 }
8048 DECODE_PRINTF2("%x\n", srcval);
8049 TRACE_AND_STEP();
8050 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8051 M.x86.R_EBX = srcval;
8052 } else {
8053 M.x86.R_BX = (u16)srcval;
8054 }
8055 DECODE_CLEAR_SEGOVR();
8056 END_OF_INSTR();
8057 }
8058
8059 /****************************************************************************
8060 REMARKS:
8061 Handles opcode 0xbc
8062 ****************************************************************************/
x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED (op1))8063 void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8064 {
8065 u32 srcval;
8066
8067 START_OF_INSTR();
8068 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8069 DECODE_PRINTF("MOV\tESP,");
8070 srcval = fetch_long_imm();
8071 } else {
8072 DECODE_PRINTF("MOV\tSP,");
8073 srcval = fetch_word_imm();
8074 }
8075 DECODE_PRINTF2("%x\n", srcval);
8076 TRACE_AND_STEP();
8077 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8078 M.x86.R_ESP = srcval;
8079 } else {
8080 M.x86.R_SP = (u16)srcval;
8081 }
8082 DECODE_CLEAR_SEGOVR();
8083 END_OF_INSTR();
8084 }
8085
8086 /****************************************************************************
8087 REMARKS:
8088 Handles opcode 0xbd
8089 ****************************************************************************/
x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED (op1))8090 void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8091 {
8092 u32 srcval;
8093
8094 START_OF_INSTR();
8095 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8096 DECODE_PRINTF("MOV\tEBP,");
8097 srcval = fetch_long_imm();
8098 } else {
8099 DECODE_PRINTF("MOV\tBP,");
8100 srcval = fetch_word_imm();
8101 }
8102 DECODE_PRINTF2("%x\n", srcval);
8103 TRACE_AND_STEP();
8104 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8105 M.x86.R_EBP = srcval;
8106 } else {
8107 M.x86.R_BP = (u16)srcval;
8108 }
8109 DECODE_CLEAR_SEGOVR();
8110 END_OF_INSTR();
8111 }
8112
8113 /****************************************************************************
8114 REMARKS:
8115 Handles opcode 0xbe
8116 ****************************************************************************/
x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED (op1))8117 void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8118 {
8119 u32 srcval;
8120
8121 START_OF_INSTR();
8122 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8123 DECODE_PRINTF("MOV\tESI,");
8124 srcval = fetch_long_imm();
8125 } else {
8126 DECODE_PRINTF("MOV\tSI,");
8127 srcval = fetch_word_imm();
8128 }
8129 DECODE_PRINTF2("%x\n", srcval);
8130 TRACE_AND_STEP();
8131 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8132 M.x86.R_ESI = srcval;
8133 } else {
8134 M.x86.R_SI = (u16)srcval;
8135 }
8136 DECODE_CLEAR_SEGOVR();
8137 END_OF_INSTR();
8138 }
8139
8140 /****************************************************************************
8141 REMARKS:
8142 Handles opcode 0xbf
8143 ****************************************************************************/
x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED (op1))8144 void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8145 {
8146 u32 srcval;
8147
8148 START_OF_INSTR();
8149 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8150 DECODE_PRINTF("MOV\tEDI,");
8151 srcval = fetch_long_imm();
8152 } else {
8153 DECODE_PRINTF("MOV\tDI,");
8154 srcval = fetch_word_imm();
8155 }
8156 DECODE_PRINTF2("%x\n", srcval);
8157 TRACE_AND_STEP();
8158 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8159 M.x86.R_EDI = srcval;
8160 } else {
8161 M.x86.R_DI = (u16)srcval;
8162 }
8163 DECODE_CLEAR_SEGOVR();
8164 END_OF_INSTR();
8165 }
8166
8167 /* used by opcodes c0, d0, and d2. */
8168 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8169 {
8170 rol_byte,
8171 ror_byte,
8172 rcl_byte,
8173 rcr_byte,
8174 shl_byte,
8175 shr_byte,
8176 shl_byte, /* sal_byte === shl_byte by definition */
8177 sar_byte,
8178 };
8179
8180 /****************************************************************************
8181 REMARKS:
8182 Handles opcode 0xc0
8183 ****************************************************************************/
x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED (op1))8184 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8185 {
8186 int mod, rl, rh;
8187 u8 *destreg;
8188 uint destoffset;
8189 u8 destval;
8190 u8 amt;
8191
8192 /*
8193 * Yet another weirdo special case instruction format. Part of
8194 * the opcode held below in "RH". Doubly nested case would
8195 * result, except that the decoded instruction
8196 */
8197 START_OF_INSTR();
8198 FETCH_DECODE_MODRM(mod, rh, rl);
8199 #ifdef DEBUG
8200 if (DEBUG_DECODE()) {
8201 /* XXX DECODE_PRINTF may be changed to something more
8202 general, so that it is important to leave the strings
8203 in the same format, even though the result is that the
8204 above test is done twice. */
8205
8206 switch (rh) {
8207 case 0:
8208 DECODE_PRINTF("ROL\t");
8209 break;
8210 case 1:
8211 DECODE_PRINTF("ROR\t");
8212 break;
8213 case 2:
8214 DECODE_PRINTF("RCL\t");
8215 break;
8216 case 3:
8217 DECODE_PRINTF("RCR\t");
8218 break;
8219 case 4:
8220 DECODE_PRINTF("SHL\t");
8221 break;
8222 case 5:
8223 DECODE_PRINTF("SHR\t");
8224 break;
8225 case 6:
8226 DECODE_PRINTF("SAL\t");
8227 break;
8228 case 7:
8229 DECODE_PRINTF("SAR\t");
8230 break;
8231 }
8232 }
8233 #endif
8234 /* know operation, decode the mod byte to find the addressing
8235 mode. */
8236 switch (mod) {
8237 case 0:
8238 DECODE_PRINTF("BYTE PTR ");
8239 destoffset = decode_rm00_address(rl);
8240 amt = fetch_byte_imm();
8241 DECODE_PRINTF2(",%x\n", amt);
8242 destval = fetch_data_byte(destoffset);
8243 TRACE_AND_STEP();
8244 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8245 store_data_byte(destoffset, destval);
8246 break;
8247 case 1:
8248 DECODE_PRINTF("BYTE PTR ");
8249 destoffset = decode_rm01_address(rl);
8250 amt = fetch_byte_imm();
8251 DECODE_PRINTF2(",%x\n", amt);
8252 destval = fetch_data_byte(destoffset);
8253 TRACE_AND_STEP();
8254 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8255 store_data_byte(destoffset, destval);
8256 break;
8257 case 2:
8258 DECODE_PRINTF("BYTE PTR ");
8259 destoffset = decode_rm10_address(rl);
8260 amt = fetch_byte_imm();
8261 DECODE_PRINTF2(",%x\n", amt);
8262 destval = fetch_data_byte(destoffset);
8263 TRACE_AND_STEP();
8264 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8265 store_data_byte(destoffset, destval);
8266 break;
8267 case 3: /* register to register */
8268 destreg = DECODE_RM_BYTE_REGISTER(rl);
8269 amt = fetch_byte_imm();
8270 DECODE_PRINTF2(",%x\n", amt);
8271 TRACE_AND_STEP();
8272 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8273 *destreg = destval;
8274 break;
8275 }
8276 DECODE_CLEAR_SEGOVR();
8277 END_OF_INSTR();
8278 }
8279
8280 /* used by opcodes c1, d1, and d3. */
8281 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8282 {
8283 rol_word,
8284 ror_word,
8285 rcl_word,
8286 rcr_word,
8287 shl_word,
8288 shr_word,
8289 shl_word, /* sal_byte === shl_byte by definition */
8290 sar_word,
8291 };
8292
8293 /* used by opcodes c1, d1, and d3. */
8294 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8295 {
8296 rol_long,
8297 ror_long,
8298 rcl_long,
8299 rcr_long,
8300 shl_long,
8301 shr_long,
8302 shl_long, /* sal_byte === shl_byte by definition */
8303 sar_long,
8304 };
8305
8306 /****************************************************************************
8307 REMARKS:
8308 Handles opcode 0xc1
8309 ****************************************************************************/
x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED (op1))8310 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8311 {
8312 int mod, rl, rh;
8313 uint destoffset;
8314 u8 amt;
8315
8316 /*
8317 * Yet another weirdo special case instruction format. Part of
8318 * the opcode held below in "RH". Doubly nested case would
8319 * result, except that the decoded instruction
8320 */
8321 START_OF_INSTR();
8322 FETCH_DECODE_MODRM(mod, rh, rl);
8323 #ifdef DEBUG
8324 if (DEBUG_DECODE()) {
8325 /* XXX DECODE_PRINTF may be changed to something more
8326 general, so that it is important to leave the strings
8327 in the same format, even though the result is that the
8328 above test is done twice. */
8329
8330 switch (rh) {
8331 case 0:
8332 DECODE_PRINTF("ROL\t");
8333 break;
8334 case 1:
8335 DECODE_PRINTF("ROR\t");
8336 break;
8337 case 2:
8338 DECODE_PRINTF("RCL\t");
8339 break;
8340 case 3:
8341 DECODE_PRINTF("RCR\t");
8342 break;
8343 case 4:
8344 DECODE_PRINTF("SHL\t");
8345 break;
8346 case 5:
8347 DECODE_PRINTF("SHR\t");
8348 break;
8349 case 6:
8350 DECODE_PRINTF("SAL\t");
8351 break;
8352 case 7:
8353 DECODE_PRINTF("SAR\t");
8354 break;
8355 }
8356 }
8357 #endif
8358 /* know operation, decode the mod byte to find the addressing
8359 mode. */
8360 switch (mod) {
8361 case 0:
8362 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8363 u32 destval;
8364
8365 DECODE_PRINTF("DWORD PTR ");
8366 destoffset = decode_rm00_address(rl);
8367 amt = fetch_byte_imm();
8368 DECODE_PRINTF2(",%x\n", amt);
8369 destval = fetch_data_long(destoffset);
8370 TRACE_AND_STEP();
8371 destval = (*opcD1_long_operation[rh]) (destval, amt);
8372 store_data_long(destoffset, destval);
8373 } else {
8374 u16 destval;
8375
8376 DECODE_PRINTF("WORD PTR ");
8377 destoffset = decode_rm00_address(rl);
8378 amt = fetch_byte_imm();
8379 DECODE_PRINTF2(",%x\n", amt);
8380 destval = fetch_data_word(destoffset);
8381 TRACE_AND_STEP();
8382 destval = (*opcD1_word_operation[rh]) (destval, amt);
8383 store_data_word(destoffset, destval);
8384 }
8385 break;
8386 case 1:
8387 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8388 u32 destval;
8389
8390 DECODE_PRINTF("DWORD PTR ");
8391 destoffset = decode_rm01_address(rl);
8392 amt = fetch_byte_imm();
8393 DECODE_PRINTF2(",%x\n", amt);
8394 destval = fetch_data_long(destoffset);
8395 TRACE_AND_STEP();
8396 destval = (*opcD1_long_operation[rh]) (destval, amt);
8397 store_data_long(destoffset, destval);
8398 } else {
8399 u16 destval;
8400
8401 DECODE_PRINTF("WORD PTR ");
8402 destoffset = decode_rm01_address(rl);
8403 amt = fetch_byte_imm();
8404 DECODE_PRINTF2(",%x\n", amt);
8405 destval = fetch_data_word(destoffset);
8406 TRACE_AND_STEP();
8407 destval = (*opcD1_word_operation[rh]) (destval, amt);
8408 store_data_word(destoffset, destval);
8409 }
8410 break;
8411 case 2:
8412 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8413 u32 destval;
8414
8415 DECODE_PRINTF("DWORD PTR ");
8416 destoffset = decode_rm10_address(rl);
8417 amt = fetch_byte_imm();
8418 DECODE_PRINTF2(",%x\n", amt);
8419 destval = fetch_data_long(destoffset);
8420 TRACE_AND_STEP();
8421 destval = (*opcD1_long_operation[rh]) (destval, amt);
8422 store_data_long(destoffset, destval);
8423 } else {
8424 u16 destval;
8425
8426 DECODE_PRINTF("WORD PTR ");
8427 destoffset = decode_rm10_address(rl);
8428 amt = fetch_byte_imm();
8429 DECODE_PRINTF2(",%x\n", amt);
8430 destval = fetch_data_word(destoffset);
8431 TRACE_AND_STEP();
8432 destval = (*opcD1_word_operation[rh]) (destval, amt);
8433 store_data_word(destoffset, destval);
8434 }
8435 break;
8436 case 3: /* register to register */
8437 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8438 u32 *destreg;
8439
8440 destreg = DECODE_RM_LONG_REGISTER(rl);
8441 amt = fetch_byte_imm();
8442 DECODE_PRINTF2(",%x\n", amt);
8443 TRACE_AND_STEP();
8444 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8445 } else {
8446 u16 *destreg;
8447
8448 destreg = DECODE_RM_WORD_REGISTER(rl);
8449 amt = fetch_byte_imm();
8450 DECODE_PRINTF2(",%x\n", amt);
8451 TRACE_AND_STEP();
8452 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8453 }
8454 break;
8455 }
8456 DECODE_CLEAR_SEGOVR();
8457 END_OF_INSTR();
8458 }
8459
8460 /****************************************************************************
8461 REMARKS:
8462 Handles opcode 0xc2
8463 ****************************************************************************/
x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED (op1))8464 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8465 {
8466 u16 imm;
8467
8468 START_OF_INSTR();
8469 DECODE_PRINTF("RET\t");
8470 imm = fetch_word_imm();
8471 DECODE_PRINTF2("%x\n", imm);
8472 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8473 TRACE_AND_STEP();
8474 M.x86.R_IP = pop_word();
8475 M.x86.R_SP += imm;
8476 DECODE_CLEAR_SEGOVR();
8477 END_OF_INSTR();
8478 }
8479
8480 /****************************************************************************
8481 REMARKS:
8482 Handles opcode 0xc3
8483 ****************************************************************************/
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))8484 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8485 {
8486 START_OF_INSTR();
8487 DECODE_PRINTF("RET\n");
8488 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8489 TRACE_AND_STEP();
8490 M.x86.R_IP = pop_word();
8491 DECODE_CLEAR_SEGOVR();
8492 END_OF_INSTR();
8493 }
8494
8495 /****************************************************************************
8496 REMARKS:
8497 Handles opcode 0xc4
8498 ****************************************************************************/
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))8499 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8500 {
8501 int mod, rh, rl;
8502 u16 *dstreg;
8503 uint srcoffset;
8504
8505 START_OF_INSTR();
8506 DECODE_PRINTF("LES\t");
8507 FETCH_DECODE_MODRM(mod, rh, rl);
8508 switch (mod) {
8509 case 0:
8510 dstreg = DECODE_RM_WORD_REGISTER(rh);
8511 DECODE_PRINTF(",");
8512 srcoffset = decode_rm00_address(rl);
8513 DECODE_PRINTF("\n");
8514 TRACE_AND_STEP();
8515 *dstreg = fetch_data_word(srcoffset);
8516 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8517 break;
8518 case 1:
8519 dstreg = DECODE_RM_WORD_REGISTER(rh);
8520 DECODE_PRINTF(",");
8521 srcoffset = decode_rm01_address(rl);
8522 DECODE_PRINTF("\n");
8523 TRACE_AND_STEP();
8524 *dstreg = fetch_data_word(srcoffset);
8525 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8526 break;
8527 case 2:
8528 dstreg = DECODE_RM_WORD_REGISTER(rh);
8529 DECODE_PRINTF(",");
8530 srcoffset = decode_rm10_address(rl);
8531 DECODE_PRINTF("\n");
8532 TRACE_AND_STEP();
8533 *dstreg = fetch_data_word(srcoffset);
8534 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8535 break;
8536 case 3: /* register to register */
8537 /* UNDEFINED! */
8538 TRACE_AND_STEP();
8539 }
8540 DECODE_CLEAR_SEGOVR();
8541 END_OF_INSTR();
8542 }
8543
8544 /****************************************************************************
8545 REMARKS:
8546 Handles opcode 0xc5
8547 ****************************************************************************/
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))8548 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8549 {
8550 int mod, rh, rl;
8551 u16 *dstreg;
8552 uint srcoffset;
8553
8554 START_OF_INSTR();
8555 DECODE_PRINTF("LDS\t");
8556 FETCH_DECODE_MODRM(mod, rh, rl);
8557 switch (mod) {
8558 case 0:
8559 dstreg = DECODE_RM_WORD_REGISTER(rh);
8560 DECODE_PRINTF(",");
8561 srcoffset = decode_rm00_address(rl);
8562 DECODE_PRINTF("\n");
8563 TRACE_AND_STEP();
8564 *dstreg = fetch_data_word(srcoffset);
8565 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8566 break;
8567 case 1:
8568 dstreg = DECODE_RM_WORD_REGISTER(rh);
8569 DECODE_PRINTF(",");
8570 srcoffset = decode_rm01_address(rl);
8571 DECODE_PRINTF("\n");
8572 TRACE_AND_STEP();
8573 *dstreg = fetch_data_word(srcoffset);
8574 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8575 break;
8576 case 2:
8577 dstreg = DECODE_RM_WORD_REGISTER(rh);
8578 DECODE_PRINTF(",");
8579 srcoffset = decode_rm10_address(rl);
8580 DECODE_PRINTF("\n");
8581 TRACE_AND_STEP();
8582 *dstreg = fetch_data_word(srcoffset);
8583 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8584 break;
8585 case 3: /* register to register */
8586 /* UNDEFINED! */
8587 TRACE_AND_STEP();
8588 }
8589 DECODE_CLEAR_SEGOVR();
8590 END_OF_INSTR();
8591 }
8592
8593 /****************************************************************************
8594 REMARKS:
8595 Handles opcode 0xc6
8596 ****************************************************************************/
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))8597 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8598 {
8599 int mod, rl, rh;
8600 u8 *destreg;
8601 uint destoffset;
8602 u8 imm;
8603
8604 START_OF_INSTR();
8605 DECODE_PRINTF("MOV\t");
8606 FETCH_DECODE_MODRM(mod, rh, rl);
8607 if (rh != 0) {
8608 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8609 HALT_SYS();
8610 }
8611 switch (mod) {
8612 case 0:
8613 DECODE_PRINTF("BYTE PTR ");
8614 destoffset = decode_rm00_address(rl);
8615 imm = fetch_byte_imm();
8616 DECODE_PRINTF2(",%2x\n", imm);
8617 TRACE_AND_STEP();
8618 store_data_byte(destoffset, imm);
8619 break;
8620 case 1:
8621 DECODE_PRINTF("BYTE PTR ");
8622 destoffset = decode_rm01_address(rl);
8623 imm = fetch_byte_imm();
8624 DECODE_PRINTF2(",%2x\n", imm);
8625 TRACE_AND_STEP();
8626 store_data_byte(destoffset, imm);
8627 break;
8628 case 2:
8629 DECODE_PRINTF("BYTE PTR ");
8630 destoffset = decode_rm10_address(rl);
8631 imm = fetch_byte_imm();
8632 DECODE_PRINTF2(",%2x\n", imm);
8633 TRACE_AND_STEP();
8634 store_data_byte(destoffset, imm);
8635 break;
8636 case 3: /* register to register */
8637 destreg = DECODE_RM_BYTE_REGISTER(rl);
8638 imm = fetch_byte_imm();
8639 DECODE_PRINTF2(",%2x\n", imm);
8640 TRACE_AND_STEP();
8641 *destreg = imm;
8642 break;
8643 }
8644 DECODE_CLEAR_SEGOVR();
8645 END_OF_INSTR();
8646 }
8647
8648 /****************************************************************************
8649 REMARKS:
8650 Handles opcode 0xc7
8651 ****************************************************************************/
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))8652 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8653 {
8654 int mod, rl, rh;
8655 uint destoffset;
8656
8657 START_OF_INSTR();
8658 DECODE_PRINTF("MOV\t");
8659 FETCH_DECODE_MODRM(mod, rh, rl);
8660 if (rh != 0) {
8661 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8662 HALT_SYS();
8663 }
8664 switch (mod) {
8665 case 0:
8666 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8667 u32 imm;
8668
8669 DECODE_PRINTF("DWORD PTR ");
8670 destoffset = decode_rm00_address(rl);
8671 imm = fetch_long_imm();
8672 DECODE_PRINTF2(",%x\n", imm);
8673 TRACE_AND_STEP();
8674 store_data_long(destoffset, imm);
8675 } else {
8676 u16 imm;
8677
8678 DECODE_PRINTF("WORD PTR ");
8679 destoffset = decode_rm00_address(rl);
8680 imm = fetch_word_imm();
8681 DECODE_PRINTF2(",%x\n", imm);
8682 TRACE_AND_STEP();
8683 store_data_word(destoffset, imm);
8684 }
8685 break;
8686 case 1:
8687 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8688 u32 imm;
8689
8690 DECODE_PRINTF("DWORD PTR ");
8691 destoffset = decode_rm01_address(rl);
8692 imm = fetch_long_imm();
8693 DECODE_PRINTF2(",%x\n", imm);
8694 TRACE_AND_STEP();
8695 store_data_long(destoffset, imm);
8696 } else {
8697 u16 imm;
8698
8699 DECODE_PRINTF("WORD PTR ");
8700 destoffset = decode_rm01_address(rl);
8701 imm = fetch_word_imm();
8702 DECODE_PRINTF2(",%x\n", imm);
8703 TRACE_AND_STEP();
8704 store_data_word(destoffset, imm);
8705 }
8706 break;
8707 case 2:
8708 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8709 u32 imm;
8710
8711 DECODE_PRINTF("DWORD PTR ");
8712 destoffset = decode_rm10_address(rl);
8713 imm = fetch_long_imm();
8714 DECODE_PRINTF2(",%x\n", imm);
8715 TRACE_AND_STEP();
8716 store_data_long(destoffset, imm);
8717 } else {
8718 u16 imm;
8719
8720 DECODE_PRINTF("WORD PTR ");
8721 destoffset = decode_rm10_address(rl);
8722 imm = fetch_word_imm();
8723 DECODE_PRINTF2(",%x\n", imm);
8724 TRACE_AND_STEP();
8725 store_data_word(destoffset, imm);
8726 }
8727 break;
8728 case 3: /* register to register */
8729 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8730 u32 *destreg;
8731 u32 imm;
8732
8733 destreg = DECODE_RM_LONG_REGISTER(rl);
8734 imm = fetch_long_imm();
8735 DECODE_PRINTF2(",%x\n", imm);
8736 TRACE_AND_STEP();
8737 *destreg = imm;
8738 } else {
8739 u16 *destreg;
8740 u16 imm;
8741
8742 destreg = DECODE_RM_WORD_REGISTER(rl);
8743 imm = fetch_word_imm();
8744 DECODE_PRINTF2(",%x\n", imm);
8745 TRACE_AND_STEP();
8746 *destreg = imm;
8747 }
8748 break;
8749 }
8750 DECODE_CLEAR_SEGOVR();
8751 END_OF_INSTR();
8752 }
8753
8754 /****************************************************************************
8755 REMARKS:
8756 Handles opcode 0xc8
8757 ****************************************************************************/
x86emuOp_enter(u8 X86EMU_UNUSED (op1))8758 void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8759 {
8760 u16 local,frame_pointer;
8761 u8 nesting;
8762 int i;
8763
8764 START_OF_INSTR();
8765 local = fetch_word_imm();
8766 nesting = fetch_byte_imm();
8767 DECODE_PRINTF2("ENTER %x\n", local);
8768 DECODE_PRINTF2(",%x\n", nesting);
8769 TRACE_AND_STEP();
8770 push_word(M.x86.R_BP);
8771 frame_pointer = M.x86.R_SP;
8772 if (nesting > 0) {
8773 for (i = 1; i < nesting; i++) {
8774 M.x86.R_BP -= 2;
8775 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8776 }
8777 push_word(frame_pointer);
8778 }
8779 M.x86.R_BP = frame_pointer;
8780 M.x86.R_SP = (u16)(M.x86.R_SP - local);
8781 DECODE_CLEAR_SEGOVR();
8782 END_OF_INSTR();
8783 }
8784
8785 /****************************************************************************
8786 REMARKS:
8787 Handles opcode 0xc9
8788 ****************************************************************************/
x86emuOp_leave(u8 X86EMU_UNUSED (op1))8789 void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8790 {
8791 START_OF_INSTR();
8792 DECODE_PRINTF("LEAVE\n");
8793 TRACE_AND_STEP();
8794 M.x86.R_SP = M.x86.R_BP;
8795 M.x86.R_BP = pop_word();
8796 DECODE_CLEAR_SEGOVR();
8797 END_OF_INSTR();
8798 }
8799
8800 /****************************************************************************
8801 REMARKS:
8802 Handles opcode 0xca
8803 ****************************************************************************/
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))8804 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8805 {
8806 u16 imm;
8807
8808 START_OF_INSTR();
8809 DECODE_PRINTF("RETF\t");
8810 imm = fetch_word_imm();
8811 DECODE_PRINTF2("%x\n", imm);
8812 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8813 TRACE_AND_STEP();
8814 M.x86.R_IP = pop_word();
8815 M.x86.R_CS = pop_word();
8816 M.x86.R_SP += imm;
8817 DECODE_CLEAR_SEGOVR();
8818 END_OF_INSTR();
8819 }
8820
8821 /****************************************************************************
8822 REMARKS:
8823 Handles opcode 0xcb
8824 ****************************************************************************/
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))8825 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8826 {
8827 START_OF_INSTR();
8828 DECODE_PRINTF("RETF\n");
8829 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8830 TRACE_AND_STEP();
8831 M.x86.R_IP = pop_word();
8832 M.x86.R_CS = pop_word();
8833 DECODE_CLEAR_SEGOVR();
8834 END_OF_INSTR();
8835 }
8836
8837 /****************************************************************************
8838 REMARKS:
8839 Handles opcode 0xcc
8840 ****************************************************************************/
x86emuOp_int3(u8 X86EMU_UNUSED (op1))8841 void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8842 {
8843 u16 tmp;
8844
8845 START_OF_INSTR();
8846 DECODE_PRINTF("INT 3\n");
8847 tmp = (u16) mem_access_word(3 * 4 + 2);
8848 /* access the segment register */
8849 TRACE_AND_STEP();
8850 if (_X86EMU_intrTab[3]) {
8851 (*_X86EMU_intrTab[3])(3);
8852 } else {
8853 push_word((u16)M.x86.R_FLG);
8854 CLEAR_FLAG(F_IF);
8855 CLEAR_FLAG(F_TF);
8856 push_word(M.x86.R_CS);
8857 M.x86.R_CS = mem_access_word(3 * 4 + 2);
8858 push_word(M.x86.R_IP);
8859 M.x86.R_IP = mem_access_word(3 * 4);
8860 }
8861 DECODE_CLEAR_SEGOVR();
8862 END_OF_INSTR();
8863 }
8864
8865 /****************************************************************************
8866 REMARKS:
8867 Handles opcode 0xcd
8868 ****************************************************************************/
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))8869 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8870 {
8871 u16 tmp;
8872 u8 intnum;
8873
8874 START_OF_INSTR();
8875 DECODE_PRINTF("INT\t");
8876 intnum = fetch_byte_imm();
8877 DECODE_PRINTF2("%x\n", intnum);
8878 tmp = mem_access_word(intnum * 4 + 2);
8879 TRACE_AND_STEP();
8880 if (_X86EMU_intrTab[intnum]) {
8881 (*_X86EMU_intrTab[intnum])(intnum);
8882 } else {
8883 push_word((u16)M.x86.R_FLG);
8884 CLEAR_FLAG(F_IF);
8885 CLEAR_FLAG(F_TF);
8886 push_word(M.x86.R_CS);
8887 M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8888 push_word(M.x86.R_IP);
8889 M.x86.R_IP = mem_access_word(intnum * 4);
8890 }
8891 DECODE_CLEAR_SEGOVR();
8892 END_OF_INSTR();
8893 }
8894
8895 /****************************************************************************
8896 REMARKS:
8897 Handles opcode 0xce
8898 ****************************************************************************/
x86emuOp_into(u8 X86EMU_UNUSED (op1))8899 void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8900 {
8901 u16 tmp;
8902
8903 START_OF_INSTR();
8904 DECODE_PRINTF("INTO\n");
8905 TRACE_AND_STEP();
8906 if (ACCESS_FLAG(F_OF)) {
8907 tmp = mem_access_word(4 * 4 + 2);
8908 if (_X86EMU_intrTab[4]) {
8909 (*_X86EMU_intrTab[4])(4);
8910 } else {
8911 push_word((u16)M.x86.R_FLG);
8912 CLEAR_FLAG(F_IF);
8913 CLEAR_FLAG(F_TF);
8914 push_word(M.x86.R_CS);
8915 M.x86.R_CS = mem_access_word(4 * 4 + 2);
8916 push_word(M.x86.R_IP);
8917 M.x86.R_IP = mem_access_word(4 * 4);
8918 }
8919 }
8920 DECODE_CLEAR_SEGOVR();
8921 END_OF_INSTR();
8922 }
8923
8924 /****************************************************************************
8925 REMARKS:
8926 Handles opcode 0xcf
8927 ****************************************************************************/
x86emuOp_iret(u8 X86EMU_UNUSED (op1))8928 void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8929 {
8930 START_OF_INSTR();
8931 DECODE_PRINTF("IRET\n");
8932
8933 TRACE_AND_STEP();
8934
8935 M.x86.R_IP = pop_word();
8936 M.x86.R_CS = pop_word();
8937 M.x86.R_FLG = pop_word();
8938 DECODE_CLEAR_SEGOVR();
8939 END_OF_INSTR();
8940 }
8941
8942 /****************************************************************************
8943 REMARKS:
8944 Handles opcode 0xd0
8945 ****************************************************************************/
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))8946 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8947 {
8948 int mod, rl, rh;
8949 u8 *destreg;
8950 uint destoffset;
8951 u8 destval;
8952
8953 /*
8954 * Yet another weirdo special case instruction format. Part of
8955 * the opcode held below in "RH". Doubly nested case would
8956 * result, except that the decoded instruction
8957 */
8958 START_OF_INSTR();
8959 FETCH_DECODE_MODRM(mod, rh, rl);
8960 #ifdef DEBUG
8961 if (DEBUG_DECODE()) {
8962 /* XXX DECODE_PRINTF may be changed to something more
8963 general, so that it is important to leave the strings
8964 in the same format, even though the result is that the
8965 above test is done twice. */
8966 switch (rh) {
8967 case 0:
8968 DECODE_PRINTF("ROL\t");
8969 break;
8970 case 1:
8971 DECODE_PRINTF("ROR\t");
8972 break;
8973 case 2:
8974 DECODE_PRINTF("RCL\t");
8975 break;
8976 case 3:
8977 DECODE_PRINTF("RCR\t");
8978 break;
8979 case 4:
8980 DECODE_PRINTF("SHL\t");
8981 break;
8982 case 5:
8983 DECODE_PRINTF("SHR\t");
8984 break;
8985 case 6:
8986 DECODE_PRINTF("SAL\t");
8987 break;
8988 case 7:
8989 DECODE_PRINTF("SAR\t");
8990 break;
8991 }
8992 }
8993 #endif
8994 /* know operation, decode the mod byte to find the addressing
8995 mode. */
8996 switch (mod) {
8997 case 0:
8998 DECODE_PRINTF("BYTE PTR ");
8999 destoffset = decode_rm00_address(rl);
9000 DECODE_PRINTF(",1\n");
9001 destval = fetch_data_byte(destoffset);
9002 TRACE_AND_STEP();
9003 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9004 store_data_byte(destoffset, destval);
9005 break;
9006 case 1:
9007 DECODE_PRINTF("BYTE PTR ");
9008 destoffset = decode_rm01_address(rl);
9009 DECODE_PRINTF(",1\n");
9010 destval = fetch_data_byte(destoffset);
9011 TRACE_AND_STEP();
9012 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9013 store_data_byte(destoffset, destval);
9014 break;
9015 case 2:
9016 DECODE_PRINTF("BYTE PTR ");
9017 destoffset = decode_rm10_address(rl);
9018 DECODE_PRINTF(",1\n");
9019 destval = fetch_data_byte(destoffset);
9020 TRACE_AND_STEP();
9021 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9022 store_data_byte(destoffset, destval);
9023 break;
9024 case 3: /* register to register */
9025 destreg = DECODE_RM_BYTE_REGISTER(rl);
9026 DECODE_PRINTF(",1\n");
9027 TRACE_AND_STEP();
9028 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9029 *destreg = destval;
9030 break;
9031 }
9032 DECODE_CLEAR_SEGOVR();
9033 END_OF_INSTR();
9034 }
9035
9036 /****************************************************************************
9037 REMARKS:
9038 Handles opcode 0xd1
9039 ****************************************************************************/
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))9040 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9041 {
9042 int mod, rl, rh;
9043 uint destoffset;
9044
9045 /*
9046 * Yet another weirdo special case instruction format. Part of
9047 * the opcode held below in "RH". Doubly nested case would
9048 * result, except that the decoded instruction
9049 */
9050 START_OF_INSTR();
9051 FETCH_DECODE_MODRM(mod, rh, rl);
9052 #ifdef DEBUG
9053 if (DEBUG_DECODE()) {
9054 /* XXX DECODE_PRINTF may be changed to something more
9055 general, so that it is important to leave the strings
9056 in the same format, even though the result is that the
9057 above test is done twice. */
9058 switch (rh) {
9059 case 0:
9060 DECODE_PRINTF("ROL\t");
9061 break;
9062 case 1:
9063 DECODE_PRINTF("ROR\t");
9064 break;
9065 case 2:
9066 DECODE_PRINTF("RCL\t");
9067 break;
9068 case 3:
9069 DECODE_PRINTF("RCR\t");
9070 break;
9071 case 4:
9072 DECODE_PRINTF("SHL\t");
9073 break;
9074 case 5:
9075 DECODE_PRINTF("SHR\t");
9076 break;
9077 case 6:
9078 DECODE_PRINTF("SAL\t");
9079 break;
9080 case 7:
9081 DECODE_PRINTF("SAR\t");
9082 break;
9083 }
9084 }
9085 #endif
9086 /* know operation, decode the mod byte to find the addressing
9087 mode. */
9088 switch (mod) {
9089 case 0:
9090 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9091 u32 destval;
9092
9093 DECODE_PRINTF("DWORD PTR ");
9094 destoffset = decode_rm00_address(rl);
9095 DECODE_PRINTF(",1\n");
9096 destval = fetch_data_long(destoffset);
9097 TRACE_AND_STEP();
9098 destval = (*opcD1_long_operation[rh]) (destval, 1);
9099 store_data_long(destoffset, destval);
9100 } else {
9101 u16 destval;
9102
9103 DECODE_PRINTF("WORD PTR ");
9104 destoffset = decode_rm00_address(rl);
9105 DECODE_PRINTF(",1\n");
9106 destval = fetch_data_word(destoffset);
9107 TRACE_AND_STEP();
9108 destval = (*opcD1_word_operation[rh]) (destval, 1);
9109 store_data_word(destoffset, destval);
9110 }
9111 break;
9112 case 1:
9113 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9114 u32 destval;
9115
9116 DECODE_PRINTF("DWORD PTR ");
9117 destoffset = decode_rm01_address(rl);
9118 DECODE_PRINTF(",1\n");
9119 destval = fetch_data_long(destoffset);
9120 TRACE_AND_STEP();
9121 destval = (*opcD1_long_operation[rh]) (destval, 1);
9122 store_data_long(destoffset, destval);
9123 } else {
9124 u16 destval;
9125
9126 DECODE_PRINTF("WORD PTR ");
9127 destoffset = decode_rm01_address(rl);
9128 DECODE_PRINTF(",1\n");
9129 destval = fetch_data_word(destoffset);
9130 TRACE_AND_STEP();
9131 destval = (*opcD1_word_operation[rh]) (destval, 1);
9132 store_data_word(destoffset, destval);
9133 }
9134 break;
9135 case 2:
9136 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9137 u32 destval;
9138
9139 DECODE_PRINTF("DWORD PTR ");
9140 destoffset = decode_rm10_address(rl);
9141 DECODE_PRINTF(",1\n");
9142 destval = fetch_data_long(destoffset);
9143 TRACE_AND_STEP();
9144 destval = (*opcD1_long_operation[rh]) (destval, 1);
9145 store_data_long(destoffset, destval);
9146 } else {
9147 u16 destval;
9148
9149 DECODE_PRINTF("BYTE PTR ");
9150 destoffset = decode_rm10_address(rl);
9151 DECODE_PRINTF(",1\n");
9152 destval = fetch_data_word(destoffset);
9153 TRACE_AND_STEP();
9154 destval = (*opcD1_word_operation[rh]) (destval, 1);
9155 store_data_word(destoffset, destval);
9156 }
9157 break;
9158 case 3: /* register to register */
9159 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9160 u32 destval;
9161 u32 *destreg;
9162
9163 destreg = DECODE_RM_LONG_REGISTER(rl);
9164 DECODE_PRINTF(",1\n");
9165 TRACE_AND_STEP();
9166 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9167 *destreg = destval;
9168 } else {
9169 u16 destval;
9170 u16 *destreg;
9171
9172 destreg = DECODE_RM_WORD_REGISTER(rl);
9173 DECODE_PRINTF(",1\n");
9174 TRACE_AND_STEP();
9175 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9176 *destreg = destval;
9177 }
9178 break;
9179 }
9180 DECODE_CLEAR_SEGOVR();
9181 END_OF_INSTR();
9182 }
9183
9184 /****************************************************************************
9185 REMARKS:
9186 Handles opcode 0xd2
9187 ****************************************************************************/
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))9188 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9189 {
9190 int mod, rl, rh;
9191 u8 *destreg;
9192 uint destoffset;
9193 u8 destval;
9194 u8 amt;
9195
9196 /*
9197 * Yet another weirdo special case instruction format. Part of
9198 * the opcode held below in "RH". Doubly nested case would
9199 * result, except that the decoded instruction
9200 */
9201 START_OF_INSTR();
9202 FETCH_DECODE_MODRM(mod, rh, rl);
9203 #ifdef DEBUG
9204 if (DEBUG_DECODE()) {
9205 /* XXX DECODE_PRINTF may be changed to something more
9206 general, so that it is important to leave the strings
9207 in the same format, even though the result is that the
9208 above test is done twice. */
9209 switch (rh) {
9210 case 0:
9211 DECODE_PRINTF("ROL\t");
9212 break;
9213 case 1:
9214 DECODE_PRINTF("ROR\t");
9215 break;
9216 case 2:
9217 DECODE_PRINTF("RCL\t");
9218 break;
9219 case 3:
9220 DECODE_PRINTF("RCR\t");
9221 break;
9222 case 4:
9223 DECODE_PRINTF("SHL\t");
9224 break;
9225 case 5:
9226 DECODE_PRINTF("SHR\t");
9227 break;
9228 case 6:
9229 DECODE_PRINTF("SAL\t");
9230 break;
9231 case 7:
9232 DECODE_PRINTF("SAR\t");
9233 break;
9234 }
9235 }
9236 #endif
9237 /* know operation, decode the mod byte to find the addressing
9238 mode. */
9239 amt = M.x86.R_CL;
9240 switch (mod) {
9241 case 0:
9242 DECODE_PRINTF("BYTE PTR ");
9243 destoffset = decode_rm00_address(rl);
9244 DECODE_PRINTF(",CL\n");
9245 destval = fetch_data_byte(destoffset);
9246 TRACE_AND_STEP();
9247 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9248 store_data_byte(destoffset, destval);
9249 break;
9250 case 1:
9251 DECODE_PRINTF("BYTE PTR ");
9252 destoffset = decode_rm01_address(rl);
9253 DECODE_PRINTF(",CL\n");
9254 destval = fetch_data_byte(destoffset);
9255 TRACE_AND_STEP();
9256 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9257 store_data_byte(destoffset, destval);
9258 break;
9259 case 2:
9260 DECODE_PRINTF("BYTE PTR ");
9261 destoffset = decode_rm10_address(rl);
9262 DECODE_PRINTF(",CL\n");
9263 destval = fetch_data_byte(destoffset);
9264 TRACE_AND_STEP();
9265 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9266 store_data_byte(destoffset, destval);
9267 break;
9268 case 3: /* register to register */
9269 destreg = DECODE_RM_BYTE_REGISTER(rl);
9270 DECODE_PRINTF(",CL\n");
9271 TRACE_AND_STEP();
9272 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9273 *destreg = destval;
9274 break;
9275 }
9276 DECODE_CLEAR_SEGOVR();
9277 END_OF_INSTR();
9278 }
9279
9280 /****************************************************************************
9281 REMARKS:
9282 Handles opcode 0xd3
9283 ****************************************************************************/
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))9284 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9285 {
9286 int mod, rl, rh;
9287 uint destoffset;
9288 u8 amt;
9289
9290 /*
9291 * Yet another weirdo special case instruction format. Part of
9292 * the opcode held below in "RH". Doubly nested case would
9293 * result, except that the decoded instruction
9294 */
9295 START_OF_INSTR();
9296 FETCH_DECODE_MODRM(mod, rh, rl);
9297 #ifdef DEBUG
9298 if (DEBUG_DECODE()) {
9299 /* XXX DECODE_PRINTF may be changed to something more
9300 general, so that it is important to leave the strings
9301 in the same format, even though the result is that the
9302 above test is done twice. */
9303 switch (rh) {
9304 case 0:
9305 DECODE_PRINTF("ROL\t");
9306 break;
9307 case 1:
9308 DECODE_PRINTF("ROR\t");
9309 break;
9310 case 2:
9311 DECODE_PRINTF("RCL\t");
9312 break;
9313 case 3:
9314 DECODE_PRINTF("RCR\t");
9315 break;
9316 case 4:
9317 DECODE_PRINTF("SHL\t");
9318 break;
9319 case 5:
9320 DECODE_PRINTF("SHR\t");
9321 break;
9322 case 6:
9323 DECODE_PRINTF("SAL\t");
9324 break;
9325 case 7:
9326 DECODE_PRINTF("SAR\t");
9327 break;
9328 }
9329 }
9330 #endif
9331 /* know operation, decode the mod byte to find the addressing
9332 mode. */
9333 amt = M.x86.R_CL;
9334 switch (mod) {
9335 case 0:
9336 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9337 u32 destval;
9338
9339 DECODE_PRINTF("DWORD PTR ");
9340 destoffset = decode_rm00_address(rl);
9341 DECODE_PRINTF(",CL\n");
9342 destval = fetch_data_long(destoffset);
9343 TRACE_AND_STEP();
9344 destval = (*opcD1_long_operation[rh]) (destval, amt);
9345 store_data_long(destoffset, destval);
9346 } else {
9347 u16 destval;
9348
9349 DECODE_PRINTF("WORD PTR ");
9350 destoffset = decode_rm00_address(rl);
9351 DECODE_PRINTF(",CL\n");
9352 destval = fetch_data_word(destoffset);
9353 TRACE_AND_STEP();
9354 destval = (*opcD1_word_operation[rh]) (destval, amt);
9355 store_data_word(destoffset, destval);
9356 }
9357 break;
9358 case 1:
9359 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9360 u32 destval;
9361
9362 DECODE_PRINTF("DWORD PTR ");
9363 destoffset = decode_rm01_address(rl);
9364 DECODE_PRINTF(",CL\n");
9365 destval = fetch_data_long(destoffset);
9366 TRACE_AND_STEP();
9367 destval = (*opcD1_long_operation[rh]) (destval, amt);
9368 store_data_long(destoffset, destval);
9369 } else {
9370 u16 destval;
9371
9372 DECODE_PRINTF("WORD PTR ");
9373 destoffset = decode_rm01_address(rl);
9374 DECODE_PRINTF(",CL\n");
9375 destval = fetch_data_word(destoffset);
9376 TRACE_AND_STEP();
9377 destval = (*opcD1_word_operation[rh]) (destval, amt);
9378 store_data_word(destoffset, destval);
9379 }
9380 break;
9381 case 2:
9382 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9383 u32 destval;
9384
9385 DECODE_PRINTF("DWORD PTR ");
9386 destoffset = decode_rm10_address(rl);
9387 DECODE_PRINTF(",CL\n");
9388 destval = fetch_data_long(destoffset);
9389 TRACE_AND_STEP();
9390 destval = (*opcD1_long_operation[rh]) (destval, amt);
9391 store_data_long(destoffset, destval);
9392 } else {
9393 u16 destval;
9394
9395 DECODE_PRINTF("WORD PTR ");
9396 destoffset = decode_rm10_address(rl);
9397 DECODE_PRINTF(",CL\n");
9398 destval = fetch_data_word(destoffset);
9399 TRACE_AND_STEP();
9400 destval = (*opcD1_word_operation[rh]) (destval, amt);
9401 store_data_word(destoffset, destval);
9402 }
9403 break;
9404 case 3: /* register to register */
9405 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9406 u32 *destreg;
9407
9408 destreg = DECODE_RM_LONG_REGISTER(rl);
9409 DECODE_PRINTF(",CL\n");
9410 TRACE_AND_STEP();
9411 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9412 } else {
9413 u16 *destreg;
9414
9415 destreg = DECODE_RM_WORD_REGISTER(rl);
9416 DECODE_PRINTF(",CL\n");
9417 TRACE_AND_STEP();
9418 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9419 }
9420 break;
9421 }
9422 DECODE_CLEAR_SEGOVR();
9423 END_OF_INSTR();
9424 }
9425
9426 /****************************************************************************
9427 REMARKS:
9428 Handles opcode 0xd4
9429 ****************************************************************************/
x86emuOp_aam(u8 X86EMU_UNUSED (op1))9430 void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9431 {
9432 u8 a;
9433
9434 START_OF_INSTR();
9435 DECODE_PRINTF("AAM\n");
9436 a = fetch_byte_imm(); /* this is a stupid encoding. */
9437 if (a != 10) {
9438 DECODE_PRINTF("ERROR DECODING AAM\n");
9439 TRACE_REGS();
9440 HALT_SYS();
9441 }
9442 TRACE_AND_STEP();
9443 /* note the type change here --- returning AL and AH in AX. */
9444 M.x86.R_AX = aam_word(M.x86.R_AL);
9445 DECODE_CLEAR_SEGOVR();
9446 END_OF_INSTR();
9447 }
9448
9449 /****************************************************************************
9450 REMARKS:
9451 Handles opcode 0xd5
9452 ****************************************************************************/
x86emuOp_aad(u8 X86EMU_UNUSED (op1))9453 void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9454 {
9455 u8 a;
9456
9457 START_OF_INSTR();
9458 DECODE_PRINTF("AAD\n");
9459 a = fetch_byte_imm();
9460 TRACE_AND_STEP();
9461 M.x86.R_AX = aad_word(M.x86.R_AX);
9462 DECODE_CLEAR_SEGOVR();
9463 END_OF_INSTR();
9464 }
9465
9466 /* opcode 0xd6 ILLEGAL OPCODE */
9467
9468 /****************************************************************************
9469 REMARKS:
9470 Handles opcode 0xd7
9471 ****************************************************************************/
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))9472 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9473 {
9474 u16 addr;
9475
9476 START_OF_INSTR();
9477 DECODE_PRINTF("XLAT\n");
9478 TRACE_AND_STEP();
9479 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9480 M.x86.R_AL = fetch_data_byte(addr);
9481 DECODE_CLEAR_SEGOVR();
9482 END_OF_INSTR();
9483 }
9484
9485 /* instuctions D8 .. DF are in i87_ops.c */
9486
9487 /****************************************************************************
9488 REMARKS:
9489 Handles opcode 0xe0
9490 ****************************************************************************/
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))9491 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9492 {
9493 s16 ip;
9494
9495 START_OF_INSTR();
9496 DECODE_PRINTF("LOOPNE\t");
9497 ip = (s8) fetch_byte_imm();
9498 ip += (s16) M.x86.R_IP;
9499 DECODE_PRINTF2("%04x\n", ip);
9500 TRACE_AND_STEP();
9501 M.x86.R_CX -= 1;
9502 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
9503 M.x86.R_IP = ip;
9504 DECODE_CLEAR_SEGOVR();
9505 END_OF_INSTR();
9506 }
9507
9508 /****************************************************************************
9509 REMARKS:
9510 Handles opcode 0xe1
9511 ****************************************************************************/
x86emuOp_loope(u8 X86EMU_UNUSED (op1))9512 void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9513 {
9514 s16 ip;
9515
9516 START_OF_INSTR();
9517 DECODE_PRINTF("LOOPE\t");
9518 ip = (s8) fetch_byte_imm();
9519 ip += (s16) M.x86.R_IP;
9520 DECODE_PRINTF2("%04x\n", ip);
9521 TRACE_AND_STEP();
9522 M.x86.R_CX -= 1;
9523 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
9524 M.x86.R_IP = ip;
9525 DECODE_CLEAR_SEGOVR();
9526 END_OF_INSTR();
9527 }
9528
9529 /****************************************************************************
9530 REMARKS:
9531 Handles opcode 0xe2
9532 ****************************************************************************/
x86emuOp_loop(u8 X86EMU_UNUSED (op1))9533 void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9534 {
9535 s16 ip;
9536
9537 START_OF_INSTR();
9538 DECODE_PRINTF("LOOP\t");
9539 ip = (s8) fetch_byte_imm();
9540 ip += (s16) M.x86.R_IP;
9541 DECODE_PRINTF2("%04x\n", ip);
9542 TRACE_AND_STEP();
9543 M.x86.R_CX -= 1;
9544 if (M.x86.R_CX != 0)
9545 M.x86.R_IP = ip;
9546 DECODE_CLEAR_SEGOVR();
9547 END_OF_INSTR();
9548 }
9549
9550 /****************************************************************************
9551 REMARKS:
9552 Handles opcode 0xe3
9553 ****************************************************************************/
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))9554 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9555 {
9556 u16 target;
9557 s8 offset;
9558
9559 /* jump to byte offset if overflow flag is set */
9560 START_OF_INSTR();
9561 DECODE_PRINTF("JCXZ\t");
9562 offset = (s8)fetch_byte_imm();
9563 target = (u16)(M.x86.R_IP + offset);
9564 DECODE_PRINTF2("%x\n", target);
9565 TRACE_AND_STEP();
9566 if (M.x86.R_CX == 0)
9567 M.x86.R_IP = target;
9568 DECODE_CLEAR_SEGOVR();
9569 END_OF_INSTR();
9570 }
9571
9572 /****************************************************************************
9573 REMARKS:
9574 Handles opcode 0xe4
9575 ****************************************************************************/
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))9576 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9577 {
9578 u8 port;
9579
9580 START_OF_INSTR();
9581 DECODE_PRINTF("IN\t");
9582 port = (u8) fetch_byte_imm();
9583 DECODE_PRINTF2("%x,AL\n", port);
9584 TRACE_AND_STEP();
9585 M.x86.R_AL = (*sys_inb)(port);
9586 DECODE_CLEAR_SEGOVR();
9587 END_OF_INSTR();
9588 }
9589
9590 /****************************************************************************
9591 REMARKS:
9592 Handles opcode 0xe5
9593 ****************************************************************************/
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))9594 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9595 {
9596 u8 port;
9597
9598 START_OF_INSTR();
9599 DECODE_PRINTF("IN\t");
9600 port = (u8) fetch_byte_imm();
9601 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9602 DECODE_PRINTF2("EAX,%x\n", port);
9603 } else {
9604 DECODE_PRINTF2("AX,%x\n", port);
9605 }
9606 TRACE_AND_STEP();
9607 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9608 M.x86.R_EAX = (*sys_inl)(port);
9609 } else {
9610 M.x86.R_AX = (*sys_inw)(port);
9611 }
9612 DECODE_CLEAR_SEGOVR();
9613 END_OF_INSTR();
9614 }
9615
9616 /****************************************************************************
9617 REMARKS:
9618 Handles opcode 0xe6
9619 ****************************************************************************/
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))9620 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9621 {
9622 u8 port;
9623
9624 START_OF_INSTR();
9625 DECODE_PRINTF("OUT\t");
9626 port = (u8) fetch_byte_imm();
9627 DECODE_PRINTF2("%x,AL\n", port);
9628 TRACE_AND_STEP();
9629 (*sys_outb)(port, M.x86.R_AL);
9630 DECODE_CLEAR_SEGOVR();
9631 END_OF_INSTR();
9632 }
9633
9634 /****************************************************************************
9635 REMARKS:
9636 Handles opcode 0xe7
9637 ****************************************************************************/
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))9638 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9639 {
9640 u8 port;
9641
9642 START_OF_INSTR();
9643 DECODE_PRINTF("OUT\t");
9644 port = (u8) fetch_byte_imm();
9645 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9646 DECODE_PRINTF2("%x,EAX\n", port);
9647 } else {
9648 DECODE_PRINTF2("%x,AX\n", port);
9649 }
9650 TRACE_AND_STEP();
9651 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9652 (*sys_outl)(port, M.x86.R_EAX);
9653 } else {
9654 (*sys_outw)(port, M.x86.R_AX);
9655 }
9656 DECODE_CLEAR_SEGOVR();
9657 END_OF_INSTR();
9658 }
9659
9660 /****************************************************************************
9661 REMARKS:
9662 Handles opcode 0xe8
9663 ****************************************************************************/
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))9664 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9665 {
9666 s16 ip;
9667
9668 START_OF_INSTR();
9669 DECODE_PRINTF("CALL\t");
9670 ip = (s16) fetch_word_imm();
9671 ip += (s16) M.x86.R_IP; /* CHECK SIGN */
9672 DECODE_PRINTF2("%04x\n", ip);
9673 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9674 TRACE_AND_STEP();
9675 push_word(M.x86.R_IP);
9676 M.x86.R_IP = ip;
9677 DECODE_CLEAR_SEGOVR();
9678 END_OF_INSTR();
9679 }
9680
9681 /****************************************************************************
9682 REMARKS:
9683 Handles opcode 0xe9
9684 ****************************************************************************/
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))9685 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9686 {
9687 int ip;
9688
9689 START_OF_INSTR();
9690 DECODE_PRINTF("JMP\t");
9691 ip = (s16)fetch_word_imm();
9692 ip += (s16)M.x86.R_IP;
9693 DECODE_PRINTF2("%04x\n", ip);
9694 TRACE_AND_STEP();
9695 M.x86.R_IP = (u16)ip;
9696 DECODE_CLEAR_SEGOVR();
9697 END_OF_INSTR();
9698 }
9699
9700 /****************************************************************************
9701 REMARKS:
9702 Handles opcode 0xea
9703 ****************************************************************************/
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))9704 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9705 {
9706 u16 cs, ip;
9707
9708 START_OF_INSTR();
9709 DECODE_PRINTF("JMP\tFAR ");
9710 ip = fetch_word_imm();
9711 cs = fetch_word_imm();
9712 DECODE_PRINTF2("%04x:", cs);
9713 DECODE_PRINTF2("%04x\n", ip);
9714 TRACE_AND_STEP();
9715 M.x86.R_IP = ip;
9716 M.x86.R_CS = cs;
9717 DECODE_CLEAR_SEGOVR();
9718 END_OF_INSTR();
9719 }
9720
9721 /****************************************************************************
9722 REMARKS:
9723 Handles opcode 0xeb
9724 ****************************************************************************/
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))9725 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9726 {
9727 u16 target;
9728 s8 offset;
9729
9730 START_OF_INSTR();
9731 DECODE_PRINTF("JMP\t");
9732 offset = (s8)fetch_byte_imm();
9733 target = (u16)(M.x86.R_IP + offset);
9734 DECODE_PRINTF2("%x\n", target);
9735 TRACE_AND_STEP();
9736 M.x86.R_IP = target;
9737 DECODE_CLEAR_SEGOVR();
9738 END_OF_INSTR();
9739 }
9740
9741 /****************************************************************************
9742 REMARKS:
9743 Handles opcode 0xec
9744 ****************************************************************************/
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))9745 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9746 {
9747 START_OF_INSTR();
9748 DECODE_PRINTF("IN\tAL,DX\n");
9749 TRACE_AND_STEP();
9750 M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9751 DECODE_CLEAR_SEGOVR();
9752 END_OF_INSTR();
9753 }
9754
9755 /****************************************************************************
9756 REMARKS:
9757 Handles opcode 0xed
9758 ****************************************************************************/
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))9759 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9760 {
9761 START_OF_INSTR();
9762 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9763 DECODE_PRINTF("IN\tEAX,DX\n");
9764 } else {
9765 DECODE_PRINTF("IN\tAX,DX\n");
9766 }
9767 TRACE_AND_STEP();
9768 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9769 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9770 } else {
9771 M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9772 }
9773 DECODE_CLEAR_SEGOVR();
9774 END_OF_INSTR();
9775 }
9776
9777 /****************************************************************************
9778 REMARKS:
9779 Handles opcode 0xee
9780 ****************************************************************************/
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))9781 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9782 {
9783 START_OF_INSTR();
9784 DECODE_PRINTF("OUT\tDX,AL\n");
9785 TRACE_AND_STEP();
9786 (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9787 DECODE_CLEAR_SEGOVR();
9788 END_OF_INSTR();
9789 }
9790
9791 /****************************************************************************
9792 REMARKS:
9793 Handles opcode 0xef
9794 ****************************************************************************/
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))9795 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9796 {
9797 START_OF_INSTR();
9798 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9799 DECODE_PRINTF("OUT\tDX,EAX\n");
9800 } else {
9801 DECODE_PRINTF("OUT\tDX,AX\n");
9802 }
9803 TRACE_AND_STEP();
9804 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9805 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9806 } else {
9807 (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9808 }
9809 DECODE_CLEAR_SEGOVR();
9810 END_OF_INSTR();
9811 }
9812
9813 /****************************************************************************
9814 REMARKS:
9815 Handles opcode 0xf0
9816 ****************************************************************************/
x86emuOp_lock(u8 X86EMU_UNUSED (op1))9817 void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9818 {
9819 START_OF_INSTR();
9820 DECODE_PRINTF("LOCK:\n");
9821 TRACE_AND_STEP();
9822 DECODE_CLEAR_SEGOVR();
9823 END_OF_INSTR();
9824 }
9825
9826 /*opcode 0xf1 ILLEGAL OPERATION */
9827
9828 /****************************************************************************
9829 REMARKS:
9830 Handles opcode 0xf2
9831 ****************************************************************************/
x86emuOp_repne(u8 X86EMU_UNUSED (op1))9832 void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9833 {
9834 START_OF_INSTR();
9835 DECODE_PRINTF("REPNE\n");
9836 TRACE_AND_STEP();
9837 M.x86.mode |= SYSMODE_PREFIX_REPNE;
9838 DECODE_CLEAR_SEGOVR();
9839 END_OF_INSTR();
9840 }
9841
9842 /****************************************************************************
9843 REMARKS:
9844 Handles opcode 0xf3
9845 ****************************************************************************/
x86emuOp_repe(u8 X86EMU_UNUSED (op1))9846 void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9847 {
9848 START_OF_INSTR();
9849 DECODE_PRINTF("REPE\n");
9850 TRACE_AND_STEP();
9851 M.x86.mode |= SYSMODE_PREFIX_REPE;
9852 DECODE_CLEAR_SEGOVR();
9853 END_OF_INSTR();
9854 }
9855
9856 /****************************************************************************
9857 REMARKS:
9858 Handles opcode 0xf4
9859 ****************************************************************************/
x86emuOp_halt(u8 X86EMU_UNUSED (op1))9860 void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9861 {
9862 START_OF_INSTR();
9863 DECODE_PRINTF("HALT\n");
9864 TRACE_AND_STEP();
9865 HALT_SYS();
9866 DECODE_CLEAR_SEGOVR();
9867 END_OF_INSTR();
9868 }
9869
9870 /****************************************************************************
9871 REMARKS:
9872 Handles opcode 0xf5
9873 ****************************************************************************/
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))9874 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9875 {
9876 /* complement the carry flag. */
9877 START_OF_INSTR();
9878 DECODE_PRINTF("CMC\n");
9879 TRACE_AND_STEP();
9880 TOGGLE_FLAG(F_CF);
9881 DECODE_CLEAR_SEGOVR();
9882 END_OF_INSTR();
9883 }
9884
9885 /****************************************************************************
9886 REMARKS:
9887 Handles opcode 0xf6
9888 ****************************************************************************/
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))9889 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9890 {
9891 int mod, rl, rh;
9892 u8 *destreg;
9893 uint destoffset;
9894 u8 destval, srcval;
9895
9896 /* long, drawn out code follows. Double switch for a total
9897 of 32 cases. */
9898 START_OF_INSTR();
9899 FETCH_DECODE_MODRM(mod, rh, rl);
9900 switch (mod) {
9901 case 0: /* mod=00 */
9902 switch (rh) {
9903 case 0: /* test byte imm */
9904 DECODE_PRINTF("TEST\tBYTE PTR ");
9905 destoffset = decode_rm00_address(rl);
9906 DECODE_PRINTF(",");
9907 srcval = fetch_byte_imm();
9908 DECODE_PRINTF2("%02x\n", srcval);
9909 destval = fetch_data_byte(destoffset);
9910 TRACE_AND_STEP();
9911 test_byte(destval, srcval);
9912 break;
9913 case 1:
9914 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9915 HALT_SYS();
9916 break;
9917 case 2:
9918 DECODE_PRINTF("NOT\tBYTE PTR ");
9919 destoffset = decode_rm00_address(rl);
9920 DECODE_PRINTF("\n");
9921 destval = fetch_data_byte(destoffset);
9922 TRACE_AND_STEP();
9923 destval = not_byte(destval);
9924 store_data_byte(destoffset, destval);
9925 break;
9926 case 3:
9927 DECODE_PRINTF("NEG\tBYTE PTR ");
9928 destoffset = decode_rm00_address(rl);
9929 DECODE_PRINTF("\n");
9930 destval = fetch_data_byte(destoffset);
9931 TRACE_AND_STEP();
9932 destval = neg_byte(destval);
9933 store_data_byte(destoffset, destval);
9934 break;
9935 case 4:
9936 DECODE_PRINTF("MUL\tBYTE PTR ");
9937 destoffset = decode_rm00_address(rl);
9938 DECODE_PRINTF("\n");
9939 destval = fetch_data_byte(destoffset);
9940 TRACE_AND_STEP();
9941 mul_byte(destval);
9942 break;
9943 case 5:
9944 DECODE_PRINTF("IMUL\tBYTE PTR ");
9945 destoffset = decode_rm00_address(rl);
9946 DECODE_PRINTF("\n");
9947 destval = fetch_data_byte(destoffset);
9948 TRACE_AND_STEP();
9949 imul_byte(destval);
9950 break;
9951 case 6:
9952 DECODE_PRINTF("DIV\tBYTE PTR ");
9953 destoffset = decode_rm00_address(rl);
9954 DECODE_PRINTF("\n");
9955 destval = fetch_data_byte(destoffset);
9956 TRACE_AND_STEP();
9957 div_byte(destval);
9958 break;
9959 case 7:
9960 DECODE_PRINTF("IDIV\tBYTE PTR ");
9961 destoffset = decode_rm00_address(rl);
9962 DECODE_PRINTF("\n");
9963 destval = fetch_data_byte(destoffset);
9964 TRACE_AND_STEP();
9965 idiv_byte(destval);
9966 break;
9967 }
9968 break; /* end mod==00 */
9969 case 1: /* mod=01 */
9970 switch (rh) {
9971 case 0: /* test byte imm */
9972 DECODE_PRINTF("TEST\tBYTE PTR ");
9973 destoffset = decode_rm01_address(rl);
9974 DECODE_PRINTF(",");
9975 srcval = fetch_byte_imm();
9976 DECODE_PRINTF2("%02x\n", srcval);
9977 destval = fetch_data_byte(destoffset);
9978 TRACE_AND_STEP();
9979 test_byte(destval, srcval);
9980 break;
9981 case 1:
9982 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9983 HALT_SYS();
9984 break;
9985 case 2:
9986 DECODE_PRINTF("NOT\tBYTE PTR ");
9987 destoffset = decode_rm01_address(rl);
9988 DECODE_PRINTF("\n");
9989 destval = fetch_data_byte(destoffset);
9990 TRACE_AND_STEP();
9991 destval = not_byte(destval);
9992 store_data_byte(destoffset, destval);
9993 break;
9994 case 3:
9995 DECODE_PRINTF("NEG\tBYTE PTR ");
9996 destoffset = decode_rm01_address(rl);
9997 DECODE_PRINTF("\n");
9998 destval = fetch_data_byte(destoffset);
9999 TRACE_AND_STEP();
10000 destval = neg_byte(destval);
10001 store_data_byte(destoffset, destval);
10002 break;
10003 case 4:
10004 DECODE_PRINTF("MUL\tBYTE PTR ");
10005 destoffset = decode_rm01_address(rl);
10006 DECODE_PRINTF("\n");
10007 destval = fetch_data_byte(destoffset);
10008 TRACE_AND_STEP();
10009 mul_byte(destval);
10010 break;
10011 case 5:
10012 DECODE_PRINTF("IMUL\tBYTE PTR ");
10013 destoffset = decode_rm01_address(rl);
10014 DECODE_PRINTF("\n");
10015 destval = fetch_data_byte(destoffset);
10016 TRACE_AND_STEP();
10017 imul_byte(destval);
10018 break;
10019 case 6:
10020 DECODE_PRINTF("DIV\tBYTE PTR ");
10021 destoffset = decode_rm01_address(rl);
10022 DECODE_PRINTF("\n");
10023 destval = fetch_data_byte(destoffset);
10024 TRACE_AND_STEP();
10025 div_byte(destval);
10026 break;
10027 case 7:
10028 DECODE_PRINTF("IDIV\tBYTE PTR ");
10029 destoffset = decode_rm01_address(rl);
10030 DECODE_PRINTF("\n");
10031 destval = fetch_data_byte(destoffset);
10032 TRACE_AND_STEP();
10033 idiv_byte(destval);
10034 break;
10035 }
10036 break; /* end mod==01 */
10037 case 2: /* mod=10 */
10038 switch (rh) {
10039 case 0: /* test byte imm */
10040 DECODE_PRINTF("TEST\tBYTE PTR ");
10041 destoffset = decode_rm10_address(rl);
10042 DECODE_PRINTF(",");
10043 srcval = fetch_byte_imm();
10044 DECODE_PRINTF2("%02x\n", srcval);
10045 destval = fetch_data_byte(destoffset);
10046 TRACE_AND_STEP();
10047 test_byte(destval, srcval);
10048 break;
10049 case 1:
10050 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10051 HALT_SYS();
10052 break;
10053 case 2:
10054 DECODE_PRINTF("NOT\tBYTE PTR ");
10055 destoffset = decode_rm10_address(rl);
10056 DECODE_PRINTF("\n");
10057 destval = fetch_data_byte(destoffset);
10058 TRACE_AND_STEP();
10059 destval = not_byte(destval);
10060 store_data_byte(destoffset, destval);
10061 break;
10062 case 3:
10063 DECODE_PRINTF("NEG\tBYTE PTR ");
10064 destoffset = decode_rm10_address(rl);
10065 DECODE_PRINTF("\n");
10066 destval = fetch_data_byte(destoffset);
10067 TRACE_AND_STEP();
10068 destval = neg_byte(destval);
10069 store_data_byte(destoffset, destval);
10070 break;
10071 case 4:
10072 DECODE_PRINTF("MUL\tBYTE PTR ");
10073 destoffset = decode_rm10_address(rl);
10074 DECODE_PRINTF("\n");
10075 destval = fetch_data_byte(destoffset);
10076 TRACE_AND_STEP();
10077 mul_byte(destval);
10078 break;
10079 case 5:
10080 DECODE_PRINTF("IMUL\tBYTE PTR ");
10081 destoffset = decode_rm10_address(rl);
10082 DECODE_PRINTF("\n");
10083 destval = fetch_data_byte(destoffset);
10084 TRACE_AND_STEP();
10085 imul_byte(destval);
10086 break;
10087 case 6:
10088 DECODE_PRINTF("DIV\tBYTE PTR ");
10089 destoffset = decode_rm10_address(rl);
10090 DECODE_PRINTF("\n");
10091 destval = fetch_data_byte(destoffset);
10092 TRACE_AND_STEP();
10093 div_byte(destval);
10094 break;
10095 case 7:
10096 DECODE_PRINTF("IDIV\tBYTE PTR ");
10097 destoffset = decode_rm10_address(rl);
10098 DECODE_PRINTF("\n");
10099 destval = fetch_data_byte(destoffset);
10100 TRACE_AND_STEP();
10101 idiv_byte(destval);
10102 break;
10103 }
10104 break; /* end mod==10 */
10105 case 3: /* mod=11 */
10106 switch (rh) {
10107 case 0: /* test byte imm */
10108 DECODE_PRINTF("TEST\t");
10109 destreg = DECODE_RM_BYTE_REGISTER(rl);
10110 DECODE_PRINTF(",");
10111 srcval = fetch_byte_imm();
10112 DECODE_PRINTF2("%02x\n", srcval);
10113 TRACE_AND_STEP();
10114 test_byte(*destreg, srcval);
10115 break;
10116 case 1:
10117 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10118 HALT_SYS();
10119 break;
10120 case 2:
10121 DECODE_PRINTF("NOT\t");
10122 destreg = DECODE_RM_BYTE_REGISTER(rl);
10123 DECODE_PRINTF("\n");
10124 TRACE_AND_STEP();
10125 *destreg = not_byte(*destreg);
10126 break;
10127 case 3:
10128 DECODE_PRINTF("NEG\t");
10129 destreg = DECODE_RM_BYTE_REGISTER(rl);
10130 DECODE_PRINTF("\n");
10131 TRACE_AND_STEP();
10132 *destreg = neg_byte(*destreg);
10133 break;
10134 case 4:
10135 DECODE_PRINTF("MUL\t");
10136 destreg = DECODE_RM_BYTE_REGISTER(rl);
10137 DECODE_PRINTF("\n");
10138 TRACE_AND_STEP();
10139 mul_byte(*destreg); /*!!! */
10140 break;
10141 case 5:
10142 DECODE_PRINTF("IMUL\t");
10143 destreg = DECODE_RM_BYTE_REGISTER(rl);
10144 DECODE_PRINTF("\n");
10145 TRACE_AND_STEP();
10146 imul_byte(*destreg);
10147 break;
10148 case 6:
10149 DECODE_PRINTF("DIV\t");
10150 destreg = DECODE_RM_BYTE_REGISTER(rl);
10151 DECODE_PRINTF("\n");
10152 TRACE_AND_STEP();
10153 div_byte(*destreg);
10154 break;
10155 case 7:
10156 DECODE_PRINTF("IDIV\t");
10157 destreg = DECODE_RM_BYTE_REGISTER(rl);
10158 DECODE_PRINTF("\n");
10159 TRACE_AND_STEP();
10160 idiv_byte(*destreg);
10161 break;
10162 }
10163 break; /* end mod==11 */
10164 }
10165 DECODE_CLEAR_SEGOVR();
10166 END_OF_INSTR();
10167 }
10168
10169 /****************************************************************************
10170 REMARKS:
10171 Handles opcode 0xf7
10172 ****************************************************************************/
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))10173 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10174 {
10175 int mod, rl, rh;
10176 uint destoffset;
10177
10178 /* long, drawn out code follows. Double switch for a total
10179 of 32 cases. */
10180 START_OF_INSTR();
10181 FETCH_DECODE_MODRM(mod, rh, rl);
10182 switch (mod) {
10183 case 0: /* mod=00 */
10184 switch (rh) {
10185 case 0: /* test word imm */
10186 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10187 u32 destval,srcval;
10188
10189 DECODE_PRINTF("TEST\tDWORD PTR ");
10190 destoffset = decode_rm00_address(rl);
10191 DECODE_PRINTF(",");
10192 srcval = fetch_long_imm();
10193 DECODE_PRINTF2("%x\n", srcval);
10194 destval = fetch_data_long(destoffset);
10195 TRACE_AND_STEP();
10196 test_long(destval, srcval);
10197 } else {
10198 u16 destval,srcval;
10199
10200 DECODE_PRINTF("TEST\tWORD PTR ");
10201 destoffset = decode_rm00_address(rl);
10202 DECODE_PRINTF(",");
10203 srcval = fetch_word_imm();
10204 DECODE_PRINTF2("%x\n", srcval);
10205 destval = fetch_data_word(destoffset);
10206 TRACE_AND_STEP();
10207 test_word(destval, srcval);
10208 }
10209 break;
10210 case 1:
10211 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10212 HALT_SYS();
10213 break;
10214 case 2:
10215 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10216 u32 destval;
10217
10218 DECODE_PRINTF("NOT\tDWORD PTR ");
10219 destoffset = decode_rm00_address(rl);
10220 DECODE_PRINTF("\n");
10221 destval = fetch_data_long(destoffset);
10222 TRACE_AND_STEP();
10223 destval = not_long(destval);
10224 store_data_long(destoffset, destval);
10225 } else {
10226 u16 destval;
10227
10228 DECODE_PRINTF("NOT\tWORD PTR ");
10229 destoffset = decode_rm00_address(rl);
10230 DECODE_PRINTF("\n");
10231 destval = fetch_data_word(destoffset);
10232 TRACE_AND_STEP();
10233 destval = not_word(destval);
10234 store_data_word(destoffset, destval);
10235 }
10236 break;
10237 case 3:
10238 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10239 u32 destval;
10240
10241 DECODE_PRINTF("NEG\tDWORD PTR ");
10242 destoffset = decode_rm00_address(rl);
10243 DECODE_PRINTF("\n");
10244 destval = fetch_data_long(destoffset);
10245 TRACE_AND_STEP();
10246 destval = neg_long(destval);
10247 store_data_long(destoffset, destval);
10248 } else {
10249 u16 destval;
10250
10251 DECODE_PRINTF("NEG\tWORD PTR ");
10252 destoffset = decode_rm00_address(rl);
10253 DECODE_PRINTF("\n");
10254 destval = fetch_data_word(destoffset);
10255 TRACE_AND_STEP();
10256 destval = neg_word(destval);
10257 store_data_word(destoffset, destval);
10258 }
10259 break;
10260 case 4:
10261 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10262 u32 destval;
10263
10264 DECODE_PRINTF("MUL\tDWORD PTR ");
10265 destoffset = decode_rm00_address(rl);
10266 DECODE_PRINTF("\n");
10267 destval = fetch_data_long(destoffset);
10268 TRACE_AND_STEP();
10269 mul_long(destval);
10270 } else {
10271 u16 destval;
10272
10273 DECODE_PRINTF("MUL\tWORD PTR ");
10274 destoffset = decode_rm00_address(rl);
10275 DECODE_PRINTF("\n");
10276 destval = fetch_data_word(destoffset);
10277 TRACE_AND_STEP();
10278 mul_word(destval);
10279 }
10280 break;
10281 case 5:
10282 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10283 u32 destval;
10284
10285 DECODE_PRINTF("IMUL\tDWORD PTR ");
10286 destoffset = decode_rm00_address(rl);
10287 DECODE_PRINTF("\n");
10288 destval = fetch_data_long(destoffset);
10289 TRACE_AND_STEP();
10290 imul_long(destval);
10291 } else {
10292 u16 destval;
10293
10294 DECODE_PRINTF("IMUL\tWORD PTR ");
10295 destoffset = decode_rm00_address(rl);
10296 DECODE_PRINTF("\n");
10297 destval = fetch_data_word(destoffset);
10298 TRACE_AND_STEP();
10299 imul_word(destval);
10300 }
10301 break;
10302 case 6:
10303 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10304 u32 destval;
10305
10306 DECODE_PRINTF("DIV\tDWORD PTR ");
10307 destoffset = decode_rm00_address(rl);
10308 DECODE_PRINTF("\n");
10309 destval = fetch_data_long(destoffset);
10310 TRACE_AND_STEP();
10311 div_long(destval);
10312 } else {
10313 u16 destval;
10314
10315 DECODE_PRINTF("DIV\tWORD PTR ");
10316 destoffset = decode_rm00_address(rl);
10317 DECODE_PRINTF("\n");
10318 destval = fetch_data_word(destoffset);
10319 TRACE_AND_STEP();
10320 div_word(destval);
10321 }
10322 break;
10323 case 7:
10324 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10325 u32 destval;
10326
10327 DECODE_PRINTF("IDIV\tDWORD PTR ");
10328 destoffset = decode_rm00_address(rl);
10329 DECODE_PRINTF("\n");
10330 destval = fetch_data_long(destoffset);
10331 TRACE_AND_STEP();
10332 idiv_long(destval);
10333 } else {
10334 u16 destval;
10335
10336 DECODE_PRINTF("IDIV\tWORD PTR ");
10337 destoffset = decode_rm00_address(rl);
10338 DECODE_PRINTF("\n");
10339 destval = fetch_data_word(destoffset);
10340 TRACE_AND_STEP();
10341 idiv_word(destval);
10342 }
10343 break;
10344 }
10345 break; /* end mod==00 */
10346 case 1: /* mod=01 */
10347 switch (rh) {
10348 case 0: /* test word imm */
10349 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10350 u32 destval,srcval;
10351
10352 DECODE_PRINTF("TEST\tDWORD PTR ");
10353 destoffset = decode_rm01_address(rl);
10354 DECODE_PRINTF(",");
10355 srcval = fetch_long_imm();
10356 DECODE_PRINTF2("%x\n", srcval);
10357 destval = fetch_data_long(destoffset);
10358 TRACE_AND_STEP();
10359 test_long(destval, srcval);
10360 } else {
10361 u16 destval,srcval;
10362
10363 DECODE_PRINTF("TEST\tWORD PTR ");
10364 destoffset = decode_rm01_address(rl);
10365 DECODE_PRINTF(",");
10366 srcval = fetch_word_imm();
10367 DECODE_PRINTF2("%x\n", srcval);
10368 destval = fetch_data_word(destoffset);
10369 TRACE_AND_STEP();
10370 test_word(destval, srcval);
10371 }
10372 break;
10373 case 1:
10374 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10375 HALT_SYS();
10376 break;
10377 case 2:
10378 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10379 u32 destval;
10380
10381 DECODE_PRINTF("NOT\tDWORD PTR ");
10382 destoffset = decode_rm01_address(rl);
10383 DECODE_PRINTF("\n");
10384 destval = fetch_data_long(destoffset);
10385 TRACE_AND_STEP();
10386 destval = not_long(destval);
10387 store_data_long(destoffset, destval);
10388 } else {
10389 u16 destval;
10390
10391 DECODE_PRINTF("NOT\tWORD PTR ");
10392 destoffset = decode_rm01_address(rl);
10393 DECODE_PRINTF("\n");
10394 destval = fetch_data_word(destoffset);
10395 TRACE_AND_STEP();
10396 destval = not_word(destval);
10397 store_data_word(destoffset, destval);
10398 }
10399 break;
10400 case 3:
10401 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10402 u32 destval;
10403
10404 DECODE_PRINTF("NEG\tDWORD PTR ");
10405 destoffset = decode_rm01_address(rl);
10406 DECODE_PRINTF("\n");
10407 destval = fetch_data_long(destoffset);
10408 TRACE_AND_STEP();
10409 destval = neg_long(destval);
10410 store_data_long(destoffset, destval);
10411 } else {
10412 u16 destval;
10413
10414 DECODE_PRINTF("NEG\tWORD PTR ");
10415 destoffset = decode_rm01_address(rl);
10416 DECODE_PRINTF("\n");
10417 destval = fetch_data_word(destoffset);
10418 TRACE_AND_STEP();
10419 destval = neg_word(destval);
10420 store_data_word(destoffset, destval);
10421 }
10422 break;
10423 case 4:
10424 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10425 u32 destval;
10426
10427 DECODE_PRINTF("MUL\tDWORD PTR ");
10428 destoffset = decode_rm01_address(rl);
10429 DECODE_PRINTF("\n");
10430 destval = fetch_data_long(destoffset);
10431 TRACE_AND_STEP();
10432 mul_long(destval);
10433 } else {
10434 u16 destval;
10435
10436 DECODE_PRINTF("MUL\tWORD PTR ");
10437 destoffset = decode_rm01_address(rl);
10438 DECODE_PRINTF("\n");
10439 destval = fetch_data_word(destoffset);
10440 TRACE_AND_STEP();
10441 mul_word(destval);
10442 }
10443 break;
10444 case 5:
10445 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10446 u32 destval;
10447
10448 DECODE_PRINTF("IMUL\tDWORD PTR ");
10449 destoffset = decode_rm01_address(rl);
10450 DECODE_PRINTF("\n");
10451 destval = fetch_data_long(destoffset);
10452 TRACE_AND_STEP();
10453 imul_long(destval);
10454 } else {
10455 u16 destval;
10456
10457 DECODE_PRINTF("IMUL\tWORD PTR ");
10458 destoffset = decode_rm01_address(rl);
10459 DECODE_PRINTF("\n");
10460 destval = fetch_data_word(destoffset);
10461 TRACE_AND_STEP();
10462 imul_word(destval);
10463 }
10464 break;
10465 case 6:
10466 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10467 u32 destval;
10468
10469 DECODE_PRINTF("DIV\tDWORD PTR ");
10470 destoffset = decode_rm01_address(rl);
10471 DECODE_PRINTF("\n");
10472 destval = fetch_data_long(destoffset);
10473 TRACE_AND_STEP();
10474 div_long(destval);
10475 } else {
10476 u16 destval;
10477
10478 DECODE_PRINTF("DIV\tWORD PTR ");
10479 destoffset = decode_rm01_address(rl);
10480 DECODE_PRINTF("\n");
10481 destval = fetch_data_word(destoffset);
10482 TRACE_AND_STEP();
10483 div_word(destval);
10484 }
10485 break;
10486 case 7:
10487 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10488 u32 destval;
10489
10490 DECODE_PRINTF("IDIV\tDWORD PTR ");
10491 destoffset = decode_rm01_address(rl);
10492 DECODE_PRINTF("\n");
10493 destval = fetch_data_long(destoffset);
10494 TRACE_AND_STEP();
10495 idiv_long(destval);
10496 } else {
10497 u16 destval;
10498
10499 DECODE_PRINTF("IDIV\tWORD PTR ");
10500 destoffset = decode_rm01_address(rl);
10501 DECODE_PRINTF("\n");
10502 destval = fetch_data_word(destoffset);
10503 TRACE_AND_STEP();
10504 idiv_word(destval);
10505 }
10506 break;
10507 }
10508 break; /* end mod==01 */
10509 case 2: /* mod=10 */
10510 switch (rh) {
10511 case 0: /* test word imm */
10512 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10513 u32 destval,srcval;
10514
10515 DECODE_PRINTF("TEST\tDWORD PTR ");
10516 destoffset = decode_rm10_address(rl);
10517 DECODE_PRINTF(",");
10518 srcval = fetch_long_imm();
10519 DECODE_PRINTF2("%x\n", srcval);
10520 destval = fetch_data_long(destoffset);
10521 TRACE_AND_STEP();
10522 test_long(destval, srcval);
10523 } else {
10524 u16 destval,srcval;
10525
10526 DECODE_PRINTF("TEST\tWORD PTR ");
10527 destoffset = decode_rm10_address(rl);
10528 DECODE_PRINTF(",");
10529 srcval = fetch_word_imm();
10530 DECODE_PRINTF2("%x\n", srcval);
10531 destval = fetch_data_word(destoffset);
10532 TRACE_AND_STEP();
10533 test_word(destval, srcval);
10534 }
10535 break;
10536 case 1:
10537 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10538 HALT_SYS();
10539 break;
10540 case 2:
10541 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10542 u32 destval;
10543
10544 DECODE_PRINTF("NOT\tDWORD PTR ");
10545 destoffset = decode_rm10_address(rl);
10546 DECODE_PRINTF("\n");
10547 destval = fetch_data_long(destoffset);
10548 TRACE_AND_STEP();
10549 destval = not_long(destval);
10550 store_data_long(destoffset, destval);
10551 } else {
10552 u16 destval;
10553
10554 DECODE_PRINTF("NOT\tWORD PTR ");
10555 destoffset = decode_rm10_address(rl);
10556 DECODE_PRINTF("\n");
10557 destval = fetch_data_word(destoffset);
10558 TRACE_AND_STEP();
10559 destval = not_word(destval);
10560 store_data_word(destoffset, destval);
10561 }
10562 break;
10563 case 3:
10564 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10565 u32 destval;
10566
10567 DECODE_PRINTF("NEG\tDWORD PTR ");
10568 destoffset = decode_rm10_address(rl);
10569 DECODE_PRINTF("\n");
10570 destval = fetch_data_long(destoffset);
10571 TRACE_AND_STEP();
10572 destval = neg_long(destval);
10573 store_data_long(destoffset, destval);
10574 } else {
10575 u16 destval;
10576
10577 DECODE_PRINTF("NEG\tWORD PTR ");
10578 destoffset = decode_rm10_address(rl);
10579 DECODE_PRINTF("\n");
10580 destval = fetch_data_word(destoffset);
10581 TRACE_AND_STEP();
10582 destval = neg_word(destval);
10583 store_data_word(destoffset, destval);
10584 }
10585 break;
10586 case 4:
10587 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10588 u32 destval;
10589
10590 DECODE_PRINTF("MUL\tDWORD PTR ");
10591 destoffset = decode_rm10_address(rl);
10592 DECODE_PRINTF("\n");
10593 destval = fetch_data_long(destoffset);
10594 TRACE_AND_STEP();
10595 mul_long(destval);
10596 } else {
10597 u16 destval;
10598
10599 DECODE_PRINTF("MUL\tWORD PTR ");
10600 destoffset = decode_rm10_address(rl);
10601 DECODE_PRINTF("\n");
10602 destval = fetch_data_word(destoffset);
10603 TRACE_AND_STEP();
10604 mul_word(destval);
10605 }
10606 break;
10607 case 5:
10608 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10609 u32 destval;
10610
10611 DECODE_PRINTF("IMUL\tDWORD PTR ");
10612 destoffset = decode_rm10_address(rl);
10613 DECODE_PRINTF("\n");
10614 destval = fetch_data_long(destoffset);
10615 TRACE_AND_STEP();
10616 imul_long(destval);
10617 } else {
10618 u16 destval;
10619
10620 DECODE_PRINTF("IMUL\tWORD PTR ");
10621 destoffset = decode_rm10_address(rl);
10622 DECODE_PRINTF("\n");
10623 destval = fetch_data_word(destoffset);
10624 TRACE_AND_STEP();
10625 imul_word(destval);
10626 }
10627 break;
10628 case 6:
10629 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10630 u32 destval;
10631
10632 DECODE_PRINTF("DIV\tDWORD PTR ");
10633 destoffset = decode_rm10_address(rl);
10634 DECODE_PRINTF("\n");
10635 destval = fetch_data_long(destoffset);
10636 TRACE_AND_STEP();
10637 div_long(destval);
10638 } else {
10639 u16 destval;
10640
10641 DECODE_PRINTF("DIV\tWORD PTR ");
10642 destoffset = decode_rm10_address(rl);
10643 DECODE_PRINTF("\n");
10644 destval = fetch_data_word(destoffset);
10645 TRACE_AND_STEP();
10646 div_word(destval);
10647 }
10648 break;
10649 case 7:
10650 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10651 u32 destval;
10652
10653 DECODE_PRINTF("IDIV\tDWORD PTR ");
10654 destoffset = decode_rm10_address(rl);
10655 DECODE_PRINTF("\n");
10656 destval = fetch_data_long(destoffset);
10657 TRACE_AND_STEP();
10658 idiv_long(destval);
10659 } else {
10660 u16 destval;
10661
10662 DECODE_PRINTF("IDIV\tWORD PTR ");
10663 destoffset = decode_rm10_address(rl);
10664 DECODE_PRINTF("\n");
10665 destval = fetch_data_word(destoffset);
10666 TRACE_AND_STEP();
10667 idiv_word(destval);
10668 }
10669 break;
10670 }
10671 break; /* end mod==10 */
10672 case 3: /* mod=11 */
10673 switch (rh) {
10674 case 0: /* test word imm */
10675 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10676 u32 *destreg;
10677 u32 srcval;
10678
10679 DECODE_PRINTF("TEST\t");
10680 destreg = DECODE_RM_LONG_REGISTER(rl);
10681 DECODE_PRINTF(",");
10682 srcval = fetch_long_imm();
10683 DECODE_PRINTF2("%x\n", srcval);
10684 TRACE_AND_STEP();
10685 test_long(*destreg, srcval);
10686 } else {
10687 u16 *destreg;
10688 u16 srcval;
10689
10690 DECODE_PRINTF("TEST\t");
10691 destreg = DECODE_RM_WORD_REGISTER(rl);
10692 DECODE_PRINTF(",");
10693 srcval = fetch_word_imm();
10694 DECODE_PRINTF2("%x\n", srcval);
10695 TRACE_AND_STEP();
10696 test_word(*destreg, srcval);
10697 }
10698 break;
10699 case 1:
10700 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10701 HALT_SYS();
10702 break;
10703 case 2:
10704 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10705 u32 *destreg;
10706
10707 DECODE_PRINTF("NOT\t");
10708 destreg = DECODE_RM_LONG_REGISTER(rl);
10709 DECODE_PRINTF("\n");
10710 TRACE_AND_STEP();
10711 *destreg = not_long(*destreg);
10712 } else {
10713 u16 *destreg;
10714
10715 DECODE_PRINTF("NOT\t");
10716 destreg = DECODE_RM_WORD_REGISTER(rl);
10717 DECODE_PRINTF("\n");
10718 TRACE_AND_STEP();
10719 *destreg = not_word(*destreg);
10720 }
10721 break;
10722 case 3:
10723 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10724 u32 *destreg;
10725
10726 DECODE_PRINTF("NEG\t");
10727 destreg = DECODE_RM_LONG_REGISTER(rl);
10728 DECODE_PRINTF("\n");
10729 TRACE_AND_STEP();
10730 *destreg = neg_long(*destreg);
10731 } else {
10732 u16 *destreg;
10733
10734 DECODE_PRINTF("NEG\t");
10735 destreg = DECODE_RM_WORD_REGISTER(rl);
10736 DECODE_PRINTF("\n");
10737 TRACE_AND_STEP();
10738 *destreg = neg_word(*destreg);
10739 }
10740 break;
10741 case 4:
10742 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10743 u32 *destreg;
10744
10745 DECODE_PRINTF("MUL\t");
10746 destreg = DECODE_RM_LONG_REGISTER(rl);
10747 DECODE_PRINTF("\n");
10748 TRACE_AND_STEP();
10749 mul_long(*destreg); /*!!! */
10750 } else {
10751 u16 *destreg;
10752
10753 DECODE_PRINTF("MUL\t");
10754 destreg = DECODE_RM_WORD_REGISTER(rl);
10755 DECODE_PRINTF("\n");
10756 TRACE_AND_STEP();
10757 mul_word(*destreg); /*!!! */
10758 }
10759 break;
10760 case 5:
10761 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10762 u32 *destreg;
10763
10764 DECODE_PRINTF("IMUL\t");
10765 destreg = DECODE_RM_LONG_REGISTER(rl);
10766 DECODE_PRINTF("\n");
10767 TRACE_AND_STEP();
10768 imul_long(*destreg);
10769 } else {
10770 u16 *destreg;
10771
10772 DECODE_PRINTF("IMUL\t");
10773 destreg = DECODE_RM_WORD_REGISTER(rl);
10774 DECODE_PRINTF("\n");
10775 TRACE_AND_STEP();
10776 imul_word(*destreg);
10777 }
10778 break;
10779 case 6:
10780 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10781 u32 *destreg;
10782
10783 DECODE_PRINTF("DIV\t");
10784 destreg = DECODE_RM_LONG_REGISTER(rl);
10785 DECODE_PRINTF("\n");
10786 TRACE_AND_STEP();
10787 div_long(*destreg);
10788 } else {
10789 u16 *destreg;
10790
10791 DECODE_PRINTF("DIV\t");
10792 destreg = DECODE_RM_WORD_REGISTER(rl);
10793 DECODE_PRINTF("\n");
10794 TRACE_AND_STEP();
10795 div_word(*destreg);
10796 }
10797 break;
10798 case 7:
10799 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10800 u32 *destreg;
10801
10802 DECODE_PRINTF("IDIV\t");
10803 destreg = DECODE_RM_LONG_REGISTER(rl);
10804 DECODE_PRINTF("\n");
10805 TRACE_AND_STEP();
10806 idiv_long(*destreg);
10807 } else {
10808 u16 *destreg;
10809
10810 DECODE_PRINTF("IDIV\t");
10811 destreg = DECODE_RM_WORD_REGISTER(rl);
10812 DECODE_PRINTF("\n");
10813 TRACE_AND_STEP();
10814 idiv_word(*destreg);
10815 }
10816 break;
10817 }
10818 break; /* end mod==11 */
10819 }
10820 DECODE_CLEAR_SEGOVR();
10821 END_OF_INSTR();
10822 }
10823
10824 /****************************************************************************
10825 REMARKS:
10826 Handles opcode 0xf8
10827 ****************************************************************************/
x86emuOp_clc(u8 X86EMU_UNUSED (op1))10828 void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10829 {
10830 /* clear the carry flag. */
10831 START_OF_INSTR();
10832 DECODE_PRINTF("CLC\n");
10833 TRACE_AND_STEP();
10834 CLEAR_FLAG(F_CF);
10835 DECODE_CLEAR_SEGOVR();
10836 END_OF_INSTR();
10837 }
10838
10839 /****************************************************************************
10840 REMARKS:
10841 Handles opcode 0xf9
10842 ****************************************************************************/
x86emuOp_stc(u8 X86EMU_UNUSED (op1))10843 void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10844 {
10845 /* set the carry flag. */
10846 START_OF_INSTR();
10847 DECODE_PRINTF("STC\n");
10848 TRACE_AND_STEP();
10849 SET_FLAG(F_CF);
10850 DECODE_CLEAR_SEGOVR();
10851 END_OF_INSTR();
10852 }
10853
10854 /****************************************************************************
10855 REMARKS:
10856 Handles opcode 0xfa
10857 ****************************************************************************/
x86emuOp_cli(u8 X86EMU_UNUSED (op1))10858 void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10859 {
10860 /* clear interrupts. */
10861 START_OF_INSTR();
10862 DECODE_PRINTF("CLI\n");
10863 TRACE_AND_STEP();
10864 CLEAR_FLAG(F_IF);
10865 DECODE_CLEAR_SEGOVR();
10866 END_OF_INSTR();
10867 }
10868
10869 /****************************************************************************
10870 REMARKS:
10871 Handles opcode 0xfb
10872 ****************************************************************************/
x86emuOp_sti(u8 X86EMU_UNUSED (op1))10873 void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10874 {
10875 /* enable interrupts. */
10876 START_OF_INSTR();
10877 DECODE_PRINTF("STI\n");
10878 TRACE_AND_STEP();
10879 SET_FLAG(F_IF);
10880 DECODE_CLEAR_SEGOVR();
10881 END_OF_INSTR();
10882 }
10883
10884 /****************************************************************************
10885 REMARKS:
10886 Handles opcode 0xfc
10887 ****************************************************************************/
x86emuOp_cld(u8 X86EMU_UNUSED (op1))10888 void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10889 {
10890 /* clear interrupts. */
10891 START_OF_INSTR();
10892 DECODE_PRINTF("CLD\n");
10893 TRACE_AND_STEP();
10894 CLEAR_FLAG(F_DF);
10895 DECODE_CLEAR_SEGOVR();
10896 END_OF_INSTR();
10897 }
10898
10899 /****************************************************************************
10900 REMARKS:
10901 Handles opcode 0xfd
10902 ****************************************************************************/
x86emuOp_std(u8 X86EMU_UNUSED (op1))10903 void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10904 {
10905 /* clear interrupts. */
10906 START_OF_INSTR();
10907 DECODE_PRINTF("STD\n");
10908 TRACE_AND_STEP();
10909 SET_FLAG(F_DF);
10910 DECODE_CLEAR_SEGOVR();
10911 END_OF_INSTR();
10912 }
10913
10914 /****************************************************************************
10915 REMARKS:
10916 Handles opcode 0xfe
10917 ****************************************************************************/
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))10918 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10919 {
10920 int mod, rh, rl;
10921 u8 destval;
10922 uint destoffset;
10923 u8 *destreg;
10924
10925 /* Yet another special case instruction. */
10926 START_OF_INSTR();
10927 FETCH_DECODE_MODRM(mod, rh, rl);
10928 #ifdef DEBUG
10929 if (DEBUG_DECODE()) {
10930 /* XXX DECODE_PRINTF may be changed to something more
10931 general, so that it is important to leave the strings
10932 in the same format, even though the result is that the
10933 above test is done twice. */
10934
10935 switch (rh) {
10936 case 0:
10937 DECODE_PRINTF("INC\t");
10938 break;
10939 case 1:
10940 DECODE_PRINTF("DEC\t");
10941 break;
10942 case 2:
10943 case 3:
10944 case 4:
10945 case 5:
10946 case 6:
10947 case 7:
10948 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10949 HALT_SYS();
10950 break;
10951 }
10952 }
10953 #endif
10954 switch (mod) {
10955 case 0:
10956 DECODE_PRINTF("BYTE PTR ");
10957 destoffset = decode_rm00_address(rl);
10958 DECODE_PRINTF("\n");
10959 switch (rh) {
10960 case 0: /* inc word ptr ... */
10961 destval = fetch_data_byte(destoffset);
10962 TRACE_AND_STEP();
10963 destval = inc_byte(destval);
10964 store_data_byte(destoffset, destval);
10965 break;
10966 case 1: /* dec word ptr ... */
10967 destval = fetch_data_byte(destoffset);
10968 TRACE_AND_STEP();
10969 destval = dec_byte(destval);
10970 store_data_byte(destoffset, destval);
10971 break;
10972 }
10973 break;
10974 case 1:
10975 DECODE_PRINTF("BYTE PTR ");
10976 destoffset = decode_rm01_address(rl);
10977 DECODE_PRINTF("\n");
10978 switch (rh) {
10979 case 0:
10980 destval = fetch_data_byte(destoffset);
10981 TRACE_AND_STEP();
10982 destval = inc_byte(destval);
10983 store_data_byte(destoffset, destval);
10984 break;
10985 case 1:
10986 destval = fetch_data_byte(destoffset);
10987 TRACE_AND_STEP();
10988 destval = dec_byte(destval);
10989 store_data_byte(destoffset, destval);
10990 break;
10991 }
10992 break;
10993 case 2:
10994 DECODE_PRINTF("BYTE PTR ");
10995 destoffset = decode_rm10_address(rl);
10996 DECODE_PRINTF("\n");
10997 switch (rh) {
10998 case 0:
10999 destval = fetch_data_byte(destoffset);
11000 TRACE_AND_STEP();
11001 destval = inc_byte(destval);
11002 store_data_byte(destoffset, destval);
11003 break;
11004 case 1:
11005 destval = fetch_data_byte(destoffset);
11006 TRACE_AND_STEP();
11007 destval = dec_byte(destval);
11008 store_data_byte(destoffset, destval);
11009 break;
11010 }
11011 break;
11012 case 3:
11013 destreg = DECODE_RM_BYTE_REGISTER(rl);
11014 DECODE_PRINTF("\n");
11015 switch (rh) {
11016 case 0:
11017 TRACE_AND_STEP();
11018 *destreg = inc_byte(*destreg);
11019 break;
11020 case 1:
11021 TRACE_AND_STEP();
11022 *destreg = dec_byte(*destreg);
11023 break;
11024 }
11025 break;
11026 }
11027 DECODE_CLEAR_SEGOVR();
11028 END_OF_INSTR();
11029 }
11030
11031 /****************************************************************************
11032 REMARKS:
11033 Handles opcode 0xff
11034 ****************************************************************************/
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))11035 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11036 {
11037 int mod, rh, rl;
11038 uint destoffset = 0;
11039 u16 *destreg;
11040 u16 destval,destval2;
11041
11042 /* Yet another special case instruction. */
11043 START_OF_INSTR();
11044 FETCH_DECODE_MODRM(mod, rh, rl);
11045 #ifdef DEBUG
11046 if (DEBUG_DECODE()) {
11047 /* XXX DECODE_PRINTF may be changed to something more
11048 general, so that it is important to leave the strings
11049 in the same format, even though the result is that the
11050 above test is done twice. */
11051
11052 switch (rh) {
11053 case 0:
11054 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11055 DECODE_PRINTF("INC\tDWORD PTR ");
11056 } else {
11057 DECODE_PRINTF("INC\tWORD PTR ");
11058 }
11059 break;
11060 case 1:
11061 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11062 DECODE_PRINTF("DEC\tDWORD PTR ");
11063 } else {
11064 DECODE_PRINTF("DEC\tWORD PTR ");
11065 }
11066 break;
11067 case 2:
11068 DECODE_PRINTF("CALL\t ");
11069 break;
11070 case 3:
11071 DECODE_PRINTF("CALL\tFAR ");
11072 break;
11073 case 4:
11074 DECODE_PRINTF("JMP\t");
11075 break;
11076 case 5:
11077 DECODE_PRINTF("JMP\tFAR ");
11078 break;
11079 case 6:
11080 DECODE_PRINTF("PUSH\t");
11081 break;
11082 case 7:
11083 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11084 HALT_SYS();
11085 break;
11086 }
11087 }
11088 #endif
11089 switch (mod) {
11090 case 0:
11091 destoffset = decode_rm00_address(rl);
11092 DECODE_PRINTF("\n");
11093 switch (rh) {
11094 case 0: /* inc word ptr ... */
11095 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11096 u32 destval;
11097
11098 destval = fetch_data_long(destoffset);
11099 TRACE_AND_STEP();
11100 destval = inc_long(destval);
11101 store_data_long(destoffset, destval);
11102 } else {
11103 u16 destval;
11104
11105 destval = fetch_data_word(destoffset);
11106 TRACE_AND_STEP();
11107 destval = inc_word(destval);
11108 store_data_word(destoffset, destval);
11109 }
11110 break;
11111 case 1: /* dec word ptr ... */
11112 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11113 u32 destval;
11114
11115 destval = fetch_data_long(destoffset);
11116 TRACE_AND_STEP();
11117 destval = dec_long(destval);
11118 store_data_long(destoffset, destval);
11119 } else {
11120 u16 destval;
11121
11122 destval = fetch_data_word(destoffset);
11123 TRACE_AND_STEP();
11124 destval = dec_word(destval);
11125 store_data_word(destoffset, destval);
11126 }
11127 break;
11128 case 2: /* call word ptr ... */
11129 destval = fetch_data_word(destoffset);
11130 TRACE_AND_STEP();
11131 push_word(M.x86.R_IP);
11132 M.x86.R_IP = destval;
11133 break;
11134 case 3: /* call far ptr ... */
11135 destval = fetch_data_word(destoffset);
11136 destval2 = fetch_data_word(destoffset + 2);
11137 TRACE_AND_STEP();
11138 push_word(M.x86.R_CS);
11139 M.x86.R_CS = destval2;
11140 push_word(M.x86.R_IP);
11141 M.x86.R_IP = destval;
11142 break;
11143 case 4: /* jmp word ptr ... */
11144 destval = fetch_data_word(destoffset);
11145 TRACE_AND_STEP();
11146 M.x86.R_IP = destval;
11147 break;
11148 case 5: /* jmp far ptr ... */
11149 destval = fetch_data_word(destoffset);
11150 destval2 = fetch_data_word(destoffset + 2);
11151 TRACE_AND_STEP();
11152 M.x86.R_IP = destval;
11153 M.x86.R_CS = destval2;
11154 break;
11155 case 6: /* push word ptr ... */
11156 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11157 u32 destval;
11158
11159 destval = fetch_data_long(destoffset);
11160 TRACE_AND_STEP();
11161 push_long(destval);
11162 } else {
11163 u16 destval;
11164
11165 destval = fetch_data_word(destoffset);
11166 TRACE_AND_STEP();
11167 push_word(destval);
11168 }
11169 break;
11170 }
11171 break;
11172 case 1:
11173 destoffset = decode_rm01_address(rl);
11174 DECODE_PRINTF("\n");
11175 switch (rh) {
11176 case 0:
11177 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11178 u32 destval;
11179
11180 destval = fetch_data_long(destoffset);
11181 TRACE_AND_STEP();
11182 destval = inc_long(destval);
11183 store_data_long(destoffset, destval);
11184 } else {
11185 u16 destval;
11186
11187 destval = fetch_data_word(destoffset);
11188 TRACE_AND_STEP();
11189 destval = inc_word(destval);
11190 store_data_word(destoffset, destval);
11191 }
11192 break;
11193 case 1:
11194 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11195 u32 destval;
11196
11197 destval = fetch_data_long(destoffset);
11198 TRACE_AND_STEP();
11199 destval = dec_long(destval);
11200 store_data_long(destoffset, destval);
11201 } else {
11202 u16 destval;
11203
11204 destval = fetch_data_word(destoffset);
11205 TRACE_AND_STEP();
11206 destval = dec_word(destval);
11207 store_data_word(destoffset, destval);
11208 }
11209 break;
11210 case 2: /* call word ptr ... */
11211 destval = fetch_data_word(destoffset);
11212 TRACE_AND_STEP();
11213 push_word(M.x86.R_IP);
11214 M.x86.R_IP = destval;
11215 break;
11216 case 3: /* call far ptr ... */
11217 destval = fetch_data_word(destoffset);
11218 destval2 = fetch_data_word(destoffset + 2);
11219 TRACE_AND_STEP();
11220 push_word(M.x86.R_CS);
11221 M.x86.R_CS = destval2;
11222 push_word(M.x86.R_IP);
11223 M.x86.R_IP = destval;
11224 break;
11225 case 4: /* jmp word ptr ... */
11226 destval = fetch_data_word(destoffset);
11227 TRACE_AND_STEP();
11228 M.x86.R_IP = destval;
11229 break;
11230 case 5: /* jmp far ptr ... */
11231 destval = fetch_data_word(destoffset);
11232 destval2 = fetch_data_word(destoffset + 2);
11233 TRACE_AND_STEP();
11234 M.x86.R_IP = destval;
11235 M.x86.R_CS = destval2;
11236 break;
11237 case 6: /* push word ptr ... */
11238 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11239 u32 destval;
11240
11241 destval = fetch_data_long(destoffset);
11242 TRACE_AND_STEP();
11243 push_long(destval);
11244 } else {
11245 u16 destval;
11246
11247 destval = fetch_data_word(destoffset);
11248 TRACE_AND_STEP();
11249 push_word(destval);
11250 }
11251 break;
11252 }
11253 break;
11254 case 2:
11255 destoffset = decode_rm10_address(rl);
11256 DECODE_PRINTF("\n");
11257 switch (rh) {
11258 case 0:
11259 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11260 u32 destval;
11261
11262 destval = fetch_data_long(destoffset);
11263 TRACE_AND_STEP();
11264 destval = inc_long(destval);
11265 store_data_long(destoffset, destval);
11266 } else {
11267 u16 destval;
11268
11269 destval = fetch_data_word(destoffset);
11270 TRACE_AND_STEP();
11271 destval = inc_word(destval);
11272 store_data_word(destoffset, destval);
11273 }
11274 break;
11275 case 1:
11276 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11277 u32 destval;
11278
11279 destval = fetch_data_long(destoffset);
11280 TRACE_AND_STEP();
11281 destval = dec_long(destval);
11282 store_data_long(destoffset, destval);
11283 } else {
11284 u16 destval;
11285
11286 destval = fetch_data_word(destoffset);
11287 TRACE_AND_STEP();
11288 destval = dec_word(destval);
11289 store_data_word(destoffset, destval);
11290 }
11291 break;
11292 case 2: /* call word ptr ... */
11293 destval = fetch_data_word(destoffset);
11294 TRACE_AND_STEP();
11295 push_word(M.x86.R_IP);
11296 M.x86.R_IP = destval;
11297 break;
11298 case 3: /* call far ptr ... */
11299 destval = fetch_data_word(destoffset);
11300 destval2 = fetch_data_word(destoffset + 2);
11301 TRACE_AND_STEP();
11302 push_word(M.x86.R_CS);
11303 M.x86.R_CS = destval2;
11304 push_word(M.x86.R_IP);
11305 M.x86.R_IP = destval;
11306 break;
11307 case 4: /* jmp word ptr ... */
11308 destval = fetch_data_word(destoffset);
11309 TRACE_AND_STEP();
11310 M.x86.R_IP = destval;
11311 break;
11312 case 5: /* jmp far ptr ... */
11313 destval = fetch_data_word(destoffset);
11314 destval2 = fetch_data_word(destoffset + 2);
11315 TRACE_AND_STEP();
11316 M.x86.R_IP = destval;
11317 M.x86.R_CS = destval2;
11318 break;
11319 case 6: /* push word ptr ... */
11320 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11321 u32 destval;
11322
11323 destval = fetch_data_long(destoffset);
11324 TRACE_AND_STEP();
11325 push_long(destval);
11326 } else {
11327 u16 destval;
11328
11329 destval = fetch_data_word(destoffset);
11330 TRACE_AND_STEP();
11331 push_word(destval);
11332 }
11333 break;
11334 }
11335 break;
11336 case 3:
11337 switch (rh) {
11338 case 0:
11339 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11340 u32 *destreg;
11341
11342 destreg = DECODE_RM_LONG_REGISTER(rl);
11343 DECODE_PRINTF("\n");
11344 TRACE_AND_STEP();
11345 *destreg = inc_long(*destreg);
11346 } else {
11347 u16 *destreg;
11348
11349 destreg = DECODE_RM_WORD_REGISTER(rl);
11350 DECODE_PRINTF("\n");
11351 TRACE_AND_STEP();
11352 *destreg = inc_word(*destreg);
11353 }
11354 break;
11355 case 1:
11356 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11357 u32 *destreg;
11358
11359 destreg = DECODE_RM_LONG_REGISTER(rl);
11360 DECODE_PRINTF("\n");
11361 TRACE_AND_STEP();
11362 *destreg = dec_long(*destreg);
11363 } else {
11364 u16 *destreg;
11365
11366 destreg = DECODE_RM_WORD_REGISTER(rl);
11367 DECODE_PRINTF("\n");
11368 TRACE_AND_STEP();
11369 *destreg = dec_word(*destreg);
11370 }
11371 break;
11372 case 2: /* call word ptr ... */
11373 destreg = DECODE_RM_WORD_REGISTER(rl);
11374 DECODE_PRINTF("\n");
11375 TRACE_AND_STEP();
11376 push_word(M.x86.R_IP);
11377 M.x86.R_IP = *destreg;
11378 break;
11379 case 3: /* jmp far ptr ... */
11380 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11381 TRACE_AND_STEP();
11382 HALT_SYS();
11383 break;
11384
11385 case 4: /* jmp ... */
11386 destreg = DECODE_RM_WORD_REGISTER(rl);
11387 DECODE_PRINTF("\n");
11388 TRACE_AND_STEP();
11389 M.x86.R_IP = (u16) (*destreg);
11390 break;
11391 case 5: /* jmp far ptr ... */
11392 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11393 TRACE_AND_STEP();
11394 HALT_SYS();
11395 break;
11396 case 6:
11397 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11398 u32 *destreg;
11399
11400 destreg = DECODE_RM_LONG_REGISTER(rl);
11401 DECODE_PRINTF("\n");
11402 TRACE_AND_STEP();
11403 push_long(*destreg);
11404 } else {
11405 u16 *destreg;
11406
11407 destreg = DECODE_RM_WORD_REGISTER(rl);
11408 DECODE_PRINTF("\n");
11409 TRACE_AND_STEP();
11410 push_word(*destreg);
11411 }
11412 break;
11413 }
11414 break;
11415 }
11416 DECODE_CLEAR_SEGOVR();
11417 END_OF_INSTR();
11418 }
11419
11420 /***************************************************************************
11421 * Single byte operation code table:
11422 **************************************************************************/
11423 void (*x86emu_optab[256])(u8) =
11424 {
11425 /* 0x00 */ x86emuOp_add_byte_RM_R,
11426 /* 0x01 */ x86emuOp_add_word_RM_R,
11427 /* 0x02 */ x86emuOp_add_byte_R_RM,
11428 /* 0x03 */ x86emuOp_add_word_R_RM,
11429 /* 0x04 */ x86emuOp_add_byte_AL_IMM,
11430 /* 0x05 */ x86emuOp_add_word_AX_IMM,
11431 /* 0x06 */ x86emuOp_push_ES,
11432 /* 0x07 */ x86emuOp_pop_ES,
11433
11434 /* 0x08 */ x86emuOp_or_byte_RM_R,
11435 /* 0x09 */ x86emuOp_or_word_RM_R,
11436 /* 0x0a */ x86emuOp_or_byte_R_RM,
11437 /* 0x0b */ x86emuOp_or_word_R_RM,
11438 /* 0x0c */ x86emuOp_or_byte_AL_IMM,
11439 /* 0x0d */ x86emuOp_or_word_AX_IMM,
11440 /* 0x0e */ x86emuOp_push_CS,
11441 /* 0x0f */ x86emuOp_two_byte,
11442
11443 /* 0x10 */ x86emuOp_adc_byte_RM_R,
11444 /* 0x11 */ x86emuOp_adc_word_RM_R,
11445 /* 0x12 */ x86emuOp_adc_byte_R_RM,
11446 /* 0x13 */ x86emuOp_adc_word_R_RM,
11447 /* 0x14 */ x86emuOp_adc_byte_AL_IMM,
11448 /* 0x15 */ x86emuOp_adc_word_AX_IMM,
11449 /* 0x16 */ x86emuOp_push_SS,
11450 /* 0x17 */ x86emuOp_pop_SS,
11451
11452 /* 0x18 */ x86emuOp_sbb_byte_RM_R,
11453 /* 0x19 */ x86emuOp_sbb_word_RM_R,
11454 /* 0x1a */ x86emuOp_sbb_byte_R_RM,
11455 /* 0x1b */ x86emuOp_sbb_word_R_RM,
11456 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
11457 /* 0x1d */ x86emuOp_sbb_word_AX_IMM,
11458 /* 0x1e */ x86emuOp_push_DS,
11459 /* 0x1f */ x86emuOp_pop_DS,
11460
11461 /* 0x20 */ x86emuOp_and_byte_RM_R,
11462 /* 0x21 */ x86emuOp_and_word_RM_R,
11463 /* 0x22 */ x86emuOp_and_byte_R_RM,
11464 /* 0x23 */ x86emuOp_and_word_R_RM,
11465 /* 0x24 */ x86emuOp_and_byte_AL_IMM,
11466 /* 0x25 */ x86emuOp_and_word_AX_IMM,
11467 /* 0x26 */ x86emuOp_segovr_ES,
11468 /* 0x27 */ x86emuOp_daa,
11469
11470 /* 0x28 */ x86emuOp_sub_byte_RM_R,
11471 /* 0x29 */ x86emuOp_sub_word_RM_R,
11472 /* 0x2a */ x86emuOp_sub_byte_R_RM,
11473 /* 0x2b */ x86emuOp_sub_word_R_RM,
11474 /* 0x2c */ x86emuOp_sub_byte_AL_IMM,
11475 /* 0x2d */ x86emuOp_sub_word_AX_IMM,
11476 /* 0x2e */ x86emuOp_segovr_CS,
11477 /* 0x2f */ x86emuOp_das,
11478
11479 /* 0x30 */ x86emuOp_xor_byte_RM_R,
11480 /* 0x31 */ x86emuOp_xor_word_RM_R,
11481 /* 0x32 */ x86emuOp_xor_byte_R_RM,
11482 /* 0x33 */ x86emuOp_xor_word_R_RM,
11483 /* 0x34 */ x86emuOp_xor_byte_AL_IMM,
11484 /* 0x35 */ x86emuOp_xor_word_AX_IMM,
11485 /* 0x36 */ x86emuOp_segovr_SS,
11486 /* 0x37 */ x86emuOp_aaa,
11487
11488 /* 0x38 */ x86emuOp_cmp_byte_RM_R,
11489 /* 0x39 */ x86emuOp_cmp_word_RM_R,
11490 /* 0x3a */ x86emuOp_cmp_byte_R_RM,
11491 /* 0x3b */ x86emuOp_cmp_word_R_RM,
11492 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
11493 /* 0x3d */ x86emuOp_cmp_word_AX_IMM,
11494 /* 0x3e */ x86emuOp_segovr_DS,
11495 /* 0x3f */ x86emuOp_aas,
11496
11497 /* 0x40 */ x86emuOp_inc_AX,
11498 /* 0x41 */ x86emuOp_inc_CX,
11499 /* 0x42 */ x86emuOp_inc_DX,
11500 /* 0x43 */ x86emuOp_inc_BX,
11501 /* 0x44 */ x86emuOp_inc_SP,
11502 /* 0x45 */ x86emuOp_inc_BP,
11503 /* 0x46 */ x86emuOp_inc_SI,
11504 /* 0x47 */ x86emuOp_inc_DI,
11505
11506 /* 0x48 */ x86emuOp_dec_AX,
11507 /* 0x49 */ x86emuOp_dec_CX,
11508 /* 0x4a */ x86emuOp_dec_DX,
11509 /* 0x4b */ x86emuOp_dec_BX,
11510 /* 0x4c */ x86emuOp_dec_SP,
11511 /* 0x4d */ x86emuOp_dec_BP,
11512 /* 0x4e */ x86emuOp_dec_SI,
11513 /* 0x4f */ x86emuOp_dec_DI,
11514
11515 /* 0x50 */ x86emuOp_push_AX,
11516 /* 0x51 */ x86emuOp_push_CX,
11517 /* 0x52 */ x86emuOp_push_DX,
11518 /* 0x53 */ x86emuOp_push_BX,
11519 /* 0x54 */ x86emuOp_push_SP,
11520 /* 0x55 */ x86emuOp_push_BP,
11521 /* 0x56 */ x86emuOp_push_SI,
11522 /* 0x57 */ x86emuOp_push_DI,
11523
11524 /* 0x58 */ x86emuOp_pop_AX,
11525 /* 0x59 */ x86emuOp_pop_CX,
11526 /* 0x5a */ x86emuOp_pop_DX,
11527 /* 0x5b */ x86emuOp_pop_BX,
11528 /* 0x5c */ x86emuOp_pop_SP,
11529 /* 0x5d */ x86emuOp_pop_BP,
11530 /* 0x5e */ x86emuOp_pop_SI,
11531 /* 0x5f */ x86emuOp_pop_DI,
11532
11533 /* 0x60 */ x86emuOp_push_all,
11534 /* 0x61 */ x86emuOp_pop_all,
11535 /* 0x62 */ x86emuOp_illegal_op, /* bound */
11536 /* 0x63 */ x86emuOp_illegal_op, /* arpl */
11537 /* 0x64 */ x86emuOp_segovr_FS,
11538 /* 0x65 */ x86emuOp_segovr_GS,
11539 /* 0x66 */ x86emuOp_prefix_data,
11540 /* 0x67 */ x86emuOp_prefix_addr,
11541
11542 /* 0x68 */ x86emuOp_push_word_IMM,
11543 /* 0x69 */ x86emuOp_imul_word_IMM,
11544 /* 0x6a */ x86emuOp_push_byte_IMM,
11545 /* 0x6b */ x86emuOp_imul_byte_IMM,
11546 /* 0x6c */ x86emuOp_ins_byte,
11547 /* 0x6d */ x86emuOp_ins_word,
11548 /* 0x6e */ x86emuOp_outs_byte,
11549 /* 0x6f */ x86emuOp_outs_word,
11550
11551 /* 0x70 */ x86emuOp_jump_near_O,
11552 /* 0x71 */ x86emuOp_jump_near_NO,
11553 /* 0x72 */ x86emuOp_jump_near_B,
11554 /* 0x73 */ x86emuOp_jump_near_NB,
11555 /* 0x74 */ x86emuOp_jump_near_Z,
11556 /* 0x75 */ x86emuOp_jump_near_NZ,
11557 /* 0x76 */ x86emuOp_jump_near_BE,
11558 /* 0x77 */ x86emuOp_jump_near_NBE,
11559
11560 /* 0x78 */ x86emuOp_jump_near_S,
11561 /* 0x79 */ x86emuOp_jump_near_NS,
11562 /* 0x7a */ x86emuOp_jump_near_P,
11563 /* 0x7b */ x86emuOp_jump_near_NP,
11564 /* 0x7c */ x86emuOp_jump_near_L,
11565 /* 0x7d */ x86emuOp_jump_near_NL,
11566 /* 0x7e */ x86emuOp_jump_near_LE,
11567 /* 0x7f */ x86emuOp_jump_near_NLE,
11568
11569 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
11570 /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
11571 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
11572 /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
11573 /* 0x84 */ x86emuOp_test_byte_RM_R,
11574 /* 0x85 */ x86emuOp_test_word_RM_R,
11575 /* 0x86 */ x86emuOp_xchg_byte_RM_R,
11576 /* 0x87 */ x86emuOp_xchg_word_RM_R,
11577
11578 /* 0x88 */ x86emuOp_mov_byte_RM_R,
11579 /* 0x89 */ x86emuOp_mov_word_RM_R,
11580 /* 0x8a */ x86emuOp_mov_byte_R_RM,
11581 /* 0x8b */ x86emuOp_mov_word_R_RM,
11582 /* 0x8c */ x86emuOp_mov_word_RM_SR,
11583 /* 0x8d */ x86emuOp_lea_word_R_M,
11584 /* 0x8e */ x86emuOp_mov_word_SR_RM,
11585 /* 0x8f */ x86emuOp_pop_RM,
11586
11587 /* 0x90 */ x86emuOp_nop,
11588 /* 0x91 */ x86emuOp_xchg_word_AX_CX,
11589 /* 0x92 */ x86emuOp_xchg_word_AX_DX,
11590 /* 0x93 */ x86emuOp_xchg_word_AX_BX,
11591 /* 0x94 */ x86emuOp_xchg_word_AX_SP,
11592 /* 0x95 */ x86emuOp_xchg_word_AX_BP,
11593 /* 0x96 */ x86emuOp_xchg_word_AX_SI,
11594 /* 0x97 */ x86emuOp_xchg_word_AX_DI,
11595
11596 /* 0x98 */ x86emuOp_cbw,
11597 /* 0x99 */ x86emuOp_cwd,
11598 /* 0x9a */ x86emuOp_call_far_IMM,
11599 /* 0x9b */ x86emuOp_wait,
11600 /* 0x9c */ x86emuOp_pushf_word,
11601 /* 0x9d */ x86emuOp_popf_word,
11602 /* 0x9e */ x86emuOp_sahf,
11603 /* 0x9f */ x86emuOp_lahf,
11604
11605 /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
11606 /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
11607 /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
11608 /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
11609 /* 0xa4 */ x86emuOp_movs_byte,
11610 /* 0xa5 */ x86emuOp_movs_word,
11611 /* 0xa6 */ x86emuOp_cmps_byte,
11612 /* 0xa7 */ x86emuOp_cmps_word,
11613 /* 0xa8 */ x86emuOp_test_AL_IMM,
11614 /* 0xa9 */ x86emuOp_test_AX_IMM,
11615 /* 0xaa */ x86emuOp_stos_byte,
11616 /* 0xab */ x86emuOp_stos_word,
11617 /* 0xac */ x86emuOp_lods_byte,
11618 /* 0xad */ x86emuOp_lods_word,
11619 /* 0xac */ x86emuOp_scas_byte,
11620 /* 0xad */ x86emuOp_scas_word,
11621
11622
11623 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
11624 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
11625 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
11626 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
11627 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
11628 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
11629 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
11630 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
11631
11632 /* 0xb8 */ x86emuOp_mov_word_AX_IMM,
11633 /* 0xb9 */ x86emuOp_mov_word_CX_IMM,
11634 /* 0xba */ x86emuOp_mov_word_DX_IMM,
11635 /* 0xbb */ x86emuOp_mov_word_BX_IMM,
11636 /* 0xbc */ x86emuOp_mov_word_SP_IMM,
11637 /* 0xbd */ x86emuOp_mov_word_BP_IMM,
11638 /* 0xbe */ x86emuOp_mov_word_SI_IMM,
11639 /* 0xbf */ x86emuOp_mov_word_DI_IMM,
11640
11641 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11642 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11643 /* 0xc2 */ x86emuOp_ret_near_IMM,
11644 /* 0xc3 */ x86emuOp_ret_near,
11645 /* 0xc4 */ x86emuOp_les_R_IMM,
11646 /* 0xc5 */ x86emuOp_lds_R_IMM,
11647 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
11648 /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
11649 /* 0xc8 */ x86emuOp_enter,
11650 /* 0xc9 */ x86emuOp_leave,
11651 /* 0xca */ x86emuOp_ret_far_IMM,
11652 /* 0xcb */ x86emuOp_ret_far,
11653 /* 0xcc */ x86emuOp_int3,
11654 /* 0xcd */ x86emuOp_int_IMM,
11655 /* 0xce */ x86emuOp_into,
11656 /* 0xcf */ x86emuOp_iret,
11657
11658 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
11659 /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
11660 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11661 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
11662 /* 0xd4 */ x86emuOp_aam,
11663 /* 0xd5 */ x86emuOp_aad,
11664 /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
11665 /* 0xd7 */ x86emuOp_xlat,
11666 /* 0xd8 */ x86emuOp_esc_coprocess_d8,
11667 /* 0xd9 */ x86emuOp_esc_coprocess_d9,
11668 /* 0xda */ x86emuOp_esc_coprocess_da,
11669 /* 0xdb */ x86emuOp_esc_coprocess_db,
11670 /* 0xdc */ x86emuOp_esc_coprocess_dc,
11671 /* 0xdd */ x86emuOp_esc_coprocess_dd,
11672 /* 0xde */ x86emuOp_esc_coprocess_de,
11673 /* 0xdf */ x86emuOp_esc_coprocess_df,
11674
11675 /* 0xe0 */ x86emuOp_loopne,
11676 /* 0xe1 */ x86emuOp_loope,
11677 /* 0xe2 */ x86emuOp_loop,
11678 /* 0xe3 */ x86emuOp_jcxz,
11679 /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
11680 /* 0xe5 */ x86emuOp_in_word_AX_IMM,
11681 /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
11682 /* 0xe7 */ x86emuOp_out_word_IMM_AX,
11683
11684 /* 0xe8 */ x86emuOp_call_near_IMM,
11685 /* 0xe9 */ x86emuOp_jump_near_IMM,
11686 /* 0xea */ x86emuOp_jump_far_IMM,
11687 /* 0xeb */ x86emuOp_jump_byte_IMM,
11688 /* 0xec */ x86emuOp_in_byte_AL_DX,
11689 /* 0xed */ x86emuOp_in_word_AX_DX,
11690 /* 0xee */ x86emuOp_out_byte_DX_AL,
11691 /* 0xef */ x86emuOp_out_word_DX_AX,
11692
11693 /* 0xf0 */ x86emuOp_lock,
11694 /* 0xf1 */ x86emuOp_illegal_op,
11695 /* 0xf2 */ x86emuOp_repne,
11696 /* 0xf3 */ x86emuOp_repe,
11697 /* 0xf4 */ x86emuOp_halt,
11698 /* 0xf5 */ x86emuOp_cmc,
11699 /* 0xf6 */ x86emuOp_opcF6_byte_RM,
11700 /* 0xf7 */ x86emuOp_opcF7_word_RM,
11701
11702 /* 0xf8 */ x86emuOp_clc,
11703 /* 0xf9 */ x86emuOp_stc,
11704 /* 0xfa */ x86emuOp_cli,
11705 /* 0xfb */ x86emuOp_sti,
11706 /* 0xfc */ x86emuOp_cld,
11707 /* 0xfd */ x86emuOp_std,
11708 /* 0xfe */ x86emuOp_opcFE_byte_RM,
11709 /* 0xff */ x86emuOp_opcFF_word_RM,
11710 };
11711
tables_relocate(unsigned int offset)11712 void tables_relocate(unsigned int offset)
11713 {
11714 int i;
11715 for (i=0; i<8; i++)
11716 {
11717 opc80_byte_operation[i] -= offset;
11718 opc81_word_operation[i] -= offset;
11719 opc81_long_operation[i] -= offset;
11720
11721 opc82_byte_operation[i] -= offset;
11722 opc83_word_operation[i] -= offset;
11723 opc83_long_operation[i] -= offset;
11724
11725 opcD0_byte_operation[i] -= offset;
11726 opcD1_word_operation[i] -= offset;
11727 opcD1_long_operation[i] -= offset;
11728 }
11729 }
11730
11731