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