uboot-cmd_s3c2410.patch
[u-boot-openmoko/mini2440.git] / drivers / bios_emulator / x86emu / ops.c
blob10f27579403bd9e7f3339cae30f279ff3399004c
1 /****************************************************************************
2 * Realmode X86 Emulator Library
4 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
5 * Jason Jin <Jason.jin@freescale.com>
7 * Copyright (C) 1991-2004 SciTech Software, Inc.
8 * Copyright (C) David Mosberger-Tang
9 * Copyright (C) 1999 Egbert Eich
11 * ========================================================================
13 * Permission to use, copy, modify, distribute, and sell this software and
14 * its documentation for any purpose is hereby granted without fee,
15 * provided that the above copyright notice appear in all copies and that
16 * both that copyright notice and this permission notice appear in
17 * supporting documentation, and that the name of the authors not be used
18 * in advertising or publicity pertaining to distribution of the software
19 * without specific, written prior permission. The authors makes no
20 * representations about the suitability of this software for any purpose.
21 * It is provided "as is" without express or implied warranty.
23 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
25 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
27 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
28 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29 * PERFORMANCE OF THIS SOFTWARE.
31 * ========================================================================
33 * Language: ANSI C
34 * Environment: Any
35 * Developer: Kendall Bennett
37 * Description: This file includes subroutines to implement the decoding
38 * and emulation of all the x86 processor instructions.
40 * There are approximately 250 subroutines in here, which correspond
41 * to the 256 byte-"opcodes" found on the 8086. The table which
42 * dispatches this is found in the files optab.[ch].
44 * Each opcode proc has a comment preceeding it which gives it's table
45 * address. Several opcodes are missing (undefined) in the table.
47 * Each proc includes information for decoding (DECODE_PRINTF and
48 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
49 * functions (START_OF_INSTR, END_OF_INSTR).
51 * Many of the procedures are *VERY* similar in coding. This has
52 * allowed for a very large amount of code to be generated in a fairly
53 * short amount of time (i.e. cut, paste, and modify). The result is
54 * that much of the code below could have been folded into subroutines
55 * for a large reduction in size of this file. The downside would be
56 * that there would be a penalty in execution speed. The file could
57 * also have been *MUCH* larger by inlining certain functions which
58 * were called. This could have resulted even faster execution. The
59 * prime directive I used to decide whether to inline the code or to
60 * modularize it, was basically: 1) no unnecessary subroutine calls,
61 * 2) no routines more than about 200 lines in size, and 3) modularize
62 * any code that I might not get right the first time. The fetch_*
63 * subroutines fall into the latter category. The The decode_* fall
64 * into the second category. The coding of the "switch(mod){ .... }"
65 * in many of the subroutines below falls into the first category.
66 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
67 * subroutines are an especially glaring case of the third guideline.
68 * Since so much of the code is cloned from other modules (compare
69 * opcode #00 to opcode #01), making the basic operations subroutine
70 * calls is especially important; otherwise mistakes in coding an
71 * "add" would represent a nightmare in maintenance.
73 * Jason ported this file to u-boot. place all the function pointer in
74 * the got2 sector. Removed some opcode.
76 ****************************************************************************/
78 #include <common.h>
80 #if defined(CONFIG_BIOSEMU)
82 #include "x86emu/x86emui.h"
84 /*----------------------------- Implementation ----------------------------*/
86 /* constant arrays to do several instructions in just one function */
88 #ifdef DEBUG
89 static char *x86emu_GenOpName[8] = {
90 "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
91 #endif
93 /* used by several opcodes */
94 static u8 (*genop_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) =
96 add_byte, /* 00 */
97 or_byte, /* 01 */
98 adc_byte, /* 02 */
99 sbb_byte, /* 03 */
100 and_byte, /* 04 */
101 sub_byte, /* 05 */
102 xor_byte, /* 06 */
103 cmp_byte, /* 07 */
106 static u16 (*genop_word_operation[])(u16 d, u16 s) __attribute__ ((section(GOT2_TYPE))) =
108 add_word, /*00 */
109 or_word, /*01 */
110 adc_word, /*02 */
111 sbb_word, /*03 */
112 and_word, /*04 */
113 sub_word, /*05 */
114 xor_word, /*06 */
115 cmp_word, /*07 */
118 static u32 (*genop_long_operation[])(u32 d, u32 s) __attribute__ ((section(GOT2_TYPE))) =
120 add_long, /*00 */
121 or_long, /*01 */
122 adc_long, /*02 */
123 sbb_long, /*03 */
124 and_long, /*04 */
125 sub_long, /*05 */
126 xor_long, /*06 */
127 cmp_long, /*07 */
130 /* used by opcodes 80, c0, d0, and d2. */
131 static u8(*opcD0_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) =
133 rol_byte,
134 ror_byte,
135 rcl_byte,
136 rcr_byte,
137 shl_byte,
138 shr_byte,
139 shl_byte, /* sal_byte === shl_byte by definition */
140 sar_byte,
143 /* used by opcodes c1, d1, and d3. */
144 static u16(*opcD1_word_operation[])(u16 s, u8 d) __attribute__ ((section(GOT2_TYPE))) =
146 rol_word,
147 ror_word,
148 rcl_word,
149 rcr_word,
150 shl_word,
151 shr_word,
152 shl_word, /* sal_byte === shl_byte by definition */
153 sar_word,
156 /* used by opcodes c1, d1, and d3. */
157 static u32 (*opcD1_long_operation[])(u32 s, u8 d) __attribute__ ((section(GOT2_TYPE))) =
159 rol_long,
160 ror_long,
161 rcl_long,
162 rcr_long,
163 shl_long,
164 shr_long,
165 shl_long, /* sal_byte === shl_byte by definition */
166 sar_long,
169 #ifdef DEBUG
171 static char *opF6_names[8] =
172 { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
174 #endif
176 /****************************************************************************
177 PARAMETERS:
178 op1 - Instruction op code
180 REMARKS:
181 Handles illegal opcodes.
182 ****************************************************************************/
183 void x86emuOp_illegal_op(
184 u8 op1)
186 START_OF_INSTR();
187 if (M.x86.R_SP != 0) {
188 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
189 TRACE_REGS();
190 DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
191 M.x86.R_CS, M.x86.R_IP-1,op1));
192 HALT_SYS();
194 else {
195 /* If we get here, it means the stack pointer is back to zero
196 * so we are just returning from an emulator service call
197 * so therte is no need to display an error message. We trap
198 * the emulator with an 0xF1 opcode to finish the service
199 * call.
201 X86EMU_halt_sys();
203 END_OF_INSTR();
206 /****************************************************************************
207 REMARKS:
208 Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
209 ****************************************************************************/
210 void x86emuOp_genop_byte_RM_R(u8 op1)
212 int mod, rl, rh;
213 uint destoffset;
214 u8 *destreg, *srcreg;
215 u8 destval;
217 op1 = (op1 >> 3) & 0x7;
219 START_OF_INSTR();
220 DECODE_PRINTF(x86emu_GenOpName[op1]);
221 DECODE_PRINTF("\t");
222 FETCH_DECODE_MODRM(mod, rh, rl);
223 if(mod<3)
224 { destoffset = decode_rmXX_address(mod,rl);
225 DECODE_PRINTF(",");
226 destval = fetch_data_byte(destoffset);
227 srcreg = DECODE_RM_BYTE_REGISTER(rh);
228 DECODE_PRINTF("\n");
229 TRACE_AND_STEP();
230 destval = genop_byte_operation[op1](destval, *srcreg);
231 store_data_byte(destoffset, destval);
233 else
234 { /* register to register */
235 destreg = DECODE_RM_BYTE_REGISTER(rl);
236 DECODE_PRINTF(",");
237 srcreg = DECODE_RM_BYTE_REGISTER(rh);
238 DECODE_PRINTF("\n");
239 TRACE_AND_STEP();
240 *destreg = genop_byte_operation[op1](*destreg, *srcreg);
242 DECODE_CLEAR_SEGOVR();
243 END_OF_INSTR();
246 /****************************************************************************
247 REMARKS:
248 Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
249 ****************************************************************************/
250 void x86emuOp_genop_word_RM_R(u8 op1)
252 int mod, rl, rh;
253 uint destoffset;
255 op1 = (op1 >> 3) & 0x7;
257 START_OF_INSTR();
258 DECODE_PRINTF(x86emu_GenOpName[op1]);
259 DECODE_PRINTF("\t");
260 FETCH_DECODE_MODRM(mod, rh, rl);
262 if(mod<3) {
263 destoffset = decode_rmXX_address(mod,rl);
264 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
265 u32 destval;
266 u32 *srcreg;
268 DECODE_PRINTF(",");
269 destval = fetch_data_long(destoffset);
270 srcreg = DECODE_RM_LONG_REGISTER(rh);
271 DECODE_PRINTF("\n");
272 TRACE_AND_STEP();
273 destval = genop_long_operation[op1](destval, *srcreg);
274 store_data_long(destoffset, destval);
275 } else {
276 u16 destval;
277 u16 *srcreg;
279 DECODE_PRINTF(",");
280 destval = fetch_data_word(destoffset);
281 srcreg = DECODE_RM_WORD_REGISTER(rh);
282 DECODE_PRINTF("\n");
283 TRACE_AND_STEP();
284 destval = genop_word_operation[op1](destval, *srcreg);
285 store_data_word(destoffset, destval);
287 } else { /* register to register */
288 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
289 u32 *destreg,*srcreg;
291 destreg = DECODE_RM_LONG_REGISTER(rl);
292 DECODE_PRINTF(",");
293 srcreg = DECODE_RM_LONG_REGISTER(rh);
294 DECODE_PRINTF("\n");
295 TRACE_AND_STEP();
296 *destreg = genop_long_operation[op1](*destreg, *srcreg);
297 } else {
298 u16 *destreg,*srcreg;
300 destreg = DECODE_RM_WORD_REGISTER(rl);
301 DECODE_PRINTF(",");
302 srcreg = DECODE_RM_WORD_REGISTER(rh);
303 DECODE_PRINTF("\n");
304 TRACE_AND_STEP();
305 *destreg = genop_word_operation[op1](*destreg, *srcreg);
308 DECODE_CLEAR_SEGOVR();
309 END_OF_INSTR();
312 /****************************************************************************
313 REMARKS:
314 Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
315 ****************************************************************************/
316 void x86emuOp_genop_byte_R_RM(u8 op1)
318 int mod, rl, rh;
319 u8 *destreg, *srcreg;
320 uint srcoffset;
321 u8 srcval;
323 op1 = (op1 >> 3) & 0x7;
325 START_OF_INSTR();
326 DECODE_PRINTF(x86emu_GenOpName[op1]);
327 DECODE_PRINTF("\t");
328 FETCH_DECODE_MODRM(mod, rh, rl);
329 if (mod < 3) {
330 destreg = DECODE_RM_BYTE_REGISTER(rh);
331 DECODE_PRINTF(",");
332 srcoffset = decode_rmXX_address(mod,rl);
333 srcval = fetch_data_byte(srcoffset);
334 } else { /* register to register */
335 destreg = DECODE_RM_BYTE_REGISTER(rh);
336 DECODE_PRINTF(",");
337 srcreg = DECODE_RM_BYTE_REGISTER(rl);
338 srcval = *srcreg;
340 DECODE_PRINTF("\n");
341 TRACE_AND_STEP();
342 *destreg = genop_byte_operation[op1](*destreg, srcval);
344 DECODE_CLEAR_SEGOVR();
345 END_OF_INSTR();
348 /****************************************************************************
349 REMARKS:
350 Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
351 ****************************************************************************/
352 void x86emuOp_genop_word_R_RM(u8 op1)
354 int mod, rl, rh;
355 uint srcoffset;
356 u32 *destreg32, srcval;
357 u16 *destreg;
359 op1 = (op1 >> 3) & 0x7;
361 START_OF_INSTR();
362 DECODE_PRINTF(x86emu_GenOpName[op1]);
363 DECODE_PRINTF("\t");
364 FETCH_DECODE_MODRM(mod, rh, rl);
365 if (mod < 3) {
366 srcoffset = decode_rmXX_address(mod,rl);
367 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
368 destreg32 = DECODE_RM_LONG_REGISTER(rh);
369 DECODE_PRINTF(",");
370 srcval = fetch_data_long(srcoffset);
371 DECODE_PRINTF("\n");
372 TRACE_AND_STEP();
373 *destreg32 = genop_long_operation[op1](*destreg32, srcval);
374 } else {
375 destreg = DECODE_RM_WORD_REGISTER(rh);
376 DECODE_PRINTF(",");
377 srcval = fetch_data_word(srcoffset);
378 DECODE_PRINTF("\n");
379 TRACE_AND_STEP();
380 *destreg = genop_word_operation[op1](*destreg, srcval);
382 } else { /* register to register */
383 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
384 u32 *srcreg;
385 destreg32 = DECODE_RM_LONG_REGISTER(rh);
386 DECODE_PRINTF(",");
387 srcreg = DECODE_RM_LONG_REGISTER(rl);
388 DECODE_PRINTF("\n");
389 TRACE_AND_STEP();
390 *destreg32 = genop_long_operation[op1](*destreg32, *srcreg);
391 } else {
392 u16 *srcreg;
393 destreg = DECODE_RM_WORD_REGISTER(rh);
394 DECODE_PRINTF(",");
395 srcreg = DECODE_RM_WORD_REGISTER(rl);
396 DECODE_PRINTF("\n");
397 TRACE_AND_STEP();
398 *destreg = genop_word_operation[op1](*destreg, *srcreg);
401 DECODE_CLEAR_SEGOVR();
402 END_OF_INSTR();
405 /****************************************************************************
406 REMARKS:
407 Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
408 ****************************************************************************/
409 void x86emuOp_genop_byte_AL_IMM(u8 op1)
411 u8 srcval;
413 op1 = (op1 >> 3) & 0x7;
415 START_OF_INSTR();
416 DECODE_PRINTF(x86emu_GenOpName[op1]);
417 DECODE_PRINTF("\tAL,");
418 srcval = fetch_byte_imm();
419 DECODE_PRINTF2("%x\n", srcval);
420 TRACE_AND_STEP();
421 M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval);
422 DECODE_CLEAR_SEGOVR();
423 END_OF_INSTR();
426 /****************************************************************************
427 REMARKS:
428 Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
429 ****************************************************************************/
430 void x86emuOp_genop_word_AX_IMM(u8 op1)
432 u32 srcval;
434 op1 = (op1 >> 3) & 0x7;
436 START_OF_INSTR();
437 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
438 DECODE_PRINTF(x86emu_GenOpName[op1]);
439 DECODE_PRINTF("\tEAX,");
440 srcval = fetch_long_imm();
441 } else {
442 DECODE_PRINTF(x86emu_GenOpName[op1]);
443 DECODE_PRINTF("\tAX,");
444 srcval = fetch_word_imm();
446 DECODE_PRINTF2("%x\n", srcval);
447 TRACE_AND_STEP();
448 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
449 M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval);
450 } else {
451 M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval);
453 DECODE_CLEAR_SEGOVR();
454 END_OF_INSTR();
457 /****************************************************************************
458 REMARKS:
459 Handles opcode 0x06
460 ****************************************************************************/
461 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
463 START_OF_INSTR();
464 DECODE_PRINTF("PUSH\tES\n");
465 TRACE_AND_STEP();
466 push_word(M.x86.R_ES);
467 DECODE_CLEAR_SEGOVR();
468 END_OF_INSTR();
471 /****************************************************************************
472 REMARKS:
473 Handles opcode 0x07
474 ****************************************************************************/
475 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
477 START_OF_INSTR();
478 DECODE_PRINTF("POP\tES\n");
479 TRACE_AND_STEP();
480 M.x86.R_ES = pop_word();
481 DECODE_CLEAR_SEGOVR();
482 END_OF_INSTR();
485 /****************************************************************************
486 REMARKS:
487 Handles opcode 0x0e
488 ****************************************************************************/
489 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
491 START_OF_INSTR();
492 DECODE_PRINTF("PUSH\tCS\n");
493 TRACE_AND_STEP();
494 push_word(M.x86.R_CS);
495 DECODE_CLEAR_SEGOVR();
496 END_OF_INSTR();
499 /****************************************************************************
500 REMARKS:
501 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
502 ****************************************************************************/
503 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
505 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
506 INC_DECODED_INST_LEN(1);
507 (*x86emu_optab2[op2])(op2);
510 /****************************************************************************
511 REMARKS:
512 Handles opcode 0x16
513 ****************************************************************************/
514 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
516 START_OF_INSTR();
517 DECODE_PRINTF("PUSH\tSS\n");
518 TRACE_AND_STEP();
519 push_word(M.x86.R_SS);
520 DECODE_CLEAR_SEGOVR();
521 END_OF_INSTR();
524 /****************************************************************************
525 REMARKS:
526 Handles opcode 0x17
527 ****************************************************************************/
528 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
530 START_OF_INSTR();
531 DECODE_PRINTF("POP\tSS\n");
532 TRACE_AND_STEP();
533 M.x86.R_SS = pop_word();
534 DECODE_CLEAR_SEGOVR();
535 END_OF_INSTR();
538 /****************************************************************************
539 REMARKS:
540 Handles opcode 0x1e
541 ****************************************************************************/
542 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
544 START_OF_INSTR();
545 DECODE_PRINTF("PUSH\tDS\n");
546 TRACE_AND_STEP();
547 push_word(M.x86.R_DS);
548 DECODE_CLEAR_SEGOVR();
549 END_OF_INSTR();
552 /****************************************************************************
553 REMARKS:
554 Handles opcode 0x1f
555 ****************************************************************************/
556 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
558 START_OF_INSTR();
559 DECODE_PRINTF("POP\tDS\n");
560 TRACE_AND_STEP();
561 M.x86.R_DS = pop_word();
562 DECODE_CLEAR_SEGOVR();
563 END_OF_INSTR();
566 /****************************************************************************
567 REMARKS:
568 Handles opcode 0x26
569 ****************************************************************************/
570 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
572 START_OF_INSTR();
573 DECODE_PRINTF("ES:\n");
574 TRACE_AND_STEP();
575 M.x86.mode |= SYSMODE_SEGOVR_ES;
577 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
578 * opcode subroutines we do not want to do this.
580 END_OF_INSTR();
583 /****************************************************************************
584 REMARKS:
585 Handles opcode 0x27
586 ****************************************************************************/
587 void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
589 START_OF_INSTR();
590 DECODE_PRINTF("DAA\n");
591 TRACE_AND_STEP();
592 M.x86.R_AL = daa_byte(M.x86.R_AL);
593 DECODE_CLEAR_SEGOVR();
594 END_OF_INSTR();
597 /****************************************************************************
598 REMARKS:
599 Handles opcode 0x2e
600 ****************************************************************************/
601 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
603 START_OF_INSTR();
604 DECODE_PRINTF("CS:\n");
605 TRACE_AND_STEP();
606 M.x86.mode |= SYSMODE_SEGOVR_CS;
607 /* note no DECODE_CLEAR_SEGOVR here. */
608 END_OF_INSTR();
611 /****************************************************************************
612 REMARKS:
613 Handles opcode 0x2f
614 ****************************************************************************/
615 void x86emuOp_das(u8 X86EMU_UNUSED(op1))
617 START_OF_INSTR();
618 DECODE_PRINTF("DAS\n");
619 TRACE_AND_STEP();
620 M.x86.R_AL = das_byte(M.x86.R_AL);
621 DECODE_CLEAR_SEGOVR();
622 END_OF_INSTR();
625 /****************************************************************************
626 REMARKS:
627 Handles opcode 0x36
628 ****************************************************************************/
629 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
631 START_OF_INSTR();
632 DECODE_PRINTF("SS:\n");
633 TRACE_AND_STEP();
634 M.x86.mode |= SYSMODE_SEGOVR_SS;
635 /* no DECODE_CLEAR_SEGOVR ! */
636 END_OF_INSTR();
639 /****************************************************************************
640 REMARKS:
641 Handles opcode 0x37
642 ****************************************************************************/
643 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
645 START_OF_INSTR();
646 DECODE_PRINTF("AAA\n");
647 TRACE_AND_STEP();
648 M.x86.R_AX = aaa_word(M.x86.R_AX);
649 DECODE_CLEAR_SEGOVR();
650 END_OF_INSTR();
653 /****************************************************************************
654 REMARKS:
655 Handles opcode 0x3e
656 ****************************************************************************/
657 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
659 START_OF_INSTR();
660 DECODE_PRINTF("DS:\n");
661 TRACE_AND_STEP();
662 M.x86.mode |= SYSMODE_SEGOVR_DS;
663 /* NO DECODE_CLEAR_SEGOVR! */
664 END_OF_INSTR();
667 /****************************************************************************
668 REMARKS:
669 Handles opcode 0x3f
670 ****************************************************************************/
671 void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
673 START_OF_INSTR();
674 DECODE_PRINTF("AAS\n");
675 TRACE_AND_STEP();
676 M.x86.R_AX = aas_word(M.x86.R_AX);
677 DECODE_CLEAR_SEGOVR();
678 END_OF_INSTR();
681 /****************************************************************************
682 REMARKS:
683 Handles opcode 0x40 - 0x47
684 ****************************************************************************/
685 void x86emuOp_inc_register(u8 op1)
687 START_OF_INSTR();
688 op1 &= 0x7;
689 DECODE_PRINTF("INC\t");
690 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
691 u32 *reg;
692 reg = DECODE_RM_LONG_REGISTER(op1);
693 DECODE_PRINTF("\n");
694 TRACE_AND_STEP();
695 *reg = inc_long(*reg);
696 } else {
697 u16 *reg;
698 reg = DECODE_RM_WORD_REGISTER(op1);
699 DECODE_PRINTF("\n");
700 TRACE_AND_STEP();
701 *reg = inc_word(*reg);
703 DECODE_CLEAR_SEGOVR();
704 END_OF_INSTR();
707 /****************************************************************************
708 REMARKS:
709 Handles opcode 0x48 - 0x4F
710 ****************************************************************************/
711 void x86emuOp_dec_register(u8 op1)
713 START_OF_INSTR();
714 op1 &= 0x7;
715 DECODE_PRINTF("DEC\t");
716 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
717 u32 *reg;
718 reg = DECODE_RM_LONG_REGISTER(op1);
719 DECODE_PRINTF("\n");
720 TRACE_AND_STEP();
721 *reg = dec_long(*reg);
722 } else {
723 u16 *reg;
724 reg = DECODE_RM_WORD_REGISTER(op1);
725 DECODE_PRINTF("\n");
726 TRACE_AND_STEP();
727 *reg = dec_word(*reg);
729 DECODE_CLEAR_SEGOVR();
730 END_OF_INSTR();
733 /****************************************************************************
734 REMARKS:
735 Handles opcode 0x50 - 0x57
736 ****************************************************************************/
737 void x86emuOp_push_register(u8 op1)
739 START_OF_INSTR();
740 op1 &= 0x7;
741 DECODE_PRINTF("PUSH\t");
742 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
743 u32 *reg;
744 reg = DECODE_RM_LONG_REGISTER(op1);
745 DECODE_PRINTF("\n");
746 TRACE_AND_STEP();
747 push_long(*reg);
748 } else {
749 u16 *reg;
750 reg = DECODE_RM_WORD_REGISTER(op1);
751 DECODE_PRINTF("\n");
752 TRACE_AND_STEP();
753 push_word(*reg);
755 DECODE_CLEAR_SEGOVR();
756 END_OF_INSTR();
759 /****************************************************************************
760 REMARKS:
761 Handles opcode 0x58 - 0x5F
762 ****************************************************************************/
763 void x86emuOp_pop_register(u8 op1)
765 START_OF_INSTR();
766 op1 &= 0x7;
767 DECODE_PRINTF("POP\t");
768 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
769 u32 *reg;
770 reg = DECODE_RM_LONG_REGISTER(op1);
771 DECODE_PRINTF("\n");
772 TRACE_AND_STEP();
773 *reg = pop_long();
774 } else {
775 u16 *reg;
776 reg = DECODE_RM_WORD_REGISTER(op1);
777 DECODE_PRINTF("\n");
778 TRACE_AND_STEP();
779 *reg = pop_word();
781 DECODE_CLEAR_SEGOVR();
782 END_OF_INSTR();
785 /****************************************************************************
786 REMARKS:
787 Handles opcode 0x60
788 ****************************************************************************/
789 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
791 START_OF_INSTR();
792 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
793 DECODE_PRINTF("PUSHAD\n");
794 } else {
795 DECODE_PRINTF("PUSHA\n");
797 TRACE_AND_STEP();
798 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
799 u32 old_sp = M.x86.R_ESP;
801 push_long(M.x86.R_EAX);
802 push_long(M.x86.R_ECX);
803 push_long(M.x86.R_EDX);
804 push_long(M.x86.R_EBX);
805 push_long(old_sp);
806 push_long(M.x86.R_EBP);
807 push_long(M.x86.R_ESI);
808 push_long(M.x86.R_EDI);
809 } else {
810 u16 old_sp = M.x86.R_SP;
812 push_word(M.x86.R_AX);
813 push_word(M.x86.R_CX);
814 push_word(M.x86.R_DX);
815 push_word(M.x86.R_BX);
816 push_word(old_sp);
817 push_word(M.x86.R_BP);
818 push_word(M.x86.R_SI);
819 push_word(M.x86.R_DI);
821 DECODE_CLEAR_SEGOVR();
822 END_OF_INSTR();
825 /****************************************************************************
826 REMARKS:
827 Handles opcode 0x61
828 ****************************************************************************/
829 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
831 START_OF_INSTR();
832 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
833 DECODE_PRINTF("POPAD\n");
834 } else {
835 DECODE_PRINTF("POPA\n");
837 TRACE_AND_STEP();
838 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
839 M.x86.R_EDI = pop_long();
840 M.x86.R_ESI = pop_long();
841 M.x86.R_EBP = pop_long();
842 M.x86.R_ESP += 4; /* skip ESP */
843 M.x86.R_EBX = pop_long();
844 M.x86.R_EDX = pop_long();
845 M.x86.R_ECX = pop_long();
846 M.x86.R_EAX = pop_long();
847 } else {
848 M.x86.R_DI = pop_word();
849 M.x86.R_SI = pop_word();
850 M.x86.R_BP = pop_word();
851 M.x86.R_SP += 2; /* skip SP */
852 M.x86.R_BX = pop_word();
853 M.x86.R_DX = pop_word();
854 M.x86.R_CX = pop_word();
855 M.x86.R_AX = pop_word();
857 DECODE_CLEAR_SEGOVR();
858 END_OF_INSTR();
861 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
862 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
864 /****************************************************************************
865 REMARKS:
866 Handles opcode 0x64
867 ****************************************************************************/
868 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
870 START_OF_INSTR();
871 DECODE_PRINTF("FS:\n");
872 TRACE_AND_STEP();
873 M.x86.mode |= SYSMODE_SEGOVR_FS;
875 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
876 * opcode subroutines we do not want to do this.
878 END_OF_INSTR();
881 /****************************************************************************
882 REMARKS:
883 Handles opcode 0x65
884 ****************************************************************************/
885 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
887 START_OF_INSTR();
888 DECODE_PRINTF("GS:\n");
889 TRACE_AND_STEP();
890 M.x86.mode |= SYSMODE_SEGOVR_GS;
892 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
893 * opcode subroutines we do not want to do this.
895 END_OF_INSTR();
898 /****************************************************************************
899 REMARKS:
900 Handles opcode 0x66 - prefix for 32-bit register
901 ****************************************************************************/
902 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
904 START_OF_INSTR();
905 DECODE_PRINTF("DATA:\n");
906 TRACE_AND_STEP();
907 M.x86.mode |= SYSMODE_PREFIX_DATA;
908 /* note no DECODE_CLEAR_SEGOVR here. */
909 END_OF_INSTR();
912 /****************************************************************************
913 REMARKS:
914 Handles opcode 0x67 - prefix for 32-bit address
915 ****************************************************************************/
916 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
918 START_OF_INSTR();
919 DECODE_PRINTF("ADDR:\n");
920 TRACE_AND_STEP();
921 M.x86.mode |= SYSMODE_PREFIX_ADDR;
922 /* note no DECODE_CLEAR_SEGOVR here. */
923 END_OF_INSTR();
926 /****************************************************************************
927 REMARKS:
928 Handles opcode 0x68
929 ****************************************************************************/
930 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
932 u32 imm;
934 START_OF_INSTR();
935 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
936 imm = fetch_long_imm();
937 } else {
938 imm = fetch_word_imm();
940 DECODE_PRINTF2("PUSH\t%x\n", imm);
941 TRACE_AND_STEP();
942 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
943 push_long(imm);
944 } else {
945 push_word((u16)imm);
947 DECODE_CLEAR_SEGOVR();
948 END_OF_INSTR();
951 /****************************************************************************
952 REMARKS:
953 Handles opcode 0x69
954 ****************************************************************************/
955 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
957 int mod, rl, rh;
958 uint srcoffset;
960 START_OF_INSTR();
961 DECODE_PRINTF("IMUL\t");
962 FETCH_DECODE_MODRM(mod, rh, rl);
963 if (mod < 3) {
964 srcoffset = decode_rmXX_address(mod, rl);
965 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
966 u32 *destreg;
967 u32 srcval;
968 u32 res_lo,res_hi;
969 s32 imm;
971 destreg = DECODE_RM_LONG_REGISTER(rh);
972 DECODE_PRINTF(",");
973 srcval = fetch_data_long(srcoffset);
974 imm = fetch_long_imm();
975 DECODE_PRINTF2(",%d\n", (s32)imm);
976 TRACE_AND_STEP();
977 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
978 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
979 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
980 CLEAR_FLAG(F_CF);
981 CLEAR_FLAG(F_OF);
982 } else {
983 SET_FLAG(F_CF);
984 SET_FLAG(F_OF);
986 *destreg = (u32)res_lo;
987 } else {
988 u16 *destreg;
989 u16 srcval;
990 u32 res;
991 s16 imm;
993 destreg = DECODE_RM_WORD_REGISTER(rh);
994 DECODE_PRINTF(",");
995 srcval = fetch_data_word(srcoffset);
996 imm = fetch_word_imm();
997 DECODE_PRINTF2(",%d\n", (s32)imm);
998 TRACE_AND_STEP();
999 res = (s16)srcval * (s16)imm;
1000 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1001 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1002 CLEAR_FLAG(F_CF);
1003 CLEAR_FLAG(F_OF);
1004 } else {
1005 SET_FLAG(F_CF);
1006 SET_FLAG(F_OF);
1008 *destreg = (u16)res;
1010 } else { /* register to register */
1011 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1012 u32 *destreg,*srcreg;
1013 u32 res_lo,res_hi;
1014 s32 imm;
1016 destreg = DECODE_RM_LONG_REGISTER(rh);
1017 DECODE_PRINTF(",");
1018 srcreg = DECODE_RM_LONG_REGISTER(rl);
1019 imm = fetch_long_imm();
1020 DECODE_PRINTF2(",%d\n", (s32)imm);
1021 TRACE_AND_STEP();
1022 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
1023 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1024 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1025 CLEAR_FLAG(F_CF);
1026 CLEAR_FLAG(F_OF);
1027 } else {
1028 SET_FLAG(F_CF);
1029 SET_FLAG(F_OF);
1031 *destreg = (u32)res_lo;
1032 } else {
1033 u16 *destreg,*srcreg;
1034 u32 res;
1035 s16 imm;
1037 destreg = DECODE_RM_WORD_REGISTER(rh);
1038 DECODE_PRINTF(",");
1039 srcreg = DECODE_RM_WORD_REGISTER(rl);
1040 imm = fetch_word_imm();
1041 DECODE_PRINTF2(",%d\n", (s32)imm);
1042 res = (s16)*srcreg * (s16)imm;
1043 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1044 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1045 CLEAR_FLAG(F_CF);
1046 CLEAR_FLAG(F_OF);
1047 } else {
1048 SET_FLAG(F_CF);
1049 SET_FLAG(F_OF);
1051 *destreg = (u16)res;
1054 DECODE_CLEAR_SEGOVR();
1055 END_OF_INSTR();
1058 /****************************************************************************
1059 REMARKS:
1060 Handles opcode 0x6a
1061 ****************************************************************************/
1062 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
1064 s16 imm;
1066 START_OF_INSTR();
1067 imm = (s8)fetch_byte_imm();
1068 DECODE_PRINTF2("PUSH\t%d\n", imm);
1069 TRACE_AND_STEP();
1070 push_word(imm);
1071 DECODE_CLEAR_SEGOVR();
1072 END_OF_INSTR();
1075 /****************************************************************************
1076 REMARKS:
1077 Handles opcode 0x6b
1078 ****************************************************************************/
1079 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
1081 int mod, rl, rh;
1082 uint srcoffset;
1083 s8 imm;
1085 START_OF_INSTR();
1086 DECODE_PRINTF("IMUL\t");
1087 FETCH_DECODE_MODRM(mod, rh, rl);
1088 if (mod < 3) {
1089 srcoffset = decode_rmXX_address(mod, rl);
1090 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1091 u32 *destreg;
1092 u32 srcval;
1093 u32 res_lo,res_hi;
1095 destreg = DECODE_RM_LONG_REGISTER(rh);
1096 DECODE_PRINTF(",");
1097 srcval = fetch_data_long(srcoffset);
1098 imm = fetch_byte_imm();
1099 DECODE_PRINTF2(",%d\n", (s32)imm);
1100 TRACE_AND_STEP();
1101 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
1102 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1103 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1104 CLEAR_FLAG(F_CF);
1105 CLEAR_FLAG(F_OF);
1106 } else {
1107 SET_FLAG(F_CF);
1108 SET_FLAG(F_OF);
1110 *destreg = (u32)res_lo;
1111 } else {
1112 u16 *destreg;
1113 u16 srcval;
1114 u32 res;
1116 destreg = DECODE_RM_WORD_REGISTER(rh);
1117 DECODE_PRINTF(",");
1118 srcval = fetch_data_word(srcoffset);
1119 imm = fetch_byte_imm();
1120 DECODE_PRINTF2(",%d\n", (s32)imm);
1121 TRACE_AND_STEP();
1122 res = (s16)srcval * (s16)imm;
1123 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1124 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1125 CLEAR_FLAG(F_CF);
1126 CLEAR_FLAG(F_OF);
1127 } else {
1128 SET_FLAG(F_CF);
1129 SET_FLAG(F_OF);
1131 *destreg = (u16)res;
1133 } else { /* register to register */
1134 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1135 u32 *destreg,*srcreg;
1136 u32 res_lo,res_hi;
1138 destreg = DECODE_RM_LONG_REGISTER(rh);
1139 DECODE_PRINTF(",");
1140 srcreg = DECODE_RM_LONG_REGISTER(rl);
1141 imm = fetch_byte_imm();
1142 DECODE_PRINTF2(",%d\n", (s32)imm);
1143 TRACE_AND_STEP();
1144 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
1145 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1146 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1147 CLEAR_FLAG(F_CF);
1148 CLEAR_FLAG(F_OF);
1149 } else {
1150 SET_FLAG(F_CF);
1151 SET_FLAG(F_OF);
1153 *destreg = (u32)res_lo;
1154 } else {
1155 u16 *destreg,*srcreg;
1156 u32 res;
1158 destreg = DECODE_RM_WORD_REGISTER(rh);
1159 DECODE_PRINTF(",");
1160 srcreg = DECODE_RM_WORD_REGISTER(rl);
1161 imm = fetch_byte_imm();
1162 DECODE_PRINTF2(",%d\n", (s32)imm);
1163 TRACE_AND_STEP();
1164 res = (s16)*srcreg * (s16)imm;
1165 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1166 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1167 CLEAR_FLAG(F_CF);
1168 CLEAR_FLAG(F_OF);
1169 } else {
1170 SET_FLAG(F_CF);
1171 SET_FLAG(F_OF);
1173 *destreg = (u16)res;
1176 DECODE_CLEAR_SEGOVR();
1177 END_OF_INSTR();
1180 /****************************************************************************
1181 REMARKS:
1182 Handles opcode 0x6c
1183 ****************************************************************************/
1184 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
1186 START_OF_INSTR();
1187 DECODE_PRINTF("INSB\n");
1188 ins(1);
1189 TRACE_AND_STEP();
1190 DECODE_CLEAR_SEGOVR();
1191 END_OF_INSTR();
1194 /****************************************************************************
1195 REMARKS:
1196 Handles opcode 0x6d
1197 ****************************************************************************/
1198 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
1200 START_OF_INSTR();
1201 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1202 DECODE_PRINTF("INSD\n");
1203 ins(4);
1204 } else {
1205 DECODE_PRINTF("INSW\n");
1206 ins(2);
1208 TRACE_AND_STEP();
1209 DECODE_CLEAR_SEGOVR();
1210 END_OF_INSTR();
1213 /****************************************************************************
1214 REMARKS:
1215 Handles opcode 0x6e
1216 ****************************************************************************/
1217 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
1219 START_OF_INSTR();
1220 DECODE_PRINTF("OUTSB\n");
1221 outs(1);
1222 TRACE_AND_STEP();
1223 DECODE_CLEAR_SEGOVR();
1224 END_OF_INSTR();
1227 /****************************************************************************
1228 REMARKS:
1229 Handles opcode 0x6f
1230 ****************************************************************************/
1231 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
1233 START_OF_INSTR();
1234 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1235 DECODE_PRINTF("OUTSD\n");
1236 outs(4);
1237 } else {
1238 DECODE_PRINTF("OUTSW\n");
1239 outs(2);
1241 TRACE_AND_STEP();
1242 DECODE_CLEAR_SEGOVR();
1243 END_OF_INSTR();
1246 /****************************************************************************
1247 REMARKS:
1248 Handles opcode 0x70 - 0x7F
1249 ****************************************************************************/
1250 int x86emu_check_jump_condition(u8 op);
1252 void x86emuOp_jump_near_cond(u8 op1)
1254 s8 offset;
1255 u16 target;
1256 int cond;
1258 /* jump to byte offset if overflow flag is set */
1259 START_OF_INSTR();
1260 cond = x86emu_check_jump_condition(op1 & 0xF);
1261 offset = (s8)fetch_byte_imm();
1262 target = (u16)(M.x86.R_IP + (s16)offset);
1263 DECODE_PRINTF2("%x\n", target);
1264 TRACE_AND_STEP();
1265 if (cond)
1266 M.x86.R_IP = target;
1267 DECODE_CLEAR_SEGOVR();
1268 END_OF_INSTR();
1271 /****************************************************************************
1272 REMARKS:
1273 Handles opcode 0x80
1274 ****************************************************************************/
1275 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
1277 int mod, rl, rh;
1278 u8 *destreg;
1279 uint destoffset;
1280 u8 imm;
1281 u8 destval;
1284 * Weirdo special case instruction format. Part of the opcode
1285 * held below in "RH". Doubly nested case would result, except
1286 * that the decoded instruction
1288 START_OF_INSTR();
1289 FETCH_DECODE_MODRM(mod, rh, rl);
1290 #ifdef DEBUG
1291 if (DEBUG_DECODE()) {
1292 /* XXX DECODE_PRINTF may be changed to something more
1293 general, so that it is important to leave the strings
1294 in the same format, even though the result is that the
1295 above test is done twice. */
1297 switch (rh) {
1298 case 0:
1299 DECODE_PRINTF("ADD\t");
1300 break;
1301 case 1:
1302 DECODE_PRINTF("OR\t");
1303 break;
1304 case 2:
1305 DECODE_PRINTF("ADC\t");
1306 break;
1307 case 3:
1308 DECODE_PRINTF("SBB\t");
1309 break;
1310 case 4:
1311 DECODE_PRINTF("AND\t");
1312 break;
1313 case 5:
1314 DECODE_PRINTF("SUB\t");
1315 break;
1316 case 6:
1317 DECODE_PRINTF("XOR\t");
1318 break;
1319 case 7:
1320 DECODE_PRINTF("CMP\t");
1321 break;
1324 #endif
1325 /* know operation, decode the mod byte to find the addressing
1326 mode. */
1327 if (mod < 3) {
1328 DECODE_PRINTF("BYTE PTR ");
1329 destoffset = decode_rmXX_address(mod, rl);
1330 DECODE_PRINTF(",");
1331 destval = fetch_data_byte(destoffset);
1332 imm = fetch_byte_imm();
1333 DECODE_PRINTF2("%x\n", imm);
1334 TRACE_AND_STEP();
1335 destval = (*genop_byte_operation[rh]) (destval, imm);
1336 if (rh != 7)
1337 store_data_byte(destoffset, destval);
1338 } else { /* register to register */
1339 destreg = DECODE_RM_BYTE_REGISTER(rl);
1340 DECODE_PRINTF(",");
1341 imm = fetch_byte_imm();
1342 DECODE_PRINTF2("%x\n", imm);
1343 TRACE_AND_STEP();
1344 destval = (*genop_byte_operation[rh]) (*destreg, imm);
1345 if (rh != 7)
1346 *destreg = destval;
1348 DECODE_CLEAR_SEGOVR();
1349 END_OF_INSTR();
1352 /****************************************************************************
1353 REMARKS:
1354 Handles opcode 0x81
1355 ****************************************************************************/
1356 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
1358 int mod, rl, rh;
1359 uint destoffset;
1362 * Weirdo special case instruction format. Part of the opcode
1363 * held below in "RH". Doubly nested case would result, except
1364 * that the decoded instruction
1366 START_OF_INSTR();
1367 FETCH_DECODE_MODRM(mod, rh, rl);
1368 #ifdef DEBUG
1369 if (DEBUG_DECODE()) {
1370 /* XXX DECODE_PRINTF may be changed to something more
1371 general, so that it is important to leave the strings
1372 in the same format, even though the result is that the
1373 above test is done twice. */
1375 switch (rh) {
1376 case 0:
1377 DECODE_PRINTF("ADD\t");
1378 break;
1379 case 1:
1380 DECODE_PRINTF("OR\t");
1381 break;
1382 case 2:
1383 DECODE_PRINTF("ADC\t");
1384 break;
1385 case 3:
1386 DECODE_PRINTF("SBB\t");
1387 break;
1388 case 4:
1389 DECODE_PRINTF("AND\t");
1390 break;
1391 case 5:
1392 DECODE_PRINTF("SUB\t");
1393 break;
1394 case 6:
1395 DECODE_PRINTF("XOR\t");
1396 break;
1397 case 7:
1398 DECODE_PRINTF("CMP\t");
1399 break;
1402 #endif
1404 * Know operation, decode the mod byte to find the addressing
1405 * mode.
1407 if (mod < 3) {
1408 DECODE_PRINTF("DWORD PTR ");
1409 destoffset = decode_rmXX_address(mod, rl);
1410 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1411 u32 destval,imm;
1413 DECODE_PRINTF(",");
1414 destval = fetch_data_long(destoffset);
1415 imm = fetch_long_imm();
1416 DECODE_PRINTF2("%x\n", imm);
1417 TRACE_AND_STEP();
1418 destval = (*genop_long_operation[rh]) (destval, imm);
1419 if (rh != 7)
1420 store_data_long(destoffset, destval);
1421 } else {
1422 u16 destval,imm;
1424 DECODE_PRINTF(",");
1425 destval = fetch_data_word(destoffset);
1426 imm = fetch_word_imm();
1427 DECODE_PRINTF2("%x\n", imm);
1428 TRACE_AND_STEP();
1429 destval = (*genop_word_operation[rh]) (destval, imm);
1430 if (rh != 7)
1431 store_data_word(destoffset, destval);
1433 } else { /* register to register */
1434 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1435 u32 *destreg;
1436 u32 destval,imm;
1438 destreg = DECODE_RM_LONG_REGISTER(rl);
1439 DECODE_PRINTF(",");
1440 imm = fetch_long_imm();
1441 DECODE_PRINTF2("%x\n", imm);
1442 TRACE_AND_STEP();
1443 destval = (*genop_long_operation[rh]) (*destreg, imm);
1444 if (rh != 7)
1445 *destreg = destval;
1446 } else {
1447 u16 *destreg;
1448 u16 destval,imm;
1450 destreg = DECODE_RM_WORD_REGISTER(rl);
1451 DECODE_PRINTF(",");
1452 imm = fetch_word_imm();
1453 DECODE_PRINTF2("%x\n", imm);
1454 TRACE_AND_STEP();
1455 destval = (*genop_word_operation[rh]) (*destreg, imm);
1456 if (rh != 7)
1457 *destreg = destval;
1460 DECODE_CLEAR_SEGOVR();
1461 END_OF_INSTR();
1464 /****************************************************************************
1465 REMARKS:
1466 Handles opcode 0x82
1467 ****************************************************************************/
1468 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
1470 int mod, rl, rh;
1471 u8 *destreg;
1472 uint destoffset;
1473 u8 imm;
1474 u8 destval;
1477 * Weirdo special case instruction format. Part of the opcode
1478 * held below in "RH". Doubly nested case would result, except
1479 * that the decoded instruction Similar to opcode 81, except that
1480 * the immediate byte is sign extended to a word length.
1482 START_OF_INSTR();
1483 FETCH_DECODE_MODRM(mod, rh, rl);
1484 #ifdef DEBUG
1485 if (DEBUG_DECODE()) {
1486 /* XXX DECODE_PRINTF may be changed to something more
1487 general, so that it is important to leave the strings
1488 in the same format, even though the result is that the
1489 above test is done twice. */
1490 switch (rh) {
1491 case 0:
1492 DECODE_PRINTF("ADD\t");
1493 break;
1494 case 1:
1495 DECODE_PRINTF("OR\t");
1496 break;
1497 case 2:
1498 DECODE_PRINTF("ADC\t");
1499 break;
1500 case 3:
1501 DECODE_PRINTF("SBB\t");
1502 break;
1503 case 4:
1504 DECODE_PRINTF("AND\t");
1505 break;
1506 case 5:
1507 DECODE_PRINTF("SUB\t");
1508 break;
1509 case 6:
1510 DECODE_PRINTF("XOR\t");
1511 break;
1512 case 7:
1513 DECODE_PRINTF("CMP\t");
1514 break;
1517 #endif
1518 /* know operation, decode the mod byte to find the addressing
1519 mode. */
1520 if (mod < 3) {
1521 DECODE_PRINTF("BYTE PTR ");
1522 destoffset = decode_rmXX_address(mod, rl);
1523 destval = fetch_data_byte(destoffset);
1524 imm = fetch_byte_imm();
1525 DECODE_PRINTF2(",%x\n", imm);
1526 TRACE_AND_STEP();
1527 destval = (*genop_byte_operation[rh]) (destval, imm);
1528 if (rh != 7)
1529 store_data_byte(destoffset, destval);
1530 } else { /* register to register */
1531 destreg = DECODE_RM_BYTE_REGISTER(rl);
1532 imm = fetch_byte_imm();
1533 DECODE_PRINTF2(",%x\n", imm);
1534 TRACE_AND_STEP();
1535 destval = (*genop_byte_operation[rh]) (*destreg, imm);
1536 if (rh != 7)
1537 *destreg = destval;
1539 DECODE_CLEAR_SEGOVR();
1540 END_OF_INSTR();
1543 /****************************************************************************
1544 REMARKS:
1545 Handles opcode 0x83
1546 ****************************************************************************/
1547 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
1549 int mod, rl, rh;
1550 uint destoffset;
1553 * Weirdo special case instruction format. Part of the opcode
1554 * held below in "RH". Doubly nested case would result, except
1555 * that the decoded instruction Similar to opcode 81, except that
1556 * the immediate byte is sign extended to a word length.
1558 START_OF_INSTR();
1559 FETCH_DECODE_MODRM(mod, rh, rl);
1560 #ifdef DEBUG
1561 if (DEBUG_DECODE()) {
1562 /* XXX DECODE_PRINTF may be changed to something more
1563 general, so that it is important to leave the strings
1564 in the same format, even though the result is that the
1565 above test is done twice. */
1566 switch (rh) {
1567 case 0:
1568 DECODE_PRINTF("ADD\t");
1569 break;
1570 case 1:
1571 DECODE_PRINTF("OR\t");
1572 break;
1573 case 2:
1574 DECODE_PRINTF("ADC\t");
1575 break;
1576 case 3:
1577 DECODE_PRINTF("SBB\t");
1578 break;
1579 case 4:
1580 DECODE_PRINTF("AND\t");
1581 break;
1582 case 5:
1583 DECODE_PRINTF("SUB\t");
1584 break;
1585 case 6:
1586 DECODE_PRINTF("XOR\t");
1587 break;
1588 case 7:
1589 DECODE_PRINTF("CMP\t");
1590 break;
1593 #endif
1594 /* know operation, decode the mod byte to find the addressing
1595 mode. */
1596 if (mod < 3) {
1597 DECODE_PRINTF("DWORD PTR ");
1598 destoffset = decode_rmXX_address(mod,rl);
1600 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1601 u32 destval,imm;
1603 destval = fetch_data_long(destoffset);
1604 imm = (s8) fetch_byte_imm();
1605 DECODE_PRINTF2(",%x\n", imm);
1606 TRACE_AND_STEP();
1607 destval = (*genop_long_operation[rh]) (destval, imm);
1608 if (rh != 7)
1609 store_data_long(destoffset, destval);
1610 } else {
1611 u16 destval,imm;
1613 destval = fetch_data_word(destoffset);
1614 imm = (s8) fetch_byte_imm();
1615 DECODE_PRINTF2(",%x\n", imm);
1616 TRACE_AND_STEP();
1617 destval = (*genop_word_operation[rh]) (destval, imm);
1618 if (rh != 7)
1619 store_data_word(destoffset, destval);
1621 } else { /* register to register */
1622 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1623 u32 *destreg;
1624 u32 destval,imm;
1626 destreg = DECODE_RM_LONG_REGISTER(rl);
1627 imm = (s8) fetch_byte_imm();
1628 DECODE_PRINTF2(",%x\n", imm);
1629 TRACE_AND_STEP();
1630 destval = (*genop_long_operation[rh]) (*destreg, imm);
1631 if (rh != 7)
1632 *destreg = destval;
1633 } else {
1634 u16 *destreg;
1635 u16 destval,imm;
1637 destreg = DECODE_RM_WORD_REGISTER(rl);
1638 imm = (s8) fetch_byte_imm();
1639 DECODE_PRINTF2(",%x\n", imm);
1640 TRACE_AND_STEP();
1641 destval = (*genop_word_operation[rh]) (*destreg, imm);
1642 if (rh != 7)
1643 *destreg = destval;
1646 DECODE_CLEAR_SEGOVR();
1647 END_OF_INSTR();
1650 /****************************************************************************
1651 REMARKS:
1652 Handles opcode 0x84
1653 ****************************************************************************/
1654 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
1656 int mod, rl, rh;
1657 u8 *destreg, *srcreg;
1658 uint destoffset;
1659 u8 destval;
1661 START_OF_INSTR();
1662 DECODE_PRINTF("TEST\t");
1663 FETCH_DECODE_MODRM(mod, rh, rl);
1664 if (mod < 3) {
1665 destoffset = decode_rmXX_address(mod, rl);
1666 DECODE_PRINTF(",");
1667 destval = fetch_data_byte(destoffset);
1668 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1669 DECODE_PRINTF("\n");
1670 TRACE_AND_STEP();
1671 test_byte(destval, *srcreg);
1672 } else { /* register to register */
1673 destreg = DECODE_RM_BYTE_REGISTER(rl);
1674 DECODE_PRINTF(",");
1675 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1676 DECODE_PRINTF("\n");
1677 TRACE_AND_STEP();
1678 test_byte(*destreg, *srcreg);
1680 DECODE_CLEAR_SEGOVR();
1681 END_OF_INSTR();
1684 /****************************************************************************
1685 REMARKS:
1686 Handles opcode 0x85
1687 ****************************************************************************/
1688 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
1690 int mod, rl, rh;
1691 uint destoffset;
1693 START_OF_INSTR();
1694 DECODE_PRINTF("TEST\t");
1695 FETCH_DECODE_MODRM(mod, rh, rl);
1696 if (mod < 3) {
1697 destoffset = decode_rmXX_address(mod, rl);
1698 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1699 u32 destval;
1700 u32 *srcreg;
1702 DECODE_PRINTF(",");
1703 destval = fetch_data_long(destoffset);
1704 srcreg = DECODE_RM_LONG_REGISTER(rh);
1705 DECODE_PRINTF("\n");
1706 TRACE_AND_STEP();
1707 test_long(destval, *srcreg);
1708 } else {
1709 u16 destval;
1710 u16 *srcreg;
1712 DECODE_PRINTF(",");
1713 destval = fetch_data_word(destoffset);
1714 srcreg = DECODE_RM_WORD_REGISTER(rh);
1715 DECODE_PRINTF("\n");
1716 TRACE_AND_STEP();
1717 test_word(destval, *srcreg);
1719 } else { /* register to register */
1720 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1721 u32 *destreg,*srcreg;
1723 destreg = DECODE_RM_LONG_REGISTER(rl);
1724 DECODE_PRINTF(",");
1725 srcreg = DECODE_RM_LONG_REGISTER(rh);
1726 DECODE_PRINTF("\n");
1727 TRACE_AND_STEP();
1728 test_long(*destreg, *srcreg);
1729 } else {
1730 u16 *destreg,*srcreg;
1732 destreg = DECODE_RM_WORD_REGISTER(rl);
1733 DECODE_PRINTF(",");
1734 srcreg = DECODE_RM_WORD_REGISTER(rh);
1735 DECODE_PRINTF("\n");
1736 TRACE_AND_STEP();
1737 test_word(*destreg, *srcreg);
1740 DECODE_CLEAR_SEGOVR();
1741 END_OF_INSTR();
1744 /****************************************************************************
1745 REMARKS:
1746 Handles opcode 0x86
1747 ****************************************************************************/
1748 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
1750 int mod, rl, rh;
1751 u8 *destreg, *srcreg;
1752 uint destoffset;
1753 u8 destval;
1754 u8 tmp;
1756 START_OF_INSTR();
1757 DECODE_PRINTF("XCHG\t");
1758 FETCH_DECODE_MODRM(mod, rh, rl);
1759 if (mod < 3) {
1760 destoffset = decode_rmXX_address(mod, rl);
1761 DECODE_PRINTF(",");
1762 destval = fetch_data_byte(destoffset);
1763 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1764 DECODE_PRINTF("\n");
1765 TRACE_AND_STEP();
1766 tmp = *srcreg;
1767 *srcreg = destval;
1768 destval = tmp;
1769 store_data_byte(destoffset, destval);
1770 } else { /* register to register */
1771 destreg = DECODE_RM_BYTE_REGISTER(rl);
1772 DECODE_PRINTF(",");
1773 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1774 DECODE_PRINTF("\n");
1775 TRACE_AND_STEP();
1776 tmp = *srcreg;
1777 *srcreg = *destreg;
1778 *destreg = tmp;
1780 DECODE_CLEAR_SEGOVR();
1781 END_OF_INSTR();
1784 /****************************************************************************
1785 REMARKS:
1786 Handles opcode 0x87
1787 ****************************************************************************/
1788 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
1790 int mod, rl, rh;
1791 uint destoffset;
1793 START_OF_INSTR();
1794 DECODE_PRINTF("XCHG\t");
1795 FETCH_DECODE_MODRM(mod, rh, rl);
1796 if (mod < 3) {
1797 destoffset = decode_rmXX_address(mod, rl);
1798 DECODE_PRINTF(",");
1799 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1800 u32 *srcreg;
1801 u32 destval,tmp;
1803 destval = fetch_data_long(destoffset);
1804 srcreg = DECODE_RM_LONG_REGISTER(rh);
1805 DECODE_PRINTF("\n");
1806 TRACE_AND_STEP();
1807 tmp = *srcreg;
1808 *srcreg = destval;
1809 destval = tmp;
1810 store_data_long(destoffset, destval);
1811 } else {
1812 u16 *srcreg;
1813 u16 destval,tmp;
1815 destval = fetch_data_word(destoffset);
1816 srcreg = DECODE_RM_WORD_REGISTER(rh);
1817 DECODE_PRINTF("\n");
1818 TRACE_AND_STEP();
1819 tmp = *srcreg;
1820 *srcreg = destval;
1821 destval = tmp;
1822 store_data_word(destoffset, destval);
1824 } else { /* register to register */
1825 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1826 u32 *destreg,*srcreg;
1827 u32 tmp;
1829 destreg = DECODE_RM_LONG_REGISTER(rl);
1830 DECODE_PRINTF(",");
1831 srcreg = DECODE_RM_LONG_REGISTER(rh);
1832 DECODE_PRINTF("\n");
1833 TRACE_AND_STEP();
1834 tmp = *srcreg;
1835 *srcreg = *destreg;
1836 *destreg = tmp;
1837 } else {
1838 u16 *destreg,*srcreg;
1839 u16 tmp;
1841 destreg = DECODE_RM_WORD_REGISTER(rl);
1842 DECODE_PRINTF(",");
1843 srcreg = DECODE_RM_WORD_REGISTER(rh);
1844 DECODE_PRINTF("\n");
1845 TRACE_AND_STEP();
1846 tmp = *srcreg;
1847 *srcreg = *destreg;
1848 *destreg = tmp;
1851 DECODE_CLEAR_SEGOVR();
1852 END_OF_INSTR();
1855 /****************************************************************************
1856 REMARKS:
1857 Handles opcode 0x88
1858 ****************************************************************************/
1859 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
1861 int mod, rl, rh;
1862 u8 *destreg, *srcreg;
1863 uint destoffset;
1865 START_OF_INSTR();
1866 DECODE_PRINTF("MOV\t");
1867 FETCH_DECODE_MODRM(mod, rh, rl);
1868 if (mod < 3) {
1869 destoffset = decode_rmXX_address(mod, rl);
1870 DECODE_PRINTF(",");
1871 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1872 DECODE_PRINTF("\n");
1873 TRACE_AND_STEP();
1874 store_data_byte(destoffset, *srcreg);
1875 } else { /* register to register */
1876 destreg = DECODE_RM_BYTE_REGISTER(rl);
1877 DECODE_PRINTF(",");
1878 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1879 DECODE_PRINTF("\n");
1880 TRACE_AND_STEP();
1881 *destreg = *srcreg;
1883 DECODE_CLEAR_SEGOVR();
1884 END_OF_INSTR();
1887 /****************************************************************************
1888 REMARKS:
1889 Handles opcode 0x89
1890 ****************************************************************************/
1891 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
1893 int mod, rl, rh;
1894 uint destoffset;
1896 START_OF_INSTR();
1897 DECODE_PRINTF("MOV\t");
1898 FETCH_DECODE_MODRM(mod, rh, rl);
1899 if (mod < 3) {
1900 destoffset = decode_rmXX_address(mod, rl);
1901 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1902 u32 *srcreg;
1904 DECODE_PRINTF(",");
1905 srcreg = DECODE_RM_LONG_REGISTER(rh);
1906 DECODE_PRINTF("\n");
1907 TRACE_AND_STEP();
1908 store_data_long(destoffset, *srcreg);
1909 } else {
1910 u16 *srcreg;
1912 DECODE_PRINTF(",");
1913 srcreg = DECODE_RM_WORD_REGISTER(rh);
1914 DECODE_PRINTF("\n");
1915 TRACE_AND_STEP();
1916 store_data_word(destoffset, *srcreg);
1918 } else { /* register to register */
1919 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1920 u32 *destreg,*srcreg;
1922 destreg = DECODE_RM_LONG_REGISTER(rl);
1923 DECODE_PRINTF(",");
1924 srcreg = DECODE_RM_LONG_REGISTER(rh);
1925 DECODE_PRINTF("\n");
1926 TRACE_AND_STEP();
1927 *destreg = *srcreg;
1928 } else {
1929 u16 *destreg,*srcreg;
1931 destreg = DECODE_RM_WORD_REGISTER(rl);
1932 DECODE_PRINTF(",");
1933 srcreg = DECODE_RM_WORD_REGISTER(rh);
1934 DECODE_PRINTF("\n");
1935 TRACE_AND_STEP();
1936 *destreg = *srcreg;
1939 DECODE_CLEAR_SEGOVR();
1940 END_OF_INSTR();
1943 /****************************************************************************
1944 REMARKS:
1945 Handles opcode 0x8a
1946 ****************************************************************************/
1947 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
1949 int mod, rl, rh;
1950 u8 *destreg, *srcreg;
1951 uint srcoffset;
1952 u8 srcval;
1954 START_OF_INSTR();
1955 DECODE_PRINTF("MOV\t");
1956 FETCH_DECODE_MODRM(mod, rh, rl);
1957 if (mod < 3) {
1958 destreg = DECODE_RM_BYTE_REGISTER(rh);
1959 DECODE_PRINTF(",");
1960 srcoffset = decode_rmXX_address(mod, rl);
1961 srcval = fetch_data_byte(srcoffset);
1962 DECODE_PRINTF("\n");
1963 TRACE_AND_STEP();
1964 *destreg = srcval;
1965 } else { /* register to register */
1966 destreg = DECODE_RM_BYTE_REGISTER(rh);
1967 DECODE_PRINTF(",");
1968 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1969 DECODE_PRINTF("\n");
1970 TRACE_AND_STEP();
1971 *destreg = *srcreg;
1973 DECODE_CLEAR_SEGOVR();
1974 END_OF_INSTR();
1977 /****************************************************************************
1978 REMARKS:
1979 Handles opcode 0x8b
1980 ****************************************************************************/
1981 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
1983 int mod, rl, rh;
1984 uint srcoffset;
1986 START_OF_INSTR();
1987 DECODE_PRINTF("MOV\t");
1988 FETCH_DECODE_MODRM(mod, rh, rl);
1989 if (mod < 3) {
1990 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1991 u32 *destreg;
1992 u32 srcval;
1994 destreg = DECODE_RM_LONG_REGISTER(rh);
1995 DECODE_PRINTF(",");
1996 srcoffset = decode_rmXX_address(mod, rl);
1997 srcval = fetch_data_long(srcoffset);
1998 DECODE_PRINTF("\n");
1999 TRACE_AND_STEP();
2000 *destreg = srcval;
2001 } else {
2002 u16 *destreg;
2003 u16 srcval;
2005 destreg = DECODE_RM_WORD_REGISTER(rh);
2006 DECODE_PRINTF(",");
2007 srcoffset = decode_rmXX_address(mod, rl);
2008 srcval = fetch_data_word(srcoffset);
2009 DECODE_PRINTF("\n");
2010 TRACE_AND_STEP();
2011 *destreg = srcval;
2013 } else { /* register to register */
2014 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2015 u32 *destreg, *srcreg;
2017 destreg = DECODE_RM_LONG_REGISTER(rh);
2018 DECODE_PRINTF(",");
2019 srcreg = DECODE_RM_LONG_REGISTER(rl);
2020 DECODE_PRINTF("\n");
2021 TRACE_AND_STEP();
2022 *destreg = *srcreg;
2023 } else {
2024 u16 *destreg, *srcreg;
2026 destreg = DECODE_RM_WORD_REGISTER(rh);
2027 DECODE_PRINTF(",");
2028 srcreg = DECODE_RM_WORD_REGISTER(rl);
2029 DECODE_PRINTF("\n");
2030 TRACE_AND_STEP();
2031 *destreg = *srcreg;
2034 DECODE_CLEAR_SEGOVR();
2035 END_OF_INSTR();
2038 /****************************************************************************
2039 REMARKS:
2040 Handles opcode 0x8c
2041 ****************************************************************************/
2042 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
2044 int mod, rl, rh;
2045 u16 *destreg, *srcreg;
2046 uint destoffset;
2047 u16 destval;
2049 START_OF_INSTR();
2050 DECODE_PRINTF("MOV\t");
2051 FETCH_DECODE_MODRM(mod, rh, rl);
2052 if (mod < 3) {
2053 destoffset = decode_rmXX_address(mod, rl);
2054 DECODE_PRINTF(",");
2055 srcreg = decode_rm_seg_register(rh);
2056 DECODE_PRINTF("\n");
2057 TRACE_AND_STEP();
2058 destval = *srcreg;
2059 store_data_word(destoffset, destval);
2060 } else { /* register to register */
2061 destreg = DECODE_RM_WORD_REGISTER(rl);
2062 DECODE_PRINTF(",");
2063 srcreg = decode_rm_seg_register(rh);
2064 DECODE_PRINTF("\n");
2065 TRACE_AND_STEP();
2066 *destreg = *srcreg;
2068 DECODE_CLEAR_SEGOVR();
2069 END_OF_INSTR();
2072 /****************************************************************************
2073 REMARKS:
2074 Handles opcode 0x8d
2075 ****************************************************************************/
2076 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
2078 int mod, rl, rh;
2079 u16 *srcreg;
2080 uint destoffset;
2083 * TODO: Need to handle address size prefix!
2085 * lea eax,[eax+ebx*2] ??
2088 START_OF_INSTR();
2089 DECODE_PRINTF("LEA\t");
2090 FETCH_DECODE_MODRM(mod, rh, rl);
2091 if (mod < 3) {
2092 srcreg = DECODE_RM_WORD_REGISTER(rh);
2093 DECODE_PRINTF(",");
2094 destoffset = decode_rmXX_address(mod, rl);
2095 DECODE_PRINTF("\n");
2096 TRACE_AND_STEP();
2097 *srcreg = (u16)destoffset;
2099 /* } else { undefined. Do nothing. } */
2100 DECODE_CLEAR_SEGOVR();
2101 END_OF_INSTR();
2104 /****************************************************************************
2105 REMARKS:
2106 Handles opcode 0x8e
2107 ****************************************************************************/
2108 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
2110 int mod, rl, rh;
2111 u16 *destreg, *srcreg;
2112 uint srcoffset;
2113 u16 srcval;
2115 START_OF_INSTR();
2116 DECODE_PRINTF("MOV\t");
2117 FETCH_DECODE_MODRM(mod, rh, rl);
2118 if (mod < 3) {
2119 destreg = decode_rm_seg_register(rh);
2120 DECODE_PRINTF(",");
2121 srcoffset = decode_rmXX_address(mod, rl);
2122 srcval = fetch_data_word(srcoffset);
2123 DECODE_PRINTF("\n");
2124 TRACE_AND_STEP();
2125 *destreg = srcval;
2126 } else { /* register to register */
2127 destreg = decode_rm_seg_register(rh);
2128 DECODE_PRINTF(",");
2129 srcreg = DECODE_RM_WORD_REGISTER(rl);
2130 DECODE_PRINTF("\n");
2131 TRACE_AND_STEP();
2132 *destreg = *srcreg;
2135 * Clean up, and reset all the R_xSP pointers to the correct
2136 * locations. This is about 3x too much overhead (doing all the
2137 * segreg ptrs when only one is needed, but this instruction
2138 * *cannot* be that common, and this isn't too much work anyway.
2140 DECODE_CLEAR_SEGOVR();
2141 END_OF_INSTR();
2144 /****************************************************************************
2145 REMARKS:
2146 Handles opcode 0x8f
2147 ****************************************************************************/
2148 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
2150 int mod, rl, rh;
2151 uint destoffset;
2153 START_OF_INSTR();
2154 DECODE_PRINTF("POP\t");
2155 FETCH_DECODE_MODRM(mod, rh, rl);
2156 if (rh != 0) {
2157 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
2158 HALT_SYS();
2160 if (mod < 3) {
2161 destoffset = decode_rmXX_address(mod, rl);
2162 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2163 u32 destval;
2165 DECODE_PRINTF("\n");
2166 TRACE_AND_STEP();
2167 destval = pop_long();
2168 store_data_long(destoffset, destval);
2169 } else {
2170 u16 destval;
2172 DECODE_PRINTF("\n");
2173 TRACE_AND_STEP();
2174 destval = pop_word();
2175 store_data_word(destoffset, destval);
2177 } else { /* register to register */
2178 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2179 u32 *destreg;
2181 destreg = DECODE_RM_LONG_REGISTER(rl);
2182 DECODE_PRINTF("\n");
2183 TRACE_AND_STEP();
2184 *destreg = pop_long();
2185 } else {
2186 u16 *destreg;
2188 destreg = DECODE_RM_WORD_REGISTER(rl);
2189 DECODE_PRINTF("\n");
2190 TRACE_AND_STEP();
2191 *destreg = pop_word();
2194 DECODE_CLEAR_SEGOVR();
2195 END_OF_INSTR();
2198 /****************************************************************************
2199 REMARKS:
2200 Handles opcode 0x90
2201 ****************************************************************************/
2202 void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
2204 START_OF_INSTR();
2205 DECODE_PRINTF("NOP\n");
2206 TRACE_AND_STEP();
2207 DECODE_CLEAR_SEGOVR();
2208 END_OF_INSTR();
2211 /****************************************************************************
2212 REMARKS:
2213 Handles opcode 0x91-0x97
2214 ****************************************************************************/
2215 void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1))
2217 u32 tmp;
2219 op1 &= 0x7;
2221 START_OF_INSTR();
2223 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2224 u32 *reg32;
2225 DECODE_PRINTF("XCHG\tEAX,");
2226 reg32 = DECODE_RM_LONG_REGISTER(op1);
2227 DECODE_PRINTF("\n");
2228 TRACE_AND_STEP();
2229 tmp = M.x86.R_EAX;
2230 M.x86.R_EAX = *reg32;
2231 *reg32 = tmp;
2232 } else {
2233 u16 *reg16;
2234 DECODE_PRINTF("XCHG\tAX,");
2235 reg16 = DECODE_RM_WORD_REGISTER(op1);
2236 DECODE_PRINTF("\n");
2237 TRACE_AND_STEP();
2238 tmp = M.x86.R_AX;
2239 M.x86.R_EAX = *reg16;
2240 *reg16 = (u16)tmp;
2242 DECODE_CLEAR_SEGOVR();
2243 END_OF_INSTR();
2246 /****************************************************************************
2247 REMARKS:
2248 Handles opcode 0x98
2249 ****************************************************************************/
2250 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
2252 START_OF_INSTR();
2253 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2254 DECODE_PRINTF("CWDE\n");
2255 } else {
2256 DECODE_PRINTF("CBW\n");
2258 TRACE_AND_STEP();
2259 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2260 if (M.x86.R_AX & 0x8000) {
2261 M.x86.R_EAX |= 0xffff0000;
2262 } else {
2263 M.x86.R_EAX &= 0x0000ffff;
2265 } else {
2266 if (M.x86.R_AL & 0x80) {
2267 M.x86.R_AH = 0xff;
2268 } else {
2269 M.x86.R_AH = 0x0;
2272 DECODE_CLEAR_SEGOVR();
2273 END_OF_INSTR();
2276 /****************************************************************************
2277 REMARKS:
2278 Handles opcode 0x99
2279 ****************************************************************************/
2280 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
2282 START_OF_INSTR();
2283 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2284 DECODE_PRINTF("CDQ\n");
2285 } else {
2286 DECODE_PRINTF("CWD\n");
2288 DECODE_PRINTF("CWD\n");
2289 TRACE_AND_STEP();
2290 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2291 if (M.x86.R_EAX & 0x80000000) {
2292 M.x86.R_EDX = 0xffffffff;
2293 } else {
2294 M.x86.R_EDX = 0x0;
2296 } else {
2297 if (M.x86.R_AX & 0x8000) {
2298 M.x86.R_DX = 0xffff;
2299 } else {
2300 M.x86.R_DX = 0x0;
2303 DECODE_CLEAR_SEGOVR();
2304 END_OF_INSTR();
2307 /****************************************************************************
2308 REMARKS:
2309 Handles opcode 0x9a
2310 ****************************************************************************/
2311 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
2313 u16 farseg, faroff;
2315 START_OF_INSTR();
2316 DECODE_PRINTF("CALL\t");
2317 faroff = fetch_word_imm();
2318 farseg = fetch_word_imm();
2319 DECODE_PRINTF2("%04x:", farseg);
2320 DECODE_PRINTF2("%04x\n", faroff);
2321 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
2323 /* XXX
2325 * Hooked interrupt vectors calling into our "BIOS" will cause
2326 * problems unless all intersegment stuff is checked for BIOS
2327 * access. Check needed here. For moment, let it alone.
2329 TRACE_AND_STEP();
2330 push_word(M.x86.R_CS);
2331 M.x86.R_CS = farseg;
2332 push_word(M.x86.R_IP);
2333 M.x86.R_IP = faroff;
2334 DECODE_CLEAR_SEGOVR();
2335 END_OF_INSTR();
2338 /****************************************************************************
2339 REMARKS:
2340 Handles opcode 0x9b
2341 ****************************************************************************/
2342 void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
2344 START_OF_INSTR();
2345 DECODE_PRINTF("WAIT");
2346 TRACE_AND_STEP();
2347 /* NADA. */
2348 DECODE_CLEAR_SEGOVR();
2349 END_OF_INSTR();
2352 /****************************************************************************
2353 REMARKS:
2354 Handles opcode 0x9c
2355 ****************************************************************************/
2356 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
2358 u32 flags;
2360 START_OF_INSTR();
2361 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2362 DECODE_PRINTF("PUSHFD\n");
2363 } else {
2364 DECODE_PRINTF("PUSHF\n");
2366 TRACE_AND_STEP();
2368 /* clear out *all* bits not representing flags, and turn on real bits */
2369 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
2370 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2371 push_long(flags);
2372 } else {
2373 push_word((u16)flags);
2375 DECODE_CLEAR_SEGOVR();
2376 END_OF_INSTR();
2379 /****************************************************************************
2380 REMARKS:
2381 Handles opcode 0x9d
2382 ****************************************************************************/
2383 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
2385 START_OF_INSTR();
2386 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2387 DECODE_PRINTF("POPFD\n");
2388 } else {
2389 DECODE_PRINTF("POPF\n");
2391 TRACE_AND_STEP();
2392 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2393 M.x86.R_EFLG = pop_long();
2394 } else {
2395 M.x86.R_FLG = pop_word();
2397 DECODE_CLEAR_SEGOVR();
2398 END_OF_INSTR();
2401 /****************************************************************************
2402 REMARKS:
2403 Handles opcode 0x9e
2404 ****************************************************************************/
2405 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
2407 START_OF_INSTR();
2408 DECODE_PRINTF("SAHF\n");
2409 TRACE_AND_STEP();
2410 /* clear the lower bits of the flag register */
2411 M.x86.R_FLG &= 0xffffff00;
2412 /* or in the AH register into the flags register */
2413 M.x86.R_FLG |= M.x86.R_AH;
2414 DECODE_CLEAR_SEGOVR();
2415 END_OF_INSTR();
2418 /****************************************************************************
2419 REMARKS:
2420 Handles opcode 0x9f
2421 ****************************************************************************/
2422 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
2424 START_OF_INSTR();
2425 DECODE_PRINTF("LAHF\n");
2426 TRACE_AND_STEP();
2427 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
2428 /*undocumented TC++ behavior??? Nope. It's documented, but
2429 you have too look real hard to notice it. */
2430 M.x86.R_AH |= 0x2;
2431 DECODE_CLEAR_SEGOVR();
2432 END_OF_INSTR();
2435 /****************************************************************************
2436 REMARKS:
2437 Handles opcode 0xa0
2438 ****************************************************************************/
2439 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
2441 u16 offset;
2443 START_OF_INSTR();
2444 DECODE_PRINTF("MOV\tAL,");
2445 offset = fetch_word_imm();
2446 DECODE_PRINTF2("[%04x]\n", offset);
2447 TRACE_AND_STEP();
2448 M.x86.R_AL = fetch_data_byte(offset);
2449 DECODE_CLEAR_SEGOVR();
2450 END_OF_INSTR();
2453 /****************************************************************************
2454 REMARKS:
2455 Handles opcode 0xa1
2456 ****************************************************************************/
2457 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
2459 u16 offset;
2461 START_OF_INSTR();
2462 offset = fetch_word_imm();
2463 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2464 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
2465 } else {
2466 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
2468 TRACE_AND_STEP();
2469 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2470 M.x86.R_EAX = fetch_data_long(offset);
2471 } else {
2472 M.x86.R_AX = fetch_data_word(offset);
2474 DECODE_CLEAR_SEGOVR();
2475 END_OF_INSTR();
2478 /****************************************************************************
2479 REMARKS:
2480 Handles opcode 0xa2
2481 ****************************************************************************/
2482 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
2484 u16 offset;
2486 START_OF_INSTR();
2487 DECODE_PRINTF("MOV\t");
2488 offset = fetch_word_imm();
2489 DECODE_PRINTF2("[%04x],AL\n", offset);
2490 TRACE_AND_STEP();
2491 store_data_byte(offset, M.x86.R_AL);
2492 DECODE_CLEAR_SEGOVR();
2493 END_OF_INSTR();
2496 /****************************************************************************
2497 REMARKS:
2498 Handles opcode 0xa3
2499 ****************************************************************************/
2500 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
2502 u16 offset;
2504 START_OF_INSTR();
2505 offset = fetch_word_imm();
2506 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2507 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
2508 } else {
2509 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
2511 TRACE_AND_STEP();
2512 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2513 store_data_long(offset, M.x86.R_EAX);
2514 } else {
2515 store_data_word(offset, M.x86.R_AX);
2517 DECODE_CLEAR_SEGOVR();
2518 END_OF_INSTR();
2521 /****************************************************************************
2522 REMARKS:
2523 Handles opcode 0xa4
2524 ****************************************************************************/
2525 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
2527 u8 val;
2528 u32 count;
2529 int inc;
2531 START_OF_INSTR();
2532 DECODE_PRINTF("MOVS\tBYTE\n");
2533 if (ACCESS_FLAG(F_DF)) /* down */
2534 inc = -1;
2535 else
2536 inc = 1;
2537 TRACE_AND_STEP();
2538 count = 1;
2539 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2540 /* dont care whether REPE or REPNE */
2541 /* move them until CX is ZERO. */
2542 count = M.x86.R_CX;
2543 M.x86.R_CX = 0;
2544 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2546 while (count--) {
2547 val = fetch_data_byte(M.x86.R_SI);
2548 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
2549 M.x86.R_SI += inc;
2550 M.x86.R_DI += inc;
2552 DECODE_CLEAR_SEGOVR();
2553 END_OF_INSTR();
2556 /****************************************************************************
2557 REMARKS:
2558 Handles opcode 0xa5
2559 ****************************************************************************/
2560 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
2562 u32 val;
2563 int inc;
2564 u32 count;
2566 START_OF_INSTR();
2567 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2568 DECODE_PRINTF("MOVS\tDWORD\n");
2569 if (ACCESS_FLAG(F_DF)) /* down */
2570 inc = -4;
2571 else
2572 inc = 4;
2573 } else {
2574 DECODE_PRINTF("MOVS\tWORD\n");
2575 if (ACCESS_FLAG(F_DF)) /* down */
2576 inc = -2;
2577 else
2578 inc = 2;
2580 TRACE_AND_STEP();
2581 count = 1;
2582 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2583 /* dont care whether REPE or REPNE */
2584 /* move them until CX is ZERO. */
2585 count = M.x86.R_CX;
2586 M.x86.R_CX = 0;
2587 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2589 while (count--) {
2590 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2591 val = fetch_data_long(M.x86.R_SI);
2592 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
2593 } else {
2594 val = fetch_data_word(M.x86.R_SI);
2595 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
2597 M.x86.R_SI += inc;
2598 M.x86.R_DI += inc;
2600 DECODE_CLEAR_SEGOVR();
2601 END_OF_INSTR();
2604 /****************************************************************************
2605 REMARKS:
2606 Handles opcode 0xa6
2607 ****************************************************************************/
2608 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
2610 s8 val1, val2;
2611 int inc;
2613 START_OF_INSTR();
2614 DECODE_PRINTF("CMPS\tBYTE\n");
2615 TRACE_AND_STEP();
2616 if (ACCESS_FLAG(F_DF)) /* down */
2617 inc = -1;
2618 else
2619 inc = 1;
2621 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2622 /* REPE */
2623 /* move them until CX is ZERO. */
2624 while (M.x86.R_CX != 0) {
2625 val1 = fetch_data_byte(M.x86.R_SI);
2626 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2627 cmp_byte(val1, val2);
2628 M.x86.R_CX -= 1;
2629 M.x86.R_SI += inc;
2630 M.x86.R_DI += inc;
2631 if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break;
2632 if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
2634 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2635 } else {
2636 val1 = fetch_data_byte(M.x86.R_SI);
2637 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2638 cmp_byte(val1, val2);
2639 M.x86.R_SI += inc;
2640 M.x86.R_DI += inc;
2642 DECODE_CLEAR_SEGOVR();
2643 END_OF_INSTR();
2646 /****************************************************************************
2647 REMARKS:
2648 Handles opcode 0xa7
2649 ****************************************************************************/
2650 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
2652 u32 val1,val2;
2653 int inc;
2655 START_OF_INSTR();
2656 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2657 DECODE_PRINTF("CMPS\tDWORD\n");
2658 inc = 4;
2659 } else {
2660 DECODE_PRINTF("CMPS\tWORD\n");
2661 inc = 2;
2663 if (ACCESS_FLAG(F_DF)) /* down */
2664 inc = -inc;
2666 TRACE_AND_STEP();
2667 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2668 /* REPE */
2669 /* move them until CX is ZERO. */
2670 while (M.x86.R_CX != 0) {
2671 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2672 val1 = fetch_data_long(M.x86.R_SI);
2673 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2674 cmp_long(val1, val2);
2675 } else {
2676 val1 = fetch_data_word(M.x86.R_SI);
2677 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2678 cmp_word((u16)val1, (u16)val2);
2680 M.x86.R_CX -= 1;
2681 M.x86.R_SI += inc;
2682 M.x86.R_DI += inc;
2683 if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break;
2684 if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
2686 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2687 } else {
2688 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2689 val1 = fetch_data_long(M.x86.R_SI);
2690 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2691 cmp_long(val1, val2);
2692 } else {
2693 val1 = fetch_data_word(M.x86.R_SI);
2694 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2695 cmp_word((u16)val1, (u16)val2);
2697 M.x86.R_SI += inc;
2698 M.x86.R_DI += inc;
2700 DECODE_CLEAR_SEGOVR();
2701 END_OF_INSTR();
2704 /****************************************************************************
2705 REMARKS:
2706 Handles opcode 0xa8
2707 ****************************************************************************/
2708 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
2710 int imm;
2712 START_OF_INSTR();
2713 DECODE_PRINTF("TEST\tAL,");
2714 imm = fetch_byte_imm();
2715 DECODE_PRINTF2("%04x\n", imm);
2716 TRACE_AND_STEP();
2717 test_byte(M.x86.R_AL, (u8)imm);
2718 DECODE_CLEAR_SEGOVR();
2719 END_OF_INSTR();
2722 /****************************************************************************
2723 REMARKS:
2724 Handles opcode 0xa9
2725 ****************************************************************************/
2726 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
2728 u32 srcval;
2730 START_OF_INSTR();
2731 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2732 DECODE_PRINTF("TEST\tEAX,");
2733 srcval = fetch_long_imm();
2734 } else {
2735 DECODE_PRINTF("TEST\tAX,");
2736 srcval = fetch_word_imm();
2738 DECODE_PRINTF2("%x\n", srcval);
2739 TRACE_AND_STEP();
2740 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2741 test_long(M.x86.R_EAX, srcval);
2742 } else {
2743 test_word(M.x86.R_AX, (u16)srcval);
2745 DECODE_CLEAR_SEGOVR();
2746 END_OF_INSTR();
2749 /****************************************************************************
2750 REMARKS:
2751 Handles opcode 0xaa
2752 ****************************************************************************/
2753 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
2755 int inc;
2757 START_OF_INSTR();
2758 DECODE_PRINTF("STOS\tBYTE\n");
2759 if (ACCESS_FLAG(F_DF)) /* down */
2760 inc = -1;
2761 else
2762 inc = 1;
2763 TRACE_AND_STEP();
2764 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2765 /* dont care whether REPE or REPNE */
2766 /* move them until CX is ZERO. */
2767 while (M.x86.R_CX != 0) {
2768 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
2769 M.x86.R_CX -= 1;
2770 M.x86.R_DI += inc;
2772 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2773 } else {
2774 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
2775 M.x86.R_DI += inc;
2777 DECODE_CLEAR_SEGOVR();
2778 END_OF_INSTR();
2781 /****************************************************************************
2782 REMARKS:
2783 Handles opcode 0xab
2784 ****************************************************************************/
2785 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
2787 int inc;
2788 u32 count;
2790 START_OF_INSTR();
2791 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2792 DECODE_PRINTF("STOS\tDWORD\n");
2793 if (ACCESS_FLAG(F_DF)) /* down */
2794 inc = -4;
2795 else
2796 inc = 4;
2797 } else {
2798 DECODE_PRINTF("STOS\tWORD\n");
2799 if (ACCESS_FLAG(F_DF)) /* down */
2800 inc = -2;
2801 else
2802 inc = 2;
2804 TRACE_AND_STEP();
2805 count = 1;
2806 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2807 /* dont care whether REPE or REPNE */
2808 /* move them until CX is ZERO. */
2809 count = M.x86.R_CX;
2810 M.x86.R_CX = 0;
2811 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2813 while (count--) {
2814 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2815 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
2816 } else {
2817 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
2819 M.x86.R_DI += inc;
2821 DECODE_CLEAR_SEGOVR();
2822 END_OF_INSTR();
2825 /****************************************************************************
2826 REMARKS:
2827 Handles opcode 0xac
2828 ****************************************************************************/
2829 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
2831 int inc;
2833 START_OF_INSTR();
2834 DECODE_PRINTF("LODS\tBYTE\n");
2835 TRACE_AND_STEP();
2836 if (ACCESS_FLAG(F_DF)) /* down */
2837 inc = -1;
2838 else
2839 inc = 1;
2840 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2841 /* dont care whether REPE or REPNE */
2842 /* move them until CX is ZERO. */
2843 while (M.x86.R_CX != 0) {
2844 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
2845 M.x86.R_CX -= 1;
2846 M.x86.R_SI += inc;
2848 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2849 } else {
2850 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
2851 M.x86.R_SI += inc;
2853 DECODE_CLEAR_SEGOVR();
2854 END_OF_INSTR();
2857 /****************************************************************************
2858 REMARKS:
2859 Handles opcode 0xad
2860 ****************************************************************************/
2861 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
2863 int inc;
2864 u32 count;
2866 START_OF_INSTR();
2867 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2868 DECODE_PRINTF("LODS\tDWORD\n");
2869 if (ACCESS_FLAG(F_DF)) /* down */
2870 inc = -4;
2871 else
2872 inc = 4;
2873 } else {
2874 DECODE_PRINTF("LODS\tWORD\n");
2875 if (ACCESS_FLAG(F_DF)) /* down */
2876 inc = -2;
2877 else
2878 inc = 2;
2880 TRACE_AND_STEP();
2881 count = 1;
2882 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2883 /* dont care whether REPE or REPNE */
2884 /* move them until CX is ZERO. */
2885 count = M.x86.R_CX;
2886 M.x86.R_CX = 0;
2887 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2889 while (count--) {
2890 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2891 M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
2892 } else {
2893 M.x86.R_AX = fetch_data_word(M.x86.R_SI);
2895 M.x86.R_SI += inc;
2897 DECODE_CLEAR_SEGOVR();
2898 END_OF_INSTR();
2901 /****************************************************************************
2902 REMARKS:
2903 Handles opcode 0xae
2904 ****************************************************************************/
2905 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
2907 s8 val2;
2908 int inc;
2910 START_OF_INSTR();
2911 DECODE_PRINTF("SCAS\tBYTE\n");
2912 TRACE_AND_STEP();
2913 if (ACCESS_FLAG(F_DF)) /* down */
2914 inc = -1;
2915 else
2916 inc = 1;
2917 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
2918 /* REPE */
2919 /* move them until CX is ZERO. */
2920 while (M.x86.R_CX != 0) {
2921 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2922 cmp_byte(M.x86.R_AL, val2);
2923 M.x86.R_CX -= 1;
2924 M.x86.R_DI += inc;
2925 if (ACCESS_FLAG(F_ZF) == 0)
2926 break;
2928 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
2929 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
2930 /* REPNE */
2931 /* move them until CX is ZERO. */
2932 while (M.x86.R_CX != 0) {
2933 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2934 cmp_byte(M.x86.R_AL, val2);
2935 M.x86.R_CX -= 1;
2936 M.x86.R_DI += inc;
2937 if (ACCESS_FLAG(F_ZF))
2938 break; /* zero flag set means equal */
2940 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
2941 } else {
2942 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2943 cmp_byte(M.x86.R_AL, val2);
2944 M.x86.R_DI += inc;
2946 DECODE_CLEAR_SEGOVR();
2947 END_OF_INSTR();
2950 /****************************************************************************
2951 REMARKS:
2952 Handles opcode 0xaf
2953 ****************************************************************************/
2954 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
2956 int inc;
2957 u32 val;
2959 START_OF_INSTR();
2960 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2961 DECODE_PRINTF("SCAS\tDWORD\n");
2962 if (ACCESS_FLAG(F_DF)) /* down */
2963 inc = -4;
2964 else
2965 inc = 4;
2966 } else {
2967 DECODE_PRINTF("SCAS\tWORD\n");
2968 if (ACCESS_FLAG(F_DF)) /* down */
2969 inc = -2;
2970 else
2971 inc = 2;
2973 TRACE_AND_STEP();
2974 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
2975 /* REPE */
2976 /* move them until CX is ZERO. */
2977 while (M.x86.R_CX != 0) {
2978 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2979 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2980 cmp_long(M.x86.R_EAX, val);
2981 } else {
2982 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2983 cmp_word(M.x86.R_AX, (u16)val);
2985 M.x86.R_CX -= 1;
2986 M.x86.R_DI += inc;
2987 if (ACCESS_FLAG(F_ZF) == 0)
2988 break;
2990 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
2991 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
2992 /* REPNE */
2993 /* move them until CX is ZERO. */
2994 while (M.x86.R_CX != 0) {
2995 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2996 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2997 cmp_long(M.x86.R_EAX, val);
2998 } else {
2999 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
3000 cmp_word(M.x86.R_AX, (u16)val);
3002 M.x86.R_CX -= 1;
3003 M.x86.R_DI += inc;
3004 if (ACCESS_FLAG(F_ZF))
3005 break; /* zero flag set means equal */
3007 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
3008 } else {
3009 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3010 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
3011 cmp_long(M.x86.R_EAX, val);
3012 } else {
3013 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
3014 cmp_word(M.x86.R_AX, (u16)val);
3016 M.x86.R_DI += inc;
3018 DECODE_CLEAR_SEGOVR();
3019 END_OF_INSTR();
3022 /****************************************************************************
3023 REMARKS:
3024 Handles opcode 0xb0 - 0xb7
3025 ****************************************************************************/
3026 void x86emuOp_mov_byte_register_IMM(u8 op1)
3028 u8 imm, *ptr;
3030 START_OF_INSTR();
3031 DECODE_PRINTF("MOV\t");
3032 ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7);
3033 DECODE_PRINTF(",");
3034 imm = fetch_byte_imm();
3035 DECODE_PRINTF2("%x\n", imm);
3036 TRACE_AND_STEP();
3037 *ptr = imm;
3038 DECODE_CLEAR_SEGOVR();
3039 END_OF_INSTR();
3042 /****************************************************************************
3043 REMARKS:
3044 Handles opcode 0xb8 - 0xbf
3045 ****************************************************************************/
3046 void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1))
3048 u32 srcval;
3050 op1 &= 0x7;
3052 START_OF_INSTR();
3053 DECODE_PRINTF("MOV\t");
3054 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3055 u32 *reg32;
3056 reg32 = DECODE_RM_LONG_REGISTER(op1);
3057 srcval = fetch_long_imm();
3058 DECODE_PRINTF2(",%x\n", srcval);
3059 TRACE_AND_STEP();
3060 *reg32 = srcval;
3061 } else {
3062 u16 *reg16;
3063 reg16 = DECODE_RM_WORD_REGISTER(op1);
3064 srcval = fetch_word_imm();
3065 DECODE_PRINTF2(",%x\n", srcval);
3066 TRACE_AND_STEP();
3067 *reg16 = (u16)srcval;
3069 DECODE_CLEAR_SEGOVR();
3070 END_OF_INSTR();
3073 /****************************************************************************
3074 REMARKS:
3075 Handles opcode 0xc0
3076 ****************************************************************************/
3077 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
3079 int mod, rl, rh;
3080 u8 *destreg;
3081 uint destoffset;
3082 u8 destval;
3083 u8 amt;
3086 * Yet another weirdo special case instruction format. Part of
3087 * the opcode held below in "RH". Doubly nested case would
3088 * result, except that the decoded instruction
3090 START_OF_INSTR();
3091 FETCH_DECODE_MODRM(mod, rh, rl);
3092 #ifdef DEBUG
3093 if (DEBUG_DECODE()) {
3094 /* XXX DECODE_PRINTF may be changed to something more
3095 general, so that it is important to leave the strings
3096 in the same format, even though the result is that the
3097 above test is done twice. */
3099 switch (rh) {
3100 case 0:
3101 DECODE_PRINTF("ROL\t");
3102 break;
3103 case 1:
3104 DECODE_PRINTF("ROR\t");
3105 break;
3106 case 2:
3107 DECODE_PRINTF("RCL\t");
3108 break;
3109 case 3:
3110 DECODE_PRINTF("RCR\t");
3111 break;
3112 case 4:
3113 DECODE_PRINTF("SHL\t");
3114 break;
3115 case 5:
3116 DECODE_PRINTF("SHR\t");
3117 break;
3118 case 6:
3119 DECODE_PRINTF("SAL\t");
3120 break;
3121 case 7:
3122 DECODE_PRINTF("SAR\t");
3123 break;
3126 #endif
3127 /* know operation, decode the mod byte to find the addressing
3128 mode. */
3129 if (mod < 3) {
3130 DECODE_PRINTF("BYTE PTR ");
3131 destoffset = decode_rmXX_address(mod, rl);
3132 amt = fetch_byte_imm();
3133 DECODE_PRINTF2(",%x\n", amt);
3134 destval = fetch_data_byte(destoffset);
3135 TRACE_AND_STEP();
3136 destval = (*opcD0_byte_operation[rh]) (destval, amt);
3137 store_data_byte(destoffset, destval);
3138 } else { /* register to register */
3139 destreg = DECODE_RM_BYTE_REGISTER(rl);
3140 amt = fetch_byte_imm();
3141 DECODE_PRINTF2(",%x\n", amt);
3142 TRACE_AND_STEP();
3143 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
3144 *destreg = destval;
3146 DECODE_CLEAR_SEGOVR();
3147 END_OF_INSTR();
3150 /****************************************************************************
3151 REMARKS:
3152 Handles opcode 0xc1
3153 ****************************************************************************/
3154 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
3156 int mod, rl, rh;
3157 uint destoffset;
3158 u8 amt;
3161 * Yet another weirdo special case instruction format. Part of
3162 * the opcode held below in "RH". Doubly nested case would
3163 * result, except that the decoded instruction
3165 START_OF_INSTR();
3166 FETCH_DECODE_MODRM(mod, rh, rl);
3167 #ifdef DEBUG
3168 if (DEBUG_DECODE()) {
3169 /* XXX DECODE_PRINTF may be changed to something more
3170 general, so that it is important to leave the strings
3171 in the same format, even though the result is that the
3172 above test is done twice. */
3174 switch (rh) {
3175 case 0:
3176 DECODE_PRINTF("ROL\t");
3177 break;
3178 case 1:
3179 DECODE_PRINTF("ROR\t");
3180 break;
3181 case 2:
3182 DECODE_PRINTF("RCL\t");
3183 break;
3184 case 3:
3185 DECODE_PRINTF("RCR\t");
3186 break;
3187 case 4:
3188 DECODE_PRINTF("SHL\t");
3189 break;
3190 case 5:
3191 DECODE_PRINTF("SHR\t");
3192 break;
3193 case 6:
3194 DECODE_PRINTF("SAL\t");
3195 break;
3196 case 7:
3197 DECODE_PRINTF("SAR\t");
3198 break;
3201 #endif
3202 /* know operation, decode the mod byte to find the addressing
3203 mode. */
3204 if (mod < 3) {
3205 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3206 u32 destval;
3208 DECODE_PRINTF("DWORD PTR ");
3209 destoffset = decode_rmXX_address(mod, rl);
3210 amt = fetch_byte_imm();
3211 DECODE_PRINTF2(",%x\n", amt);
3212 destval = fetch_data_long(destoffset);
3213 TRACE_AND_STEP();
3214 destval = (*opcD1_long_operation[rh]) (destval, amt);
3215 store_data_long(destoffset, destval);
3216 } else {
3217 u16 destval;
3219 DECODE_PRINTF("WORD PTR ");
3220 destoffset = decode_rmXX_address(mod, rl);
3221 amt = fetch_byte_imm();
3222 DECODE_PRINTF2(",%x\n", amt);
3223 destval = fetch_data_word(destoffset);
3224 TRACE_AND_STEP();
3225 destval = (*opcD1_word_operation[rh]) (destval, amt);
3226 store_data_word(destoffset, destval);
3228 } else { /* register to register */
3229 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3230 u32 *destreg;
3232 destreg = DECODE_RM_LONG_REGISTER(rl);
3233 amt = fetch_byte_imm();
3234 DECODE_PRINTF2(",%x\n", amt);
3235 TRACE_AND_STEP();
3236 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
3237 } else {
3238 u16 *destreg;
3240 destreg = DECODE_RM_WORD_REGISTER(rl);
3241 amt = fetch_byte_imm();
3242 DECODE_PRINTF2(",%x\n", amt);
3243 TRACE_AND_STEP();
3244 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
3247 DECODE_CLEAR_SEGOVR();
3248 END_OF_INSTR();
3251 /****************************************************************************
3252 REMARKS:
3253 Handles opcode 0xc2
3254 ****************************************************************************/
3255 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
3257 u16 imm;
3259 START_OF_INSTR();
3260 DECODE_PRINTF("RET\t");
3261 imm = fetch_word_imm();
3262 DECODE_PRINTF2("%x\n", imm);
3263 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
3264 TRACE_AND_STEP();
3265 M.x86.R_IP = pop_word();
3266 M.x86.R_SP += imm;
3267 DECODE_CLEAR_SEGOVR();
3268 END_OF_INSTR();
3271 /****************************************************************************
3272 REMARKS:
3273 Handles opcode 0xc3
3274 ****************************************************************************/
3275 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
3277 START_OF_INSTR();
3278 DECODE_PRINTF("RET\n");
3279 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
3280 TRACE_AND_STEP();
3281 M.x86.R_IP = pop_word();
3282 DECODE_CLEAR_SEGOVR();
3283 END_OF_INSTR();
3286 /****************************************************************************
3287 REMARKS:
3288 Handles opcode 0xc4
3289 ****************************************************************************/
3290 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
3292 int mod, rh, rl;
3293 u16 *dstreg;
3294 uint srcoffset;
3296 START_OF_INSTR();
3297 DECODE_PRINTF("LES\t");
3298 FETCH_DECODE_MODRM(mod, rh, rl);
3299 if (mod < 3) {
3300 dstreg = DECODE_RM_WORD_REGISTER(rh);
3301 DECODE_PRINTF(",");
3302 srcoffset = decode_rmXX_address(mod, rl);
3303 DECODE_PRINTF("\n");
3304 TRACE_AND_STEP();
3305 *dstreg = fetch_data_word(srcoffset);
3306 M.x86.R_ES = fetch_data_word(srcoffset + 2);
3308 /* else UNDEFINED! register to register */
3310 DECODE_CLEAR_SEGOVR();
3311 END_OF_INSTR();
3314 /****************************************************************************
3315 REMARKS:
3316 Handles opcode 0xc5
3317 ****************************************************************************/
3318 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
3320 int mod, rh, rl;
3321 u16 *dstreg;
3322 uint srcoffset;
3324 START_OF_INSTR();
3325 DECODE_PRINTF("LDS\t");
3326 FETCH_DECODE_MODRM(mod, rh, rl);
3327 if (mod < 3) {
3328 dstreg = DECODE_RM_WORD_REGISTER(rh);
3329 DECODE_PRINTF(",");
3330 srcoffset = decode_rmXX_address(mod, rl);
3331 DECODE_PRINTF("\n");
3332 TRACE_AND_STEP();
3333 *dstreg = fetch_data_word(srcoffset);
3334 M.x86.R_DS = fetch_data_word(srcoffset + 2);
3336 /* else UNDEFINED! */
3337 DECODE_CLEAR_SEGOVR();
3338 END_OF_INSTR();
3341 /****************************************************************************
3342 REMARKS:
3343 Handles opcode 0xc6
3344 ****************************************************************************/
3345 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
3347 int mod, rl, rh;
3348 u8 *destreg;
3349 uint destoffset;
3350 u8 imm;
3352 START_OF_INSTR();
3353 DECODE_PRINTF("MOV\t");
3354 FETCH_DECODE_MODRM(mod, rh, rl);
3355 if (rh != 0) {
3356 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
3357 HALT_SYS();
3359 if (mod < 3) {
3360 DECODE_PRINTF("BYTE PTR ");
3361 destoffset = decode_rmXX_address(mod, rl);
3362 imm = fetch_byte_imm();
3363 DECODE_PRINTF2(",%2x\n", imm);
3364 TRACE_AND_STEP();
3365 store_data_byte(destoffset, imm);
3366 } else { /* register to register */
3367 destreg = DECODE_RM_BYTE_REGISTER(rl);
3368 imm = fetch_byte_imm();
3369 DECODE_PRINTF2(",%2x\n", imm);
3370 TRACE_AND_STEP();
3371 *destreg = imm;
3373 DECODE_CLEAR_SEGOVR();
3374 END_OF_INSTR();
3377 /****************************************************************************
3378 REMARKS:
3379 Handles opcode 0xc7
3380 ****************************************************************************/
3381 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
3383 int mod, rl, rh;
3384 uint destoffset;
3386 START_OF_INSTR();
3387 DECODE_PRINTF("MOV\t");
3388 FETCH_DECODE_MODRM(mod, rh, rl);
3389 if (rh != 0) {
3390 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
3391 HALT_SYS();
3393 if (mod < 3) {
3394 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3395 u32 imm;
3397 DECODE_PRINTF("DWORD PTR ");
3398 destoffset = decode_rmXX_address(mod, rl);
3399 imm = fetch_long_imm();
3400 DECODE_PRINTF2(",%x\n", imm);
3401 TRACE_AND_STEP();
3402 store_data_long(destoffset, imm);
3403 } else {
3404 u16 imm;
3406 DECODE_PRINTF("WORD PTR ");
3407 destoffset = decode_rmXX_address(mod, rl);
3408 imm = fetch_word_imm();
3409 DECODE_PRINTF2(",%x\n", imm);
3410 TRACE_AND_STEP();
3411 store_data_word(destoffset, imm);
3413 } else { /* register to register */
3414 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3415 u32 *destreg;
3416 u32 imm;
3418 destreg = DECODE_RM_LONG_REGISTER(rl);
3419 imm = fetch_long_imm();
3420 DECODE_PRINTF2(",%x\n", imm);
3421 TRACE_AND_STEP();
3422 *destreg = imm;
3423 } else {
3424 u16 *destreg;
3425 u16 imm;
3427 destreg = DECODE_RM_WORD_REGISTER(rl);
3428 imm = fetch_word_imm();
3429 DECODE_PRINTF2(",%x\n", imm);
3430 TRACE_AND_STEP();
3431 *destreg = imm;
3434 DECODE_CLEAR_SEGOVR();
3435 END_OF_INSTR();
3438 /****************************************************************************
3439 REMARKS:
3440 Handles opcode 0xc8
3441 ****************************************************************************/
3442 void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
3444 u16 local,frame_pointer;
3445 u8 nesting;
3446 int i;
3448 START_OF_INSTR();
3449 local = fetch_word_imm();
3450 nesting = fetch_byte_imm();
3451 DECODE_PRINTF2("ENTER %x\n", local);
3452 DECODE_PRINTF2(",%x\n", nesting);
3453 TRACE_AND_STEP();
3454 push_word(M.x86.R_BP);
3455 frame_pointer = M.x86.R_SP;
3456 if (nesting > 0) {
3457 for (i = 1; i < nesting; i++) {
3458 M.x86.R_BP -= 2;
3459 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
3461 push_word(frame_pointer);
3463 M.x86.R_BP = frame_pointer;
3464 M.x86.R_SP = (u16)(M.x86.R_SP - local);
3465 DECODE_CLEAR_SEGOVR();
3466 END_OF_INSTR();
3469 /****************************************************************************
3470 REMARKS:
3471 Handles opcode 0xc9
3472 ****************************************************************************/
3473 void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
3475 START_OF_INSTR();
3476 DECODE_PRINTF("LEAVE\n");
3477 TRACE_AND_STEP();
3478 M.x86.R_SP = M.x86.R_BP;
3479 M.x86.R_BP = pop_word();
3480 DECODE_CLEAR_SEGOVR();
3481 END_OF_INSTR();
3484 /****************************************************************************
3485 REMARKS:
3486 Handles opcode 0xca
3487 ****************************************************************************/
3488 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
3490 u16 imm;
3492 START_OF_INSTR();
3493 DECODE_PRINTF("RETF\t");
3494 imm = fetch_word_imm();
3495 DECODE_PRINTF2("%x\n", imm);
3496 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
3497 TRACE_AND_STEP();
3498 M.x86.R_IP = pop_word();
3499 M.x86.R_CS = pop_word();
3500 M.x86.R_SP += imm;
3501 DECODE_CLEAR_SEGOVR();
3502 END_OF_INSTR();
3505 /****************************************************************************
3506 REMARKS:
3507 Handles opcode 0xcb
3508 ****************************************************************************/
3509 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
3511 START_OF_INSTR();
3512 DECODE_PRINTF("RETF\n");
3513 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
3514 TRACE_AND_STEP();
3515 M.x86.R_IP = pop_word();
3516 M.x86.R_CS = pop_word();
3517 DECODE_CLEAR_SEGOVR();
3518 END_OF_INSTR();
3521 /****************************************************************************
3522 REMARKS:
3523 Handles opcode 0xcc
3524 ****************************************************************************/
3525 void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
3527 u16 tmp;
3529 START_OF_INSTR();
3530 DECODE_PRINTF("INT 3\n");
3531 tmp = (u16) mem_access_word(3 * 4 + 2);
3532 /* access the segment register */
3533 TRACE_AND_STEP();
3534 if (_X86EMU_intrTab[3]) {
3535 (*_X86EMU_intrTab[3])(3);
3536 } else {
3537 push_word((u16)M.x86.R_FLG);
3538 CLEAR_FLAG(F_IF);
3539 CLEAR_FLAG(F_TF);
3540 push_word(M.x86.R_CS);
3541 M.x86.R_CS = mem_access_word(3 * 4 + 2);
3542 push_word(M.x86.R_IP);
3543 M.x86.R_IP = mem_access_word(3 * 4);
3545 DECODE_CLEAR_SEGOVR();
3546 END_OF_INSTR();
3549 /****************************************************************************
3550 REMARKS:
3551 Handles opcode 0xcd
3552 ****************************************************************************/
3553 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
3555 u16 tmp;
3556 u8 intnum;
3558 START_OF_INSTR();
3559 DECODE_PRINTF("INT\t");
3560 intnum = fetch_byte_imm();
3561 DECODE_PRINTF2("%x\n", intnum);
3562 tmp = mem_access_word(intnum * 4 + 2);
3563 TRACE_AND_STEP();
3564 if (_X86EMU_intrTab[intnum]) {
3565 (*_X86EMU_intrTab[intnum])(intnum);
3566 } else {
3567 push_word((u16)M.x86.R_FLG);
3568 CLEAR_FLAG(F_IF);
3569 CLEAR_FLAG(F_TF);
3570 push_word(M.x86.R_CS);
3571 M.x86.R_CS = mem_access_word(intnum * 4 + 2);
3572 push_word(M.x86.R_IP);
3573 M.x86.R_IP = mem_access_word(intnum * 4);
3575 DECODE_CLEAR_SEGOVR();
3576 END_OF_INSTR();
3579 /****************************************************************************
3580 REMARKS:
3581 Handles opcode 0xce
3582 ****************************************************************************/
3583 void x86emuOp_into(u8 X86EMU_UNUSED(op1))
3585 u16 tmp;
3587 START_OF_INSTR();
3588 DECODE_PRINTF("INTO\n");
3589 TRACE_AND_STEP();
3590 if (ACCESS_FLAG(F_OF)) {
3591 tmp = mem_access_word(4 * 4 + 2);
3592 if (_X86EMU_intrTab[4]) {
3593 (*_X86EMU_intrTab[4])(4);
3594 } else {
3595 push_word((u16)M.x86.R_FLG);
3596 CLEAR_FLAG(F_IF);
3597 CLEAR_FLAG(F_TF);
3598 push_word(M.x86.R_CS);
3599 M.x86.R_CS = mem_access_word(4 * 4 + 2);
3600 push_word(M.x86.R_IP);
3601 M.x86.R_IP = mem_access_word(4 * 4);
3604 DECODE_CLEAR_SEGOVR();
3605 END_OF_INSTR();
3608 /****************************************************************************
3609 REMARKS:
3610 Handles opcode 0xcf
3611 ****************************************************************************/
3612 void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
3614 START_OF_INSTR();
3615 DECODE_PRINTF("IRET\n");
3617 TRACE_AND_STEP();
3619 M.x86.R_IP = pop_word();
3620 M.x86.R_CS = pop_word();
3621 M.x86.R_FLG = pop_word();
3622 DECODE_CLEAR_SEGOVR();
3623 END_OF_INSTR();
3626 /****************************************************************************
3627 REMARKS:
3628 Handles opcode 0xd0
3629 ****************************************************************************/
3630 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
3632 int mod, rl, rh;
3633 u8 *destreg;
3634 uint destoffset;
3635 u8 destval;
3638 * Yet another weirdo special case instruction format. Part of
3639 * the opcode held below in "RH". Doubly nested case would
3640 * result, except that the decoded instruction
3642 START_OF_INSTR();
3643 FETCH_DECODE_MODRM(mod, rh, rl);
3644 #ifdef DEBUG
3645 if (DEBUG_DECODE()) {
3646 /* XXX DECODE_PRINTF may be changed to something more
3647 general, so that it is important to leave the strings
3648 in the same format, even though the result is that the
3649 above test is done twice. */
3650 switch (rh) {
3651 case 0:
3652 DECODE_PRINTF("ROL\t");
3653 break;
3654 case 1:
3655 DECODE_PRINTF("ROR\t");
3656 break;
3657 case 2:
3658 DECODE_PRINTF("RCL\t");
3659 break;
3660 case 3:
3661 DECODE_PRINTF("RCR\t");
3662 break;
3663 case 4:
3664 DECODE_PRINTF("SHL\t");
3665 break;
3666 case 5:
3667 DECODE_PRINTF("SHR\t");
3668 break;
3669 case 6:
3670 DECODE_PRINTF("SAL\t");
3671 break;
3672 case 7:
3673 DECODE_PRINTF("SAR\t");
3674 break;
3677 #endif
3678 /* know operation, decode the mod byte to find the addressing
3679 mode. */
3680 if (mod < 3) {
3681 DECODE_PRINTF("BYTE PTR ");
3682 destoffset = decode_rmXX_address(mod, rl);
3683 DECODE_PRINTF(",1\n");
3684 destval = fetch_data_byte(destoffset);
3685 TRACE_AND_STEP();
3686 destval = (*opcD0_byte_operation[rh]) (destval, 1);
3687 store_data_byte(destoffset, destval);
3688 } else { /* register to register */
3689 destreg = DECODE_RM_BYTE_REGISTER(rl);
3690 DECODE_PRINTF(",1\n");
3691 TRACE_AND_STEP();
3692 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
3693 *destreg = destval;
3695 DECODE_CLEAR_SEGOVR();
3696 END_OF_INSTR();
3699 /****************************************************************************
3700 REMARKS:
3701 Handles opcode 0xd1
3702 ****************************************************************************/
3703 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
3705 int mod, rl, rh;
3706 uint destoffset;
3709 * Yet another weirdo special case instruction format. Part of
3710 * the opcode held below in "RH". Doubly nested case would
3711 * result, except that the decoded instruction
3713 START_OF_INSTR();
3714 FETCH_DECODE_MODRM(mod, rh, rl);
3715 #ifdef DEBUG
3716 if (DEBUG_DECODE()) {
3717 /* XXX DECODE_PRINTF may be changed to something more
3718 general, so that it is important to leave the strings
3719 in the same format, even though the result is that the
3720 above test is done twice. */
3721 switch (rh) {
3722 case 0:
3723 DECODE_PRINTF("ROL\t");
3724 break;
3725 case 1:
3726 DECODE_PRINTF("ROR\t");
3727 break;
3728 case 2:
3729 DECODE_PRINTF("RCL\t");
3730 break;
3731 case 3:
3732 DECODE_PRINTF("RCR\t");
3733 break;
3734 case 4:
3735 DECODE_PRINTF("SHL\t");
3736 break;
3737 case 5:
3738 DECODE_PRINTF("SHR\t");
3739 break;
3740 case 6:
3741 DECODE_PRINTF("SAL\t");
3742 break;
3743 case 7:
3744 DECODE_PRINTF("SAR\t");
3745 break;
3748 #endif
3749 /* know operation, decode the mod byte to find the addressing
3750 mode. */
3751 if (mod < 3) {
3752 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3753 u32 destval;
3755 DECODE_PRINTF("DWORD PTR ");
3756 destoffset = decode_rmXX_address(mod, rl);
3757 DECODE_PRINTF(",1\n");
3758 destval = fetch_data_long(destoffset);
3759 TRACE_AND_STEP();
3760 destval = (*opcD1_long_operation[rh]) (destval, 1);
3761 store_data_long(destoffset, destval);
3762 } else {
3763 u16 destval;
3765 DECODE_PRINTF("WORD PTR ");
3766 destoffset = decode_rmXX_address(mod, rl);
3767 DECODE_PRINTF(",1\n");
3768 destval = fetch_data_word(destoffset);
3769 TRACE_AND_STEP();
3770 destval = (*opcD1_word_operation[rh]) (destval, 1);
3771 store_data_word(destoffset, destval);
3773 } else { /* register to register */
3774 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3775 u32 destval;
3776 u32 *destreg;
3778 destreg = DECODE_RM_LONG_REGISTER(rl);
3779 DECODE_PRINTF(",1\n");
3780 TRACE_AND_STEP();
3781 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
3782 *destreg = destval;
3783 } else {
3784 u16 destval;
3785 u16 *destreg;
3787 destreg = DECODE_RM_WORD_REGISTER(rl);
3788 DECODE_PRINTF(",1\n");
3789 TRACE_AND_STEP();
3790 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
3791 *destreg = destval;
3794 DECODE_CLEAR_SEGOVR();
3795 END_OF_INSTR();
3798 /****************************************************************************
3799 REMARKS:
3800 Handles opcode 0xd2
3801 ****************************************************************************/
3802 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
3804 int mod, rl, rh;
3805 u8 *destreg;
3806 uint destoffset;
3807 u8 destval;
3808 u8 amt;
3811 * Yet another weirdo special case instruction format. Part of
3812 * the opcode held below in "RH". Doubly nested case would
3813 * result, except that the decoded instruction
3815 START_OF_INSTR();
3816 FETCH_DECODE_MODRM(mod, rh, rl);
3817 #ifdef DEBUG
3818 if (DEBUG_DECODE()) {
3819 /* XXX DECODE_PRINTF may be changed to something more
3820 general, so that it is important to leave the strings
3821 in the same format, even though the result is that the
3822 above test is done twice. */
3823 switch (rh) {
3824 case 0:
3825 DECODE_PRINTF("ROL\t");
3826 break;
3827 case 1:
3828 DECODE_PRINTF("ROR\t");
3829 break;
3830 case 2:
3831 DECODE_PRINTF("RCL\t");
3832 break;
3833 case 3:
3834 DECODE_PRINTF("RCR\t");
3835 break;
3836 case 4:
3837 DECODE_PRINTF("SHL\t");
3838 break;
3839 case 5:
3840 DECODE_PRINTF("SHR\t");
3841 break;
3842 case 6:
3843 DECODE_PRINTF("SAL\t");
3844 break;
3845 case 7:
3846 DECODE_PRINTF("SAR\t");
3847 break;
3850 #endif
3851 /* know operation, decode the mod byte to find the addressing
3852 mode. */
3853 amt = M.x86.R_CL;
3854 if (mod < 3) {
3855 DECODE_PRINTF("BYTE PTR ");
3856 destoffset = decode_rmXX_address(mod, rl);
3857 DECODE_PRINTF(",CL\n");
3858 destval = fetch_data_byte(destoffset);
3859 TRACE_AND_STEP();
3860 destval = (*opcD0_byte_operation[rh]) (destval, amt);
3861 store_data_byte(destoffset, destval);
3862 } else { /* register to register */
3863 destreg = DECODE_RM_BYTE_REGISTER(rl);
3864 DECODE_PRINTF(",CL\n");
3865 TRACE_AND_STEP();
3866 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
3867 *destreg = destval;
3869 DECODE_CLEAR_SEGOVR();
3870 END_OF_INSTR();
3873 /****************************************************************************
3874 REMARKS:
3875 Handles opcode 0xd3
3876 ****************************************************************************/
3877 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
3879 int mod, rl, rh;
3880 uint destoffset;
3881 u8 amt;
3884 * Yet another weirdo special case instruction format. Part of
3885 * the opcode held below in "RH". Doubly nested case would
3886 * result, except that the decoded instruction
3888 START_OF_INSTR();
3889 FETCH_DECODE_MODRM(mod, rh, rl);
3890 #ifdef DEBUG
3891 if (DEBUG_DECODE()) {
3892 /* XXX DECODE_PRINTF may be changed to something more
3893 general, so that it is important to leave the strings
3894 in the same format, even though the result is that the
3895 above test is done twice. */
3896 switch (rh) {
3897 case 0:
3898 DECODE_PRINTF("ROL\t");
3899 break;
3900 case 1:
3901 DECODE_PRINTF("ROR\t");
3902 break;
3903 case 2:
3904 DECODE_PRINTF("RCL\t");
3905 break;
3906 case 3:
3907 DECODE_PRINTF("RCR\t");
3908 break;
3909 case 4:
3910 DECODE_PRINTF("SHL\t");
3911 break;
3912 case 5:
3913 DECODE_PRINTF("SHR\t");
3914 break;
3915 case 6:
3916 DECODE_PRINTF("SAL\t");
3917 break;
3918 case 7:
3919 DECODE_PRINTF("SAR\t");
3920 break;
3923 #endif
3924 /* know operation, decode the mod byte to find the addressing
3925 mode. */
3926 amt = M.x86.R_CL;
3927 if (mod < 3) {
3928 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3929 u32 destval;
3931 DECODE_PRINTF("DWORD PTR ");
3932 destoffset = decode_rmXX_address(mod, rl);
3933 DECODE_PRINTF(",CL\n");
3934 destval = fetch_data_long(destoffset);
3935 TRACE_AND_STEP();
3936 destval = (*opcD1_long_operation[rh]) (destval, amt);
3937 store_data_long(destoffset, destval);
3938 } else {
3939 u16 destval;
3941 DECODE_PRINTF("WORD PTR ");
3942 destoffset = decode_rmXX_address(mod, rl);
3943 DECODE_PRINTF(",CL\n");
3944 destval = fetch_data_word(destoffset);
3945 TRACE_AND_STEP();
3946 destval = (*opcD1_word_operation[rh]) (destval, amt);
3947 store_data_word(destoffset, destval);
3949 } else { /* register to register */
3950 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3951 u32 *destreg;
3953 destreg = DECODE_RM_LONG_REGISTER(rl);
3954 DECODE_PRINTF(",CL\n");
3955 TRACE_AND_STEP();
3956 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
3957 } else {
3958 u16 *destreg;
3960 destreg = DECODE_RM_WORD_REGISTER(rl);
3961 DECODE_PRINTF(",CL\n");
3962 TRACE_AND_STEP();
3963 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
3966 DECODE_CLEAR_SEGOVR();
3967 END_OF_INSTR();
3970 /****************************************************************************
3971 REMARKS:
3972 Handles opcode 0xd4
3973 ****************************************************************************/
3974 void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
3976 u8 a;
3978 START_OF_INSTR();
3979 DECODE_PRINTF("AAM\n");
3980 a = fetch_byte_imm(); /* this is a stupid encoding. */
3981 if (a != 10) {
3982 DECODE_PRINTF("ERROR DECODING AAM\n");
3983 TRACE_REGS();
3984 HALT_SYS();
3986 TRACE_AND_STEP();
3987 /* note the type change here --- returning AL and AH in AX. */
3988 M.x86.R_AX = aam_word(M.x86.R_AL);
3989 DECODE_CLEAR_SEGOVR();
3990 END_OF_INSTR();
3993 /****************************************************************************
3994 REMARKS:
3995 Handles opcode 0xd5
3996 ****************************************************************************/
3997 void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
3999 u8 a;
4001 START_OF_INSTR();
4002 DECODE_PRINTF("AAD\n");
4003 a = fetch_byte_imm();
4004 TRACE_AND_STEP();
4005 M.x86.R_AX = aad_word(M.x86.R_AX);
4006 DECODE_CLEAR_SEGOVR();
4007 END_OF_INSTR();
4010 /* opcode 0xd6 ILLEGAL OPCODE */
4012 /****************************************************************************
4013 REMARKS:
4014 Handles opcode 0xd7
4015 ****************************************************************************/
4016 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
4018 u16 addr;
4020 START_OF_INSTR();
4021 DECODE_PRINTF("XLAT\n");
4022 TRACE_AND_STEP();
4023 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
4024 M.x86.R_AL = fetch_data_byte(addr);
4025 DECODE_CLEAR_SEGOVR();
4026 END_OF_INSTR();
4029 /* instuctions D8 .. DF are in i87_ops.c */
4031 /****************************************************************************
4032 REMARKS:
4033 Handles opcode 0xe0
4034 ****************************************************************************/
4035 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
4037 s16 ip;
4039 START_OF_INSTR();
4040 DECODE_PRINTF("LOOPNE\t");
4041 ip = (s8) fetch_byte_imm();
4042 ip += (s16) M.x86.R_IP;
4043 DECODE_PRINTF2("%04x\n", ip);
4044 TRACE_AND_STEP();
4045 M.x86.R_CX -= 1;
4046 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
4047 M.x86.R_IP = ip;
4048 DECODE_CLEAR_SEGOVR();
4049 END_OF_INSTR();
4052 /****************************************************************************
4053 REMARKS:
4054 Handles opcode 0xe1
4055 ****************************************************************************/
4056 void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
4058 s16 ip;
4060 START_OF_INSTR();
4061 DECODE_PRINTF("LOOPE\t");
4062 ip = (s8) fetch_byte_imm();
4063 ip += (s16) M.x86.R_IP;
4064 DECODE_PRINTF2("%04x\n", ip);
4065 TRACE_AND_STEP();
4066 M.x86.R_CX -= 1;
4067 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
4068 M.x86.R_IP = ip;
4069 DECODE_CLEAR_SEGOVR();
4070 END_OF_INSTR();
4073 /****************************************************************************
4074 REMARKS:
4075 Handles opcode 0xe2
4076 ****************************************************************************/
4077 void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
4079 s16 ip;
4081 START_OF_INSTR();
4082 DECODE_PRINTF("LOOP\t");
4083 ip = (s8) fetch_byte_imm();
4084 ip += (s16) M.x86.R_IP;
4085 DECODE_PRINTF2("%04x\n", ip);
4086 TRACE_AND_STEP();
4087 M.x86.R_CX -= 1;
4088 if (M.x86.R_CX != 0)
4089 M.x86.R_IP = ip;
4090 DECODE_CLEAR_SEGOVR();
4091 END_OF_INSTR();
4094 /****************************************************************************
4095 REMARKS:
4096 Handles opcode 0xe3
4097 ****************************************************************************/
4098 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
4100 u16 target;
4101 s8 offset;
4103 /* jump to byte offset if overflow flag is set */
4104 START_OF_INSTR();
4105 DECODE_PRINTF("JCXZ\t");
4106 offset = (s8)fetch_byte_imm();
4107 target = (u16)(M.x86.R_IP + offset);
4108 DECODE_PRINTF2("%x\n", target);
4109 TRACE_AND_STEP();
4110 if (M.x86.R_CX == 0)
4111 M.x86.R_IP = target;
4112 DECODE_CLEAR_SEGOVR();
4113 END_OF_INSTR();
4116 /****************************************************************************
4117 REMARKS:
4118 Handles opcode 0xe4
4119 ****************************************************************************/
4120 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
4122 u8 port;
4124 START_OF_INSTR();
4125 DECODE_PRINTF("IN\t");
4126 port = (u8) fetch_byte_imm();
4127 DECODE_PRINTF2("%x,AL\n", port);
4128 TRACE_AND_STEP();
4129 M.x86.R_AL = (*sys_inb)(port);
4130 DECODE_CLEAR_SEGOVR();
4131 END_OF_INSTR();
4134 /****************************************************************************
4135 REMARKS:
4136 Handles opcode 0xe5
4137 ****************************************************************************/
4138 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
4140 u8 port;
4142 START_OF_INSTR();
4143 DECODE_PRINTF("IN\t");
4144 port = (u8) fetch_byte_imm();
4145 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146 DECODE_PRINTF2("EAX,%x\n", port);
4147 } else {
4148 DECODE_PRINTF2("AX,%x\n", port);
4150 TRACE_AND_STEP();
4151 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4152 M.x86.R_EAX = (*sys_inl)(port);
4153 } else {
4154 M.x86.R_AX = (*sys_inw)(port);
4156 DECODE_CLEAR_SEGOVR();
4157 END_OF_INSTR();
4160 /****************************************************************************
4161 REMARKS:
4162 Handles opcode 0xe6
4163 ****************************************************************************/
4164 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
4166 u8 port;
4168 START_OF_INSTR();
4169 DECODE_PRINTF("OUT\t");
4170 port = (u8) fetch_byte_imm();
4171 DECODE_PRINTF2("%x,AL\n", port);
4172 TRACE_AND_STEP();
4173 (*sys_outb)(port, M.x86.R_AL);
4174 DECODE_CLEAR_SEGOVR();
4175 END_OF_INSTR();
4178 /****************************************************************************
4179 REMARKS:
4180 Handles opcode 0xe7
4181 ****************************************************************************/
4182 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
4184 u8 port;
4186 START_OF_INSTR();
4187 DECODE_PRINTF("OUT\t");
4188 port = (u8) fetch_byte_imm();
4189 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4190 DECODE_PRINTF2("%x,EAX\n", port);
4191 } else {
4192 DECODE_PRINTF2("%x,AX\n", port);
4194 TRACE_AND_STEP();
4195 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4196 (*sys_outl)(port, M.x86.R_EAX);
4197 } else {
4198 (*sys_outw)(port, M.x86.R_AX);
4200 DECODE_CLEAR_SEGOVR();
4201 END_OF_INSTR();
4204 /****************************************************************************
4205 REMARKS:
4206 Handles opcode 0xe8
4207 ****************************************************************************/
4208 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
4210 s16 ip;
4212 START_OF_INSTR();
4213 DECODE_PRINTF("CALL\t");
4214 ip = (s16) fetch_word_imm();
4215 ip += (s16) M.x86.R_IP; /* CHECK SIGN */
4216 DECODE_PRINTF2("%04x\n", ip);
4217 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
4218 TRACE_AND_STEP();
4219 push_word(M.x86.R_IP);
4220 M.x86.R_IP = ip;
4221 DECODE_CLEAR_SEGOVR();
4222 END_OF_INSTR();
4225 /****************************************************************************
4226 REMARKS:
4227 Handles opcode 0xe9
4228 ****************************************************************************/
4229 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
4231 int ip;
4233 START_OF_INSTR();
4234 DECODE_PRINTF("JMP\t");
4235 ip = (s16)fetch_word_imm();
4236 ip += (s16)M.x86.R_IP;
4237 DECODE_PRINTF2("%04x\n", ip);
4238 TRACE_AND_STEP();
4239 M.x86.R_IP = (u16)ip;
4240 DECODE_CLEAR_SEGOVR();
4241 END_OF_INSTR();
4244 /****************************************************************************
4245 REMARKS:
4246 Handles opcode 0xea
4247 ****************************************************************************/
4248 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
4250 u16 cs, ip;
4252 START_OF_INSTR();
4253 DECODE_PRINTF("JMP\tFAR ");
4254 ip = fetch_word_imm();
4255 cs = fetch_word_imm();
4256 DECODE_PRINTF2("%04x:", cs);
4257 DECODE_PRINTF2("%04x\n", ip);
4258 TRACE_AND_STEP();
4259 M.x86.R_IP = ip;
4260 M.x86.R_CS = cs;
4261 DECODE_CLEAR_SEGOVR();
4262 END_OF_INSTR();
4265 /****************************************************************************
4266 REMARKS:
4267 Handles opcode 0xeb
4268 ****************************************************************************/
4269 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
4271 u16 target;
4272 s8 offset;
4274 START_OF_INSTR();
4275 DECODE_PRINTF("JMP\t");
4276 offset = (s8)fetch_byte_imm();
4277 target = (u16)(M.x86.R_IP + offset);
4278 DECODE_PRINTF2("%x\n", target);
4279 TRACE_AND_STEP();
4280 M.x86.R_IP = target;
4281 DECODE_CLEAR_SEGOVR();
4282 END_OF_INSTR();
4285 /****************************************************************************
4286 REMARKS:
4287 Handles opcode 0xec
4288 ****************************************************************************/
4289 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
4291 START_OF_INSTR();
4292 DECODE_PRINTF("IN\tAL,DX\n");
4293 TRACE_AND_STEP();
4294 M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
4295 DECODE_CLEAR_SEGOVR();
4296 END_OF_INSTR();
4299 /****************************************************************************
4300 REMARKS:
4301 Handles opcode 0xed
4302 ****************************************************************************/
4303 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
4305 START_OF_INSTR();
4306 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4307 DECODE_PRINTF("IN\tEAX,DX\n");
4308 } else {
4309 DECODE_PRINTF("IN\tAX,DX\n");
4311 TRACE_AND_STEP();
4312 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4313 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
4314 } else {
4315 M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
4317 DECODE_CLEAR_SEGOVR();
4318 END_OF_INSTR();
4321 /****************************************************************************
4322 REMARKS:
4323 Handles opcode 0xee
4324 ****************************************************************************/
4325 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
4327 START_OF_INSTR();
4328 DECODE_PRINTF("OUT\tDX,AL\n");
4329 TRACE_AND_STEP();
4330 (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
4331 DECODE_CLEAR_SEGOVR();
4332 END_OF_INSTR();
4335 /****************************************************************************
4336 REMARKS:
4337 Handles opcode 0xef
4338 ****************************************************************************/
4339 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
4341 START_OF_INSTR();
4342 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4343 DECODE_PRINTF("OUT\tDX,EAX\n");
4344 } else {
4345 DECODE_PRINTF("OUT\tDX,AX\n");
4347 TRACE_AND_STEP();
4348 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4349 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
4350 } else {
4351 (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
4353 DECODE_CLEAR_SEGOVR();
4354 END_OF_INSTR();
4357 /****************************************************************************
4358 REMARKS:
4359 Handles opcode 0xf0
4360 ****************************************************************************/
4361 void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
4363 START_OF_INSTR();
4364 DECODE_PRINTF("LOCK:\n");
4365 TRACE_AND_STEP();
4366 DECODE_CLEAR_SEGOVR();
4367 END_OF_INSTR();
4370 /*opcode 0xf1 ILLEGAL OPERATION */
4372 /****************************************************************************
4373 REMARKS:
4374 Handles opcode 0xf2
4375 ****************************************************************************/
4376 void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
4378 START_OF_INSTR();
4379 DECODE_PRINTF("REPNE\n");
4380 TRACE_AND_STEP();
4381 M.x86.mode |= SYSMODE_PREFIX_REPNE;
4382 DECODE_CLEAR_SEGOVR();
4383 END_OF_INSTR();
4386 /****************************************************************************
4387 REMARKS:
4388 Handles opcode 0xf3
4389 ****************************************************************************/
4390 void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
4392 START_OF_INSTR();
4393 DECODE_PRINTF("REPE\n");
4394 TRACE_AND_STEP();
4395 M.x86.mode |= SYSMODE_PREFIX_REPE;
4396 DECODE_CLEAR_SEGOVR();
4397 END_OF_INSTR();
4400 /****************************************************************************
4401 REMARKS:
4402 Handles opcode 0xf4
4403 ****************************************************************************/
4404 void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
4406 START_OF_INSTR();
4407 DECODE_PRINTF("HALT\n");
4408 TRACE_AND_STEP();
4409 HALT_SYS();
4410 DECODE_CLEAR_SEGOVR();
4411 END_OF_INSTR();
4414 /****************************************************************************
4415 REMARKS:
4416 Handles opcode 0xf5
4417 ****************************************************************************/
4418 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
4420 /* complement the carry flag. */
4421 START_OF_INSTR();
4422 DECODE_PRINTF("CMC\n");
4423 TRACE_AND_STEP();
4424 TOGGLE_FLAG(F_CF);
4425 DECODE_CLEAR_SEGOVR();
4426 END_OF_INSTR();
4429 /****************************************************************************
4430 REMARKS:
4431 Handles opcode 0xf6
4432 ****************************************************************************/
4433 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
4435 int mod, rl, rh;
4436 u8 *destreg;
4437 uint destoffset;
4438 u8 destval, srcval;
4440 /* long, drawn out code follows. Double switch for a total
4441 of 32 cases. */
4442 START_OF_INSTR();
4443 FETCH_DECODE_MODRM(mod, rh, rl);
4444 DECODE_PRINTF(opF6_names[rh]);
4445 if (mod < 3) {
4446 DECODE_PRINTF("BYTE PTR ");
4447 destoffset = decode_rmXX_address(mod, rl);
4448 destval = fetch_data_byte(destoffset);
4450 switch (rh) {
4451 case 0: /* test byte imm */
4452 DECODE_PRINTF(",");
4453 srcval = fetch_byte_imm();
4454 DECODE_PRINTF2("%02x\n", srcval);
4455 TRACE_AND_STEP();
4456 test_byte(destval, srcval);
4457 break;
4458 case 1:
4459 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4460 HALT_SYS();
4461 break;
4462 case 2:
4463 DECODE_PRINTF("\n");
4464 TRACE_AND_STEP();
4465 destval = not_byte(destval);
4466 store_data_byte(destoffset, destval);
4467 break;
4468 case 3:
4469 DECODE_PRINTF("\n");
4470 TRACE_AND_STEP();
4471 destval = neg_byte(destval);
4472 store_data_byte(destoffset, destval);
4473 break;
4474 case 4:
4475 DECODE_PRINTF("\n");
4476 TRACE_AND_STEP();
4477 mul_byte(destval);
4478 break;
4479 case 5:
4480 DECODE_PRINTF("\n");
4481 TRACE_AND_STEP();
4482 imul_byte(destval);
4483 break;
4484 case 6:
4485 DECODE_PRINTF("\n");
4486 TRACE_AND_STEP();
4487 div_byte(destval);
4488 break;
4489 default:
4490 DECODE_PRINTF("\n");
4491 TRACE_AND_STEP();
4492 idiv_byte(destval);
4493 break;
4495 } else { /* mod=11 */
4496 destreg = DECODE_RM_BYTE_REGISTER(rl);
4497 switch (rh) {
4498 case 0: /* test byte imm */
4499 DECODE_PRINTF(",");
4500 srcval = fetch_byte_imm();
4501 DECODE_PRINTF2("%02x\n", srcval);
4502 TRACE_AND_STEP();
4503 test_byte(*destreg, srcval);
4504 break;
4505 case 1:
4506 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4507 HALT_SYS();
4508 break;
4509 case 2:
4510 DECODE_PRINTF("\n");
4511 TRACE_AND_STEP();
4512 *destreg = not_byte(*destreg);
4513 break;
4514 case 3:
4515 DECODE_PRINTF("\n");
4516 TRACE_AND_STEP();
4517 *destreg = neg_byte(*destreg);
4518 break;
4519 case 4:
4520 DECODE_PRINTF("\n");
4521 TRACE_AND_STEP();
4522 mul_byte(*destreg); /*!!! */
4523 break;
4524 case 5:
4525 DECODE_PRINTF("\n");
4526 TRACE_AND_STEP();
4527 imul_byte(*destreg);
4528 break;
4529 case 6:
4530 DECODE_PRINTF("\n");
4531 TRACE_AND_STEP();
4532 div_byte(*destreg);
4533 break;
4534 default:
4535 DECODE_PRINTF("\n");
4536 TRACE_AND_STEP();
4537 idiv_byte(*destreg);
4538 break;
4541 DECODE_CLEAR_SEGOVR();
4542 END_OF_INSTR();
4545 /****************************************************************************
4546 REMARKS:
4547 Handles opcode 0xf7
4548 ****************************************************************************/
4549 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
4551 int mod, rl, rh;
4552 uint destoffset;
4554 START_OF_INSTR();
4555 FETCH_DECODE_MODRM(mod, rh, rl);
4556 DECODE_PRINTF(opF6_names[rh]);
4557 if (mod < 3) {
4559 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4560 u32 destval, srcval;
4562 DECODE_PRINTF("DWORD PTR ");
4563 destoffset = decode_rmXX_address(mod, rl);
4564 destval = fetch_data_long(destoffset);
4566 switch (rh) {
4567 case 0:
4568 DECODE_PRINTF(",");
4569 srcval = fetch_long_imm();
4570 DECODE_PRINTF2("%x\n", srcval);
4571 TRACE_AND_STEP();
4572 test_long(destval, srcval);
4573 break;
4574 case 1:
4575 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4576 HALT_SYS();
4577 break;
4578 case 2:
4579 DECODE_PRINTF("\n");
4580 TRACE_AND_STEP();
4581 destval = not_long(destval);
4582 store_data_long(destoffset, destval);
4583 break;
4584 case 3:
4585 DECODE_PRINTF("\n");
4586 TRACE_AND_STEP();
4587 destval = neg_long(destval);
4588 store_data_long(destoffset, destval);
4589 break;
4590 case 4:
4591 DECODE_PRINTF("\n");
4592 TRACE_AND_STEP();
4593 mul_long(destval);
4594 break;
4595 case 5:
4596 DECODE_PRINTF("\n");
4597 TRACE_AND_STEP();
4598 imul_long(destval);
4599 break;
4600 case 6:
4601 DECODE_PRINTF("\n");
4602 TRACE_AND_STEP();
4603 div_long(destval);
4604 break;
4605 case 7:
4606 DECODE_PRINTF("\n");
4607 TRACE_AND_STEP();
4608 idiv_long(destval);
4609 break;
4611 } else {
4612 u16 destval, srcval;
4614 DECODE_PRINTF("WORD PTR ");
4615 destoffset = decode_rmXX_address(mod, rl);
4616 destval = fetch_data_word(destoffset);
4618 switch (rh) {
4619 case 0: /* test word imm */
4620 DECODE_PRINTF(",");
4621 srcval = fetch_word_imm();
4622 DECODE_PRINTF2("%x\n", srcval);
4623 TRACE_AND_STEP();
4624 test_word(destval, srcval);
4625 break;
4626 case 1:
4627 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4628 HALT_SYS();
4629 break;
4630 case 2:
4631 DECODE_PRINTF("\n");
4632 TRACE_AND_STEP();
4633 destval = not_word(destval);
4634 store_data_word(destoffset, destval);
4635 break;
4636 case 3:
4637 DECODE_PRINTF("\n");
4638 TRACE_AND_STEP();
4639 destval = neg_word(destval);
4640 store_data_word(destoffset, destval);
4641 break;
4642 case 4:
4643 DECODE_PRINTF("\n");
4644 TRACE_AND_STEP();
4645 mul_word(destval);
4646 break;
4647 case 5:
4648 DECODE_PRINTF("\n");
4649 TRACE_AND_STEP();
4650 imul_word(destval);
4651 break;
4652 case 6:
4653 DECODE_PRINTF("\n");
4654 TRACE_AND_STEP();
4655 div_word(destval);
4656 break;
4657 case 7:
4658 DECODE_PRINTF("\n");
4659 TRACE_AND_STEP();
4660 idiv_word(destval);
4661 break;
4665 } else { /* mod=11 */
4667 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4668 u32 *destreg;
4669 u32 srcval;
4671 destreg = DECODE_RM_LONG_REGISTER(rl);
4673 switch (rh) {
4674 case 0: /* test word imm */
4675 DECODE_PRINTF(",");
4676 srcval = fetch_long_imm();
4677 DECODE_PRINTF2("%x\n", srcval);
4678 TRACE_AND_STEP();
4679 test_long(*destreg, srcval);
4680 break;
4681 case 1:
4682 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4683 HALT_SYS();
4684 break;
4685 case 2:
4686 DECODE_PRINTF("\n");
4687 TRACE_AND_STEP();
4688 *destreg = not_long(*destreg);
4689 break;
4690 case 3:
4691 DECODE_PRINTF("\n");
4692 TRACE_AND_STEP();
4693 *destreg = neg_long(*destreg);
4694 break;
4695 case 4:
4696 DECODE_PRINTF("\n");
4697 TRACE_AND_STEP();
4698 mul_long(*destreg); /*!!! */
4699 break;
4700 case 5:
4701 DECODE_PRINTF("\n");
4702 TRACE_AND_STEP();
4703 imul_long(*destreg);
4704 break;
4705 case 6:
4706 DECODE_PRINTF("\n");
4707 TRACE_AND_STEP();
4708 div_long(*destreg);
4709 break;
4710 case 7:
4711 DECODE_PRINTF("\n");
4712 TRACE_AND_STEP();
4713 idiv_long(*destreg);
4714 break;
4716 } else {
4717 u16 *destreg;
4718 u16 srcval;
4720 destreg = DECODE_RM_WORD_REGISTER(rl);
4722 switch (rh) {
4723 case 0: /* test word imm */
4724 DECODE_PRINTF(",");
4725 srcval = fetch_word_imm();
4726 DECODE_PRINTF2("%x\n", srcval);
4727 TRACE_AND_STEP();
4728 test_word(*destreg, srcval);
4729 break;
4730 case 1:
4731 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4732 HALT_SYS();
4733 break;
4734 case 2:
4735 DECODE_PRINTF("\n");
4736 TRACE_AND_STEP();
4737 *destreg = not_word(*destreg);
4738 break;
4739 case 3:
4740 DECODE_PRINTF("\n");
4741 TRACE_AND_STEP();
4742 *destreg = neg_word(*destreg);
4743 break;
4744 case 4:
4745 DECODE_PRINTF("\n");
4746 TRACE_AND_STEP();
4747 mul_word(*destreg); /*!!! */
4748 break;
4749 case 5:
4750 DECODE_PRINTF("\n");
4751 TRACE_AND_STEP();
4752 imul_word(*destreg);
4753 break;
4754 case 6:
4755 DECODE_PRINTF("\n");
4756 TRACE_AND_STEP();
4757 div_word(*destreg);
4758 break;
4759 case 7:
4760 DECODE_PRINTF("\n");
4761 TRACE_AND_STEP();
4762 idiv_word(*destreg);
4763 break;
4767 DECODE_CLEAR_SEGOVR();
4768 END_OF_INSTR();
4771 /****************************************************************************
4772 REMARKS:
4773 Handles opcode 0xf8
4774 ****************************************************************************/
4775 void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
4777 /* clear the carry flag. */
4778 START_OF_INSTR();
4779 DECODE_PRINTF("CLC\n");
4780 TRACE_AND_STEP();
4781 CLEAR_FLAG(F_CF);
4782 DECODE_CLEAR_SEGOVR();
4783 END_OF_INSTR();
4786 /****************************************************************************
4787 REMARKS:
4788 Handles opcode 0xf9
4789 ****************************************************************************/
4790 void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
4792 /* set the carry flag. */
4793 START_OF_INSTR();
4794 DECODE_PRINTF("STC\n");
4795 TRACE_AND_STEP();
4796 SET_FLAG(F_CF);
4797 DECODE_CLEAR_SEGOVR();
4798 END_OF_INSTR();
4801 /****************************************************************************
4802 REMARKS:
4803 Handles opcode 0xfa
4804 ****************************************************************************/
4805 void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
4807 /* clear interrupts. */
4808 START_OF_INSTR();
4809 DECODE_PRINTF("CLI\n");
4810 TRACE_AND_STEP();
4811 CLEAR_FLAG(F_IF);
4812 DECODE_CLEAR_SEGOVR();
4813 END_OF_INSTR();
4816 /****************************************************************************
4817 REMARKS:
4818 Handles opcode 0xfb
4819 ****************************************************************************/
4820 void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
4822 /* enable interrupts. */
4823 START_OF_INSTR();
4824 DECODE_PRINTF("STI\n");
4825 TRACE_AND_STEP();
4826 SET_FLAG(F_IF);
4827 DECODE_CLEAR_SEGOVR();
4828 END_OF_INSTR();
4831 /****************************************************************************
4832 REMARKS:
4833 Handles opcode 0xfc
4834 ****************************************************************************/
4835 void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
4837 /* clear interrupts. */
4838 START_OF_INSTR();
4839 DECODE_PRINTF("CLD\n");
4840 TRACE_AND_STEP();
4841 CLEAR_FLAG(F_DF);
4842 DECODE_CLEAR_SEGOVR();
4843 END_OF_INSTR();
4846 /****************************************************************************
4847 REMARKS:
4848 Handles opcode 0xfd
4849 ****************************************************************************/
4850 void x86emuOp_std(u8 X86EMU_UNUSED(op1))
4852 /* clear interrupts. */
4853 START_OF_INSTR();
4854 DECODE_PRINTF("STD\n");
4855 TRACE_AND_STEP();
4856 SET_FLAG(F_DF);
4857 DECODE_CLEAR_SEGOVR();
4858 END_OF_INSTR();
4861 /****************************************************************************
4862 REMARKS:
4863 Handles opcode 0xfe
4864 ****************************************************************************/
4865 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
4867 int mod, rh, rl;
4868 u8 destval;
4869 uint destoffset;
4870 u8 *destreg;
4872 /* Yet another special case instruction. */
4873 START_OF_INSTR();
4874 FETCH_DECODE_MODRM(mod, rh, rl);
4875 #ifdef DEBUG
4876 if (DEBUG_DECODE()) {
4877 /* XXX DECODE_PRINTF may be changed to something more
4878 general, so that it is important to leave the strings
4879 in the same format, even though the result is that the
4880 above test is done twice. */
4882 switch (rh) {
4883 case 0:
4884 DECODE_PRINTF("INC\t");
4885 break;
4886 case 1:
4887 DECODE_PRINTF("DEC\t");
4888 break;
4889 case 2:
4890 case 3:
4891 case 4:
4892 case 5:
4893 case 6:
4894 case 7:
4895 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
4896 HALT_SYS();
4897 break;
4900 #endif
4901 if (mod < 3) {
4902 DECODE_PRINTF("BYTE PTR ");
4903 destoffset = decode_rmXX_address(mod, rl);
4904 DECODE_PRINTF("\n");
4905 destval = fetch_data_byte(destoffset);
4906 TRACE_AND_STEP();
4907 if (rh == 0)
4908 destval = inc_byte(destval);
4909 else
4910 destval = dec_byte(destval);
4911 store_data_byte(destoffset, destval);
4912 } else {
4913 destreg = DECODE_RM_BYTE_REGISTER(rl);
4914 DECODE_PRINTF("\n");
4915 TRACE_AND_STEP();
4916 if (rh == 0)
4917 *destreg = inc_byte(*destreg);
4918 else
4919 *destreg = dec_byte(*destreg);
4921 DECODE_CLEAR_SEGOVR();
4922 END_OF_INSTR();
4925 /****************************************************************************
4926 REMARKS:
4927 Handles opcode 0xff
4928 ****************************************************************************/
4929 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
4931 int mod, rh, rl;
4932 uint destoffset = 0;
4933 u16 *destreg;
4934 u16 destval,destval2;
4936 /* Yet another special case instruction. */
4937 START_OF_INSTR();
4938 FETCH_DECODE_MODRM(mod, rh, rl);
4939 #ifdef DEBUG
4940 if (DEBUG_DECODE()) {
4941 /* XXX DECODE_PRINTF may be changed to something more
4942 general, so that it is important to leave the strings
4943 in the same format, even though the result is that the
4944 above test is done twice. */
4946 switch (rh) {
4947 case 0:
4948 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4949 DECODE_PRINTF("INC\tDWORD PTR ");
4950 } else {
4951 DECODE_PRINTF("INC\tWORD PTR ");
4953 break;
4954 case 1:
4955 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4956 DECODE_PRINTF("DEC\tDWORD PTR ");
4957 } else {
4958 DECODE_PRINTF("DEC\tWORD PTR ");
4960 break;
4961 case 2:
4962 DECODE_PRINTF("CALL\t ");
4963 break;
4964 case 3:
4965 DECODE_PRINTF("CALL\tFAR ");
4966 break;
4967 case 4:
4968 DECODE_PRINTF("JMP\t");
4969 break;
4970 case 5:
4971 DECODE_PRINTF("JMP\tFAR ");
4972 break;
4973 case 6:
4974 DECODE_PRINTF("PUSH\t");
4975 break;
4976 case 7:
4977 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
4978 HALT_SYS();
4979 break;
4982 #endif
4983 if (mod < 3) {
4984 destoffset = decode_rmXX_address(mod, rl);
4985 DECODE_PRINTF("\n");
4986 switch (rh) {
4987 case 0: /* inc word ptr ... */
4988 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4989 u32 destval;
4991 destval = fetch_data_long(destoffset);
4992 TRACE_AND_STEP();
4993 destval = inc_long(destval);
4994 store_data_long(destoffset, destval);
4995 } else {
4996 u16 destval;
4998 destval = fetch_data_word(destoffset);
4999 TRACE_AND_STEP();
5000 destval = inc_word(destval);
5001 store_data_word(destoffset, destval);
5003 break;
5004 case 1: /* dec word ptr ... */
5005 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5006 u32 destval;
5008 destval = fetch_data_long(destoffset);
5009 TRACE_AND_STEP();
5010 destval = dec_long(destval);
5011 store_data_long(destoffset, destval);
5012 } else {
5013 u16 destval;
5015 destval = fetch_data_word(destoffset);
5016 TRACE_AND_STEP();
5017 destval = dec_word(destval);
5018 store_data_word(destoffset, destval);
5020 break;
5021 case 2: /* call word ptr ... */
5022 destval = fetch_data_word(destoffset);
5023 TRACE_AND_STEP();
5024 push_word(M.x86.R_IP);
5025 M.x86.R_IP = destval;
5026 break;
5027 case 3: /* call far ptr ... */
5028 destval = fetch_data_word(destoffset);
5029 destval2 = fetch_data_word(destoffset + 2);
5030 TRACE_AND_STEP();
5031 push_word(M.x86.R_CS);
5032 M.x86.R_CS = destval2;
5033 push_word(M.x86.R_IP);
5034 M.x86.R_IP = destval;
5035 break;
5036 case 4: /* jmp word ptr ... */
5037 destval = fetch_data_word(destoffset);
5038 TRACE_AND_STEP();
5039 M.x86.R_IP = destval;
5040 break;
5041 case 5: /* jmp far ptr ... */
5042 destval = fetch_data_word(destoffset);
5043 destval2 = fetch_data_word(destoffset + 2);
5044 TRACE_AND_STEP();
5045 M.x86.R_IP = destval;
5046 M.x86.R_CS = destval2;
5047 break;
5048 case 6: /* push word ptr ... */
5049 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5050 u32 destval;
5052 destval = fetch_data_long(destoffset);
5053 TRACE_AND_STEP();
5054 push_long(destval);
5055 } else {
5056 u16 destval;
5058 destval = fetch_data_word(destoffset);
5059 TRACE_AND_STEP();
5060 push_word(destval);
5062 break;
5064 } else {
5065 switch (rh) {
5066 case 0:
5067 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5068 u32 *destreg;
5070 destreg = DECODE_RM_LONG_REGISTER(rl);
5071 DECODE_PRINTF("\n");
5072 TRACE_AND_STEP();
5073 *destreg = inc_long(*destreg);
5074 } else {
5075 u16 *destreg;
5077 destreg = DECODE_RM_WORD_REGISTER(rl);
5078 DECODE_PRINTF("\n");
5079 TRACE_AND_STEP();
5080 *destreg = inc_word(*destreg);
5082 break;
5083 case 1:
5084 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5085 u32 *destreg;
5087 destreg = DECODE_RM_LONG_REGISTER(rl);
5088 DECODE_PRINTF("\n");
5089 TRACE_AND_STEP();
5090 *destreg = dec_long(*destreg);
5091 } else {
5092 u16 *destreg;
5094 destreg = DECODE_RM_WORD_REGISTER(rl);
5095 DECODE_PRINTF("\n");
5096 TRACE_AND_STEP();
5097 *destreg = dec_word(*destreg);
5099 break;
5100 case 2: /* call word ptr ... */
5101 destreg = DECODE_RM_WORD_REGISTER(rl);
5102 DECODE_PRINTF("\n");
5103 TRACE_AND_STEP();
5104 push_word(M.x86.R_IP);
5105 M.x86.R_IP = *destreg;
5106 break;
5107 case 3: /* jmp far ptr ... */
5108 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
5109 TRACE_AND_STEP();
5110 HALT_SYS();
5111 break;
5113 case 4: /* jmp ... */
5114 destreg = DECODE_RM_WORD_REGISTER(rl);
5115 DECODE_PRINTF("\n");
5116 TRACE_AND_STEP();
5117 M.x86.R_IP = (u16) (*destreg);
5118 break;
5119 case 5: /* jmp far ptr ... */
5120 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
5121 TRACE_AND_STEP();
5122 HALT_SYS();
5123 break;
5124 case 6:
5125 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5126 u32 *destreg;
5128 destreg = DECODE_RM_LONG_REGISTER(rl);
5129 DECODE_PRINTF("\n");
5130 TRACE_AND_STEP();
5131 push_long(*destreg);
5132 } else {
5133 u16 *destreg;
5135 destreg = DECODE_RM_WORD_REGISTER(rl);
5136 DECODE_PRINTF("\n");
5137 TRACE_AND_STEP();
5138 push_word(*destreg);
5140 break;
5143 DECODE_CLEAR_SEGOVR();
5144 END_OF_INSTR();
5147 /***************************************************************************
5148 * Single byte operation code table:
5149 **************************************************************************/
5150 void (*x86emu_optab[256])(u8) __attribute__ ((section(GOT2_TYPE))) =
5152 /* 0x00 */ x86emuOp_genop_byte_RM_R,
5153 /* 0x01 */ x86emuOp_genop_word_RM_R,
5154 /* 0x02 */ x86emuOp_genop_byte_R_RM,
5155 /* 0x03 */ x86emuOp_genop_word_R_RM,
5156 /* 0x04 */ x86emuOp_genop_byte_AL_IMM,
5157 /* 0x05 */ x86emuOp_genop_word_AX_IMM,
5158 /* 0x06 */ x86emuOp_push_ES,
5159 /* 0x07 */ x86emuOp_pop_ES,
5161 /* 0x08 */ x86emuOp_genop_byte_RM_R,
5162 /* 0x09 */ x86emuOp_genop_word_RM_R,
5163 /* 0x0a */ x86emuOp_genop_byte_R_RM,
5164 /* 0x0b */ x86emuOp_genop_word_R_RM,
5165 /* 0x0c */ x86emuOp_genop_byte_AL_IMM,
5166 /* 0x0d */ x86emuOp_genop_word_AX_IMM,
5167 /* 0x0e */ x86emuOp_push_CS,
5168 /* 0x0f */ x86emuOp_two_byte,
5170 /* 0x10 */ x86emuOp_genop_byte_RM_R,
5171 /* 0x11 */ x86emuOp_genop_word_RM_R,
5172 /* 0x12 */ x86emuOp_genop_byte_R_RM,
5173 /* 0x13 */ x86emuOp_genop_word_R_RM,
5174 /* 0x14 */ x86emuOp_genop_byte_AL_IMM,
5175 /* 0x15 */ x86emuOp_genop_word_AX_IMM,
5176 /* 0x16 */ x86emuOp_push_SS,
5177 /* 0x17 */ x86emuOp_pop_SS,
5179 /* 0x18 */ x86emuOp_genop_byte_RM_R,
5180 /* 0x19 */ x86emuOp_genop_word_RM_R,
5181 /* 0x1a */ x86emuOp_genop_byte_R_RM,
5182 /* 0x1b */ x86emuOp_genop_word_R_RM,
5183 /* 0x1c */ x86emuOp_genop_byte_AL_IMM,
5184 /* 0x1d */ x86emuOp_genop_word_AX_IMM,
5185 /* 0x1e */ x86emuOp_push_DS,
5186 /* 0x1f */ x86emuOp_pop_DS,
5188 /* 0x20 */ x86emuOp_genop_byte_RM_R,
5189 /* 0x21 */ x86emuOp_genop_word_RM_R,
5190 /* 0x22 */ x86emuOp_genop_byte_R_RM,
5191 /* 0x23 */ x86emuOp_genop_word_R_RM,
5192 /* 0x24 */ x86emuOp_genop_byte_AL_IMM,
5193 /* 0x25 */ x86emuOp_genop_word_AX_IMM,
5194 /* 0x26 */ x86emuOp_segovr_ES,
5195 /* 0x27 */ x86emuOp_daa,
5197 /* 0x28 */ x86emuOp_genop_byte_RM_R,
5198 /* 0x29 */ x86emuOp_genop_word_RM_R,
5199 /* 0x2a */ x86emuOp_genop_byte_R_RM,
5200 /* 0x2b */ x86emuOp_genop_word_R_RM,
5201 /* 0x2c */ x86emuOp_genop_byte_AL_IMM,
5202 /* 0x2d */ x86emuOp_genop_word_AX_IMM,
5203 /* 0x2e */ x86emuOp_segovr_CS,
5204 /* 0x2f */ x86emuOp_das,
5206 /* 0x30 */ x86emuOp_genop_byte_RM_R,
5207 /* 0x31 */ x86emuOp_genop_word_RM_R,
5208 /* 0x32 */ x86emuOp_genop_byte_R_RM,
5209 /* 0x33 */ x86emuOp_genop_word_R_RM,
5210 /* 0x34 */ x86emuOp_genop_byte_AL_IMM,
5211 /* 0x35 */ x86emuOp_genop_word_AX_IMM,
5212 /* 0x36 */ x86emuOp_segovr_SS,
5213 /* 0x37 */ x86emuOp_aaa,
5215 /* 0x38 */ x86emuOp_genop_byte_RM_R,
5216 /* 0x39 */ x86emuOp_genop_word_RM_R,
5217 /* 0x3a */ x86emuOp_genop_byte_R_RM,
5218 /* 0x3b */ x86emuOp_genop_word_R_RM,
5219 /* 0x3c */ x86emuOp_genop_byte_AL_IMM,
5220 /* 0x3d */ x86emuOp_genop_word_AX_IMM,
5221 /* 0x3e */ x86emuOp_segovr_DS,
5222 /* 0x3f */ x86emuOp_aas,
5224 /* 0x40 */ x86emuOp_inc_register,
5225 /* 0x41 */ x86emuOp_inc_register,
5226 /* 0x42 */ x86emuOp_inc_register,
5227 /* 0x43 */ x86emuOp_inc_register,
5228 /* 0x44 */ x86emuOp_inc_register,
5229 /* 0x45 */ x86emuOp_inc_register,
5230 /* 0x46 */ x86emuOp_inc_register,
5231 /* 0x47 */ x86emuOp_inc_register,
5233 /* 0x48 */ x86emuOp_dec_register,
5234 /* 0x49 */ x86emuOp_dec_register,
5235 /* 0x4a */ x86emuOp_dec_register,
5236 /* 0x4b */ x86emuOp_dec_register,
5237 /* 0x4c */ x86emuOp_dec_register,
5238 /* 0x4d */ x86emuOp_dec_register,
5239 /* 0x4e */ x86emuOp_dec_register,
5240 /* 0x4f */ x86emuOp_dec_register,
5242 /* 0x50 */ x86emuOp_push_register,
5243 /* 0x51 */ x86emuOp_push_register,
5244 /* 0x52 */ x86emuOp_push_register,
5245 /* 0x53 */ x86emuOp_push_register,
5246 /* 0x54 */ x86emuOp_push_register,
5247 /* 0x55 */ x86emuOp_push_register,
5248 /* 0x56 */ x86emuOp_push_register,
5249 /* 0x57 */ x86emuOp_push_register,
5251 /* 0x58 */ x86emuOp_pop_register,
5252 /* 0x59 */ x86emuOp_pop_register,
5253 /* 0x5a */ x86emuOp_pop_register,
5254 /* 0x5b */ x86emuOp_pop_register,
5255 /* 0x5c */ x86emuOp_pop_register,
5256 /* 0x5d */ x86emuOp_pop_register,
5257 /* 0x5e */ x86emuOp_pop_register,
5258 /* 0x5f */ x86emuOp_pop_register,
5260 /* 0x60 */ x86emuOp_push_all,
5261 /* 0x61 */ x86emuOp_pop_all,
5262 /* 0x62 */ x86emuOp_illegal_op, /* bound */
5263 /* 0x63 */ x86emuOp_illegal_op, /* arpl */
5264 /* 0x64 */ x86emuOp_segovr_FS,
5265 /* 0x65 */ x86emuOp_segovr_GS,
5266 /* 0x66 */ x86emuOp_prefix_data,
5267 /* 0x67 */ x86emuOp_prefix_addr,
5269 /* 0x68 */ x86emuOp_push_word_IMM,
5270 /* 0x69 */ x86emuOp_imul_word_IMM,
5271 /* 0x6a */ x86emuOp_push_byte_IMM,
5272 /* 0x6b */ x86emuOp_imul_byte_IMM,
5273 /* 0x6c */ x86emuOp_ins_byte,
5274 /* 0x6d */ x86emuOp_ins_word,
5275 /* 0x6e */ x86emuOp_outs_byte,
5276 /* 0x6f */ x86emuOp_outs_word,
5278 /* 0x70 */ x86emuOp_jump_near_cond,
5279 /* 0x71 */ x86emuOp_jump_near_cond,
5280 /* 0x72 */ x86emuOp_jump_near_cond,
5281 /* 0x73 */ x86emuOp_jump_near_cond,
5282 /* 0x74 */ x86emuOp_jump_near_cond,
5283 /* 0x75 */ x86emuOp_jump_near_cond,
5284 /* 0x76 */ x86emuOp_jump_near_cond,
5285 /* 0x77 */ x86emuOp_jump_near_cond,
5287 /* 0x78 */ x86emuOp_jump_near_cond,
5288 /* 0x79 */ x86emuOp_jump_near_cond,
5289 /* 0x7a */ x86emuOp_jump_near_cond,
5290 /* 0x7b */ x86emuOp_jump_near_cond,
5291 /* 0x7c */ x86emuOp_jump_near_cond,
5292 /* 0x7d */ x86emuOp_jump_near_cond,
5293 /* 0x7e */ x86emuOp_jump_near_cond,
5294 /* 0x7f */ x86emuOp_jump_near_cond,
5296 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
5297 /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
5298 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
5299 /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
5300 /* 0x84 */ x86emuOp_test_byte_RM_R,
5301 /* 0x85 */ x86emuOp_test_word_RM_R,
5302 /* 0x86 */ x86emuOp_xchg_byte_RM_R,
5303 /* 0x87 */ x86emuOp_xchg_word_RM_R,
5305 /* 0x88 */ x86emuOp_mov_byte_RM_R,
5306 /* 0x89 */ x86emuOp_mov_word_RM_R,
5307 /* 0x8a */ x86emuOp_mov_byte_R_RM,
5308 /* 0x8b */ x86emuOp_mov_word_R_RM,
5309 /* 0x8c */ x86emuOp_mov_word_RM_SR,
5310 /* 0x8d */ x86emuOp_lea_word_R_M,
5311 /* 0x8e */ x86emuOp_mov_word_SR_RM,
5312 /* 0x8f */ x86emuOp_pop_RM,
5314 /* 0x90 */ x86emuOp_nop,
5315 /* 0x91 */ x86emuOp_xchg_word_AX_register,
5316 /* 0x92 */ x86emuOp_xchg_word_AX_register,
5317 /* 0x93 */ x86emuOp_xchg_word_AX_register,
5318 /* 0x94 */ x86emuOp_xchg_word_AX_register,
5319 /* 0x95 */ x86emuOp_xchg_word_AX_register,
5320 /* 0x96 */ x86emuOp_xchg_word_AX_register,
5321 /* 0x97 */ x86emuOp_xchg_word_AX_register,
5323 /* 0x98 */ x86emuOp_cbw,
5324 /* 0x99 */ x86emuOp_cwd,
5325 /* 0x9a */ x86emuOp_call_far_IMM,
5326 /* 0x9b */ x86emuOp_wait,
5327 /* 0x9c */ x86emuOp_pushf_word,
5328 /* 0x9d */ x86emuOp_popf_word,
5329 /* 0x9e */ x86emuOp_sahf,
5330 /* 0x9f */ x86emuOp_lahf,
5332 /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
5333 /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
5334 /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
5335 /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
5336 /* 0xa4 */ x86emuOp_movs_byte,
5337 /* 0xa5 */ x86emuOp_movs_word,
5338 /* 0xa6 */ x86emuOp_cmps_byte,
5339 /* 0xa7 */ x86emuOp_cmps_word,
5340 /* 0xa8 */ x86emuOp_test_AL_IMM,
5341 /* 0xa9 */ x86emuOp_test_AX_IMM,
5342 /* 0xaa */ x86emuOp_stos_byte,
5343 /* 0xab */ x86emuOp_stos_word,
5344 /* 0xac */ x86emuOp_lods_byte,
5345 /* 0xad */ x86emuOp_lods_word,
5346 /* 0xac */ x86emuOp_scas_byte,
5347 /* 0xad */ x86emuOp_scas_word,
5349 /* 0xb0 */ x86emuOp_mov_byte_register_IMM,
5350 /* 0xb1 */ x86emuOp_mov_byte_register_IMM,
5351 /* 0xb2 */ x86emuOp_mov_byte_register_IMM,
5352 /* 0xb3 */ x86emuOp_mov_byte_register_IMM,
5353 /* 0xb4 */ x86emuOp_mov_byte_register_IMM,
5354 /* 0xb5 */ x86emuOp_mov_byte_register_IMM,
5355 /* 0xb6 */ x86emuOp_mov_byte_register_IMM,
5356 /* 0xb7 */ x86emuOp_mov_byte_register_IMM,
5358 /* 0xb8 */ x86emuOp_mov_word_register_IMM,
5359 /* 0xb9 */ x86emuOp_mov_word_register_IMM,
5360 /* 0xba */ x86emuOp_mov_word_register_IMM,
5361 /* 0xbb */ x86emuOp_mov_word_register_IMM,
5362 /* 0xbc */ x86emuOp_mov_word_register_IMM,
5363 /* 0xbd */ x86emuOp_mov_word_register_IMM,
5364 /* 0xbe */ x86emuOp_mov_word_register_IMM,
5365 /* 0xbf */ x86emuOp_mov_word_register_IMM,
5367 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
5368 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
5369 /* 0xc2 */ x86emuOp_ret_near_IMM,
5370 /* 0xc3 */ x86emuOp_ret_near,
5371 /* 0xc4 */ x86emuOp_les_R_IMM,
5372 /* 0xc5 */ x86emuOp_lds_R_IMM,
5373 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
5374 /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
5375 /* 0xc8 */ x86emuOp_enter,
5376 /* 0xc9 */ x86emuOp_leave,
5377 /* 0xca */ x86emuOp_ret_far_IMM,
5378 /* 0xcb */ x86emuOp_ret_far,
5379 /* 0xcc */ x86emuOp_int3,
5380 /* 0xcd */ x86emuOp_int_IMM,
5381 /* 0xce */ x86emuOp_into,
5382 /* 0xcf */ x86emuOp_iret,
5384 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
5385 /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
5386 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
5387 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
5388 /* 0xd4 */ x86emuOp_aam,
5389 /* 0xd5 */ x86emuOp_aad,
5390 /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
5391 /* 0xd7 */ x86emuOp_xlat,
5392 /* 0xd8 */ NULL, /*x86emuOp_esc_coprocess_d8,*/
5393 /* 0xd9 */ NULL, /*x86emuOp_esc_coprocess_d9,*/
5394 /* 0xda */ NULL, /*x86emuOp_esc_coprocess_da,*/
5395 /* 0xdb */ NULL, /*x86emuOp_esc_coprocess_db,*/
5396 /* 0xdc */ NULL, /*x86emuOp_esc_coprocess_dc,*/
5397 /* 0xdd */ NULL, /*x86emuOp_esc_coprocess_dd,*/
5398 /* 0xde */ NULL, /*x86emuOp_esc_coprocess_de,*/
5399 /* 0xdf */ NULL, /*x86emuOp_esc_coprocess_df,*/
5401 /* 0xe0 */ x86emuOp_loopne,
5402 /* 0xe1 */ x86emuOp_loope,
5403 /* 0xe2 */ x86emuOp_loop,
5404 /* 0xe3 */ x86emuOp_jcxz,
5405 /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
5406 /* 0xe5 */ x86emuOp_in_word_AX_IMM,
5407 /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
5408 /* 0xe7 */ x86emuOp_out_word_IMM_AX,
5410 /* 0xe8 */ x86emuOp_call_near_IMM,
5411 /* 0xe9 */ x86emuOp_jump_near_IMM,
5412 /* 0xea */ x86emuOp_jump_far_IMM,
5413 /* 0xeb */ x86emuOp_jump_byte_IMM,
5414 /* 0xec */ x86emuOp_in_byte_AL_DX,
5415 /* 0xed */ x86emuOp_in_word_AX_DX,
5416 /* 0xee */ x86emuOp_out_byte_DX_AL,
5417 /* 0xef */ x86emuOp_out_word_DX_AX,
5419 /* 0xf0 */ x86emuOp_lock,
5420 /* 0xf1 */ x86emuOp_illegal_op,
5421 /* 0xf2 */ x86emuOp_repne,
5422 /* 0xf3 */ x86emuOp_repe,
5423 /* 0xf4 */ x86emuOp_halt,
5424 /* 0xf5 */ x86emuOp_cmc,
5425 /* 0xf6 */ x86emuOp_opcF6_byte_RM,
5426 /* 0xf7 */ x86emuOp_opcF7_word_RM,
5428 /* 0xf8 */ x86emuOp_clc,
5429 /* 0xf9 */ x86emuOp_stc,
5430 /* 0xfa */ x86emuOp_cli,
5431 /* 0xfb */ x86emuOp_sti,
5432 /* 0xfc */ x86emuOp_cld,
5433 /* 0xfd */ x86emuOp_std,
5434 /* 0xfe */ x86emuOp_opcFE_byte_RM,
5435 /* 0xff */ x86emuOp_opcFF_word_RM,
5438 #endif